blob: df5b6db5d0e893b43b07358eaf6c52dfa12433f5 [file] [log] [blame]
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001//
Geoff Langcec35902014-04-16 10:52:36 -04002// Copyright (c) 2013-2014 The ANGLE Project Authors. All rights reserved.
Geoff Lange8ebe7f2013-08-05 15:03:13 -04003// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// validationES2.cpp: Validation functions for OpenGL ES 2.0 entry point parameters
8
Geoff Lang2b5420c2014-11-19 14:20:15 -05009#include "libANGLE/validationES2.h"
Sami Väisänene45e53b2016-05-25 10:36:04 +030010
11#include <cstdint>
12
Geoff Lange8ebe7f2013-08-05 15:03:13 -040013#include "common/mathutil.h"
Sami Väisänen46eaa942016-06-29 10:26:37 +030014#include "common/string_utils.h"
Geoff Lange8ebe7f2013-08-05 15:03:13 -040015#include "common/utilities.h"
Jamie Madillef300b12016-10-07 15:12:09 -040016#include "libANGLE/Context.h"
Brandon Jones6cad5662017-06-14 13:25:13 -070017#include "libANGLE/ErrorStrings.h"
Jamie Madill2b7bbc22017-12-21 17:30:38 -050018#include "libANGLE/Fence.h"
Jamie Madillef300b12016-10-07 15:12:09 -040019#include "libANGLE/Framebuffer.h"
20#include "libANGLE/FramebufferAttachment.h"
21#include "libANGLE/Renderbuffer.h"
22#include "libANGLE/Shader.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040023#include "libANGLE/Texture.h"
Jamie Madillef300b12016-10-07 15:12:09 -040024#include "libANGLE/Uniform.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040025#include "libANGLE/VertexArray.h"
Jamie Madillef300b12016-10-07 15:12:09 -040026#include "libANGLE/formatutils.h"
27#include "libANGLE/validationES.h"
28#include "libANGLE/validationES3.h"
Geoff Lange8ebe7f2013-08-05 15:03:13 -040029
30namespace gl
31{
32
Jamie Madillc29968b2016-01-20 11:17:23 -050033namespace
34{
35
36bool IsPartialBlit(gl::Context *context,
37 const FramebufferAttachment *readBuffer,
38 const FramebufferAttachment *writeBuffer,
39 GLint srcX0,
40 GLint srcY0,
41 GLint srcX1,
42 GLint srcY1,
43 GLint dstX0,
44 GLint dstY0,
45 GLint dstX1,
46 GLint dstY1)
47{
48 const Extents &writeSize = writeBuffer->getSize();
49 const Extents &readSize = readBuffer->getSize();
50
51 if (srcX0 != 0 || srcY0 != 0 || dstX0 != 0 || dstY0 != 0 || dstX1 != writeSize.width ||
52 dstY1 != writeSize.height || srcX1 != readSize.width || srcY1 != readSize.height)
53 {
54 return true;
55 }
56
Jamie Madilldfde6ab2016-06-09 07:07:18 -070057 if (context->getGLState().isScissorTestEnabled())
Jamie Madillc29968b2016-01-20 11:17:23 -050058 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -070059 const Rectangle &scissor = context->getGLState().getScissor();
Jamie Madillc29968b2016-01-20 11:17:23 -050060 return scissor.x > 0 || scissor.y > 0 || scissor.width < writeSize.width ||
61 scissor.height < writeSize.height;
62 }
63
64 return false;
65}
66
Sami Väisänend59ca052016-06-21 16:10:00 +030067template <typename T>
68bool ValidatePathInstances(gl::Context *context,
69 GLsizei numPaths,
70 const void *paths,
71 GLuint pathBase)
72{
73 const auto *array = static_cast<const T *>(paths);
74
75 for (GLsizei i = 0; i < numPaths; ++i)
76 {
77 const GLuint pathName = array[i] + pathBase;
Brandon Jones59770802018-04-02 13:18:42 -070078 if (context->isPathGenerated(pathName) && !context->isPath(pathName))
Sami Väisänend59ca052016-06-21 16:10:00 +030079 {
Brandon Jonesafa75152017-07-21 13:11:29 -070080 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänend59ca052016-06-21 16:10:00 +030081 return false;
82 }
83 }
84 return true;
85}
86
87bool ValidateInstancedPathParameters(gl::Context *context,
88 GLsizei numPaths,
89 GLenum pathNameType,
90 const void *paths,
91 GLuint pathBase,
92 GLenum transformType,
93 const GLfloat *transformValues)
94{
95 if (!context->getExtensions().pathRendering)
96 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -050097 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänend59ca052016-06-21 16:10:00 +030098 return false;
99 }
100
101 if (paths == nullptr)
102 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500103 context->handleError(InvalidValue() << "No path name array.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300104 return false;
105 }
106
107 if (numPaths < 0)
108 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500109 context->handleError(InvalidValue() << "Invalid (negative) numPaths.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300110 return false;
111 }
112
113 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(numPaths))
114 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700115 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänend59ca052016-06-21 16:10:00 +0300116 return false;
117 }
118
119 std::uint32_t pathNameTypeSize = 0;
120 std::uint32_t componentCount = 0;
121
122 switch (pathNameType)
123 {
124 case GL_UNSIGNED_BYTE:
125 pathNameTypeSize = sizeof(GLubyte);
126 if (!ValidatePathInstances<GLubyte>(context, numPaths, paths, pathBase))
127 return false;
128 break;
129
130 case GL_BYTE:
131 pathNameTypeSize = sizeof(GLbyte);
132 if (!ValidatePathInstances<GLbyte>(context, numPaths, paths, pathBase))
133 return false;
134 break;
135
136 case GL_UNSIGNED_SHORT:
137 pathNameTypeSize = sizeof(GLushort);
138 if (!ValidatePathInstances<GLushort>(context, numPaths, paths, pathBase))
139 return false;
140 break;
141
142 case GL_SHORT:
143 pathNameTypeSize = sizeof(GLshort);
144 if (!ValidatePathInstances<GLshort>(context, numPaths, paths, pathBase))
145 return false;
146 break;
147
148 case GL_UNSIGNED_INT:
149 pathNameTypeSize = sizeof(GLuint);
150 if (!ValidatePathInstances<GLuint>(context, numPaths, paths, pathBase))
151 return false;
152 break;
153
154 case GL_INT:
155 pathNameTypeSize = sizeof(GLint);
156 if (!ValidatePathInstances<GLint>(context, numPaths, paths, pathBase))
157 return false;
158 break;
159
160 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500161 context->handleError(InvalidEnum() << "Invalid path name type.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300162 return false;
163 }
164
165 switch (transformType)
166 {
167 case GL_NONE:
168 componentCount = 0;
169 break;
170 case GL_TRANSLATE_X_CHROMIUM:
171 case GL_TRANSLATE_Y_CHROMIUM:
172 componentCount = 1;
173 break;
174 case GL_TRANSLATE_2D_CHROMIUM:
175 componentCount = 2;
176 break;
177 case GL_TRANSLATE_3D_CHROMIUM:
178 componentCount = 3;
179 break;
180 case GL_AFFINE_2D_CHROMIUM:
181 case GL_TRANSPOSE_AFFINE_2D_CHROMIUM:
182 componentCount = 6;
183 break;
184 case GL_AFFINE_3D_CHROMIUM:
185 case GL_TRANSPOSE_AFFINE_3D_CHROMIUM:
186 componentCount = 12;
187 break;
188 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500189 context->handleError(InvalidEnum() << "Invalid transformation.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300190 return false;
191 }
192 if (componentCount != 0 && transformValues == nullptr)
193 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500194 context->handleError(InvalidValue() << "No transform array given.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300195 return false;
196 }
197
198 angle::CheckedNumeric<std::uint32_t> checkedSize(0);
199 checkedSize += (numPaths * pathNameTypeSize);
200 checkedSize += (numPaths * sizeof(GLfloat) * componentCount);
201 if (!checkedSize.IsValid())
202 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700203 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänend59ca052016-06-21 16:10:00 +0300204 return false;
205 }
206
207 return true;
208}
209
Geoff Lang4f0e0032017-05-01 16:04:35 -0400210bool IsValidCopyTextureSourceInternalFormatEnum(GLenum internalFormat)
Geoff Lang97073d12016-04-20 10:42:34 -0700211{
Geoff Lang4f0e0032017-05-01 16:04:35 -0400212 // Table 1.1 from the CHROMIUM_copy_texture spec
Geoff Langca271392017-04-05 12:30:00 -0400213 switch (GetUnsizedFormat(internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -0700214 {
Geoff Lang4f0e0032017-05-01 16:04:35 -0400215 case GL_RED:
Geoff Lang97073d12016-04-20 10:42:34 -0700216 case GL_ALPHA:
217 case GL_LUMINANCE:
218 case GL_LUMINANCE_ALPHA:
219 case GL_RGB:
220 case GL_RGBA:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400221 case GL_RGB8:
222 case GL_RGBA8:
223 case GL_BGRA_EXT:
224 case GL_BGRA8_EXT:
Geoff Lang97073d12016-04-20 10:42:34 -0700225 return true;
226
Geoff Lang4f0e0032017-05-01 16:04:35 -0400227 default:
228 return false;
229 }
230}
Geoff Lang97073d12016-04-20 10:42:34 -0700231
Geoff Lang4f0e0032017-05-01 16:04:35 -0400232bool IsValidCopySubTextureSourceInternalFormat(GLenum internalFormat)
233{
234 return IsValidCopyTextureSourceInternalFormatEnum(internalFormat);
235}
236
Geoff Lang4f0e0032017-05-01 16:04:35 -0400237bool IsValidCopyTextureDestinationInternalFormatEnum(GLint internalFormat)
238{
239 // Table 1.0 from the CHROMIUM_copy_texture spec
240 switch (internalFormat)
241 {
242 case GL_RGB:
243 case GL_RGBA:
244 case GL_RGB8:
245 case GL_RGBA8:
Geoff Lang97073d12016-04-20 10:42:34 -0700246 case GL_BGRA_EXT:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400247 case GL_BGRA8_EXT:
248 case GL_SRGB_EXT:
249 case GL_SRGB_ALPHA_EXT:
250 case GL_R8:
251 case GL_R8UI:
252 case GL_RG8:
253 case GL_RG8UI:
254 case GL_SRGB8:
255 case GL_RGB565:
256 case GL_RGB8UI:
Geoff Lang6be3d4c2017-06-16 15:54:15 -0400257 case GL_RGB10_A2:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400258 case GL_SRGB8_ALPHA8:
259 case GL_RGB5_A1:
260 case GL_RGBA4:
261 case GL_RGBA8UI:
262 case GL_RGB9_E5:
263 case GL_R16F:
264 case GL_R32F:
265 case GL_RG16F:
266 case GL_RG32F:
267 case GL_RGB16F:
268 case GL_RGB32F:
269 case GL_RGBA16F:
270 case GL_RGBA32F:
271 case GL_R11F_G11F_B10F:
Brandon Jones340b7b82017-06-26 13:02:31 -0700272 case GL_LUMINANCE:
273 case GL_LUMINANCE_ALPHA:
274 case GL_ALPHA:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400275 return true;
Geoff Lang97073d12016-04-20 10:42:34 -0700276
277 default:
278 return false;
279 }
280}
281
Geoff Lang6be3d4c2017-06-16 15:54:15 -0400282bool IsValidCopySubTextureDestionationInternalFormat(GLenum internalFormat)
283{
284 return IsValidCopyTextureDestinationInternalFormatEnum(internalFormat);
285}
286
Geoff Lang97073d12016-04-20 10:42:34 -0700287bool IsValidCopyTextureDestinationFormatType(Context *context, GLint internalFormat, GLenum type)
288{
Geoff Lang4f0e0032017-05-01 16:04:35 -0400289 if (!IsValidCopyTextureDestinationInternalFormatEnum(internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -0700290 {
Brandon Jones4e6f2ae2018-09-19 11:09:51 -0700291 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang4f0e0032017-05-01 16:04:35 -0400292 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700293 }
294
Geoff Langc0094ec2017-08-16 14:16:24 -0400295 if (!ValidES3FormatCombination(GetUnsizedFormat(internalFormat), type, internalFormat))
296 {
Brandon Jones4e6f2ae2018-09-19 11:09:51 -0700297 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Langc0094ec2017-08-16 14:16:24 -0400298 return false;
299 }
300
Geoff Lang4f0e0032017-05-01 16:04:35 -0400301 const InternalFormat &internalFormatInfo = GetInternalFormatInfo(internalFormat, type);
302 if (!internalFormatInfo.textureSupport(context->getClientVersion(), context->getExtensions()))
Geoff Lang97073d12016-04-20 10:42:34 -0700303 {
Brandon Jones4e6f2ae2018-09-19 11:09:51 -0700304 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang4f0e0032017-05-01 16:04:35 -0400305 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700306 }
307
308 return true;
309}
310
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800311bool IsValidCopyTextureDestinationTargetEnum(Context *context, TextureTarget target)
Geoff Lang97073d12016-04-20 10:42:34 -0700312{
313 switch (target)
314 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800315 case TextureTarget::_2D:
316 case TextureTarget::CubeMapNegativeX:
317 case TextureTarget::CubeMapNegativeY:
318 case TextureTarget::CubeMapNegativeZ:
319 case TextureTarget::CubeMapPositiveX:
320 case TextureTarget::CubeMapPositiveY:
321 case TextureTarget::CubeMapPositiveZ:
Geoff Lang63458a32017-10-30 15:16:53 -0400322 return true;
Geoff Lang97073d12016-04-20 10:42:34 -0700323
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800324 case TextureTarget::Rectangle:
Geoff Lang63458a32017-10-30 15:16:53 -0400325 return context->getExtensions().textureRectangle;
Geoff Lang97073d12016-04-20 10:42:34 -0700326
327 default:
328 return false;
329 }
330}
331
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800332bool IsValidCopyTextureDestinationTarget(Context *context,
333 TextureType textureType,
334 TextureTarget target)
Geoff Lang63458a32017-10-30 15:16:53 -0400335{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800336 return TextureTargetToType(target) == textureType;
Geoff Lang63458a32017-10-30 15:16:53 -0400337}
338
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800339bool IsValidCopyTextureSourceTarget(Context *context, TextureType type)
Geoff Lang97073d12016-04-20 10:42:34 -0700340{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800341 switch (type)
Geoff Lang97073d12016-04-20 10:42:34 -0700342 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800343 case TextureType::_2D:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400344 return true;
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800345 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400346 return context->getExtensions().textureRectangle;
Geoff Lang4f0e0032017-05-01 16:04:35 -0400347
348 // TODO(geofflang): accept GL_TEXTURE_EXTERNAL_OES if the texture_external extension is
349 // supported
350
351 default:
352 return false;
353 }
354}
355
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800356bool IsValidCopyTextureSourceLevel(Context *context, TextureType type, GLint level)
Geoff Lang4f0e0032017-05-01 16:04:35 -0400357{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800358 if (!ValidMipLevel(context, type, level))
Geoff Lang4f0e0032017-05-01 16:04:35 -0400359 {
360 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700361 }
362
Geoff Lang4f0e0032017-05-01 16:04:35 -0400363 if (level > 0 && context->getClientVersion() < ES_3_0)
364 {
365 return false;
366 }
Geoff Lang97073d12016-04-20 10:42:34 -0700367
Geoff Lang4f0e0032017-05-01 16:04:35 -0400368 return true;
369}
370
371bool IsValidCopyTextureDestinationLevel(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800372 TextureType type,
Geoff Lang4f0e0032017-05-01 16:04:35 -0400373 GLint level,
374 GLsizei width,
Brandon Jones28783792018-03-05 09:37:32 -0800375 GLsizei height,
376 bool isSubImage)
Geoff Lang4f0e0032017-05-01 16:04:35 -0400377{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800378 if (!ValidMipLevel(context, type, level))
Geoff Lang4f0e0032017-05-01 16:04:35 -0400379 {
380 return false;
381 }
382
Brandon Jones28783792018-03-05 09:37:32 -0800383 if (!ValidImageSizeParameters(context, type, level, width, height, 1, isSubImage))
384 {
385 return false;
386 }
387
Geoff Lang4f0e0032017-05-01 16:04:35 -0400388 const Caps &caps = context->getCaps();
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800389 switch (type)
Geoff Lang4f0e0032017-05-01 16:04:35 -0400390 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800391 case TextureType::_2D:
392 return static_cast<GLuint>(width) <= (caps.max2DTextureSize >> level) &&
393 static_cast<GLuint>(height) <= (caps.max2DTextureSize >> level);
394 case TextureType::Rectangle:
395 ASSERT(level == 0);
396 return static_cast<GLuint>(width) <= (caps.max2DTextureSize >> level) &&
397 static_cast<GLuint>(height) <= (caps.max2DTextureSize >> level);
Geoff Lang4f0e0032017-05-01 16:04:35 -0400398
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800399 case TextureType::CubeMap:
400 return static_cast<GLuint>(width) <= (caps.maxCubeMapTextureSize >> level) &&
401 static_cast<GLuint>(height) <= (caps.maxCubeMapTextureSize >> level);
402 default:
403 return true;
404 }
Geoff Lang97073d12016-04-20 10:42:34 -0700405}
406
Jamie Madillc1d770e2017-04-13 17:31:24 -0400407bool IsValidStencilFunc(GLenum func)
408{
409 switch (func)
410 {
411 case GL_NEVER:
412 case GL_ALWAYS:
413 case GL_LESS:
414 case GL_LEQUAL:
415 case GL_EQUAL:
416 case GL_GEQUAL:
417 case GL_GREATER:
418 case GL_NOTEQUAL:
419 return true;
420
421 default:
422 return false;
423 }
424}
425
426bool IsValidStencilFace(GLenum face)
427{
428 switch (face)
429 {
430 case GL_FRONT:
431 case GL_BACK:
432 case GL_FRONT_AND_BACK:
433 return true;
434
435 default:
436 return false;
437 }
438}
439
440bool IsValidStencilOp(GLenum op)
441{
442 switch (op)
443 {
444 case GL_ZERO:
445 case GL_KEEP:
446 case GL_REPLACE:
447 case GL_INCR:
448 case GL_DECR:
449 case GL_INVERT:
450 case GL_INCR_WRAP:
451 case GL_DECR_WRAP:
452 return true;
453
454 default:
455 return false;
456 }
457}
458
Jamie Madill5b772312018-03-08 20:28:32 -0500459bool ValidateES2CopyTexImageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800460 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -0400461 GLint level,
462 GLenum internalformat,
463 bool isSubImage,
464 GLint xoffset,
465 GLint yoffset,
466 GLint x,
467 GLint y,
468 GLsizei width,
469 GLsizei height,
470 GLint border)
471{
472 if (!ValidTexture2DDestinationTarget(context, target))
473 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700474 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -0400475 return false;
476 }
477
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800478 TextureType texType = TextureTargetToType(target);
479 if (!ValidImageSizeParameters(context, texType, level, width, height, 1, isSubImage))
Jamie Madillbe849e42017-05-02 15:49:00 -0400480 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500481 context->handleError(InvalidValue() << "Invalid texture dimensions.");
Jamie Madillbe849e42017-05-02 15:49:00 -0400482 return false;
483 }
484
485 Format textureFormat = Format::Invalid();
486 if (!ValidateCopyTexImageParametersBase(context, target, level, internalformat, isSubImage,
487 xoffset, yoffset, 0, x, y, width, height, border,
488 &textureFormat))
489 {
490 return false;
491 }
492
493 const gl::Framebuffer *framebuffer = context->getGLState().getReadFramebuffer();
494 GLenum colorbufferFormat =
495 framebuffer->getReadColorbuffer()->getFormat().info->sizedInternalFormat;
496 const auto &formatInfo = *textureFormat.info;
497
498 // [OpenGL ES 2.0.24] table 3.9
499 if (isSubImage)
500 {
501 switch (formatInfo.format)
502 {
503 case GL_ALPHA:
504 if (colorbufferFormat != GL_ALPHA8_EXT && colorbufferFormat != GL_RGBA4 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400505 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGBA8_OES &&
506 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400507 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700508 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400509 return false;
510 }
511 break;
512 case GL_LUMINANCE:
513 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
514 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
515 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400516 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGRA8_EXT &&
517 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400518 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700519 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400520 return false;
521 }
522 break;
523 case GL_RED_EXT:
524 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
525 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
526 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
527 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_R32F &&
528 colorbufferFormat != GL_RG32F && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400529 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
530 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400531 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700532 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400533 return false;
534 }
535 break;
536 case GL_RG_EXT:
537 if (colorbufferFormat != GL_RG8_EXT && colorbufferFormat != GL_RGB565 &&
538 colorbufferFormat != GL_RGB8_OES && colorbufferFormat != GL_RGBA4 &&
539 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGBA8_OES &&
540 colorbufferFormat != GL_RG32F && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400541 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
542 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400543 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700544 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400545 return false;
546 }
547 break;
548 case GL_RGB:
549 if (colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
550 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
551 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400552 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
553 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400554 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700555 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400556 return false;
557 }
558 break;
559 case GL_LUMINANCE_ALPHA:
560 case GL_RGBA:
561 if (colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400562 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_RGBA32F &&
563 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400564 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700565 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400566 return false;
567 }
568 break;
569 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
570 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
571 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
572 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
573 case GL_ETC1_RGB8_OES:
574 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
575 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
576 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
577 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
578 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
Brandon Jones6cad5662017-06-14 13:25:13 -0700579 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400580 return false;
581 case GL_DEPTH_COMPONENT:
582 case GL_DEPTH_STENCIL_OES:
Brandon Jones6cad5662017-06-14 13:25:13 -0700583 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400584 return false;
585 default:
Brandon Jones6cad5662017-06-14 13:25:13 -0700586 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400587 return false;
588 }
589
590 if (formatInfo.type == GL_FLOAT && !context->getExtensions().textureFloat)
591 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700592 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400593 return false;
594 }
595 }
596 else
597 {
598 switch (internalformat)
599 {
600 case GL_ALPHA:
601 if (colorbufferFormat != GL_ALPHA8_EXT && colorbufferFormat != GL_RGBA4 &&
602 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_BGRA8_EXT &&
603 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGR5_A1_ANGLEX)
604 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700605 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400606 return false;
607 }
608 break;
609 case GL_LUMINANCE:
610 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
611 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
612 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
613 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
614 colorbufferFormat != GL_BGR5_A1_ANGLEX)
615 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700616 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400617 return false;
618 }
619 break;
620 case GL_RED_EXT:
621 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
622 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
623 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
624 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
625 colorbufferFormat != GL_BGR5_A1_ANGLEX)
626 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700627 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400628 return false;
629 }
630 break;
631 case GL_RG_EXT:
632 if (colorbufferFormat != GL_RG8_EXT && colorbufferFormat != GL_RGB565 &&
633 colorbufferFormat != GL_RGB8_OES && colorbufferFormat != GL_RGBA4 &&
634 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_BGRA8_EXT &&
635 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGR5_A1_ANGLEX)
636 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700637 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400638 return false;
639 }
640 break;
641 case GL_RGB:
642 if (colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
643 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
644 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
645 colorbufferFormat != GL_BGR5_A1_ANGLEX)
646 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700647 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400648 return false;
649 }
650 break;
651 case GL_LUMINANCE_ALPHA:
652 case GL_RGBA:
653 if (colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
654 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
655 colorbufferFormat != GL_BGR5_A1_ANGLEX)
656 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700657 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400658 return false;
659 }
660 break;
661 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
662 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
663 if (context->getExtensions().textureCompressionDXT1)
664 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700665 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400666 return false;
667 }
668 else
669 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700670 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400671 return false;
672 }
673 break;
674 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
675 if (context->getExtensions().textureCompressionDXT3)
676 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700677 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400678 return false;
679 }
680 else
681 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700682 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400683 return false;
684 }
685 break;
686 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
687 if (context->getExtensions().textureCompressionDXT5)
688 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700689 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400690 return false;
691 }
692 else
693 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700694 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400695 return false;
696 }
697 break;
698 case GL_ETC1_RGB8_OES:
699 if (context->getExtensions().compressedETC1RGB8Texture)
700 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500701 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -0400702 return false;
703 }
704 else
705 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500706 context->handleError(InvalidEnum());
Jamie Madillbe849e42017-05-02 15:49:00 -0400707 return false;
708 }
709 break;
710 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
711 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
712 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
713 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
714 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
715 if (context->getExtensions().lossyETCDecode)
716 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500717 context->handleError(InvalidOperation()
718 << "ETC lossy decode formats can't be copied to.");
Jamie Madillbe849e42017-05-02 15:49:00 -0400719 return false;
720 }
721 else
722 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500723 context->handleError(InvalidEnum()
724 << "ANGLE_lossy_etc_decode extension is not supported.");
Jamie Madillbe849e42017-05-02 15:49:00 -0400725 return false;
726 }
727 break;
728 case GL_DEPTH_COMPONENT:
729 case GL_DEPTH_COMPONENT16:
730 case GL_DEPTH_COMPONENT32_OES:
731 case GL_DEPTH_STENCIL_OES:
732 case GL_DEPTH24_STENCIL8_OES:
733 if (context->getExtensions().depthTextures)
734 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500735 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -0400736 return false;
737 }
738 else
739 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500740 context->handleError(InvalidEnum());
Jamie Madillbe849e42017-05-02 15:49:00 -0400741 return false;
742 }
743 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500744 context->handleError(InvalidEnum());
Jamie Madillbe849e42017-05-02 15:49:00 -0400745 return false;
746 }
747 }
748
749 // If width or height is zero, it is a no-op. Return false without setting an error.
750 return (width > 0 && height > 0);
751}
752
753bool ValidCap(const Context *context, GLenum cap, bool queryOnly)
754{
755 switch (cap)
756 {
757 // EXT_multisample_compatibility
758 case GL_MULTISAMPLE_EXT:
759 case GL_SAMPLE_ALPHA_TO_ONE_EXT:
760 return context->getExtensions().multisampleCompatibility;
761
762 case GL_CULL_FACE:
763 case GL_POLYGON_OFFSET_FILL:
764 case GL_SAMPLE_ALPHA_TO_COVERAGE:
765 case GL_SAMPLE_COVERAGE:
766 case GL_SCISSOR_TEST:
767 case GL_STENCIL_TEST:
768 case GL_DEPTH_TEST:
769 case GL_BLEND:
770 case GL_DITHER:
771 return true;
772
773 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
774 case GL_RASTERIZER_DISCARD:
775 return (context->getClientMajorVersion() >= 3);
776
777 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
778 case GL_DEBUG_OUTPUT:
779 return context->getExtensions().debug;
780
781 case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
782 return queryOnly && context->getExtensions().bindGeneratesResource;
783
784 case GL_CLIENT_ARRAYS_ANGLE:
785 return queryOnly && context->getExtensions().clientArrays;
786
787 case GL_FRAMEBUFFER_SRGB_EXT:
788 return context->getExtensions().sRGBWriteControl;
789
790 case GL_SAMPLE_MASK:
791 return context->getClientVersion() >= Version(3, 1);
792
Geoff Langb433e872017-10-05 14:01:47 -0400793 case GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
Jamie Madillbe849e42017-05-02 15:49:00 -0400794 return queryOnly && context->getExtensions().robustResourceInitialization;
795
Lingfeng Yang13b708f2018-03-21 12:14:10 -0700796 // GLES1 emulation: GLES1-specific caps
797 case GL_ALPHA_TEST:
Lingfeng Yang01074432018-04-16 10:19:51 -0700798 case GL_VERTEX_ARRAY:
799 case GL_NORMAL_ARRAY:
800 case GL_COLOR_ARRAY:
801 case GL_TEXTURE_COORD_ARRAY:
Lingfeng Yang23dc90b2018-04-23 09:01:49 -0700802 case GL_TEXTURE_2D:
Lingfeng Yangd0febe72018-05-17 22:36:52 -0700803 case GL_LIGHTING:
804 case GL_LIGHT0:
805 case GL_LIGHT1:
806 case GL_LIGHT2:
807 case GL_LIGHT3:
808 case GL_LIGHT4:
809 case GL_LIGHT5:
810 case GL_LIGHT6:
811 case GL_LIGHT7:
812 case GL_NORMALIZE:
813 case GL_RESCALE_NORMAL:
814 case GL_COLOR_MATERIAL:
Lingfeng Yang060088a2018-05-30 20:40:57 -0700815 case GL_CLIP_PLANE0:
816 case GL_CLIP_PLANE1:
817 case GL_CLIP_PLANE2:
818 case GL_CLIP_PLANE3:
819 case GL_CLIP_PLANE4:
820 case GL_CLIP_PLANE5:
Lingfeng Yang7ba3f422018-06-01 09:43:04 -0700821 case GL_FOG:
Lingfeng Yang9c4c0922018-06-13 09:29:00 -0700822 case GL_POINT_SMOOTH:
Lingfeng Yang6e5bf362018-08-15 09:53:17 -0700823 case GL_LINE_SMOOTH:
824 case GL_COLOR_LOGIC_OP:
Lingfeng Yang13b708f2018-03-21 12:14:10 -0700825 return context->getClientVersion() < Version(2, 0);
Lingfeng Yang01074432018-04-16 10:19:51 -0700826 case GL_POINT_SIZE_ARRAY_OES:
827 return context->getClientVersion() < Version(2, 0) &&
828 context->getExtensions().pointSizeArray;
Lingfeng Yang23dc90b2018-04-23 09:01:49 -0700829 case GL_TEXTURE_CUBE_MAP:
830 return context->getClientVersion() < Version(2, 0) &&
831 context->getExtensions().textureCubeMap;
Lingfeng Yang9c4c0922018-06-13 09:29:00 -0700832 case GL_POINT_SPRITE_OES:
833 return context->getClientVersion() < Version(2, 0) &&
834 context->getExtensions().pointSprite;
Jamie Madillbe849e42017-05-02 15:49:00 -0400835 default:
836 return false;
837 }
838}
839
Geoff Langfc32e8b2017-05-31 14:16:59 -0400840// Return true if a character belongs to the ASCII subset as defined in GLSL ES 1.0 spec section
841// 3.1.
Geoff Langcab92ee2017-07-19 17:32:07 -0400842bool IsValidESSLCharacter(unsigned char c)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400843{
844 // Printing characters are valid except " $ ` @ \ ' DEL.
Geoff Langcab92ee2017-07-19 17:32:07 -0400845 if (c >= 32 && c <= 126 && c != '"' && c != '$' && c != '`' && c != '@' && c != '\\' &&
846 c != '\'')
Geoff Langfc32e8b2017-05-31 14:16:59 -0400847 {
848 return true;
849 }
850
851 // Horizontal tab, line feed, vertical tab, form feed, carriage return are also valid.
852 if (c >= 9 && c <= 13)
853 {
854 return true;
855 }
856
857 return false;
858}
859
Geoff Langcab92ee2017-07-19 17:32:07 -0400860bool IsValidESSLString(const char *str, size_t len)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400861{
Geoff Langa71a98e2017-06-19 15:15:00 -0400862 for (size_t i = 0; i < len; i++)
863 {
Geoff Langcab92ee2017-07-19 17:32:07 -0400864 if (!IsValidESSLCharacter(str[i]))
Geoff Langa71a98e2017-06-19 15:15:00 -0400865 {
866 return false;
867 }
868 }
869
870 return true;
Geoff Langfc32e8b2017-05-31 14:16:59 -0400871}
872
Geoff Langcab92ee2017-07-19 17:32:07 -0400873bool IsValidESSLShaderSourceString(const char *str, size_t len, bool lineContinuationAllowed)
874{
875 enum class ParseState
876 {
877 // Have not seen an ASCII non-whitespace character yet on
878 // this line. Possible that we might see a preprocessor
879 // directive.
880 BEGINING_OF_LINE,
881
882 // Have seen at least one ASCII non-whitespace character
883 // on this line.
884 MIDDLE_OF_LINE,
885
886 // Handling a preprocessor directive. Passes through all
887 // characters up to the end of the line. Disables comment
888 // processing.
889 IN_PREPROCESSOR_DIRECTIVE,
890
891 // Handling a single-line comment. The comment text is
892 // replaced with a single space.
893 IN_SINGLE_LINE_COMMENT,
894
895 // Handling a multi-line comment. Newlines are passed
896 // through to preserve line numbers.
897 IN_MULTI_LINE_COMMENT
898 };
899
900 ParseState state = ParseState::BEGINING_OF_LINE;
901 size_t pos = 0;
902
903 while (pos < len)
904 {
905 char c = str[pos];
906 char next = pos + 1 < len ? str[pos + 1] : 0;
907
908 // Check for newlines
909 if (c == '\n' || c == '\r')
910 {
911 if (state != ParseState::IN_MULTI_LINE_COMMENT)
912 {
913 state = ParseState::BEGINING_OF_LINE;
914 }
915
916 pos++;
917 continue;
918 }
919
920 switch (state)
921 {
922 case ParseState::BEGINING_OF_LINE:
923 if (c == ' ')
924 {
925 // Maintain the BEGINING_OF_LINE state until a non-space is seen
926 pos++;
927 }
928 else if (c == '#')
929 {
930 state = ParseState::IN_PREPROCESSOR_DIRECTIVE;
931 pos++;
932 }
933 else
934 {
935 // Don't advance, re-process this character with the MIDDLE_OF_LINE state
936 state = ParseState::MIDDLE_OF_LINE;
937 }
938 break;
939
940 case ParseState::MIDDLE_OF_LINE:
941 if (c == '/' && next == '/')
942 {
943 state = ParseState::IN_SINGLE_LINE_COMMENT;
944 pos++;
945 }
946 else if (c == '/' && next == '*')
947 {
948 state = ParseState::IN_MULTI_LINE_COMMENT;
949 pos++;
950 }
951 else if (lineContinuationAllowed && c == '\\' && (next == '\n' || next == '\r'))
952 {
953 // Skip line continuation characters
954 }
955 else if (!IsValidESSLCharacter(c))
956 {
957 return false;
958 }
959 pos++;
960 break;
961
962 case ParseState::IN_PREPROCESSOR_DIRECTIVE:
Bryan Bernhart (Intel Americas Inc)335d8bf2017-10-23 15:41:43 -0700963 // Line-continuation characters may not be permitted.
964 // Otherwise, just pass it through. Do not parse comments in this state.
965 if (!lineContinuationAllowed && c == '\\')
966 {
967 return false;
968 }
Geoff Langcab92ee2017-07-19 17:32:07 -0400969 pos++;
970 break;
971
972 case ParseState::IN_SINGLE_LINE_COMMENT:
973 // Line-continuation characters are processed before comment processing.
974 // Advance string if a new line character is immediately behind
975 // line-continuation character.
976 if (c == '\\' && (next == '\n' || next == '\r'))
977 {
978 pos++;
979 }
980 pos++;
981 break;
982
983 case ParseState::IN_MULTI_LINE_COMMENT:
984 if (c == '*' && next == '/')
985 {
986 state = ParseState::MIDDLE_OF_LINE;
987 pos++;
988 }
989 pos++;
990 break;
991 }
992 }
993
994 return true;
995}
996
Jamie Madill5b772312018-03-08 20:28:32 -0500997bool ValidateWebGLNamePrefix(Context *context, const GLchar *name)
Brandon Jonesed5b46f2017-07-21 08:39:17 -0700998{
999 ASSERT(context->isWebGL());
1000
1001 // WebGL 1.0 [Section 6.16] GLSL Constructs
1002 // Identifiers starting with "webgl_" and "_webgl_" are reserved for use by WebGL.
1003 if (strncmp(name, "webgl_", 6) == 0 || strncmp(name, "_webgl_", 7) == 0)
1004 {
1005 ANGLE_VALIDATION_ERR(context, InvalidOperation(), WebglBindAttribLocationReservedPrefix);
1006 return false;
1007 }
1008
1009 return true;
1010}
1011
Jamie Madill5b772312018-03-08 20:28:32 -05001012bool ValidateWebGLNameLength(Context *context, size_t length)
Brandon Jonesed5b46f2017-07-21 08:39:17 -07001013{
1014 ASSERT(context->isWebGL());
1015
1016 if (context->isWebGL1() && length > 256)
1017 {
1018 // WebGL 1.0 [Section 6.21] Maxmimum Uniform and Attribute Location Lengths
1019 // WebGL imposes a limit of 256 characters on the lengths of uniform and attribute
1020 // locations.
1021 ANGLE_VALIDATION_ERR(context, InvalidValue(), WebglNameLengthLimitExceeded);
1022
1023 return false;
1024 }
1025 else if (length > 1024)
1026 {
1027 // WebGL 2.0 [Section 4.3.2] WebGL 2.0 imposes a limit of 1024 characters on the lengths of
1028 // uniform and attribute locations.
1029 ANGLE_VALIDATION_ERR(context, InvalidValue(), Webgl2NameLengthLimitExceeded);
1030 return false;
1031 }
1032
1033 return true;
1034}
1035
Jamie Madill007530e2017-12-28 14:27:04 -05001036bool ValidateMatrixMode(Context *context, GLenum matrixMode)
1037{
1038 if (!context->getExtensions().pathRendering)
1039 {
1040 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
1041 return false;
1042 }
1043
1044 if (matrixMode != GL_PATH_MODELVIEW_CHROMIUM && matrixMode != GL_PATH_PROJECTION_CHROMIUM)
1045 {
1046 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidMatrixMode);
1047 return false;
1048 }
1049 return true;
1050}
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03001051
1052bool ValidBlendFunc(const Context *context, GLenum val)
1053{
1054 const gl::Extensions &ext = context->getExtensions();
1055
1056 // these are always valid for src and dst.
1057 switch (val)
1058 {
1059 case GL_ZERO:
1060 case GL_ONE:
1061 case GL_SRC_COLOR:
1062 case GL_ONE_MINUS_SRC_COLOR:
1063 case GL_DST_COLOR:
1064 case GL_ONE_MINUS_DST_COLOR:
1065 case GL_SRC_ALPHA:
1066 case GL_ONE_MINUS_SRC_ALPHA:
1067 case GL_DST_ALPHA:
1068 case GL_ONE_MINUS_DST_ALPHA:
1069 case GL_CONSTANT_COLOR:
1070 case GL_ONE_MINUS_CONSTANT_COLOR:
1071 case GL_CONSTANT_ALPHA:
1072 case GL_ONE_MINUS_CONSTANT_ALPHA:
1073 return true;
1074
1075 // EXT_blend_func_extended.
1076 case GL_SRC1_COLOR_EXT:
1077 case GL_SRC1_ALPHA_EXT:
1078 case GL_ONE_MINUS_SRC1_COLOR_EXT:
1079 case GL_ONE_MINUS_SRC1_ALPHA_EXT:
1080 case GL_SRC_ALPHA_SATURATE_EXT:
1081 return ext.blendFuncExtended;
1082
1083 default:
1084 return false;
1085 }
1086}
1087
1088bool ValidSrcBlendFunc(const Context *context, GLenum val)
1089{
1090 if (ValidBlendFunc(context, val))
1091 return true;
1092
1093 if (val == GL_SRC_ALPHA_SATURATE)
1094 return true;
1095
1096 return false;
1097}
1098
1099bool ValidDstBlendFunc(const Context *context, GLenum val)
1100{
1101 if (ValidBlendFunc(context, val))
1102 return true;
1103
1104 if (val == GL_SRC_ALPHA_SATURATE)
1105 {
1106 if (context->getClientMajorVersion() >= 3)
1107 return true;
1108 }
1109
1110 return false;
1111}
1112
Jamie Madillac66f982018-10-09 18:30:01 -04001113void RecordBindTextureTypeError(Context *context, TextureType target)
1114{
1115 ASSERT(!context->getStateCache().isValidBindTextureType(target));
1116
1117 switch (target)
1118 {
1119 case TextureType::Rectangle:
1120 ASSERT(!context->getExtensions().textureRectangle);
1121 context->handleError(InvalidEnum()
1122 << "Context does not support GL_ANGLE_texture_rectangle");
1123 break;
1124
1125 case TextureType::_3D:
1126 case TextureType::_2DArray:
1127 ASSERT(context->getClientMajorVersion() < 3);
1128 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES3Required);
1129 break;
1130
1131 case TextureType::_2DMultisample:
1132 ASSERT(context->getClientVersion() < Version(3, 1));
1133 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
1134 break;
1135
1136 case TextureType::_2DMultisampleArray:
1137 ASSERT(!context->getExtensions().textureStorageMultisample2DArray);
1138 ANGLE_VALIDATION_ERR(context, InvalidEnum(), MultisampleArrayExtensionRequired);
1139 break;
1140
1141 case TextureType::External:
1142 ASSERT(!context->getExtensions().eglImageExternal &&
1143 !context->getExtensions().eglStreamConsumerExternal);
1144 context->handleError(InvalidEnum() << "External texture extension not enabled");
1145 break;
1146
1147 default:
1148 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
1149 }
1150}
Jamie Madillc29968b2016-01-20 11:17:23 -05001151} // anonymous namespace
1152
Geoff Langff5b2d52016-09-07 11:32:23 -04001153bool ValidateES2TexImageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001154 TextureTarget target,
Geoff Langff5b2d52016-09-07 11:32:23 -04001155 GLint level,
1156 GLenum internalformat,
1157 bool isCompressed,
1158 bool isSubImage,
1159 GLint xoffset,
1160 GLint yoffset,
1161 GLsizei width,
1162 GLsizei height,
1163 GLint border,
1164 GLenum format,
1165 GLenum type,
1166 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04001167 const void *pixels)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001168{
Jamie Madill6f38f822014-06-06 17:12:20 -04001169 if (!ValidTexture2DDestinationTarget(context, target))
1170 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001171 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001172 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -04001173 }
1174
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001175 TextureType texType = TextureTargetToType(target);
1176 if (!ValidImageSizeParameters(context, texType, level, width, height, 1, isSubImage))
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001177 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001178 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001179 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001180 }
1181
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001182 if (!ValidMipLevel(context, texType, level))
Brandon Jones6cad5662017-06-14 13:25:13 -07001183 {
1184 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
1185 return false;
1186 }
1187
1188 if (xoffset < 0 || std::numeric_limits<GLsizei>::max() - xoffset < width ||
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001189 std::numeric_limits<GLsizei>::max() - yoffset < height)
1190 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001191 ANGLE_VALIDATION_ERR(context, InvalidValue(), ResourceMaxTextureSize);
Geoff Langb1196682014-07-23 13:47:29 -04001192 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001193 }
1194
Geoff Lang6e898aa2017-06-02 11:17:26 -04001195 // From GL_CHROMIUM_color_buffer_float_rgb[a]:
1196 // GL_RGB[A] / GL_RGB[A]32F becomes an allowable format / internalformat parameter pair for
1197 // TexImage2D. The restriction in section 3.7.1 of the OpenGL ES 2.0 spec that the
1198 // internalformat parameter and format parameter of TexImage2D must match is lifted for this
1199 // case.
1200 bool nonEqualFormatsAllowed =
1201 (internalformat == GL_RGB32F && context->getExtensions().colorBufferFloatRGB) ||
1202 (internalformat == GL_RGBA32F && context->getExtensions().colorBufferFloatRGBA);
1203
1204 if (!isSubImage && !isCompressed && internalformat != format && !nonEqualFormatsAllowed)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001205 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001206 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001207 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001208 }
1209
Geoff Langaae65a42014-05-26 12:43:44 -04001210 const gl::Caps &caps = context->getCaps();
1211
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001212 switch (texType)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001213 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001214 case TextureType::_2D:
1215 if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
1216 static_cast<GLuint>(height) > (caps.max2DTextureSize >> level))
1217 {
1218 context->handleError(InvalidValue());
1219 return false;
1220 }
1221 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001222
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001223 case TextureType::Rectangle:
1224 ASSERT(level == 0);
1225 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1226 static_cast<GLuint>(height) > caps.maxRectangleTextureSize)
1227 {
1228 context->handleError(InvalidValue());
1229 return false;
1230 }
1231 if (isCompressed)
1232 {
1233 context->handleError(InvalidEnum()
1234 << "Rectangle texture cannot have a compressed format.");
1235 return false;
1236 }
1237 break;
1238
1239 case TextureType::CubeMap:
1240 if (!isSubImage && width != height)
1241 {
1242 ANGLE_VALIDATION_ERR(context, InvalidValue(), CubemapFacesEqualDimensions);
1243 return false;
1244 }
1245
1246 if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level) ||
1247 static_cast<GLuint>(height) > (caps.maxCubeMapTextureSize >> level))
1248 {
1249 context->handleError(InvalidValue());
1250 return false;
1251 }
1252 break;
1253
1254 default:
1255 context->handleError(InvalidEnum());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001256 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001257 }
1258
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001259 gl::Texture *texture = context->getTargetTexture(texType);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001260 if (!texture)
1261 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001262 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Geoff Langb1196682014-07-23 13:47:29 -04001263 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001264 }
1265
Geoff Langa9be0dc2014-12-17 12:34:40 -05001266 if (isSubImage)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001267 {
Geoff Langca271392017-04-05 12:30:00 -04001268 const InternalFormat &textureInternalFormat = *texture->getFormat(target, level).info;
1269 if (textureInternalFormat.internalFormat == GL_NONE)
Geoff Langc51642b2016-11-14 16:18:26 -05001270 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001271 context->handleError(InvalidOperation() << "Texture level does not exist.");
Geoff Langc51642b2016-11-14 16:18:26 -05001272 return false;
1273 }
1274
Geoff Langa9be0dc2014-12-17 12:34:40 -05001275 if (format != GL_NONE)
1276 {
Geoff Langca271392017-04-05 12:30:00 -04001277 if (GetInternalFormatInfo(format, type).sizedInternalFormat !=
1278 textureInternalFormat.sizedInternalFormat)
Geoff Langa9be0dc2014-12-17 12:34:40 -05001279 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001280 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TypeMismatch);
Geoff Langa9be0dc2014-12-17 12:34:40 -05001281 return false;
1282 }
1283 }
1284
1285 if (static_cast<size_t>(xoffset + width) > texture->getWidth(target, level) ||
1286 static_cast<size_t>(yoffset + height) > texture->getHeight(target, level))
1287 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001288 context->handleError(InvalidValue());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001289 return false;
1290 }
Geoff Langfb052642017-10-24 13:42:09 -04001291
1292 if (width > 0 && height > 0 && pixels == nullptr &&
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001293 context->getGLState().getTargetBuffer(BufferBinding::PixelUnpack) == nullptr)
Geoff Langfb052642017-10-24 13:42:09 -04001294 {
1295 ANGLE_VALIDATION_ERR(context, InvalidValue(), PixelDataNull);
1296 return false;
1297 }
Geoff Langa9be0dc2014-12-17 12:34:40 -05001298 }
1299 else
1300 {
Geoff Lang69cce582015-09-17 13:20:36 -04001301 if (texture->getImmutableFormat())
Geoff Langa9be0dc2014-12-17 12:34:40 -05001302 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001303 context->handleError(InvalidOperation());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001304 return false;
1305 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001306 }
1307
1308 // Verify zero border
1309 if (border != 0)
1310 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001311 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidBorder);
Geoff Langb1196682014-07-23 13:47:29 -04001312 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001313 }
1314
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001315 if (isCompressed)
1316 {
tmartino0ccd5ae2015-10-01 14:33:14 -04001317 GLenum actualInternalFormat =
Geoff Langca271392017-04-05 12:30:00 -04001318 isSubImage ? texture->getFormat(target, level).info->sizedInternalFormat
1319 : internalformat;
Geoff Lange88e4542018-05-03 15:05:57 -04001320
1321 const InternalFormat &internalFormatInfo = GetSizedInternalFormatInfo(actualInternalFormat);
1322
1323 if (!internalFormatInfo.compressed)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001324 {
Geoff Lange88e4542018-05-03 15:05:57 -04001325 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
1326 return false;
1327 }
1328
1329 if (!internalFormatInfo.textureSupport(context->getClientVersion(),
1330 context->getExtensions()))
1331 {
1332 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
1333 return false;
tmartino0ccd5ae2015-10-01 14:33:14 -04001334 }
Geoff Lang966c9402017-04-18 12:38:27 -04001335
1336 if (isSubImage)
tmartino0ccd5ae2015-10-01 14:33:14 -04001337 {
Geoff Lange88e4542018-05-03 15:05:57 -04001338 // From the OES_compressed_ETC1_RGB8_texture spec:
1339 // INVALID_OPERATION is generated by CompressedTexSubImage2D, TexSubImage2D, or
1340 // CopyTexSubImage2D if the texture image <level> bound to <target> has internal format
1341 // ETC1_RGB8_OES.
1342 if (actualInternalFormat == GL_ETC1_RGB8_OES)
1343 {
1344 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
1345 return false;
1346 }
1347
Geoff Lang966c9402017-04-18 12:38:27 -04001348 if (!ValidCompressedSubImageSize(context, actualInternalFormat, xoffset, yoffset, width,
1349 height, texture->getWidth(target, level),
1350 texture->getHeight(target, level)))
1351 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001352 context->handleError(InvalidOperation() << "Invalid compressed format dimension.");
Geoff Lang966c9402017-04-18 12:38:27 -04001353 return false;
1354 }
1355
1356 if (format != actualInternalFormat)
1357 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001358 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Geoff Lang966c9402017-04-18 12:38:27 -04001359 return false;
1360 }
1361 }
1362 else
1363 {
1364 if (!ValidCompressedImageSize(context, actualInternalFormat, level, width, height))
1365 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001366 context->handleError(InvalidOperation() << "Invalid compressed format dimension.");
Geoff Lang966c9402017-04-18 12:38:27 -04001367 return false;
1368 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001369 }
1370 }
1371 else
1372 {
1373 // validate <type> by itself (used as secondary key below)
1374 switch (type)
1375 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001376 case GL_UNSIGNED_BYTE:
1377 case GL_UNSIGNED_SHORT_5_6_5:
1378 case GL_UNSIGNED_SHORT_4_4_4_4:
1379 case GL_UNSIGNED_SHORT_5_5_5_1:
1380 case GL_UNSIGNED_SHORT:
1381 case GL_UNSIGNED_INT:
1382 case GL_UNSIGNED_INT_24_8_OES:
1383 case GL_HALF_FLOAT_OES:
1384 case GL_FLOAT:
1385 break;
1386 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001387 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidType);
He Yunchaoced53ae2016-11-29 15:00:51 +08001388 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001389 }
1390
1391 // validate <format> + <type> combinations
1392 // - invalid <format> -> sets INVALID_ENUM
1393 // - invalid <format>+<type> combination -> sets INVALID_OPERATION
1394 switch (format)
1395 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001396 case GL_ALPHA:
1397 case GL_LUMINANCE:
1398 case GL_LUMINANCE_ALPHA:
1399 switch (type)
1400 {
1401 case GL_UNSIGNED_BYTE:
1402 case GL_FLOAT:
1403 case GL_HALF_FLOAT_OES:
1404 break;
1405 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001406 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001407 return false;
1408 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001409 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001410 case GL_RED:
1411 case GL_RG:
1412 if (!context->getExtensions().textureRG)
1413 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001414 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001415 return false;
1416 }
1417 switch (type)
1418 {
1419 case GL_UNSIGNED_BYTE:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001420 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001421 case GL_FLOAT:
1422 case GL_HALF_FLOAT_OES:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001423 if (!context->getExtensions().textureFloat)
1424 {
1425 context->handleError(InvalidEnum());
1426 return false;
1427 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001428 break;
1429 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001430 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001431 return false;
1432 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001433 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001434 case GL_RGB:
1435 switch (type)
1436 {
1437 case GL_UNSIGNED_BYTE:
1438 case GL_UNSIGNED_SHORT_5_6_5:
1439 case GL_FLOAT:
1440 case GL_HALF_FLOAT_OES:
1441 break;
1442 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001443 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001444 return false;
1445 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001446 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001447 case GL_RGBA:
1448 switch (type)
1449 {
1450 case GL_UNSIGNED_BYTE:
1451 case GL_UNSIGNED_SHORT_4_4_4_4:
1452 case GL_UNSIGNED_SHORT_5_5_5_1:
1453 case GL_FLOAT:
1454 case GL_HALF_FLOAT_OES:
1455 break;
1456 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001457 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001458 return false;
1459 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001460 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001461 case GL_BGRA_EXT:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001462 if (!context->getExtensions().textureFormatBGRA8888)
1463 {
1464 context->handleError(InvalidEnum());
1465 return false;
1466 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001467 switch (type)
1468 {
1469 case GL_UNSIGNED_BYTE:
1470 break;
1471 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001472 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001473 return false;
1474 }
1475 break;
1476 case GL_SRGB_EXT:
1477 case GL_SRGB_ALPHA_EXT:
1478 if (!context->getExtensions().sRGB)
1479 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001480 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001481 return false;
1482 }
1483 switch (type)
1484 {
1485 case GL_UNSIGNED_BYTE:
1486 break;
1487 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001488 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001489 return false;
1490 }
1491 break;
1492 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are
1493 // handled below
1494 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1495 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1496 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1497 break;
1498 case GL_DEPTH_COMPONENT:
1499 switch (type)
1500 {
1501 case GL_UNSIGNED_SHORT:
1502 case GL_UNSIGNED_INT:
1503 break;
1504 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001505 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001506 return false;
1507 }
1508 break;
1509 case GL_DEPTH_STENCIL_OES:
1510 switch (type)
1511 {
1512 case GL_UNSIGNED_INT_24_8_OES:
1513 break;
1514 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001515 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001516 return false;
1517 }
1518 break;
1519 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001520 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001521 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001522 }
1523
1524 switch (format)
1525 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001526 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1527 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1528 if (context->getExtensions().textureCompressionDXT1)
1529 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001530 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001531 return false;
1532 }
1533 else
1534 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001535 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001536 return false;
1537 }
1538 break;
1539 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1540 if (context->getExtensions().textureCompressionDXT3)
1541 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001542 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001543 return false;
1544 }
1545 else
1546 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001547 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001548 return false;
1549 }
1550 break;
1551 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1552 if (context->getExtensions().textureCompressionDXT5)
1553 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001554 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001555 return false;
1556 }
1557 else
1558 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001559 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001560 return false;
1561 }
1562 break;
1563 case GL_ETC1_RGB8_OES:
1564 if (context->getExtensions().compressedETC1RGB8Texture)
1565 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001566 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001567 return false;
1568 }
1569 else
1570 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001571 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001572 return false;
1573 }
1574 break;
1575 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001576 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1577 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1578 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1579 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001580 if (context->getExtensions().lossyETCDecode)
1581 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001582 context->handleError(InvalidOperation()
1583 << "ETC lossy decode formats can't work with this type.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001584 return false;
1585 }
1586 else
1587 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001588 context->handleError(InvalidEnum()
1589 << "ANGLE_lossy_etc_decode extension is not supported.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001590 return false;
1591 }
1592 break;
1593 case GL_DEPTH_COMPONENT:
1594 case GL_DEPTH_STENCIL_OES:
1595 if (!context->getExtensions().depthTextures)
1596 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001597 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001598 return false;
1599 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001600 if (target != TextureTarget::_2D)
He Yunchaoced53ae2016-11-29 15:00:51 +08001601 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001602 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTargetAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001603 return false;
1604 }
1605 // OES_depth_texture supports loading depth data and multiple levels,
1606 // but ANGLE_depth_texture does not
Brandon Jonesafa75152017-07-21 13:11:29 -07001607 if (pixels != nullptr)
He Yunchaoced53ae2016-11-29 15:00:51 +08001608 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001609 ANGLE_VALIDATION_ERR(context, InvalidOperation(), PixelDataNotNull);
1610 return false;
1611 }
1612 if (level != 0)
1613 {
1614 ANGLE_VALIDATION_ERR(context, InvalidOperation(), LevelNotZero);
He Yunchaoced53ae2016-11-29 15:00:51 +08001615 return false;
1616 }
1617 break;
1618 default:
1619 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001620 }
1621
Geoff Lang6e898aa2017-06-02 11:17:26 -04001622 if (!isSubImage)
1623 {
1624 switch (internalformat)
1625 {
1626 case GL_RGBA32F:
1627 if (!context->getExtensions().colorBufferFloatRGBA)
1628 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001629 context->handleError(InvalidValue()
1630 << "Sized GL_RGBA32F internal format requires "
1631 "GL_CHROMIUM_color_buffer_float_rgba");
Geoff Lang6e898aa2017-06-02 11:17:26 -04001632 return false;
1633 }
1634 if (type != GL_FLOAT)
1635 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001636 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001637 return false;
1638 }
1639 if (format != GL_RGBA)
1640 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001641 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001642 return false;
1643 }
1644 break;
1645
1646 case GL_RGB32F:
1647 if (!context->getExtensions().colorBufferFloatRGB)
1648 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001649 context->handleError(InvalidValue()
1650 << "Sized GL_RGB32F internal format requires "
1651 "GL_CHROMIUM_color_buffer_float_rgb");
Geoff Lang6e898aa2017-06-02 11:17:26 -04001652 return false;
1653 }
1654 if (type != GL_FLOAT)
1655 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001656 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001657 return false;
1658 }
1659 if (format != GL_RGB)
1660 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001661 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001662 return false;
1663 }
1664 break;
1665
1666 default:
1667 break;
1668 }
1669 }
1670
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001671 if (type == GL_FLOAT)
1672 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001673 if (!context->getExtensions().textureFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001674 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001675 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001676 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001677 }
1678 }
1679 else if (type == GL_HALF_FLOAT_OES)
1680 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001681 if (!context->getExtensions().textureHalfFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001682 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001683 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001684 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001685 }
1686 }
1687 }
1688
Geoff Langdbcced82017-06-06 15:55:54 -04001689 GLenum sizeCheckFormat = isSubImage ? format : internalformat;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001690 if (!ValidImageDataSize(context, texType, width, height, 1, sizeCheckFormat, type, pixels,
Geoff Langff5b2d52016-09-07 11:32:23 -04001691 imageSize))
1692 {
1693 return false;
1694 }
1695
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001696 return true;
1697}
1698
He Yunchaoced53ae2016-11-29 15:00:51 +08001699bool ValidateES2TexStorageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001700 TextureType target,
He Yunchaoced53ae2016-11-29 15:00:51 +08001701 GLsizei levels,
1702 GLenum internalformat,
1703 GLsizei width,
1704 GLsizei height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001705{
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001706 if (target != TextureType::_2D && target != TextureType::CubeMap &&
1707 target != TextureType::Rectangle)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001708 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001709 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001710 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001711 }
1712
1713 if (width < 1 || height < 1 || levels < 1)
1714 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001715 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001716 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001717 }
1718
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001719 if (target == TextureType::CubeMap && width != height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001720 {
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
1725 if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1)
1726 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001727 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001728 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001729 }
1730
Geoff Langca271392017-04-05 12:30:00 -04001731 const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalformat);
Geoff Lang5d601382014-07-22 15:14:06 -04001732 if (formatInfo.format == GL_NONE || formatInfo.type == GL_NONE)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001733 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001734 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001735 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001736 }
1737
Geoff Langaae65a42014-05-26 12:43:44 -04001738 const gl::Caps &caps = context->getCaps();
1739
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001740 switch (target)
1741 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001742 case TextureType::_2D:
He Yunchaoced53ae2016-11-29 15:00:51 +08001743 if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
1744 static_cast<GLuint>(height) > caps.max2DTextureSize)
1745 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001746 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001747 return false;
1748 }
1749 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001750 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001751 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1752 static_cast<GLuint>(height) > caps.maxRectangleTextureSize || levels != 1)
1753 {
1754 context->handleError(InvalidValue());
1755 return false;
1756 }
1757 if (formatInfo.compressed)
1758 {
1759 context->handleError(InvalidEnum()
1760 << "Rectangle texture cannot have a compressed format.");
1761 return false;
1762 }
1763 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001764 case TextureType::CubeMap:
He Yunchaoced53ae2016-11-29 15:00:51 +08001765 if (static_cast<GLuint>(width) > caps.maxCubeMapTextureSize ||
1766 static_cast<GLuint>(height) > caps.maxCubeMapTextureSize)
1767 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001768 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001769 return false;
1770 }
1771 break;
1772 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001773 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001774 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001775 }
1776
Geoff Langc0b9ef42014-07-02 10:02:37 -04001777 if (levels != 1 && !context->getExtensions().textureNPOT)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001778 {
1779 if (!gl::isPow2(width) || !gl::isPow2(height))
1780 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001781 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001782 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001783 }
1784 }
1785
1786 switch (internalformat)
1787 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001788 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1789 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1790 if (!context->getExtensions().textureCompressionDXT1)
1791 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001792 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001793 return false;
1794 }
1795 break;
1796 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1797 if (!context->getExtensions().textureCompressionDXT3)
1798 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001799 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001800 return false;
1801 }
1802 break;
1803 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1804 if (!context->getExtensions().textureCompressionDXT5)
1805 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001806 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001807 return false;
1808 }
1809 break;
1810 case GL_ETC1_RGB8_OES:
1811 if (!context->getExtensions().compressedETC1RGB8Texture)
1812 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001813 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001814 return false;
1815 }
1816 break;
1817 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001818 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1819 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1820 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1821 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001822 if (!context->getExtensions().lossyETCDecode)
1823 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001824 context->handleError(InvalidEnum()
1825 << "ANGLE_lossy_etc_decode extension is not supported.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001826 return false;
1827 }
1828 break;
1829 case GL_RGBA32F_EXT:
1830 case GL_RGB32F_EXT:
1831 case GL_ALPHA32F_EXT:
1832 case GL_LUMINANCE32F_EXT:
1833 case GL_LUMINANCE_ALPHA32F_EXT:
1834 if (!context->getExtensions().textureFloat)
1835 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001836 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001837 return false;
1838 }
1839 break;
1840 case GL_RGBA16F_EXT:
1841 case GL_RGB16F_EXT:
1842 case GL_ALPHA16F_EXT:
1843 case GL_LUMINANCE16F_EXT:
1844 case GL_LUMINANCE_ALPHA16F_EXT:
1845 if (!context->getExtensions().textureHalfFloat)
1846 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001847 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001848 return false;
1849 }
1850 break;
1851 case GL_R8_EXT:
1852 case GL_RG8_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001853 if (!context->getExtensions().textureRG)
1854 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001855 context->handleError(InvalidEnum());
Geoff Lang677bb6f2017-04-05 12:40:40 -04001856 return false;
1857 }
1858 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001859 case GL_R16F_EXT:
1860 case GL_RG16F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001861 if (!context->getExtensions().textureRG || !context->getExtensions().textureHalfFloat)
1862 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001863 context->handleError(InvalidEnum());
Geoff Lang677bb6f2017-04-05 12:40:40 -04001864 return false;
1865 }
1866 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001867 case GL_R32F_EXT:
1868 case GL_RG32F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001869 if (!context->getExtensions().textureRG || !context->getExtensions().textureFloat)
He Yunchaoced53ae2016-11-29 15:00:51 +08001870 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001871 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001872 return false;
1873 }
1874 break;
1875 case GL_DEPTH_COMPONENT16:
1876 case GL_DEPTH_COMPONENT32_OES:
1877 case GL_DEPTH24_STENCIL8_OES:
1878 if (!context->getExtensions().depthTextures)
1879 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001880 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001881 return false;
1882 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001883 if (target != TextureType::_2D)
He Yunchaoced53ae2016-11-29 15:00:51 +08001884 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001885 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001886 return false;
1887 }
1888 // ANGLE_depth_texture only supports 1-level textures
1889 if (levels != 1)
1890 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001891 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001892 return false;
1893 }
1894 break;
1895 default:
1896 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001897 }
1898
Geoff Lang691e58c2014-12-19 17:03:25 -05001899 gl::Texture *texture = context->getTargetTexture(target);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001900 if (!texture || texture->id() == 0)
1901 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001902 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001903 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001904 }
1905
Geoff Lang69cce582015-09-17 13:20:36 -04001906 if (texture->getImmutableFormat())
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001907 {
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
1912 return true;
1913}
1914
He Yunchaoced53ae2016-11-29 15:00:51 +08001915bool ValidateDiscardFramebufferEXT(Context *context,
1916 GLenum target,
1917 GLsizei numAttachments,
Austin Kinross08332632015-05-05 13:35:47 -07001918 const GLenum *attachments)
1919{
Jamie Madillc29968b2016-01-20 11:17:23 -05001920 if (!context->getExtensions().discardFramebuffer)
1921 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001922 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Jamie Madillc29968b2016-01-20 11:17:23 -05001923 return false;
1924 }
1925
Austin Kinross08332632015-05-05 13:35:47 -07001926 bool defaultFramebuffer = false;
1927
1928 switch (target)
1929 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001930 case GL_FRAMEBUFFER:
1931 defaultFramebuffer =
1932 (context->getGLState().getTargetFramebuffer(GL_FRAMEBUFFER)->id() == 0);
1933 break;
1934 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001935 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
He Yunchaoced53ae2016-11-29 15:00:51 +08001936 return false;
Austin Kinross08332632015-05-05 13:35:47 -07001937 }
1938
He Yunchaoced53ae2016-11-29 15:00:51 +08001939 return ValidateDiscardFramebufferBase(context, target, numAttachments, attachments,
1940 defaultFramebuffer);
Austin Kinross08332632015-05-05 13:35:47 -07001941}
1942
Austin Kinrossbc781f32015-10-26 09:27:38 -07001943bool ValidateBindVertexArrayOES(Context *context, GLuint array)
1944{
1945 if (!context->getExtensions().vertexArrayObject)
1946 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001947 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001948 return false;
1949 }
1950
1951 return ValidateBindVertexArrayBase(context, array);
1952}
1953
Jamie Madilld7576732017-08-26 18:49:50 -04001954bool ValidateDeleteVertexArraysOES(Context *context, GLsizei n, const GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001955{
1956 if (!context->getExtensions().vertexArrayObject)
1957 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001958 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001959 return false;
1960 }
1961
Olli Etuaho41997e72016-03-10 13:38:39 +02001962 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001963}
1964
Jamie Madilld7576732017-08-26 18:49:50 -04001965bool ValidateGenVertexArraysOES(Context *context, GLsizei n, GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001966{
1967 if (!context->getExtensions().vertexArrayObject)
1968 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001969 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001970 return false;
1971 }
1972
Olli Etuaho41997e72016-03-10 13:38:39 +02001973 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001974}
1975
Jamie Madilld7576732017-08-26 18:49:50 -04001976bool ValidateIsVertexArrayOES(Context *context, GLuint array)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001977{
1978 if (!context->getExtensions().vertexArrayObject)
1979 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001980 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001981 return false;
1982 }
1983
1984 return true;
1985}
Geoff Langc5629752015-12-07 16:29:04 -05001986
1987bool ValidateProgramBinaryOES(Context *context,
1988 GLuint program,
1989 GLenum binaryFormat,
1990 const void *binary,
1991 GLint length)
1992{
1993 if (!context->getExtensions().getProgramBinary)
1994 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001995 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05001996 return false;
1997 }
1998
1999 return ValidateProgramBinaryBase(context, program, binaryFormat, binary, length);
2000}
2001
2002bool ValidateGetProgramBinaryOES(Context *context,
2003 GLuint program,
2004 GLsizei bufSize,
2005 GLsizei *length,
2006 GLenum *binaryFormat,
2007 void *binary)
2008{
2009 if (!context->getExtensions().getProgramBinary)
2010 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002011 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05002012 return false;
2013 }
2014
2015 return ValidateGetProgramBinaryBase(context, program, bufSize, length, binaryFormat, binary);
2016}
Geoff Lange102fee2015-12-10 11:23:30 -05002017
Geoff Lang70d0f492015-12-10 17:45:46 -05002018static bool ValidDebugSource(GLenum source, bool mustBeThirdPartyOrApplication)
2019{
2020 switch (source)
2021 {
2022 case GL_DEBUG_SOURCE_API:
2023 case GL_DEBUG_SOURCE_SHADER_COMPILER:
2024 case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
2025 case GL_DEBUG_SOURCE_OTHER:
2026 // Only THIRD_PARTY and APPLICATION sources are allowed to be manually inserted
2027 return !mustBeThirdPartyOrApplication;
2028
2029 case GL_DEBUG_SOURCE_THIRD_PARTY:
2030 case GL_DEBUG_SOURCE_APPLICATION:
2031 return true;
2032
2033 default:
2034 return false;
2035 }
2036}
2037
2038static bool ValidDebugType(GLenum type)
2039{
2040 switch (type)
2041 {
2042 case GL_DEBUG_TYPE_ERROR:
2043 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
2044 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
2045 case GL_DEBUG_TYPE_PERFORMANCE:
2046 case GL_DEBUG_TYPE_PORTABILITY:
2047 case GL_DEBUG_TYPE_OTHER:
2048 case GL_DEBUG_TYPE_MARKER:
2049 case GL_DEBUG_TYPE_PUSH_GROUP:
2050 case GL_DEBUG_TYPE_POP_GROUP:
2051 return true;
2052
2053 default:
2054 return false;
2055 }
2056}
2057
2058static bool ValidDebugSeverity(GLenum severity)
2059{
2060 switch (severity)
2061 {
2062 case GL_DEBUG_SEVERITY_HIGH:
2063 case GL_DEBUG_SEVERITY_MEDIUM:
2064 case GL_DEBUG_SEVERITY_LOW:
2065 case GL_DEBUG_SEVERITY_NOTIFICATION:
2066 return true;
2067
2068 default:
2069 return false;
2070 }
2071}
2072
Geoff Lange102fee2015-12-10 11:23:30 -05002073bool ValidateDebugMessageControlKHR(Context *context,
2074 GLenum source,
2075 GLenum type,
2076 GLenum severity,
2077 GLsizei count,
2078 const GLuint *ids,
2079 GLboolean enabled)
2080{
2081 if (!context->getExtensions().debug)
2082 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002083 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002084 return false;
2085 }
2086
Geoff Lang70d0f492015-12-10 17:45:46 -05002087 if (!ValidDebugSource(source, false) && source != GL_DONT_CARE)
2088 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002089 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002090 return false;
2091 }
2092
2093 if (!ValidDebugType(type) && type != GL_DONT_CARE)
2094 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002095 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05002096 return false;
2097 }
2098
2099 if (!ValidDebugSeverity(severity) && severity != GL_DONT_CARE)
2100 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002101 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSeverity);
Geoff Lang70d0f492015-12-10 17:45:46 -05002102 return false;
2103 }
2104
2105 if (count > 0)
2106 {
2107 if (source == GL_DONT_CARE || type == GL_DONT_CARE)
2108 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002109 context->handleError(
2110 InvalidOperation()
2111 << "If count is greater than zero, source and severity cannot be GL_DONT_CARE.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002112 return false;
2113 }
2114
2115 if (severity != GL_DONT_CARE)
2116 {
Jamie Madill437fa652016-05-03 15:13:24 -04002117 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002118 InvalidOperation()
2119 << "If count is greater than zero, severity must be GL_DONT_CARE.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002120 return false;
2121 }
2122 }
2123
Geoff Lange102fee2015-12-10 11:23:30 -05002124 return true;
2125}
2126
2127bool ValidateDebugMessageInsertKHR(Context *context,
2128 GLenum source,
2129 GLenum type,
2130 GLuint id,
2131 GLenum severity,
2132 GLsizei length,
2133 const GLchar *buf)
2134{
2135 if (!context->getExtensions().debug)
2136 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002137 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002138 return false;
2139 }
2140
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002141 if (!context->getGLState().getDebug().isOutputEnabled())
Geoff Lang70d0f492015-12-10 17:45:46 -05002142 {
2143 // If the DEBUG_OUTPUT state is disabled calls to DebugMessageInsert are discarded and do
2144 // not generate an error.
2145 return false;
2146 }
2147
2148 if (!ValidDebugSeverity(severity))
2149 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002150 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002151 return false;
2152 }
2153
2154 if (!ValidDebugType(type))
2155 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002156 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05002157 return false;
2158 }
2159
2160 if (!ValidDebugSource(source, true))
2161 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002162 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002163 return false;
2164 }
2165
2166 size_t messageLength = (length < 0) ? strlen(buf) : length;
2167 if (messageLength > context->getExtensions().maxDebugMessageLength)
2168 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002169 context->handleError(InvalidValue()
2170 << "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002171 return false;
2172 }
2173
Geoff Lange102fee2015-12-10 11:23:30 -05002174 return true;
2175}
2176
2177bool ValidateDebugMessageCallbackKHR(Context *context,
2178 GLDEBUGPROCKHR callback,
2179 const void *userParam)
2180{
2181 if (!context->getExtensions().debug)
2182 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002183 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002184 return false;
2185 }
2186
Geoff Lange102fee2015-12-10 11:23:30 -05002187 return true;
2188}
2189
2190bool ValidateGetDebugMessageLogKHR(Context *context,
2191 GLuint count,
2192 GLsizei bufSize,
2193 GLenum *sources,
2194 GLenum *types,
2195 GLuint *ids,
2196 GLenum *severities,
2197 GLsizei *lengths,
2198 GLchar *messageLog)
2199{
2200 if (!context->getExtensions().debug)
2201 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002202 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002203 return false;
2204 }
2205
Geoff Lang70d0f492015-12-10 17:45:46 -05002206 if (bufSize < 0 && messageLog != nullptr)
2207 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002208 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002209 return false;
2210 }
2211
Geoff Lange102fee2015-12-10 11:23:30 -05002212 return true;
2213}
2214
2215bool ValidatePushDebugGroupKHR(Context *context,
2216 GLenum source,
2217 GLuint id,
2218 GLsizei length,
2219 const GLchar *message)
2220{
2221 if (!context->getExtensions().debug)
2222 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002223 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002224 return false;
2225 }
2226
Geoff Lang70d0f492015-12-10 17:45:46 -05002227 if (!ValidDebugSource(source, true))
2228 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002229 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002230 return false;
2231 }
2232
2233 size_t messageLength = (length < 0) ? strlen(message) : length;
2234 if (messageLength > context->getExtensions().maxDebugMessageLength)
2235 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002236 context->handleError(InvalidValue()
2237 << "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002238 return false;
2239 }
2240
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002241 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002242 if (currentStackSize >= context->getExtensions().maxDebugGroupStackDepth)
2243 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002244 context
2245 ->handleError(StackOverflow()
2246 << "Cannot push more than GL_MAX_DEBUG_GROUP_STACK_DEPTH debug groups.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002247 return false;
2248 }
2249
Geoff Lange102fee2015-12-10 11:23:30 -05002250 return true;
2251}
2252
2253bool ValidatePopDebugGroupKHR(Context *context)
2254{
2255 if (!context->getExtensions().debug)
2256 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002257 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002258 return false;
2259 }
2260
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002261 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002262 if (currentStackSize <= 1)
2263 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002264 context->handleError(StackUnderflow() << "Cannot pop the default debug group.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002265 return false;
2266 }
2267
2268 return true;
2269}
2270
2271static bool ValidateObjectIdentifierAndName(Context *context, GLenum identifier, GLuint name)
2272{
2273 switch (identifier)
2274 {
2275 case GL_BUFFER:
2276 if (context->getBuffer(name) == nullptr)
2277 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002278 context->handleError(InvalidValue() << "name is not a valid buffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002279 return false;
2280 }
2281 return true;
2282
2283 case GL_SHADER:
2284 if (context->getShader(name) == nullptr)
2285 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002286 context->handleError(InvalidValue() << "name is not a valid shader.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002287 return false;
2288 }
2289 return true;
2290
2291 case GL_PROGRAM:
Jamie Madill44a6fbf2018-10-02 13:38:56 -04002292 if (context->getProgramNoResolveLink(name) == nullptr)
Geoff Lang70d0f492015-12-10 17:45:46 -05002293 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002294 context->handleError(InvalidValue() << "name is not a valid program.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002295 return false;
2296 }
2297 return true;
2298
2299 case GL_VERTEX_ARRAY:
2300 if (context->getVertexArray(name) == nullptr)
2301 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002302 context->handleError(InvalidValue() << "name is not a valid vertex array.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002303 return false;
2304 }
2305 return true;
2306
2307 case GL_QUERY:
2308 if (context->getQuery(name) == nullptr)
2309 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002310 context->handleError(InvalidValue() << "name is not a valid query.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002311 return false;
2312 }
2313 return true;
2314
2315 case GL_TRANSFORM_FEEDBACK:
2316 if (context->getTransformFeedback(name) == nullptr)
2317 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002318 context->handleError(InvalidValue() << "name is not a valid transform feedback.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002319 return false;
2320 }
2321 return true;
2322
2323 case GL_SAMPLER:
2324 if (context->getSampler(name) == nullptr)
2325 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002326 context->handleError(InvalidValue() << "name is not a valid sampler.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002327 return false;
2328 }
2329 return true;
2330
2331 case GL_TEXTURE:
2332 if (context->getTexture(name) == nullptr)
2333 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002334 context->handleError(InvalidValue() << "name is not a valid texture.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002335 return false;
2336 }
2337 return true;
2338
2339 case GL_RENDERBUFFER:
2340 if (context->getRenderbuffer(name) == nullptr)
2341 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002342 context->handleError(InvalidValue() << "name is not a valid renderbuffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002343 return false;
2344 }
2345 return true;
2346
2347 case GL_FRAMEBUFFER:
2348 if (context->getFramebuffer(name) == nullptr)
2349 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002350 context->handleError(InvalidValue() << "name is not a valid framebuffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002351 return false;
2352 }
2353 return true;
2354
2355 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002356 context->handleError(InvalidEnum() << "Invalid identifier.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002357 return false;
2358 }
Geoff Lange102fee2015-12-10 11:23:30 -05002359}
2360
Martin Radev9d901792016-07-15 15:58:58 +03002361static bool ValidateLabelLength(Context *context, GLsizei length, const GLchar *label)
2362{
2363 size_t labelLength = 0;
2364
2365 if (length < 0)
2366 {
2367 if (label != nullptr)
2368 {
2369 labelLength = strlen(label);
2370 }
2371 }
2372 else
2373 {
2374 labelLength = static_cast<size_t>(length);
2375 }
2376
2377 if (labelLength > context->getExtensions().maxLabelLength)
2378 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002379 context->handleError(InvalidValue() << "Label length is larger than GL_MAX_LABEL_LENGTH.");
Martin Radev9d901792016-07-15 15:58:58 +03002380 return false;
2381 }
2382
2383 return true;
2384}
2385
Geoff Lange102fee2015-12-10 11:23:30 -05002386bool ValidateObjectLabelKHR(Context *context,
2387 GLenum identifier,
2388 GLuint name,
2389 GLsizei length,
2390 const GLchar *label)
2391{
2392 if (!context->getExtensions().debug)
2393 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002394 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002395 return false;
2396 }
2397
Geoff Lang70d0f492015-12-10 17:45:46 -05002398 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2399 {
2400 return false;
2401 }
2402
Martin Radev9d901792016-07-15 15:58:58 +03002403 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002404 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002405 return false;
2406 }
2407
Geoff Lange102fee2015-12-10 11:23:30 -05002408 return true;
2409}
2410
2411bool ValidateGetObjectLabelKHR(Context *context,
2412 GLenum identifier,
2413 GLuint name,
2414 GLsizei bufSize,
2415 GLsizei *length,
2416 GLchar *label)
2417{
2418 if (!context->getExtensions().debug)
2419 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002420 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002421 return false;
2422 }
2423
Geoff Lang70d0f492015-12-10 17:45:46 -05002424 if (bufSize < 0)
2425 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002426 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002427 return false;
2428 }
2429
2430 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2431 {
2432 return false;
2433 }
2434
Martin Radev9d901792016-07-15 15:58:58 +03002435 return true;
Geoff Lang70d0f492015-12-10 17:45:46 -05002436}
2437
2438static bool ValidateObjectPtrName(Context *context, const void *ptr)
2439{
Jamie Madill70b5bb02017-08-28 13:32:37 -04002440 if (context->getSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr))) == nullptr)
Geoff Lang70d0f492015-12-10 17:45:46 -05002441 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002442 context->handleError(InvalidValue() << "name is not a valid sync.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002443 return false;
2444 }
2445
Geoff Lange102fee2015-12-10 11:23:30 -05002446 return true;
2447}
2448
2449bool ValidateObjectPtrLabelKHR(Context *context,
2450 const void *ptr,
2451 GLsizei length,
2452 const GLchar *label)
2453{
2454 if (!context->getExtensions().debug)
2455 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002456 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002457 return false;
2458 }
2459
Geoff Lang70d0f492015-12-10 17:45:46 -05002460 if (!ValidateObjectPtrName(context, ptr))
2461 {
2462 return false;
2463 }
2464
Martin Radev9d901792016-07-15 15:58:58 +03002465 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002466 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002467 return false;
2468 }
2469
Geoff Lange102fee2015-12-10 11:23:30 -05002470 return true;
2471}
2472
2473bool ValidateGetObjectPtrLabelKHR(Context *context,
2474 const void *ptr,
2475 GLsizei bufSize,
2476 GLsizei *length,
2477 GLchar *label)
2478{
2479 if (!context->getExtensions().debug)
2480 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002481 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002482 return false;
2483 }
2484
Geoff Lang70d0f492015-12-10 17:45:46 -05002485 if (bufSize < 0)
2486 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002487 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002488 return false;
2489 }
2490
2491 if (!ValidateObjectPtrName(context, ptr))
2492 {
2493 return false;
2494 }
2495
Martin Radev9d901792016-07-15 15:58:58 +03002496 return true;
Geoff Lange102fee2015-12-10 11:23:30 -05002497}
2498
2499bool ValidateGetPointervKHR(Context *context, GLenum pname, void **params)
2500{
2501 if (!context->getExtensions().debug)
2502 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002503 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002504 return false;
2505 }
2506
Geoff Lang70d0f492015-12-10 17:45:46 -05002507 // TODO: represent this in Context::getQueryParameterInfo.
2508 switch (pname)
2509 {
2510 case GL_DEBUG_CALLBACK_FUNCTION:
2511 case GL_DEBUG_CALLBACK_USER_PARAM:
2512 break;
2513
2514 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07002515 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Geoff Lang70d0f492015-12-10 17:45:46 -05002516 return false;
2517 }
2518
Geoff Lange102fee2015-12-10 11:23:30 -05002519 return true;
2520}
Jamie Madillc29968b2016-01-20 11:17:23 -05002521
Brandon Jonesfe4bbe62018-04-06 13:50:14 -07002522bool ValidateGetPointervRobustANGLERobustANGLE(Context *context,
2523 GLenum pname,
2524 GLsizei bufSize,
2525 GLsizei *length,
2526 void **params)
2527{
2528 UNIMPLEMENTED();
2529 return false;
2530}
2531
Jamie Madillc29968b2016-01-20 11:17:23 -05002532bool ValidateBlitFramebufferANGLE(Context *context,
2533 GLint srcX0,
2534 GLint srcY0,
2535 GLint srcX1,
2536 GLint srcY1,
2537 GLint dstX0,
2538 GLint dstY0,
2539 GLint dstX1,
2540 GLint dstY1,
2541 GLbitfield mask,
2542 GLenum filter)
2543{
2544 if (!context->getExtensions().framebufferBlit)
2545 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03002546 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BlitExtensionNotAvailable);
Jamie Madillc29968b2016-01-20 11:17:23 -05002547 return false;
2548 }
2549
2550 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
2551 {
2552 // TODO(jmadill): Determine if this should be available on other implementations.
Olli Etuahof0e3c192018-08-15 13:37:21 +03002553 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BlitExtensionScaleOrFlip);
Jamie Madillc29968b2016-01-20 11:17:23 -05002554 return false;
2555 }
2556
2557 if (filter == GL_LINEAR)
2558 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03002559 ANGLE_VALIDATION_ERR(context, InvalidEnum(), BlitExtensionLinear);
Jamie Madillc29968b2016-01-20 11:17:23 -05002560 return false;
2561 }
2562
Jamie Madill51f40ec2016-06-15 14:06:00 -04002563 Framebuffer *readFramebuffer = context->getGLState().getReadFramebuffer();
2564 Framebuffer *drawFramebuffer = context->getGLState().getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002565
2566 if (mask & GL_COLOR_BUFFER_BIT)
2567 {
2568 const FramebufferAttachment *readColorAttachment = readFramebuffer->getReadColorbuffer();
2569 const FramebufferAttachment *drawColorAttachment = drawFramebuffer->getFirstColorbuffer();
2570
2571 if (readColorAttachment && drawColorAttachment)
2572 {
2573 if (!(readColorAttachment->type() == GL_TEXTURE &&
Jamie Madillcc129372018-04-12 09:13:18 -04002574 readColorAttachment->getTextureImageIndex().getType() == TextureType::_2D) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002575 readColorAttachment->type() != GL_RENDERBUFFER &&
2576 readColorAttachment->type() != GL_FRAMEBUFFER_DEFAULT)
2577 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03002578 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
2579 BlitExtensionFromInvalidAttachmentType);
Jamie Madillc29968b2016-01-20 11:17:23 -05002580 return false;
2581 }
2582
Geoff Langa15472a2015-08-11 11:48:03 -04002583 for (size_t drawbufferIdx = 0;
2584 drawbufferIdx < drawFramebuffer->getDrawbufferStateCount(); ++drawbufferIdx)
Jamie Madillc29968b2016-01-20 11:17:23 -05002585 {
Geoff Langa15472a2015-08-11 11:48:03 -04002586 const FramebufferAttachment *attachment =
2587 drawFramebuffer->getDrawBuffer(drawbufferIdx);
2588 if (attachment)
Jamie Madillc29968b2016-01-20 11:17:23 -05002589 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002590 if (!(attachment->type() == GL_TEXTURE &&
Jamie Madillcc129372018-04-12 09:13:18 -04002591 attachment->getTextureImageIndex().getType() == TextureType::_2D) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002592 attachment->type() != GL_RENDERBUFFER &&
2593 attachment->type() != GL_FRAMEBUFFER_DEFAULT)
2594 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03002595 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
2596 BlitExtensionToInvalidAttachmentType);
Jamie Madillc29968b2016-01-20 11:17:23 -05002597 return false;
2598 }
2599
2600 // Return an error if the destination formats do not match
Kenneth Russell69382852017-07-21 16:38:44 -04002601 if (!Format::EquivalentForBlit(attachment->getFormat(),
2602 readColorAttachment->getFormat()))
Jamie Madillc29968b2016-01-20 11:17:23 -05002603 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03002604 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
2605 BlitExtensionFormatMismatch);
Jamie Madillc29968b2016-01-20 11:17:23 -05002606 return false;
2607 }
2608 }
2609 }
2610
Jamie Madill427064d2018-04-13 16:20:34 -04002611 GLint samples = readFramebuffer->getSamples(context);
Jamie Madille98b1b52018-03-08 09:47:23 -05002612 if (samples != 0 &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002613 IsPartialBlit(context, readColorAttachment, drawColorAttachment, srcX0, srcY0,
2614 srcX1, srcY1, dstX0, dstY0, dstX1, dstY1))
2615 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03002616 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
2617 BlitExtensionMultisampledWholeBufferBlit);
Jamie Madillc29968b2016-01-20 11:17:23 -05002618 return false;
2619 }
2620 }
2621 }
2622
2623 GLenum masks[] = {GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT};
2624 GLenum attachments[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
2625 for (size_t i = 0; i < 2; i++)
2626 {
2627 if (mask & masks[i])
2628 {
2629 const FramebufferAttachment *readBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002630 readFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002631 const FramebufferAttachment *drawBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002632 drawFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002633
2634 if (readBuffer && drawBuffer)
2635 {
2636 if (IsPartialBlit(context, readBuffer, drawBuffer, srcX0, srcY0, srcX1, srcY1,
2637 dstX0, dstY0, dstX1, dstY1))
2638 {
2639 // only whole-buffer copies are permitted
Olli Etuahof0e3c192018-08-15 13:37:21 +03002640 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
2641 BlitExtensionDepthStencilWholeBufferBlit);
Jamie Madillc29968b2016-01-20 11:17:23 -05002642 return false;
2643 }
2644
2645 if (readBuffer->getSamples() != 0 || drawBuffer->getSamples() != 0)
2646 {
Olli Etuahof0e3c192018-08-15 13:37:21 +03002647 ANGLE_VALIDATION_ERR(context, InvalidOperation(),
2648 BlitExtensionMultisampledDepthOrStencil);
Jamie Madillc29968b2016-01-20 11:17:23 -05002649 return false;
2650 }
2651 }
2652 }
2653 }
2654
2655 return ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0,
2656 dstX1, dstY1, mask, filter);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04002657}
Jamie Madillc29968b2016-01-20 11:17:23 -05002658
Jamie Madill5b772312018-03-08 20:28:32 -05002659bool ValidateClear(Context *context, GLbitfield mask)
Jamie Madillc29968b2016-01-20 11:17:23 -05002660{
Lingfeng Yang6e5bf362018-08-15 09:53:17 -07002661 Framebuffer *fbo = context->getGLState().getDrawFramebuffer();
Olli Etuaho94c91a92018-07-19 15:10:24 +03002662 const Extensions &extensions = context->getExtensions();
Jamie Madille98b1b52018-03-08 09:47:23 -05002663
Jamie Madill427064d2018-04-13 16:20:34 -04002664 if (!ValidateFramebufferComplete(context, fbo))
Jamie Madillc29968b2016-01-20 11:17:23 -05002665 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002666 return false;
2667 }
2668
2669 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
2670 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002671 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidClearMask);
Jamie Madillc29968b2016-01-20 11:17:23 -05002672 return false;
2673 }
2674
Olli Etuaho94c91a92018-07-19 15:10:24 +03002675 if (extensions.webglCompatibility && (mask & GL_COLOR_BUFFER_BIT) != 0)
Geoff Lang76e65652017-03-27 14:58:02 -04002676 {
2677 constexpr GLenum validComponentTypes[] = {GL_FLOAT, GL_UNSIGNED_NORMALIZED,
2678 GL_SIGNED_NORMALIZED};
2679
Corentin Wallez59c41592017-07-11 13:19:54 -04002680 for (GLuint drawBufferIdx = 0; drawBufferIdx < fbo->getDrawbufferStateCount();
Geoff Lang76e65652017-03-27 14:58:02 -04002681 drawBufferIdx++)
2682 {
2683 if (!ValidateWebGLFramebufferAttachmentClearType(
2684 context, drawBufferIdx, validComponentTypes, ArraySize(validComponentTypes)))
2685 {
2686 return false;
2687 }
2688 }
2689 }
2690
Olli Etuaho94c91a92018-07-19 15:10:24 +03002691 if (extensions.multiview && extensions.disjointTimerQuery)
2692 {
2693 const State &state = context->getGLState();
2694 Framebuffer *framebuffer = state.getDrawFramebuffer();
2695 if (framebuffer->getNumViews() > 1 && state.isQueryActive(QueryType::TimeElapsed))
2696 {
2697 context->handleError(InvalidOperation() << "There is an active query for target "
2698 "GL_TIME_ELAPSED_EXT when the number of "
2699 "views in the active draw framebuffer is "
2700 "greater than 1.");
2701 return false;
2702 }
2703 }
2704
Jamie Madillc29968b2016-01-20 11:17:23 -05002705 return true;
2706}
2707
Jamie Madill5b772312018-03-08 20:28:32 -05002708bool ValidateDrawBuffersEXT(Context *context, GLsizei n, const GLenum *bufs)
Jamie Madillc29968b2016-01-20 11:17:23 -05002709{
2710 if (!context->getExtensions().drawBuffers)
2711 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002712 context->handleError(InvalidOperation() << "Extension not supported.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002713 return false;
2714 }
2715
2716 return ValidateDrawBuffersBase(context, n, bufs);
2717}
2718
Jamie Madill73a84962016-02-12 09:27:23 -05002719bool ValidateTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002720 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002721 GLint level,
2722 GLint internalformat,
2723 GLsizei width,
2724 GLsizei height,
2725 GLint border,
2726 GLenum format,
2727 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002728 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002729{
Martin Radev1be913c2016-07-11 17:59:16 +03002730 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002731 {
2732 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
Geoff Langff5b2d52016-09-07 11:32:23 -04002733 0, 0, width, height, border, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002734 }
2735
Martin Radev1be913c2016-07-11 17:59:16 +03002736 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002737 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002738 0, 0, width, height, 1, border, format, type, -1,
2739 pixels);
2740}
2741
Brandon Jones416aaf92018-04-10 08:10:16 -07002742bool ValidateTexImage2DRobustANGLE(Context *context,
2743 TextureTarget target,
2744 GLint level,
2745 GLint internalformat,
2746 GLsizei width,
2747 GLsizei height,
2748 GLint border,
2749 GLenum format,
2750 GLenum type,
2751 GLsizei bufSize,
2752 const void *pixels)
Geoff Langff5b2d52016-09-07 11:32:23 -04002753{
2754 if (!ValidateRobustEntryPoint(context, bufSize))
2755 {
2756 return false;
2757 }
2758
2759 if (context->getClientMajorVersion() < 3)
2760 {
2761 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
2762 0, 0, width, height, border, format, type, bufSize,
2763 pixels);
2764 }
2765
2766 ASSERT(context->getClientMajorVersion() >= 3);
2767 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
2768 0, 0, width, height, 1, border, format, type, bufSize,
2769 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002770}
2771
2772bool ValidateTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002773 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002774 GLint level,
2775 GLint xoffset,
2776 GLint yoffset,
2777 GLsizei width,
2778 GLsizei height,
2779 GLenum format,
2780 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002781 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002782{
2783
Martin Radev1be913c2016-07-11 17:59:16 +03002784 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002785 {
2786 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002787 yoffset, width, height, 0, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002788 }
2789
Martin Radev1be913c2016-07-11 17:59:16 +03002790 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002791 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002792 yoffset, 0, width, height, 1, 0, format, type, -1,
2793 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002794}
2795
Geoff Langc52f6f12016-10-14 10:18:00 -04002796bool ValidateTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002797 TextureTarget target,
Geoff Langc52f6f12016-10-14 10:18:00 -04002798 GLint level,
2799 GLint xoffset,
2800 GLint yoffset,
2801 GLsizei width,
2802 GLsizei height,
2803 GLenum format,
2804 GLenum type,
2805 GLsizei bufSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002806 const void *pixels)
Geoff Langc52f6f12016-10-14 10:18:00 -04002807{
2808 if (!ValidateRobustEntryPoint(context, bufSize))
2809 {
2810 return false;
2811 }
2812
2813 if (context->getClientMajorVersion() < 3)
2814 {
2815 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
2816 yoffset, width, height, 0, format, type, bufSize,
2817 pixels);
2818 }
2819
2820 ASSERT(context->getClientMajorVersion() >= 3);
2821 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
2822 yoffset, 0, width, height, 1, 0, format, type, bufSize,
2823 pixels);
2824}
2825
Jamie Madill73a84962016-02-12 09:27:23 -05002826bool ValidateCompressedTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002827 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002828 GLint level,
2829 GLenum internalformat,
2830 GLsizei width,
2831 GLsizei height,
2832 GLint border,
2833 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002834 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002835{
Martin Radev1be913c2016-07-11 17:59:16 +03002836 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002837 {
2838 if (!ValidateES2TexImageParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002839 0, width, height, border, GL_NONE, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002840 {
2841 return false;
2842 }
2843 }
2844 else
2845 {
Martin Radev1be913c2016-07-11 17:59:16 +03002846 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002847 if (!ValidateES3TexImage2DParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002848 0, 0, width, height, 1, border, GL_NONE, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002849 data))
2850 {
2851 return false;
2852 }
2853 }
2854
Geoff Langca271392017-04-05 12:30:00 -04002855 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalformat);
Jamie Madillca2ff382018-07-11 09:01:17 -04002856
2857 GLuint blockSize = 0;
2858 if (!formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1), &blockSize))
Jamie Madille2e406c2016-06-02 13:04:10 -04002859 {
Jamie Madillca2ff382018-07-11 09:01:17 -04002860 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Jamie Madille2e406c2016-06-02 13:04:10 -04002861 return false;
2862 }
2863
Jamie Madillca2ff382018-07-11 09:01:17 -04002864 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSize)
Jamie Madill73a84962016-02-12 09:27:23 -05002865 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002866 ANGLE_VALIDATION_ERR(context, InvalidValue(), CompressedTextureDimensionsMustMatchData);
Jamie Madill73a84962016-02-12 09:27:23 -05002867 return false;
2868 }
2869
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002870 if (target == TextureTarget::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002871 {
2872 context->handleError(InvalidEnum() << "Rectangle texture cannot have a compressed format.");
2873 return false;
2874 }
2875
Jamie Madill73a84962016-02-12 09:27:23 -05002876 return true;
2877}
2878
Corentin Wallezb2931602017-04-11 15:58:57 -04002879bool ValidateCompressedTexImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002880 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04002881 GLint level,
2882 GLenum internalformat,
2883 GLsizei width,
2884 GLsizei height,
2885 GLint border,
2886 GLsizei imageSize,
2887 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002888 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002889{
2890 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2891 {
2892 return false;
2893 }
2894
2895 return ValidateCompressedTexImage2D(context, target, level, internalformat, width, height,
2896 border, imageSize, data);
2897}
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002898
Corentin Wallezb2931602017-04-11 15:58:57 -04002899bool ValidateCompressedTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002900 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04002901 GLint level,
2902 GLint xoffset,
2903 GLint yoffset,
2904 GLsizei width,
2905 GLsizei height,
2906 GLenum format,
2907 GLsizei imageSize,
2908 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002909 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002910{
2911 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2912 {
2913 return false;
2914 }
2915
2916 return ValidateCompressedTexSubImage2D(context, target, level, xoffset, yoffset, width, height,
2917 format, imageSize, data);
2918}
2919
Jamie Madill73a84962016-02-12 09:27:23 -05002920bool ValidateCompressedTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002921 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002922 GLint level,
2923 GLint xoffset,
2924 GLint yoffset,
2925 GLsizei width,
2926 GLsizei height,
2927 GLenum format,
2928 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002929 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002930{
Martin Radev1be913c2016-07-11 17:59:16 +03002931 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002932 {
2933 if (!ValidateES2TexImageParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002934 yoffset, width, height, 0, format, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002935 {
2936 return false;
2937 }
2938 }
2939 else
2940 {
Martin Radev1be913c2016-07-11 17:59:16 +03002941 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002942 if (!ValidateES3TexImage2DParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002943 yoffset, 0, width, height, 1, 0, format, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002944 data))
2945 {
2946 return false;
2947 }
2948 }
2949
Geoff Langca271392017-04-05 12:30:00 -04002950 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(format);
Jamie Madillca2ff382018-07-11 09:01:17 -04002951 GLuint blockSize = 0;
2952 if (!formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1), &blockSize))
Jamie Madille2e406c2016-06-02 13:04:10 -04002953 {
Jamie Madillca2ff382018-07-11 09:01:17 -04002954 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Jamie Madille2e406c2016-06-02 13:04:10 -04002955 return false;
2956 }
2957
Jamie Madillca2ff382018-07-11 09:01:17 -04002958 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSize)
Jamie Madill73a84962016-02-12 09:27:23 -05002959 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002960 context->handleError(InvalidValue());
Jamie Madill73a84962016-02-12 09:27:23 -05002961 return false;
2962 }
2963
2964 return true;
2965}
2966
Corentin Wallez336129f2017-10-17 15:55:40 -04002967bool ValidateGetBufferPointervOES(Context *context,
2968 BufferBinding target,
2969 GLenum pname,
2970 void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03002971{
Geoff Lang496c02d2016-10-20 11:38:11 -07002972 return ValidateGetBufferPointervBase(context, target, pname, nullptr, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03002973}
2974
Corentin Wallez336129f2017-10-17 15:55:40 -04002975bool ValidateMapBufferOES(Context *context, BufferBinding target, GLenum access)
Olli Etuaho4f667482016-03-30 15:56:35 +03002976{
2977 if (!context->getExtensions().mapBuffer)
2978 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002979 context->handleError(InvalidOperation() << "Map buffer extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002980 return false;
2981 }
2982
Corentin Walleze4477002017-12-01 14:39:58 -05002983 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03002984 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002985 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03002986 return false;
2987 }
2988
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002989 Buffer *buffer = context->getGLState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002990
2991 if (buffer == nullptr)
2992 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002993 context->handleError(InvalidOperation() << "Attempted to map buffer object zero.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002994 return false;
2995 }
2996
2997 if (access != GL_WRITE_ONLY_OES)
2998 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002999 context->handleError(InvalidEnum() << "Non-write buffer mapping not supported.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003000 return false;
3001 }
3002
3003 if (buffer->isMapped())
3004 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003005 context->handleError(InvalidOperation() << "Buffer is already mapped.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003006 return false;
3007 }
3008
Geoff Lang79f71042017-08-14 16:43:43 -04003009 return ValidateMapBufferBase(context, target);
Olli Etuaho4f667482016-03-30 15:56:35 +03003010}
3011
Corentin Wallez336129f2017-10-17 15:55:40 -04003012bool ValidateUnmapBufferOES(Context *context, BufferBinding target)
Olli Etuaho4f667482016-03-30 15:56:35 +03003013{
3014 if (!context->getExtensions().mapBuffer)
3015 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003016 context->handleError(InvalidOperation() << "Map buffer extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003017 return false;
3018 }
3019
3020 return ValidateUnmapBufferBase(context, target);
3021}
3022
3023bool ValidateMapBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04003024 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03003025 GLintptr offset,
3026 GLsizeiptr length,
3027 GLbitfield access)
3028{
3029 if (!context->getExtensions().mapBufferRange)
3030 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003031 context->handleError(InvalidOperation() << "Map buffer range extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003032 return false;
3033 }
3034
3035 return ValidateMapBufferRangeBase(context, target, offset, length, access);
3036}
3037
Corentin Wallez336129f2017-10-17 15:55:40 -04003038bool ValidateMapBufferBase(Context *context, BufferBinding target)
Geoff Lang79f71042017-08-14 16:43:43 -04003039{
3040 Buffer *buffer = context->getGLState().getTargetBuffer(target);
3041 ASSERT(buffer != nullptr);
3042
3043 // Check if this buffer is currently being used as a transform feedback output buffer
3044 TransformFeedback *transformFeedback = context->getGLState().getCurrentTransformFeedback();
3045 if (transformFeedback != nullptr && transformFeedback->isActive())
3046 {
3047 for (size_t i = 0; i < transformFeedback->getIndexedBufferCount(); i++)
3048 {
3049 const auto &transformFeedbackBuffer = transformFeedback->getIndexedBuffer(i);
3050 if (transformFeedbackBuffer.get() == buffer)
3051 {
3052 context->handleError(InvalidOperation()
3053 << "Buffer is currently bound for transform feedback.");
3054 return false;
3055 }
3056 }
3057 }
3058
James Darpiniane8a93c62018-01-04 18:02:24 -08003059 if (context->getExtensions().webglCompatibility &&
3060 buffer->isBoundForTransformFeedbackAndOtherUse())
3061 {
3062 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
3063 return false;
3064 }
3065
Geoff Lang79f71042017-08-14 16:43:43 -04003066 return true;
3067}
3068
Olli Etuaho4f667482016-03-30 15:56:35 +03003069bool ValidateFlushMappedBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04003070 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03003071 GLintptr offset,
3072 GLsizeiptr length)
3073{
3074 if (!context->getExtensions().mapBufferRange)
3075 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003076 context->handleError(InvalidOperation() << "Map buffer range extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03003077 return false;
3078 }
3079
3080 return ValidateFlushMappedBufferRangeBase(context, target, offset, length);
3081}
3082
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003083bool ValidateBindTexture(Context *context, TextureType target, GLuint texture)
Ian Ewell54f87462016-03-10 13:47:21 -05003084{
Jamie Madillac66f982018-10-09 18:30:01 -04003085 if (!context->getStateCache().isValidBindTextureType(target))
Ian Ewell54f87462016-03-10 13:47:21 -05003086 {
Jamie Madillac66f982018-10-09 18:30:01 -04003087 RecordBindTextureTypeError(context, target);
3088 return false;
Ian Ewell54f87462016-03-10 13:47:21 -05003089 }
3090
Jamie Madill0fdb9562018-09-17 17:18:43 -04003091 if (texture == 0)
3092 {
3093 return true;
3094 }
3095
3096 Texture *textureObject = context->getTexture(texture);
3097 if (textureObject && textureObject->getType() != target)
3098 {
3099 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TypeMismatch);
3100 return false;
3101 }
3102
3103 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
3104 !context->isTextureGenerated(texture))
3105 {
3106 context->handleError(InvalidOperation() << "Texture was not generated");
3107 return false;
3108 }
3109
Ian Ewell54f87462016-03-10 13:47:21 -05003110 return true;
3111}
3112
Geoff Langd8605522016-04-13 10:19:12 -04003113bool ValidateBindUniformLocationCHROMIUM(Context *context,
3114 GLuint program,
3115 GLint location,
3116 const GLchar *name)
3117{
3118 if (!context->getExtensions().bindUniformLocation)
3119 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003120 context->handleError(InvalidOperation()
3121 << "GL_CHROMIUM_bind_uniform_location is not available.");
Geoff Langd8605522016-04-13 10:19:12 -04003122 return false;
3123 }
3124
3125 Program *programObject = GetValidProgram(context, program);
3126 if (!programObject)
3127 {
3128 return false;
3129 }
3130
3131 if (location < 0)
3132 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003133 context->handleError(InvalidValue() << "Location cannot be less than 0.");
Geoff Langd8605522016-04-13 10:19:12 -04003134 return false;
3135 }
3136
3137 const Caps &caps = context->getCaps();
3138 if (static_cast<size_t>(location) >=
3139 (caps.maxVertexUniformVectors + caps.maxFragmentUniformVectors) * 4)
3140 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003141 context->handleError(InvalidValue() << "Location must be less than "
3142 "(MAX_VERTEX_UNIFORM_VECTORS + "
3143 "MAX_FRAGMENT_UNIFORM_VECTORS) * 4");
Geoff Langd8605522016-04-13 10:19:12 -04003144 return false;
3145 }
3146
Geoff Langfc32e8b2017-05-31 14:16:59 -04003147 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
3148 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04003149 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04003150 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003151 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04003152 return false;
3153 }
3154
Geoff Langd8605522016-04-13 10:19:12 -04003155 if (strncmp(name, "gl_", 3) == 0)
3156 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003157 ANGLE_VALIDATION_ERR(context, InvalidValue(), NameBeginsWithGL);
Geoff Langd8605522016-04-13 10:19:12 -04003158 return false;
3159 }
3160
3161 return true;
3162}
3163
Jamie Madille2e406c2016-06-02 13:04:10 -04003164bool ValidateCoverageModulationCHROMIUM(Context *context, GLenum components)
Sami Väisänena797e062016-05-12 15:23:40 +03003165{
3166 if (!context->getExtensions().framebufferMixedSamples)
3167 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003168 context->handleError(InvalidOperation()
3169 << "GL_CHROMIUM_framebuffer_mixed_samples is not available.");
Sami Väisänena797e062016-05-12 15:23:40 +03003170 return false;
3171 }
3172 switch (components)
3173 {
3174 case GL_RGB:
3175 case GL_RGBA:
3176 case GL_ALPHA:
3177 case GL_NONE:
3178 break;
3179 default:
3180 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003181 InvalidEnum()
3182 << "GLenum components is not one of GL_RGB, GL_RGBA, GL_ALPHA or GL_NONE.");
Sami Väisänena797e062016-05-12 15:23:40 +03003183 return false;
3184 }
3185
3186 return true;
3187}
3188
Sami Väisänene45e53b2016-05-25 10:36:04 +03003189// CHROMIUM_path_rendering
3190
Jamie Madill007530e2017-12-28 14:27:04 -05003191bool ValidateMatrixLoadfCHROMIUM(Context *context, GLenum matrixMode, const GLfloat *matrix)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003192{
Jamie Madill007530e2017-12-28 14:27:04 -05003193 if (!ValidateMatrixMode(context, matrixMode))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003194 {
Sami Väisänene45e53b2016-05-25 10:36:04 +03003195 return false;
3196 }
Jamie Madill007530e2017-12-28 14:27:04 -05003197
Sami Väisänene45e53b2016-05-25 10:36:04 +03003198 if (matrix == nullptr)
3199 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003200 context->handleError(InvalidOperation() << "Invalid matrix.");
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 return true;
3205}
3206
Jamie Madill007530e2017-12-28 14:27:04 -05003207bool ValidateMatrixLoadIdentityCHROMIUM(Context *context, GLenum matrixMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003208{
Jamie Madill007530e2017-12-28 14:27:04 -05003209 return ValidateMatrixMode(context, matrixMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003210}
3211
Jamie Madill007530e2017-12-28 14:27:04 -05003212bool ValidateGenPathsCHROMIUM(Context *context, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003213{
3214 if (!context->getExtensions().pathRendering)
3215 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003216 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003217 return false;
3218 }
3219
3220 // range = 0 is undefined in NV_path_rendering.
3221 // we add stricter semantic check here and require a non zero positive range.
3222 if (range <= 0)
3223 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003224 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003225 return false;
3226 }
3227
3228 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range))
3229 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003230 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003231 return false;
3232 }
3233
3234 return true;
3235}
3236
Jamie Madill007530e2017-12-28 14:27:04 -05003237bool ValidateDeletePathsCHROMIUM(Context *context, GLuint path, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003238{
3239 if (!context->getExtensions().pathRendering)
3240 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003241 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003242 return false;
3243 }
3244
3245 // range = 0 is undefined in NV_path_rendering.
3246 // we add stricter semantic check here and require a non zero positive range.
3247 if (range <= 0)
3248 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003249 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003250 return false;
3251 }
3252
3253 angle::CheckedNumeric<std::uint32_t> checkedRange(path);
3254 checkedRange += range;
3255
3256 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range) || !checkedRange.IsValid())
3257 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003258 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003259 return false;
3260 }
3261 return true;
3262}
3263
Jamie Madill007530e2017-12-28 14:27:04 -05003264bool ValidatePathCommandsCHROMIUM(Context *context,
3265 GLuint path,
3266 GLsizei numCommands,
3267 const GLubyte *commands,
3268 GLsizei numCoords,
3269 GLenum coordType,
3270 const void *coords)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003271{
3272 if (!context->getExtensions().pathRendering)
3273 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003274 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003275 return false;
3276 }
Brandon Jones59770802018-04-02 13:18:42 -07003277 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003278 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003279 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003280 return false;
3281 }
3282
3283 if (numCommands < 0)
3284 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003285 context->handleError(InvalidValue() << "Invalid number of commands.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003286 return false;
3287 }
3288 else if (numCommands > 0)
3289 {
3290 if (!commands)
3291 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003292 context->handleError(InvalidValue() << "No commands array given.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003293 return false;
3294 }
3295 }
3296
3297 if (numCoords < 0)
3298 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003299 context->handleError(InvalidValue() << "Invalid number of coordinates.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003300 return false;
3301 }
3302 else if (numCoords > 0)
3303 {
3304 if (!coords)
3305 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003306 context->handleError(InvalidValue() << "No coordinate array given.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003307 return false;
3308 }
3309 }
3310
3311 std::uint32_t coordTypeSize = 0;
3312 switch (coordType)
3313 {
3314 case GL_BYTE:
3315 coordTypeSize = sizeof(GLbyte);
3316 break;
3317
3318 case GL_UNSIGNED_BYTE:
3319 coordTypeSize = sizeof(GLubyte);
3320 break;
3321
3322 case GL_SHORT:
3323 coordTypeSize = sizeof(GLshort);
3324 break;
3325
3326 case GL_UNSIGNED_SHORT:
3327 coordTypeSize = sizeof(GLushort);
3328 break;
3329
3330 case GL_FLOAT:
3331 coordTypeSize = sizeof(GLfloat);
3332 break;
3333
3334 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003335 context->handleError(InvalidEnum() << "Invalid coordinate type.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003336 return false;
3337 }
3338
3339 angle::CheckedNumeric<std::uint32_t> checkedSize(numCommands);
3340 checkedSize += (coordTypeSize * numCoords);
3341 if (!checkedSize.IsValid())
3342 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003343 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003344 return false;
3345 }
3346
3347 // early return skips command data validation when it doesn't exist.
3348 if (!commands)
3349 return true;
3350
3351 GLsizei expectedNumCoords = 0;
3352 for (GLsizei i = 0; i < numCommands; ++i)
3353 {
3354 switch (commands[i])
3355 {
3356 case GL_CLOSE_PATH_CHROMIUM: // no coordinates.
3357 break;
3358 case GL_MOVE_TO_CHROMIUM:
3359 case GL_LINE_TO_CHROMIUM:
3360 expectedNumCoords += 2;
3361 break;
3362 case GL_QUADRATIC_CURVE_TO_CHROMIUM:
3363 expectedNumCoords += 4;
3364 break;
3365 case GL_CUBIC_CURVE_TO_CHROMIUM:
3366 expectedNumCoords += 6;
3367 break;
3368 case GL_CONIC_CURVE_TO_CHROMIUM:
3369 expectedNumCoords += 5;
3370 break;
3371 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003372 context->handleError(InvalidEnum() << "Invalid command.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003373 return false;
3374 }
3375 }
3376 if (expectedNumCoords != numCoords)
3377 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003378 context->handleError(InvalidValue() << "Invalid number of coordinates.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003379 return false;
3380 }
3381
3382 return true;
3383}
3384
Jamie Madill007530e2017-12-28 14:27:04 -05003385bool ValidatePathParameterfCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003386{
3387 if (!context->getExtensions().pathRendering)
3388 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003389 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003390 return false;
3391 }
Brandon Jones59770802018-04-02 13:18:42 -07003392 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003393 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003394 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003395 return false;
3396 }
3397
3398 switch (pname)
3399 {
3400 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3401 if (value < 0.0f)
3402 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003403 context->handleError(InvalidValue() << "Invalid stroke width.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003404 return false;
3405 }
3406 break;
3407 case GL_PATH_END_CAPS_CHROMIUM:
3408 switch (static_cast<GLenum>(value))
3409 {
3410 case GL_FLAT_CHROMIUM:
3411 case GL_SQUARE_CHROMIUM:
3412 case GL_ROUND_CHROMIUM:
3413 break;
3414 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003415 context->handleError(InvalidEnum() << "Invalid end caps.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003416 return false;
3417 }
3418 break;
3419 case GL_PATH_JOIN_STYLE_CHROMIUM:
3420 switch (static_cast<GLenum>(value))
3421 {
3422 case GL_MITER_REVERT_CHROMIUM:
3423 case GL_BEVEL_CHROMIUM:
3424 case GL_ROUND_CHROMIUM:
3425 break;
3426 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003427 context->handleError(InvalidEnum() << "Invalid join style.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003428 return false;
3429 }
Nico Weber41b072b2018-02-09 10:01:32 -05003430 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03003431 case GL_PATH_MITER_LIMIT_CHROMIUM:
3432 if (value < 0.0f)
3433 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003434 context->handleError(InvalidValue() << "Invalid miter limit.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003435 return false;
3436 }
3437 break;
3438
3439 case GL_PATH_STROKE_BOUND_CHROMIUM:
3440 // no errors, only clamping.
3441 break;
3442
3443 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003444 context->handleError(InvalidEnum() << "Invalid path parameter.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003445 return false;
3446 }
3447 return true;
3448}
3449
Jamie Madill007530e2017-12-28 14:27:04 -05003450bool ValidatePathParameteriCHROMIUM(Context *context, GLuint path, GLenum pname, GLint value)
3451{
3452 // TODO(jmadill): Use proper clamping cast.
3453 return ValidatePathParameterfCHROMIUM(context, path, pname, static_cast<GLfloat>(value));
3454}
3455
3456bool ValidateGetPathParameterfvCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat *value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003457{
3458 if (!context->getExtensions().pathRendering)
3459 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003460 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003461 return false;
3462 }
3463
Brandon Jones59770802018-04-02 13:18:42 -07003464 if (!context->isPathGenerated(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003465 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003466 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003467 return false;
3468 }
3469 if (!value)
3470 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003471 context->handleError(InvalidValue() << "No value array.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003472 return false;
3473 }
3474
3475 switch (pname)
3476 {
3477 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3478 case GL_PATH_END_CAPS_CHROMIUM:
3479 case GL_PATH_JOIN_STYLE_CHROMIUM:
3480 case GL_PATH_MITER_LIMIT_CHROMIUM:
3481 case GL_PATH_STROKE_BOUND_CHROMIUM:
3482 break;
3483
3484 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003485 context->handleError(InvalidEnum() << "Invalid path parameter.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003486 return false;
3487 }
3488
3489 return true;
3490}
3491
Jamie Madill007530e2017-12-28 14:27:04 -05003492bool ValidateGetPathParameterivCHROMIUM(Context *context, GLuint path, GLenum pname, GLint *value)
3493{
3494 return ValidateGetPathParameterfvCHROMIUM(context, path, pname,
3495 reinterpret_cast<GLfloat *>(value));
3496}
3497
3498bool ValidatePathStencilFuncCHROMIUM(Context *context, GLenum func, GLint ref, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003499{
3500 if (!context->getExtensions().pathRendering)
3501 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003502 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003503 return false;
3504 }
3505
3506 switch (func)
3507 {
3508 case GL_NEVER:
3509 case GL_ALWAYS:
3510 case GL_LESS:
3511 case GL_LEQUAL:
3512 case GL_EQUAL:
3513 case GL_GEQUAL:
3514 case GL_GREATER:
3515 case GL_NOTEQUAL:
3516 break;
3517 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07003518 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003519 return false;
3520 }
3521
3522 return true;
3523}
3524
3525// Note that the spec specifies that for the path drawing commands
3526// if the path object is not an existing path object the command
3527// does nothing and no error is generated.
3528// However if the path object exists but has not been specified any
3529// commands then an error is generated.
3530
Jamie Madill007530e2017-12-28 14:27:04 -05003531bool ValidateStencilFillPathCHROMIUM(Context *context, GLuint path, GLenum fillMode, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003532{
3533 if (!context->getExtensions().pathRendering)
3534 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003535 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003536 return false;
3537 }
Brandon Jones59770802018-04-02 13:18:42 -07003538 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003539 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003540 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003541 return false;
3542 }
3543
3544 switch (fillMode)
3545 {
3546 case GL_COUNT_UP_CHROMIUM:
3547 case GL_COUNT_DOWN_CHROMIUM:
3548 break;
3549 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003550 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003551 return false;
3552 }
3553
3554 if (!isPow2(mask + 1))
3555 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003556 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003557 return false;
3558 }
3559
3560 return true;
3561}
3562
Jamie Madill007530e2017-12-28 14:27:04 -05003563bool ValidateStencilStrokePathCHROMIUM(Context *context, GLuint path, GLint reference, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003564{
3565 if (!context->getExtensions().pathRendering)
3566 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003567 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003568 return false;
3569 }
Brandon Jones59770802018-04-02 13:18:42 -07003570 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003571 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003572 context->handleError(InvalidOperation() << "No such path or path has no data.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003573 return false;
3574 }
3575
3576 return true;
3577}
3578
Brandon Jonesd1049182018-03-28 10:02:20 -07003579bool ValidateCoverFillPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
3580{
3581 return ValidateCoverPathCHROMIUM(context, path, coverMode);
3582}
3583
3584bool ValidateCoverStrokePathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
3585{
3586 return ValidateCoverPathCHROMIUM(context, path, coverMode);
3587}
3588
Jamie Madill007530e2017-12-28 14:27:04 -05003589bool ValidateCoverPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003590{
3591 if (!context->getExtensions().pathRendering)
3592 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003593 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003594 return false;
3595 }
Brandon Jones59770802018-04-02 13:18:42 -07003596 if (context->isPathGenerated(path) && !context->isPath(path))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003597 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003598 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003599 return false;
3600 }
3601
3602 switch (coverMode)
3603 {
3604 case GL_CONVEX_HULL_CHROMIUM:
3605 case GL_BOUNDING_BOX_CHROMIUM:
3606 break;
3607 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003608 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003609 return false;
3610 }
3611 return true;
3612}
3613
Jamie Madill007530e2017-12-28 14:27:04 -05003614bool ValidateStencilThenCoverFillPathCHROMIUM(Context *context,
3615 GLuint path,
3616 GLenum fillMode,
3617 GLuint mask,
3618 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003619{
Jamie Madill007530e2017-12-28 14:27:04 -05003620 return ValidateStencilFillPathCHROMIUM(context, path, fillMode, mask) &&
3621 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003622}
3623
Jamie Madill007530e2017-12-28 14:27:04 -05003624bool ValidateStencilThenCoverStrokePathCHROMIUM(Context *context,
3625 GLuint path,
3626 GLint reference,
3627 GLuint mask,
3628 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003629{
Jamie Madill007530e2017-12-28 14:27:04 -05003630 return ValidateStencilStrokePathCHROMIUM(context, path, reference, mask) &&
3631 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003632}
3633
Brandon Jonesd1049182018-03-28 10:02:20 -07003634bool ValidateIsPathCHROMIUM(Context *context, GLuint path)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003635{
3636 if (!context->getExtensions().pathRendering)
3637 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003638 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003639 return false;
3640 }
3641 return true;
3642}
3643
Jamie Madill007530e2017-12-28 14:27:04 -05003644bool ValidateCoverFillPathInstancedCHROMIUM(Context *context,
3645 GLsizei numPaths,
3646 GLenum pathNameType,
3647 const void *paths,
3648 GLuint pathBase,
3649 GLenum coverMode,
3650 GLenum transformType,
3651 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003652{
3653 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3654 transformType, transformValues))
3655 return false;
3656
3657 switch (coverMode)
3658 {
3659 case GL_CONVEX_HULL_CHROMIUM:
3660 case GL_BOUNDING_BOX_CHROMIUM:
3661 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3662 break;
3663 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003664 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003665 return false;
3666 }
3667
3668 return true;
3669}
3670
Jamie Madill007530e2017-12-28 14:27:04 -05003671bool ValidateCoverStrokePathInstancedCHROMIUM(Context *context,
3672 GLsizei numPaths,
3673 GLenum pathNameType,
3674 const void *paths,
3675 GLuint pathBase,
3676 GLenum coverMode,
3677 GLenum transformType,
3678 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003679{
3680 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3681 transformType, transformValues))
3682 return false;
3683
3684 switch (coverMode)
3685 {
3686 case GL_CONVEX_HULL_CHROMIUM:
3687 case GL_BOUNDING_BOX_CHROMIUM:
3688 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3689 break;
3690 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003691 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003692 return false;
3693 }
3694
3695 return true;
3696}
3697
Jamie Madill007530e2017-12-28 14:27:04 -05003698bool ValidateStencilFillPathInstancedCHROMIUM(Context *context,
3699 GLsizei numPaths,
3700 GLenum pathNameType,
3701 const void *paths,
3702 GLuint pathBase,
3703 GLenum fillMode,
3704 GLuint mask,
3705 GLenum transformType,
3706 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003707{
3708
3709 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3710 transformType, transformValues))
3711 return false;
3712
3713 switch (fillMode)
3714 {
3715 case GL_COUNT_UP_CHROMIUM:
3716 case GL_COUNT_DOWN_CHROMIUM:
3717 break;
3718 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003719 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003720 return false;
3721 }
3722 if (!isPow2(mask + 1))
3723 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003724 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003725 return false;
3726 }
3727 return true;
3728}
3729
Jamie Madill007530e2017-12-28 14:27:04 -05003730bool ValidateStencilStrokePathInstancedCHROMIUM(Context *context,
3731 GLsizei numPaths,
3732 GLenum pathNameType,
3733 const void *paths,
3734 GLuint pathBase,
3735 GLint reference,
3736 GLuint mask,
3737 GLenum transformType,
3738 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003739{
3740 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3741 transformType, transformValues))
3742 return false;
3743
3744 // no more validation here.
3745
3746 return true;
3747}
3748
Jamie Madill007530e2017-12-28 14:27:04 -05003749bool ValidateStencilThenCoverFillPathInstancedCHROMIUM(Context *context,
3750 GLsizei numPaths,
3751 GLenum pathNameType,
3752 const void *paths,
3753 GLuint pathBase,
3754 GLenum fillMode,
3755 GLuint mask,
3756 GLenum coverMode,
3757 GLenum transformType,
3758 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003759{
3760 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3761 transformType, transformValues))
3762 return false;
3763
3764 switch (coverMode)
3765 {
3766 case GL_CONVEX_HULL_CHROMIUM:
3767 case GL_BOUNDING_BOX_CHROMIUM:
3768 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3769 break;
3770 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003771 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003772 return false;
3773 }
3774
3775 switch (fillMode)
3776 {
3777 case GL_COUNT_UP_CHROMIUM:
3778 case GL_COUNT_DOWN_CHROMIUM:
3779 break;
3780 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003781 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003782 return false;
3783 }
3784 if (!isPow2(mask + 1))
3785 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003786 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003787 return false;
3788 }
3789
3790 return true;
3791}
3792
Jamie Madill007530e2017-12-28 14:27:04 -05003793bool ValidateStencilThenCoverStrokePathInstancedCHROMIUM(Context *context,
3794 GLsizei numPaths,
3795 GLenum pathNameType,
3796 const void *paths,
3797 GLuint pathBase,
3798 GLint reference,
3799 GLuint mask,
3800 GLenum coverMode,
3801 GLenum transformType,
3802 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003803{
3804 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3805 transformType, transformValues))
3806 return false;
3807
3808 switch (coverMode)
3809 {
3810 case GL_CONVEX_HULL_CHROMIUM:
3811 case GL_BOUNDING_BOX_CHROMIUM:
3812 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3813 break;
3814 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003815 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003816 return false;
3817 }
3818
3819 return true;
3820}
3821
Jamie Madill007530e2017-12-28 14:27:04 -05003822bool ValidateBindFragmentInputLocationCHROMIUM(Context *context,
3823 GLuint program,
3824 GLint location,
3825 const GLchar *name)
Sami Väisänen46eaa942016-06-29 10:26:37 +03003826{
3827 if (!context->getExtensions().pathRendering)
3828 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003829 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003830 return false;
3831 }
3832
3833 const GLint MaxLocation = context->getCaps().maxVaryingVectors * 4;
3834 if (location >= MaxLocation)
3835 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003836 context->handleError(InvalidValue() << "Location exceeds max varying.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003837 return false;
3838 }
3839
Jamie Madill44a6fbf2018-10-02 13:38:56 -04003840 const auto *programObject = context->getProgramNoResolveLink(program);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003841 if (!programObject)
3842 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003843 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003844 return false;
3845 }
3846
3847 if (!name)
3848 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003849 context->handleError(InvalidValue() << "No name given.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003850 return false;
3851 }
3852
3853 if (angle::BeginsWith(name, "gl_"))
3854 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003855 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003856 return false;
3857 }
3858
3859 return true;
3860}
3861
Jamie Madill007530e2017-12-28 14:27:04 -05003862bool ValidateProgramPathFragmentInputGenCHROMIUM(Context *context,
3863 GLuint program,
3864 GLint location,
3865 GLenum genMode,
3866 GLint components,
3867 const GLfloat *coeffs)
Sami Väisänen46eaa942016-06-29 10:26:37 +03003868{
3869 if (!context->getExtensions().pathRendering)
3870 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003871 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003872 return false;
3873 }
3874
Jamie Madill44a6fbf2018-10-02 13:38:56 -04003875 const auto *programObject = context->getProgramResolveLink(program);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003876 if (!programObject || programObject->isFlaggedForDeletion())
3877 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003878 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramDoesNotExist);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003879 return false;
3880 }
3881
3882 if (!programObject->isLinked())
3883 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003884 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003885 return false;
3886 }
3887
3888 switch (genMode)
3889 {
3890 case GL_NONE:
3891 if (components != 0)
3892 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003893 context->handleError(InvalidValue() << "Invalid components.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003894 return false;
3895 }
3896 break;
3897
3898 case GL_OBJECT_LINEAR_CHROMIUM:
3899 case GL_EYE_LINEAR_CHROMIUM:
3900 case GL_CONSTANT_CHROMIUM:
3901 if (components < 1 || components > 4)
3902 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003903 context->handleError(InvalidValue() << "Invalid components.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003904 return false;
3905 }
3906 if (!coeffs)
3907 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003908 context->handleError(InvalidValue() << "No coefficients array given.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003909 return false;
3910 }
3911 break;
3912
3913 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003914 context->handleError(InvalidEnum() << "Invalid gen mode.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003915 return false;
3916 }
3917
3918 // If the location is -1 then the command is silently ignored
3919 // and no further validation is needed.
3920 if (location == -1)
3921 return true;
3922
jchen103fd614d2018-08-13 12:21:58 +08003923 const auto &binding = programObject->getFragmentInputBindingInfo(location);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003924
3925 if (!binding.valid)
3926 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003927 context->handleError(InvalidOperation() << "No such binding.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003928 return false;
3929 }
3930
3931 if (binding.type != GL_NONE)
3932 {
3933 GLint expectedComponents = 0;
3934 switch (binding.type)
3935 {
3936 case GL_FLOAT:
3937 expectedComponents = 1;
3938 break;
3939 case GL_FLOAT_VEC2:
3940 expectedComponents = 2;
3941 break;
3942 case GL_FLOAT_VEC3:
3943 expectedComponents = 3;
3944 break;
3945 case GL_FLOAT_VEC4:
3946 expectedComponents = 4;
3947 break;
3948 default:
He Yunchaoced53ae2016-11-29 15:00:51 +08003949 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003950 InvalidOperation()
3951 << "Fragment input type is not a floating point scalar or vector.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003952 return false;
3953 }
3954 if (expectedComponents != components && genMode != GL_NONE)
3955 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003956 context->handleError(InvalidOperation() << "Unexpected number of components");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003957 return false;
3958 }
3959 }
3960 return true;
3961}
3962
Geoff Lang97073d12016-04-20 10:42:34 -07003963bool ValidateCopyTextureCHROMIUM(Context *context,
3964 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003965 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003966 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003967 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003968 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003969 GLint internalFormat,
3970 GLenum destType,
3971 GLboolean unpackFlipY,
3972 GLboolean unpackPremultiplyAlpha,
3973 GLboolean unpackUnmultiplyAlpha)
3974{
3975 if (!context->getExtensions().copyTexture)
3976 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003977 context->handleError(InvalidOperation()
3978 << "GL_CHROMIUM_copy_texture extension not available.");
Geoff Lang97073d12016-04-20 10:42:34 -07003979 return false;
3980 }
3981
Geoff Lang4f0e0032017-05-01 16:04:35 -04003982 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07003983 if (source == nullptr)
3984 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003985 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003986 return false;
3987 }
3988
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003989 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07003990 {
Brandon Jones4e6f2ae2018-09-19 11:09:51 -07003991 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07003992 return false;
3993 }
3994
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003995 TextureType sourceType = source->getType();
3996 ASSERT(sourceType != TextureType::CubeMap);
3997 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003998
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003999 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004000 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004001 context->handleError(InvalidValue() << "Source texture level is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004002 return false;
4003 }
4004
Geoff Lang4f0e0032017-05-01 16:04:35 -04004005 GLsizei sourceWidth = static_cast<GLsizei>(source->getWidth(sourceTarget, sourceLevel));
4006 GLsizei sourceHeight = static_cast<GLsizei>(source->getHeight(sourceTarget, sourceLevel));
4007 if (sourceWidth == 0 || sourceHeight == 0)
4008 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004009 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004010 return false;
4011 }
4012
4013 const InternalFormat &sourceFormat = *source->getFormat(sourceTarget, sourceLevel).info;
4014 if (!IsValidCopyTextureSourceInternalFormatEnum(sourceFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004015 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004016 context->handleError(InvalidOperation() << "Source texture internal format is invalid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004017 return false;
4018 }
4019
Geoff Lang63458a32017-10-30 15:16:53 -04004020 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
4021 {
4022 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
4023 return false;
4024 }
4025
Geoff Lang4f0e0032017-05-01 16:04:35 -04004026 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07004027 if (dest == nullptr)
4028 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004029 context->handleError(InvalidValue()
4030 << "Destination texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07004031 return false;
4032 }
4033
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004034 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07004035 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004036 context->handleError(InvalidValue() << "Destination texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07004037 return false;
4038 }
4039
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004040 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, sourceWidth,
Brandon Jones28783792018-03-05 09:37:32 -08004041 sourceHeight, false))
Geoff Lang4f0e0032017-05-01 16:04:35 -04004042 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004043 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004044 return false;
4045 }
4046
Geoff Lang97073d12016-04-20 10:42:34 -07004047 if (!IsValidCopyTextureDestinationFormatType(context, internalFormat, destType))
4048 {
Geoff Lang97073d12016-04-20 10:42:34 -07004049 return false;
4050 }
4051
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004052 if (dest->getType() == TextureType::CubeMap && sourceWidth != sourceHeight)
Geoff Lang4f0e0032017-05-01 16:04:35 -04004053 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004054 context->handleError(
4055 InvalidValue() << "Destination width and height must be equal for cube map textures.");
Geoff Lang4f0e0032017-05-01 16:04:35 -04004056 return false;
4057 }
4058
Geoff Lang97073d12016-04-20 10:42:34 -07004059 if (dest->getImmutableFormat())
4060 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004061 context->handleError(InvalidOperation() << "Destination texture is immutable.");
Geoff Lang97073d12016-04-20 10:42:34 -07004062 return false;
4063 }
4064
4065 return true;
4066}
4067
4068bool ValidateCopySubTextureCHROMIUM(Context *context,
4069 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04004070 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004071 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07004072 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04004073 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07004074 GLint xoffset,
4075 GLint yoffset,
4076 GLint x,
4077 GLint y,
4078 GLsizei width,
4079 GLsizei height,
4080 GLboolean unpackFlipY,
4081 GLboolean unpackPremultiplyAlpha,
4082 GLboolean unpackUnmultiplyAlpha)
4083{
4084 if (!context->getExtensions().copyTexture)
4085 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004086 context->handleError(InvalidOperation()
4087 << "GL_CHROMIUM_copy_texture extension not available.");
Geoff Lang97073d12016-04-20 10:42:34 -07004088 return false;
4089 }
4090
Geoff Lang4f0e0032017-05-01 16:04:35 -04004091 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07004092 if (source == nullptr)
4093 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004094 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07004095 return false;
4096 }
4097
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004098 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07004099 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004100 context->handleError(InvalidValue() << "Source texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07004101 return false;
4102 }
4103
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004104 TextureType sourceType = source->getType();
4105 ASSERT(sourceType != TextureType::CubeMap);
4106 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004107
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004108 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang4f0e0032017-05-01 16:04:35 -04004109 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004110 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04004111 return false;
4112 }
4113
4114 if (source->getWidth(sourceTarget, sourceLevel) == 0 ||
4115 source->getHeight(sourceTarget, sourceLevel) == 0)
Geoff Lang97073d12016-04-20 10:42:34 -07004116 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004117 context->handleError(InvalidValue()
4118 << "The source level of the source texture must be defined.");
Geoff Lang97073d12016-04-20 10:42:34 -07004119 return false;
4120 }
4121
4122 if (x < 0 || y < 0)
4123 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004124 context->handleError(InvalidValue() << "x and y cannot be negative.");
Geoff Lang97073d12016-04-20 10:42:34 -07004125 return false;
4126 }
4127
4128 if (width < 0 || height < 0)
4129 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004130 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Geoff Lang97073d12016-04-20 10:42:34 -07004131 return false;
4132 }
4133
Geoff Lang4f0e0032017-05-01 16:04:35 -04004134 if (static_cast<size_t>(x + width) > source->getWidth(sourceTarget, sourceLevel) ||
4135 static_cast<size_t>(y + height) > source->getHeight(sourceTarget, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004136 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004137 ANGLE_VALIDATION_ERR(context, InvalidValue(), SourceTextureTooSmall);
Geoff Lang97073d12016-04-20 10:42:34 -07004138 return false;
4139 }
4140
Geoff Lang4f0e0032017-05-01 16:04:35 -04004141 const Format &sourceFormat = source->getFormat(sourceTarget, sourceLevel);
4142 if (!IsValidCopySubTextureSourceInternalFormat(sourceFormat.info->internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004143 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004144 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07004145 return false;
4146 }
4147
Geoff Lang63458a32017-10-30 15:16:53 -04004148 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
4149 {
4150 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
4151 return false;
4152 }
4153
Geoff Lang4f0e0032017-05-01 16:04:35 -04004154 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07004155 if (dest == nullptr)
4156 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004157 context->handleError(InvalidValue()
4158 << "Destination texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07004159 return false;
4160 }
4161
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004162 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07004163 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004164 context->handleError(InvalidValue() << "Destination texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07004165 return false;
4166 }
4167
Brandon Jones28783792018-03-05 09:37:32 -08004168 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, width, height,
4169 true))
Geoff Lang97073d12016-04-20 10:42:34 -07004170 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004171 context->handleError(InvalidValue() << "Destination texture level is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004172 return false;
4173 }
4174
Geoff Lang4f0e0032017-05-01 16:04:35 -04004175 if (dest->getWidth(destTarget, destLevel) == 0 || dest->getHeight(destTarget, destLevel) == 0)
4176 {
Geoff Langbb1b19b2017-06-16 16:59:00 -04004177 context
4178 ->handleError(InvalidOperation()
4179 << "The destination level of the destination texture must be defined.");
Geoff Lang4f0e0032017-05-01 16:04:35 -04004180 return false;
4181 }
4182
4183 const InternalFormat &destFormat = *dest->getFormat(destTarget, destLevel).info;
4184 if (!IsValidCopySubTextureDestionationInternalFormat(destFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004185 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004186 context->handleError(InvalidOperation()
4187 << "Destination internal format and type combination is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004188 return false;
4189 }
4190
4191 if (xoffset < 0 || yoffset < 0)
4192 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004193 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Geoff Lang97073d12016-04-20 10:42:34 -07004194 return false;
4195 }
4196
Geoff Lang4f0e0032017-05-01 16:04:35 -04004197 if (static_cast<size_t>(xoffset + width) > dest->getWidth(destTarget, destLevel) ||
4198 static_cast<size_t>(yoffset + height) > dest->getHeight(destTarget, destLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004199 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004200 context->handleError(InvalidValue() << "Destination texture not large enough to copy to.");
Geoff Lang97073d12016-04-20 10:42:34 -07004201 return false;
4202 }
4203
4204 return true;
4205}
4206
Geoff Lang47110bf2016-04-20 11:13:22 -07004207bool ValidateCompressedCopyTextureCHROMIUM(Context *context, GLuint sourceId, GLuint destId)
4208{
4209 if (!context->getExtensions().copyCompressedTexture)
4210 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004211 context->handleError(InvalidOperation()
4212 << "GL_CHROMIUM_copy_compressed_texture extension not available.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004213 return false;
4214 }
4215
4216 const gl::Texture *source = context->getTexture(sourceId);
4217 if (source == nullptr)
4218 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004219 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004220 return false;
4221 }
4222
Corentin Wallez99d492c2018-02-27 15:17:10 -05004223 if (source->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004224 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004225 context->handleError(InvalidValue() << "Source texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004226 return false;
4227 }
4228
Corentin Wallez99d492c2018-02-27 15:17:10 -05004229 if (source->getWidth(TextureTarget::_2D, 0) == 0 ||
4230 source->getHeight(TextureTarget::_2D, 0) == 0)
Geoff Lang47110bf2016-04-20 11:13:22 -07004231 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004232 context->handleError(InvalidValue() << "Source texture must level 0 defined.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004233 return false;
4234 }
4235
Corentin Wallez99d492c2018-02-27 15:17:10 -05004236 const gl::Format &sourceFormat = source->getFormat(TextureTarget::_2D, 0);
Geoff Lang47110bf2016-04-20 11:13:22 -07004237 if (!sourceFormat.info->compressed)
4238 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004239 context->handleError(InvalidOperation()
4240 << "Source texture must have a compressed internal format.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004241 return false;
4242 }
4243
4244 const gl::Texture *dest = context->getTexture(destId);
4245 if (dest == nullptr)
4246 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004247 context->handleError(InvalidValue()
4248 << "Destination texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004249 return false;
4250 }
4251
Corentin Wallez99d492c2018-02-27 15:17:10 -05004252 if (dest->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004253 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004254 context->handleError(InvalidValue()
4255 << "Destination texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004256 return false;
4257 }
4258
4259 if (dest->getImmutableFormat())
4260 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004261 context->handleError(InvalidOperation() << "Destination cannot be immutable.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004262 return false;
4263 }
4264
4265 return true;
4266}
4267
Jiawei Shao385b3e02018-03-21 09:43:28 +08004268bool ValidateCreateShader(Context *context, ShaderType type)
Martin Radev4c4c8e72016-08-04 12:25:34 +03004269{
4270 switch (type)
4271 {
Jiawei Shao385b3e02018-03-21 09:43:28 +08004272 case ShaderType::Vertex:
4273 case ShaderType::Fragment:
Martin Radev4c4c8e72016-08-04 12:25:34 +03004274 break;
Geoff Langeb66a6e2016-10-31 13:06:12 -04004275
Jiawei Shao385b3e02018-03-21 09:43:28 +08004276 case ShaderType::Compute:
Geoff Langeb66a6e2016-10-31 13:06:12 -04004277 if (context->getClientVersion() < Version(3, 1))
Martin Radev4c4c8e72016-08-04 12:25:34 +03004278 {
Yunchao Hef0fd87d2017-09-12 04:55:05 +08004279 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
Geoff Langeb66a6e2016-10-31 13:06:12 -04004280 return false;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004281 }
Geoff Langeb66a6e2016-10-31 13:06:12 -04004282 break;
4283
Jiawei Shao385b3e02018-03-21 09:43:28 +08004284 case ShaderType::Geometry:
Jiawei Shao89be29a2017-11-06 14:36:45 +08004285 if (!context->getExtensions().geometryShader)
4286 {
4287 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
4288 return false;
4289 }
4290 break;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004291 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004292 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Martin Radev4c4c8e72016-08-04 12:25:34 +03004293 return false;
4294 }
Jamie Madill29639852016-09-02 15:00:09 -04004295
4296 return true;
4297}
4298
Jamie Madill5b772312018-03-08 20:28:32 -05004299bool ValidateBufferData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004300 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004301 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004302 const void *data,
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004303 BufferUsage usage)
Jamie Madill29639852016-09-02 15:00:09 -04004304{
4305 if (size < 0)
4306 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004307 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madill29639852016-09-02 15:00:09 -04004308 return false;
4309 }
4310
4311 switch (usage)
4312 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004313 case BufferUsage::StreamDraw:
4314 case BufferUsage::StaticDraw:
4315 case BufferUsage::DynamicDraw:
Jamie Madill29639852016-09-02 15:00:09 -04004316 break;
4317
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004318 case BufferUsage::StreamRead:
4319 case BufferUsage::StaticRead:
4320 case BufferUsage::DynamicRead:
4321 case BufferUsage::StreamCopy:
4322 case BufferUsage::StaticCopy:
4323 case BufferUsage::DynamicCopy:
Jamie Madill29639852016-09-02 15:00:09 -04004324 if (context->getClientMajorVersion() < 3)
4325 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004326 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004327 return false;
4328 }
4329 break;
4330
4331 default:
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
Corentin Walleze4477002017-12-01 14:39:58 -05004336 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004337 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004338 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004339 return false;
4340 }
4341
4342 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4343
4344 if (!buffer)
4345 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004346 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004347 return false;
4348 }
4349
James Darpiniane8a93c62018-01-04 18:02:24 -08004350 if (context->getExtensions().webglCompatibility &&
4351 buffer->isBoundForTransformFeedbackAndOtherUse())
4352 {
4353 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
4354 return false;
4355 }
4356
Jamie Madill29639852016-09-02 15:00:09 -04004357 return true;
4358}
4359
Jamie Madill5b772312018-03-08 20:28:32 -05004360bool ValidateBufferSubData(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004361 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004362 GLintptr offset,
4363 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004364 const void *data)
Jamie Madill29639852016-09-02 15:00:09 -04004365{
Brandon Jones6cad5662017-06-14 13:25:13 -07004366 if (size < 0)
Jamie Madill29639852016-09-02 15:00:09 -04004367 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004368 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
4369 return false;
4370 }
4371
4372 if (offset < 0)
4373 {
4374 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Jamie Madill29639852016-09-02 15:00:09 -04004375 return false;
4376 }
4377
Corentin Walleze4477002017-12-01 14:39:58 -05004378 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004379 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004380 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004381 return false;
4382 }
4383
4384 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4385
4386 if (!buffer)
4387 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004388 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004389 return false;
4390 }
4391
4392 if (buffer->isMapped())
4393 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004394 context->handleError(InvalidOperation());
Jamie Madill29639852016-09-02 15:00:09 -04004395 return false;
4396 }
4397
James Darpiniane8a93c62018-01-04 18:02:24 -08004398 if (context->getExtensions().webglCompatibility &&
4399 buffer->isBoundForTransformFeedbackAndOtherUse())
4400 {
4401 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferBoundForTransformFeedback);
4402 return false;
4403 }
4404
Jamie Madill29639852016-09-02 15:00:09 -04004405 // Check for possible overflow of size + offset
4406 angle::CheckedNumeric<size_t> checkedSize(size);
4407 checkedSize += offset;
4408 if (!checkedSize.IsValid())
4409 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004410 context->handleError(OutOfMemory());
Jamie Madill29639852016-09-02 15:00:09 -04004411 return false;
4412 }
4413
4414 if (size + offset > buffer->getSize())
4415 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004416 ANGLE_VALIDATION_ERR(context, InvalidValue(), InsufficientBufferSize);
Jamie Madill29639852016-09-02 15:00:09 -04004417 return false;
4418 }
4419
Martin Radev4c4c8e72016-08-04 12:25:34 +03004420 return true;
4421}
4422
Geoff Lang111a99e2017-10-17 10:58:41 -04004423bool ValidateRequestExtensionANGLE(Context *context, const GLchar *name)
Geoff Langc287ea62016-09-16 14:46:51 -04004424{
Geoff Langc339c4e2016-11-29 10:37:36 -05004425 if (!context->getExtensions().requestExtension)
Geoff Langc287ea62016-09-16 14:46:51 -04004426 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004427 context->handleError(InvalidOperation() << "GL_ANGLE_request_extension is not available.");
Geoff Langc287ea62016-09-16 14:46:51 -04004428 return false;
4429 }
4430
Geoff Lang111a99e2017-10-17 10:58:41 -04004431 if (!context->isExtensionRequestable(name))
Geoff Langc287ea62016-09-16 14:46:51 -04004432 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004433 context->handleError(InvalidOperation() << "Extension " << name << " is not requestable.");
Geoff Langc287ea62016-09-16 14:46:51 -04004434 return false;
4435 }
4436
4437 return true;
4438}
4439
Jamie Madill5b772312018-03-08 20:28:32 -05004440bool ValidateActiveTexture(Context *context, GLenum texture)
Jamie Madillef300b12016-10-07 15:12:09 -04004441{
Lingfeng Yang038dd532018-03-29 17:31:52 -07004442 if (context->getClientMajorVersion() < 2)
4443 {
4444 return ValidateMultitextureUnit(context, texture);
4445 }
4446
Jamie Madillef300b12016-10-07 15:12:09 -04004447 if (texture < GL_TEXTURE0 ||
4448 texture > GL_TEXTURE0 + context->getCaps().maxCombinedTextureImageUnits - 1)
4449 {
Lingfeng Yang96310cd2018-03-28 11:56:28 -07004450 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCombinedImageUnit);
Jamie Madillef300b12016-10-07 15:12:09 -04004451 return false;
4452 }
4453
4454 return true;
4455}
4456
Jamie Madill5b772312018-03-08 20:28:32 -05004457bool ValidateAttachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillef300b12016-10-07 15:12:09 -04004458{
4459 Program *programObject = GetValidProgram(context, program);
4460 if (!programObject)
4461 {
4462 return false;
4463 }
4464
4465 Shader *shaderObject = GetValidShader(context, shader);
4466 if (!shaderObject)
4467 {
4468 return false;
4469 }
4470
Jiawei Shao385b3e02018-03-21 09:43:28 +08004471 if (programObject->getAttachedShader(shaderObject->getType()))
Jamie Madillef300b12016-10-07 15:12:09 -04004472 {
Jiawei Shao385b3e02018-03-21 09:43:28 +08004473 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
4474 return false;
Jamie Madillef300b12016-10-07 15:12:09 -04004475 }
4476
4477 return true;
4478}
4479
Jamie Madill5b772312018-03-08 20:28:32 -05004480bool ValidateBindAttribLocation(Context *context, GLuint program, GLuint index, const GLchar *name)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004481{
4482 if (index >= MAX_VERTEX_ATTRIBS)
4483 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004484 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004485 return false;
4486 }
4487
4488 if (strncmp(name, "gl_", 3) == 0)
4489 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004490 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004491 return false;
4492 }
4493
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004494 if (context->isWebGL())
Geoff Langfc32e8b2017-05-31 14:16:59 -04004495 {
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004496 const size_t length = strlen(name);
4497
4498 if (!IsValidESSLString(name, length))
4499 {
4500 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters
4501 // for shader-related entry points
4502 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
4503 return false;
4504 }
4505
4506 if (!ValidateWebGLNameLength(context, length) || !ValidateWebGLNamePrefix(context, name))
4507 {
4508 return false;
4509 }
Geoff Langfc32e8b2017-05-31 14:16:59 -04004510 }
4511
Jamie Madill01a80ee2016-11-07 12:06:18 -05004512 return GetValidProgram(context, program) != nullptr;
4513}
4514
Jamie Madill5b772312018-03-08 20:28:32 -05004515bool ValidateBindFramebuffer(Context *context, GLenum target, GLuint framebuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004516{
Geoff Lange8afa902017-09-27 15:00:43 -04004517 if (!ValidFramebufferTarget(context, target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004518 {
Jamie Madilla139f012018-10-10 16:13:03 -04004519 context->validationError(GL_INVALID_ENUM, kErrorInvalidFramebufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004520 return false;
4521 }
4522
4523 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4524 !context->isFramebufferGenerated(framebuffer))
4525 {
Jamie Madilla139f012018-10-10 16:13:03 -04004526 context->validationError(GL_INVALID_OPERATION, kErrorObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004527 return false;
4528 }
4529
4530 return true;
4531}
4532
Jamie Madill5b772312018-03-08 20:28:32 -05004533bool ValidateBindRenderbuffer(Context *context, GLenum target, GLuint renderbuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004534{
4535 if (target != GL_RENDERBUFFER)
4536 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004537 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004538 return false;
4539 }
4540
4541 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4542 !context->isRenderbufferGenerated(renderbuffer))
4543 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004544 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004545 return false;
4546 }
4547
4548 return true;
4549}
4550
Jamie Madill5b772312018-03-08 20:28:32 -05004551static bool ValidBlendEquationMode(const Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004552{
4553 switch (mode)
4554 {
4555 case GL_FUNC_ADD:
4556 case GL_FUNC_SUBTRACT:
4557 case GL_FUNC_REVERSE_SUBTRACT:
Geoff Lang50cac572017-09-26 17:37:43 -04004558 return true;
4559
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004560 case GL_MIN:
4561 case GL_MAX:
Geoff Lang50cac572017-09-26 17:37:43 -04004562 return context->getClientVersion() >= ES_3_0 || context->getExtensions().blendMinMax;
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004563
4564 default:
4565 return false;
4566 }
4567}
4568
Jamie Madill5b772312018-03-08 20:28:32 -05004569bool ValidateBlendColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004570{
4571 return true;
4572}
4573
Jamie Madill5b772312018-03-08 20:28:32 -05004574bool ValidateBlendEquation(Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004575{
Geoff Lang50cac572017-09-26 17:37:43 -04004576 if (!ValidBlendEquationMode(context, mode))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004577 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004578 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004579 return false;
4580 }
4581
4582 return true;
4583}
4584
Jamie Madill5b772312018-03-08 20:28:32 -05004585bool ValidateBlendEquationSeparate(Context *context, GLenum modeRGB, GLenum modeAlpha)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004586{
Geoff Lang50cac572017-09-26 17:37:43 -04004587 if (!ValidBlendEquationMode(context, modeRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004588 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004589 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004590 return false;
4591 }
4592
Geoff Lang50cac572017-09-26 17:37:43 -04004593 if (!ValidBlendEquationMode(context, modeAlpha))
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
4599 return true;
4600}
4601
Jamie Madill5b772312018-03-08 20:28:32 -05004602bool ValidateBlendFunc(Context *context, GLenum sfactor, GLenum dfactor)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004603{
4604 return ValidateBlendFuncSeparate(context, sfactor, dfactor, sfactor, dfactor);
4605}
4606
Jamie Madill5b772312018-03-08 20:28:32 -05004607bool ValidateBlendFuncSeparate(Context *context,
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004608 GLenum srcRGB,
4609 GLenum dstRGB,
4610 GLenum srcAlpha,
4611 GLenum dstAlpha)
4612{
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03004613 if (!ValidSrcBlendFunc(context, srcRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004614 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004615 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004616 return false;
4617 }
4618
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03004619 if (!ValidDstBlendFunc(context, dstRGB))
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 (!ValidSrcBlendFunc(context, srcAlpha))
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 (!ValidDstBlendFunc(context, dstAlpha))
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
Frank Henigman146e8a12017-03-02 23:22:37 -05004637 if (context->getLimitations().noSimultaneousConstantColorAndAlphaBlendFunc ||
4638 context->getExtensions().webglCompatibility)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004639 {
4640 bool constantColorUsed =
4641 (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
4642 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
4643
4644 bool constantAlphaUsed =
4645 (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
4646 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
4647
4648 if (constantColorUsed && constantAlphaUsed)
4649 {
Frank Henigman146e8a12017-03-02 23:22:37 -05004650 const char *msg;
4651 if (context->getExtensions().webglCompatibility)
4652 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004653 msg = kErrorInvalidConstantColor;
Frank Henigman146e8a12017-03-02 23:22:37 -05004654 }
4655 else
4656 {
4657 msg =
4658 "Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and "
4659 "GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR not supported by this "
4660 "implementation.";
Jamie Madilla2f043d2018-07-10 17:21:20 -04004661 WARN() << msg;
Frank Henigman146e8a12017-03-02 23:22:37 -05004662 }
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004663 context->handleError(InvalidOperation() << msg);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004664 return false;
4665 }
4666 }
4667
4668 return true;
4669}
4670
Geoff Langc339c4e2016-11-29 10:37:36 -05004671bool ValidateGetString(Context *context, GLenum name)
4672{
4673 switch (name)
4674 {
4675 case GL_VENDOR:
4676 case GL_RENDERER:
4677 case GL_VERSION:
4678 case GL_SHADING_LANGUAGE_VERSION:
4679 case GL_EXTENSIONS:
4680 break;
4681
4682 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
4683 if (!context->getExtensions().requestExtension)
4684 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004685 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004686 return false;
4687 }
4688 break;
4689
4690 default:
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
4695 return true;
4696}
4697
Jamie Madill5b772312018-03-08 20:28:32 -05004698bool ValidateLineWidth(Context *context, GLfloat width)
Geoff Lang47c48082016-12-07 15:38:13 -05004699{
4700 if (width <= 0.0f || isNaN(width))
4701 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004702 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidWidth);
Geoff Lang47c48082016-12-07 15:38:13 -05004703 return false;
4704 }
4705
4706 return true;
4707}
4708
Jamie Madill5b772312018-03-08 20:28:32 -05004709bool ValidateVertexAttribPointer(Context *context,
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004710 GLuint index,
4711 GLint size,
4712 GLenum type,
4713 GLboolean normalized,
4714 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04004715 const void *ptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004716{
Shao80957d92017-02-20 21:25:59 +08004717 if (!ValidateVertexFormatBase(context, index, size, type, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004718 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004719 return false;
4720 }
4721
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004722 if (stride < 0)
4723 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004724 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeStride);
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004725 return false;
4726 }
4727
Shao80957d92017-02-20 21:25:59 +08004728 const Caps &caps = context->getCaps();
4729 if (context->getClientVersion() >= ES_3_1)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004730 {
Shao80957d92017-02-20 21:25:59 +08004731 if (stride > caps.maxVertexAttribStride)
4732 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004733 context->handleError(InvalidValue()
4734 << "stride cannot be greater than MAX_VERTEX_ATTRIB_STRIDE.");
Shao80957d92017-02-20 21:25:59 +08004735 return false;
4736 }
4737
4738 if (index >= caps.maxVertexAttribBindings)
4739 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004740 context->handleError(InvalidValue()
4741 << "index must be smaller than MAX_VERTEX_ATTRIB_BINDINGS.");
Shao80957d92017-02-20 21:25:59 +08004742 return false;
4743 }
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004744 }
4745
4746 // [OpenGL ES 3.0.2] Section 2.8 page 24:
4747 // An INVALID_OPERATION error is generated when a non-zero vertex array object
4748 // is bound, zero is bound to the ARRAY_BUFFER buffer object binding point,
4749 // and the pointer argument is not NULL.
Geoff Langfeb8c682017-02-13 16:07:35 -05004750 bool nullBufferAllowed = context->getGLState().areClientArraysEnabled() &&
4751 context->getGLState().getVertexArray()->id() == 0;
Corentin Wallez336129f2017-10-17 15:55:40 -04004752 if (!nullBufferAllowed && context->getGLState().getTargetBuffer(BufferBinding::Array) == 0 &&
4753 ptr != nullptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004754 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004755 context
4756 ->handleError(InvalidOperation()
4757 << "Client data cannot be used with a non-default vertex array object.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004758 return false;
4759 }
4760
4761 if (context->getExtensions().webglCompatibility)
4762 {
4763 // WebGL 1.0 [Section 6.14] Fixed point support
4764 // The WebGL API does not support the GL_FIXED data type.
4765 if (type == GL_FIXED)
4766 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004767 context->handleError(InvalidEnum() << "GL_FIXED is not supported in WebGL.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004768 return false;
4769 }
4770
Geoff Lang2d62ab72017-03-23 16:54:40 -04004771 if (!ValidateWebGLVertexAttribPointer(context, type, normalized, stride, ptr, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004772 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004773 return false;
4774 }
4775 }
4776
4777 return true;
4778}
4779
Jamie Madill5b772312018-03-08 20:28:32 -05004780bool ValidateDepthRangef(Context *context, GLfloat zNear, GLfloat zFar)
Frank Henigman6137ddc2017-02-10 18:55:07 -05004781{
4782 if (context->getExtensions().webglCompatibility && zNear > zFar)
4783 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004784 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidDepthRange);
Frank Henigman6137ddc2017-02-10 18:55:07 -05004785 return false;
4786 }
4787
4788 return true;
4789}
4790
Jamie Madill5b772312018-03-08 20:28:32 -05004791bool ValidateRenderbufferStorage(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05004792 GLenum target,
4793 GLenum internalformat,
4794 GLsizei width,
4795 GLsizei height)
4796{
4797 return ValidateRenderbufferStorageParametersBase(context, target, 0, internalformat, width,
4798 height);
4799}
4800
Jamie Madill5b772312018-03-08 20:28:32 -05004801bool ValidateRenderbufferStorageMultisampleANGLE(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05004802 GLenum target,
4803 GLsizei samples,
4804 GLenum internalformat,
4805 GLsizei width,
4806 GLsizei height)
4807{
4808 if (!context->getExtensions().framebufferMultisample)
4809 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004810 context->handleError(InvalidOperation()
4811 << "GL_ANGLE_framebuffer_multisample not available");
Jamie Madille8fb6402017-02-14 17:56:40 -05004812 return false;
4813 }
4814
4815 // ANGLE_framebuffer_multisample states that the value of samples must be less than or equal
4816 // to MAX_SAMPLES_ANGLE (Context::getCaps().maxSamples) otherwise GL_INVALID_OPERATION is
4817 // generated.
4818 if (static_cast<GLuint>(samples) > context->getCaps().maxSamples)
4819 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004820 context->handleError(InvalidValue());
Jamie Madille8fb6402017-02-14 17:56:40 -05004821 return false;
4822 }
4823
4824 // ANGLE_framebuffer_multisample states GL_OUT_OF_MEMORY is generated on a failure to create
4825 // the specified storage. This is different than ES 3.0 in which a sample number higher
4826 // than the maximum sample number supported by this format generates a GL_INVALID_VALUE.
4827 // The TextureCaps::getMaxSamples method is only guarenteed to be valid when the context is ES3.
4828 if (context->getClientMajorVersion() >= 3)
4829 {
4830 const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
4831 if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
4832 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004833 context->handleError(OutOfMemory());
Jamie Madille8fb6402017-02-14 17:56:40 -05004834 return false;
4835 }
4836 }
4837
4838 return ValidateRenderbufferStorageParametersBase(context, target, samples, internalformat,
4839 width, height);
4840}
4841
Jamie Madill5b772312018-03-08 20:28:32 -05004842bool ValidateCheckFramebufferStatus(Context *context, GLenum target)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004843{
Geoff Lange8afa902017-09-27 15:00:43 -04004844 if (!ValidFramebufferTarget(context, target))
Jamie Madillc1d770e2017-04-13 17:31:24 -04004845 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004846 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004847 return false;
4848 }
4849
4850 return true;
4851}
4852
Jamie Madill5b772312018-03-08 20:28:32 -05004853bool ValidateClearColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004854{
4855 return true;
4856}
4857
Jamie Madill5b772312018-03-08 20:28:32 -05004858bool ValidateClearDepthf(Context *context, GLfloat depth)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004859{
4860 return true;
4861}
4862
Jamie Madill5b772312018-03-08 20:28:32 -05004863bool ValidateClearStencil(Context *context, GLint s)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004864{
4865 return true;
4866}
4867
Jamie Madill5b772312018-03-08 20:28:32 -05004868bool ValidateColorMask(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04004869 GLboolean red,
4870 GLboolean green,
4871 GLboolean blue,
4872 GLboolean alpha)
4873{
4874 return true;
4875}
4876
Jamie Madill5b772312018-03-08 20:28:32 -05004877bool ValidateCompileShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004878{
4879 return true;
4880}
4881
Jamie Madill5b772312018-03-08 20:28:32 -05004882bool ValidateCreateProgram(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004883{
4884 return true;
4885}
4886
Jamie Madill5b772312018-03-08 20:28:32 -05004887bool ValidateCullFace(Context *context, CullFaceMode mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004888{
4889 switch (mode)
4890 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004891 case CullFaceMode::Front:
4892 case CullFaceMode::Back:
4893 case CullFaceMode::FrontAndBack:
Jamie Madillc1d770e2017-04-13 17:31:24 -04004894 break;
4895
4896 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004897 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCullMode);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004898 return false;
4899 }
4900
4901 return true;
4902}
4903
Jamie Madill5b772312018-03-08 20:28:32 -05004904bool ValidateDeleteProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004905{
4906 if (program == 0)
4907 {
4908 return false;
4909 }
4910
Jamie Madill44a6fbf2018-10-02 13:38:56 -04004911 if (!context->getProgramResolveLink(program))
Jamie Madillc1d770e2017-04-13 17:31:24 -04004912 {
4913 if (context->getShader(program))
4914 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004915 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004916 return false;
4917 }
4918 else
4919 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004920 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004921 return false;
4922 }
4923 }
4924
4925 return true;
4926}
4927
Jamie Madill5b772312018-03-08 20:28:32 -05004928bool ValidateDeleteShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004929{
4930 if (shader == 0)
4931 {
4932 return false;
4933 }
4934
4935 if (!context->getShader(shader))
4936 {
Jamie Madill44a6fbf2018-10-02 13:38:56 -04004937 if (context->getProgramResolveLink(shader))
Jamie Madillc1d770e2017-04-13 17:31:24 -04004938 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004939 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004940 return false;
4941 }
4942 else
4943 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004944 ANGLE_VALIDATION_ERR(context, InvalidValue(), ExpectedShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004945 return false;
4946 }
4947 }
4948
4949 return true;
4950}
4951
Jamie Madill5b772312018-03-08 20:28:32 -05004952bool ValidateDepthFunc(Context *context, GLenum func)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004953{
4954 switch (func)
4955 {
4956 case GL_NEVER:
4957 case GL_ALWAYS:
4958 case GL_LESS:
4959 case GL_LEQUAL:
4960 case GL_EQUAL:
4961 case GL_GREATER:
4962 case GL_GEQUAL:
4963 case GL_NOTEQUAL:
4964 break;
4965
4966 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004967 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004968 return false;
4969 }
4970
4971 return true;
4972}
4973
Jamie Madill5b772312018-03-08 20:28:32 -05004974bool ValidateDepthMask(Context *context, GLboolean flag)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004975{
4976 return true;
4977}
4978
Jamie Madill5b772312018-03-08 20:28:32 -05004979bool ValidateDetachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004980{
4981 Program *programObject = GetValidProgram(context, program);
4982 if (!programObject)
4983 {
4984 return false;
4985 }
4986
4987 Shader *shaderObject = GetValidShader(context, shader);
4988 if (!shaderObject)
4989 {
4990 return false;
4991 }
4992
Jiawei Shao385b3e02018-03-21 09:43:28 +08004993 const Shader *attachedShader = programObject->getAttachedShader(shaderObject->getType());
Jamie Madillc1d770e2017-04-13 17:31:24 -04004994 if (attachedShader != shaderObject)
4995 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004996 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderToDetachMustBeAttached);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004997 return false;
4998 }
4999
5000 return true;
5001}
5002
Jamie Madill5b772312018-03-08 20:28:32 -05005003bool ValidateDisableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005004{
5005 if (index >= MAX_VERTEX_ATTRIBS)
5006 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005007 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005008 return false;
5009 }
5010
5011 return true;
5012}
5013
Jamie Madill5b772312018-03-08 20:28:32 -05005014bool ValidateEnableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005015{
5016 if (index >= MAX_VERTEX_ATTRIBS)
5017 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005018 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005019 return false;
5020 }
5021
5022 return true;
5023}
5024
Jamie Madill5b772312018-03-08 20:28:32 -05005025bool ValidateFinish(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005026{
5027 return true;
5028}
5029
Jamie Madill5b772312018-03-08 20:28:32 -05005030bool ValidateFlush(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005031{
5032 return true;
5033}
5034
Jamie Madill5b772312018-03-08 20:28:32 -05005035bool ValidateFrontFace(Context *context, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005036{
5037 switch (mode)
5038 {
5039 case GL_CW:
5040 case GL_CCW:
5041 break;
5042 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005043 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005044 return false;
5045 }
5046
5047 return true;
5048}
5049
Jamie Madill5b772312018-03-08 20:28:32 -05005050bool ValidateGetActiveAttrib(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005051 GLuint program,
5052 GLuint index,
5053 GLsizei bufsize,
5054 GLsizei *length,
5055 GLint *size,
5056 GLenum *type,
5057 GLchar *name)
5058{
5059 if (bufsize < 0)
5060 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005061 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005062 return false;
5063 }
5064
5065 Program *programObject = GetValidProgram(context, program);
5066
5067 if (!programObject)
5068 {
5069 return false;
5070 }
5071
5072 if (index >= static_cast<GLuint>(programObject->getActiveAttributeCount()))
5073 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005074 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005075 return false;
5076 }
5077
5078 return true;
5079}
5080
Jamie Madill5b772312018-03-08 20:28:32 -05005081bool ValidateGetActiveUniform(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005082 GLuint program,
5083 GLuint index,
5084 GLsizei bufsize,
5085 GLsizei *length,
5086 GLint *size,
5087 GLenum *type,
5088 GLchar *name)
5089{
5090 if (bufsize < 0)
5091 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005092 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005093 return false;
5094 }
5095
5096 Program *programObject = GetValidProgram(context, program);
5097
5098 if (!programObject)
5099 {
5100 return false;
5101 }
5102
5103 if (index >= static_cast<GLuint>(programObject->getActiveUniformCount()))
5104 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005105 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005106 return false;
5107 }
5108
5109 return true;
5110}
5111
Jamie Madill5b772312018-03-08 20:28:32 -05005112bool ValidateGetAttachedShaders(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005113 GLuint program,
5114 GLsizei maxcount,
5115 GLsizei *count,
5116 GLuint *shaders)
5117{
5118 if (maxcount < 0)
5119 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005120 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeMaxCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005121 return false;
5122 }
5123
5124 Program *programObject = GetValidProgram(context, program);
5125
5126 if (!programObject)
5127 {
5128 return false;
5129 }
5130
5131 return true;
5132}
5133
Jamie Madill5b772312018-03-08 20:28:32 -05005134bool ValidateGetAttribLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005135{
Geoff Langfc32e8b2017-05-31 14:16:59 -04005136 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5137 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005138 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005139 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005140 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005141 return false;
5142 }
5143
Jamie Madillc1d770e2017-04-13 17:31:24 -04005144 Program *programObject = GetValidProgram(context, program);
5145
5146 if (!programObject)
5147 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005148 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005149 return false;
5150 }
5151
5152 if (!programObject->isLinked())
5153 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005154 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005155 return false;
5156 }
5157
5158 return true;
5159}
5160
Jamie Madill5b772312018-03-08 20:28:32 -05005161bool ValidateGetBooleanv(Context *context, GLenum pname, GLboolean *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005162{
5163 GLenum nativeType;
5164 unsigned int numParams = 0;
5165 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5166}
5167
Jamie Madill5b772312018-03-08 20:28:32 -05005168bool ValidateGetError(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005169{
5170 return true;
5171}
5172
Jamie Madill5b772312018-03-08 20:28:32 -05005173bool ValidateGetFloatv(Context *context, GLenum pname, GLfloat *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005174{
5175 GLenum nativeType;
5176 unsigned int numParams = 0;
5177 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5178}
5179
Jamie Madill5b772312018-03-08 20:28:32 -05005180bool ValidateGetIntegerv(Context *context, GLenum pname, GLint *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005181{
5182 GLenum nativeType;
5183 unsigned int numParams = 0;
5184 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5185}
5186
Jamie Madill5b772312018-03-08 20:28:32 -05005187bool ValidateGetProgramInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005188 GLuint program,
5189 GLsizei bufsize,
5190 GLsizei *length,
5191 GLchar *infolog)
5192{
5193 if (bufsize < 0)
5194 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005195 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005196 return false;
5197 }
5198
5199 Program *programObject = GetValidProgram(context, program);
5200 if (!programObject)
5201 {
5202 return false;
5203 }
5204
5205 return true;
5206}
5207
Jamie Madill5b772312018-03-08 20:28:32 -05005208bool ValidateGetShaderInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005209 GLuint shader,
5210 GLsizei bufsize,
5211 GLsizei *length,
5212 GLchar *infolog)
5213{
5214 if (bufsize < 0)
5215 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005216 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005217 return false;
5218 }
5219
5220 Shader *shaderObject = GetValidShader(context, shader);
5221 if (!shaderObject)
5222 {
5223 return false;
5224 }
5225
5226 return true;
5227}
5228
Jamie Madill5b772312018-03-08 20:28:32 -05005229bool ValidateGetShaderPrecisionFormat(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005230 GLenum shadertype,
5231 GLenum precisiontype,
5232 GLint *range,
5233 GLint *precision)
5234{
5235 switch (shadertype)
5236 {
5237 case GL_VERTEX_SHADER:
5238 case GL_FRAGMENT_SHADER:
5239 break;
5240 case GL_COMPUTE_SHADER:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005241 context->handleError(InvalidOperation()
5242 << "compute shader precision not yet implemented.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005243 return false;
5244 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005245 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005246 return false;
5247 }
5248
5249 switch (precisiontype)
5250 {
5251 case GL_LOW_FLOAT:
5252 case GL_MEDIUM_FLOAT:
5253 case GL_HIGH_FLOAT:
5254 case GL_LOW_INT:
5255 case GL_MEDIUM_INT:
5256 case GL_HIGH_INT:
5257 break;
5258
5259 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005260 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPrecision);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005261 return false;
5262 }
5263
5264 return true;
5265}
5266
Jamie Madill5b772312018-03-08 20:28:32 -05005267bool ValidateGetShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005268 GLuint shader,
5269 GLsizei bufsize,
5270 GLsizei *length,
5271 GLchar *source)
5272{
5273 if (bufsize < 0)
5274 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005275 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005276 return false;
5277 }
5278
5279 Shader *shaderObject = GetValidShader(context, shader);
5280 if (!shaderObject)
5281 {
5282 return false;
5283 }
5284
5285 return true;
5286}
5287
Jamie Madill5b772312018-03-08 20:28:32 -05005288bool ValidateGetUniformLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005289{
5290 if (strstr(name, "gl_") == name)
5291 {
5292 return false;
5293 }
5294
Geoff Langfc32e8b2017-05-31 14:16:59 -04005295 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5296 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005297 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005298 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005299 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005300 return false;
5301 }
5302
Jamie Madillc1d770e2017-04-13 17:31:24 -04005303 Program *programObject = GetValidProgram(context, program);
5304
5305 if (!programObject)
5306 {
5307 return false;
5308 }
5309
5310 if (!programObject->isLinked())
5311 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005312 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005313 return false;
5314 }
5315
5316 return true;
5317}
5318
Jamie Madill5b772312018-03-08 20:28:32 -05005319bool ValidateHint(Context *context, GLenum target, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005320{
5321 switch (mode)
5322 {
5323 case GL_FASTEST:
5324 case GL_NICEST:
5325 case GL_DONT_CARE:
5326 break;
5327
5328 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005329 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005330 return false;
5331 }
5332
5333 switch (target)
5334 {
5335 case GL_GENERATE_MIPMAP_HINT:
5336 break;
5337
Geoff Lange7bd2182017-06-16 16:13:13 -04005338 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
5339 if (context->getClientVersion() < ES_3_0 &&
5340 !context->getExtensions().standardDerivatives)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005341 {
Brandon Jones72f58fa2017-09-19 10:47:41 -07005342 context->handleError(InvalidEnum() << "hint requires OES_standard_derivatives.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005343 return false;
5344 }
5345 break;
5346
Lingfeng Yang6e5bf362018-08-15 09:53:17 -07005347 case GL_PERSPECTIVE_CORRECTION_HINT:
5348 case GL_POINT_SMOOTH_HINT:
5349 case GL_LINE_SMOOTH_HINT:
5350 case GL_FOG_HINT:
5351 if (context->getClientMajorVersion() >= 2)
5352 {
5353 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
5354 return false;
5355 }
5356 break;
5357
Jamie Madillc1d770e2017-04-13 17:31:24 -04005358 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005359 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005360 return false;
5361 }
5362
5363 return true;
5364}
5365
Jamie Madill5b772312018-03-08 20:28:32 -05005366bool ValidateIsBuffer(Context *context, GLuint buffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005367{
5368 return true;
5369}
5370
Jamie Madill5b772312018-03-08 20:28:32 -05005371bool ValidateIsFramebuffer(Context *context, GLuint framebuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005372{
5373 return true;
5374}
5375
Jamie Madill5b772312018-03-08 20:28:32 -05005376bool ValidateIsProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005377{
5378 return true;
5379}
5380
Jamie Madill5b772312018-03-08 20:28:32 -05005381bool ValidateIsRenderbuffer(Context *context, GLuint renderbuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005382{
5383 return true;
5384}
5385
Jamie Madill5b772312018-03-08 20:28:32 -05005386bool ValidateIsShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005387{
5388 return true;
5389}
5390
Jamie Madill5b772312018-03-08 20:28:32 -05005391bool ValidateIsTexture(Context *context, GLuint texture)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005392{
5393 return true;
5394}
5395
Jamie Madill5b772312018-03-08 20:28:32 -05005396bool ValidatePixelStorei(Context *context, GLenum pname, GLint param)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005397{
5398 if (context->getClientMajorVersion() < 3)
5399 {
5400 switch (pname)
5401 {
5402 case GL_UNPACK_IMAGE_HEIGHT:
5403 case GL_UNPACK_SKIP_IMAGES:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005404 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005405 return false;
5406
5407 case GL_UNPACK_ROW_LENGTH:
5408 case GL_UNPACK_SKIP_ROWS:
5409 case GL_UNPACK_SKIP_PIXELS:
5410 if (!context->getExtensions().unpackSubimage)
5411 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005412 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005413 return false;
5414 }
5415 break;
5416
5417 case GL_PACK_ROW_LENGTH:
5418 case GL_PACK_SKIP_ROWS:
5419 case GL_PACK_SKIP_PIXELS:
5420 if (!context->getExtensions().packSubimage)
5421 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005422 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005423 return false;
5424 }
5425 break;
5426 }
5427 }
5428
5429 if (param < 0)
5430 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005431 context->handleError(InvalidValue() << "Cannot use negative values in PixelStorei");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005432 return false;
5433 }
5434
5435 switch (pname)
5436 {
5437 case GL_UNPACK_ALIGNMENT:
5438 if (param != 1 && param != 2 && param != 4 && param != 8)
5439 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005440 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005441 return false;
5442 }
5443 break;
5444
5445 case GL_PACK_ALIGNMENT:
5446 if (param != 1 && param != 2 && param != 4 && param != 8)
5447 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005448 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005449 return false;
5450 }
5451 break;
5452
5453 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Geoff Lang000dab82017-09-27 14:27:07 -04005454 if (!context->getExtensions().packReverseRowOrder)
5455 {
5456 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
5457 }
5458 break;
5459
Jamie Madillc1d770e2017-04-13 17:31:24 -04005460 case GL_UNPACK_ROW_LENGTH:
5461 case GL_UNPACK_IMAGE_HEIGHT:
5462 case GL_UNPACK_SKIP_IMAGES:
5463 case GL_UNPACK_SKIP_ROWS:
5464 case GL_UNPACK_SKIP_PIXELS:
5465 case GL_PACK_ROW_LENGTH:
5466 case GL_PACK_SKIP_ROWS:
5467 case GL_PACK_SKIP_PIXELS:
5468 break;
5469
5470 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005471 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005472 return false;
5473 }
5474
5475 return true;
5476}
5477
Jamie Madill5b772312018-03-08 20:28:32 -05005478bool ValidatePolygonOffset(Context *context, GLfloat factor, GLfloat units)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005479{
5480 return true;
5481}
5482
Jamie Madill5b772312018-03-08 20:28:32 -05005483bool ValidateReleaseShaderCompiler(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005484{
5485 return true;
5486}
5487
Jamie Madill5b772312018-03-08 20:28:32 -05005488bool ValidateSampleCoverage(Context *context, GLfloat value, GLboolean invert)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005489{
5490 return true;
5491}
5492
Jamie Madill5b772312018-03-08 20:28:32 -05005493bool ValidateScissor(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005494{
5495 if (width < 0 || height < 0)
5496 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005497 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005498 return false;
5499 }
5500
5501 return true;
5502}
5503
Jamie Madill5b772312018-03-08 20:28:32 -05005504bool ValidateShaderBinary(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005505 GLsizei n,
5506 const GLuint *shaders,
5507 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04005508 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005509 GLsizei length)
5510{
5511 const std::vector<GLenum> &shaderBinaryFormats = context->getCaps().shaderBinaryFormats;
5512 if (std::find(shaderBinaryFormats.begin(), shaderBinaryFormats.end(), binaryformat) ==
5513 shaderBinaryFormats.end())
5514 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005515 context->handleError(InvalidEnum() << "Invalid shader binary format.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005516 return false;
5517 }
5518
5519 return true;
5520}
5521
Jamie Madill5b772312018-03-08 20:28:32 -05005522bool ValidateShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005523 GLuint shader,
5524 GLsizei count,
5525 const GLchar *const *string,
5526 const GLint *length)
5527{
5528 if (count < 0)
5529 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005530 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005531 return false;
5532 }
5533
Geoff Langfc32e8b2017-05-31 14:16:59 -04005534 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5535 // shader-related entry points
5536 if (context->getExtensions().webglCompatibility)
5537 {
5538 for (GLsizei i = 0; i < count; i++)
5539 {
Geoff Langcab92ee2017-07-19 17:32:07 -04005540 size_t len =
5541 (length && length[i] >= 0) ? static_cast<size_t>(length[i]) : strlen(string[i]);
Geoff Langa71a98e2017-06-19 15:15:00 -04005542
5543 // Backslash as line-continuation is allowed in WebGL 2.0.
Geoff Langcab92ee2017-07-19 17:32:07 -04005544 if (!IsValidESSLShaderSourceString(string[i], len,
5545 context->getClientVersion() >= ES_3_0))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005546 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005547 ANGLE_VALIDATION_ERR(context, InvalidValue(), ShaderSourceInvalidCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005548 return false;
5549 }
5550 }
5551 }
5552
Jamie Madillc1d770e2017-04-13 17:31:24 -04005553 Shader *shaderObject = GetValidShader(context, shader);
5554 if (!shaderObject)
5555 {
5556 return false;
5557 }
5558
5559 return true;
5560}
5561
Jamie Madill5b772312018-03-08 20:28:32 -05005562bool ValidateStencilFunc(Context *context, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005563{
5564 if (!IsValidStencilFunc(func))
5565 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005566 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005567 return false;
5568 }
5569
5570 return true;
5571}
5572
Jamie Madill5b772312018-03-08 20:28:32 -05005573bool ValidateStencilFuncSeparate(Context *context, GLenum face, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005574{
5575 if (!IsValidStencilFace(face))
5576 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005577 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005578 return false;
5579 }
5580
5581 if (!IsValidStencilFunc(func))
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 return true;
5588}
5589
Jamie Madill5b772312018-03-08 20:28:32 -05005590bool ValidateStencilMask(Context *context, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005591{
5592 return true;
5593}
5594
Jamie Madill5b772312018-03-08 20:28:32 -05005595bool ValidateStencilMaskSeparate(Context *context, GLenum face, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005596{
5597 if (!IsValidStencilFace(face))
5598 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005599 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005600 return false;
5601 }
5602
5603 return true;
5604}
5605
Jamie Madill5b772312018-03-08 20:28:32 -05005606bool ValidateStencilOp(Context *context, GLenum fail, GLenum zfail, GLenum zpass)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005607{
5608 if (!IsValidStencilOp(fail))
5609 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005610 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005611 return false;
5612 }
5613
5614 if (!IsValidStencilOp(zfail))
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(zpass))
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 return true;
5627}
5628
Jamie Madill5b772312018-03-08 20:28:32 -05005629bool ValidateStencilOpSeparate(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005630 GLenum face,
5631 GLenum fail,
5632 GLenum zfail,
5633 GLenum zpass)
5634{
5635 if (!IsValidStencilFace(face))
5636 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005637 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005638 return false;
5639 }
5640
5641 return ValidateStencilOp(context, fail, zfail, zpass);
5642}
5643
Jamie Madill5b772312018-03-08 20:28:32 -05005644bool ValidateUniform1f(Context *context, GLint location, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005645{
5646 return ValidateUniform(context, GL_FLOAT, location, 1);
5647}
5648
Jamie Madill5b772312018-03-08 20:28:32 -05005649bool ValidateUniform1fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005650{
5651 return ValidateUniform(context, GL_FLOAT, location, count);
5652}
5653
Jamie Madill5b772312018-03-08 20:28:32 -05005654bool ValidateUniform1i(Context *context, GLint location, GLint x)
Jamie Madillbe849e42017-05-02 15:49:00 -04005655{
5656 return ValidateUniform1iv(context, location, 1, &x);
5657}
5658
Jamie Madill5b772312018-03-08 20:28:32 -05005659bool ValidateUniform2fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005660{
5661 return ValidateUniform(context, GL_FLOAT_VEC2, location, count);
5662}
5663
Jamie Madill5b772312018-03-08 20:28:32 -05005664bool ValidateUniform2i(Context *context, GLint location, GLint x, GLint y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005665{
5666 return ValidateUniform(context, GL_INT_VEC2, location, 1);
5667}
5668
Jamie Madill5b772312018-03-08 20:28:32 -05005669bool ValidateUniform2iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005670{
5671 return ValidateUniform(context, GL_INT_VEC2, location, count);
5672}
5673
Jamie Madill5b772312018-03-08 20:28:32 -05005674bool ValidateUniform3f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005675{
5676 return ValidateUniform(context, GL_FLOAT_VEC3, location, 1);
5677}
5678
Jamie Madill5b772312018-03-08 20:28:32 -05005679bool ValidateUniform3fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005680{
5681 return ValidateUniform(context, GL_FLOAT_VEC3, location, count);
5682}
5683
Jamie Madill5b772312018-03-08 20:28:32 -05005684bool ValidateUniform3i(Context *context, GLint location, GLint x, GLint y, GLint z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005685{
5686 return ValidateUniform(context, GL_INT_VEC3, location, 1);
5687}
5688
Jamie Madill5b772312018-03-08 20:28:32 -05005689bool ValidateUniform3iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005690{
5691 return ValidateUniform(context, GL_INT_VEC3, location, count);
5692}
5693
Jamie Madill5b772312018-03-08 20:28:32 -05005694bool ValidateUniform4f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005695{
5696 return ValidateUniform(context, GL_FLOAT_VEC4, location, 1);
5697}
5698
Jamie Madill5b772312018-03-08 20:28:32 -05005699bool ValidateUniform4fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005700{
5701 return ValidateUniform(context, GL_FLOAT_VEC4, location, count);
5702}
5703
Jamie Madill5b772312018-03-08 20:28:32 -05005704bool ValidateUniform4i(Context *context, GLint location, GLint x, GLint y, GLint z, GLint w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005705{
5706 return ValidateUniform(context, GL_INT_VEC4, location, 1);
5707}
5708
Jamie Madill5b772312018-03-08 20:28:32 -05005709bool ValidateUniform4iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005710{
5711 return ValidateUniform(context, GL_INT_VEC4, location, count);
5712}
5713
Jamie Madill5b772312018-03-08 20:28:32 -05005714bool ValidateUniformMatrix2fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005715 GLint location,
5716 GLsizei count,
5717 GLboolean transpose,
5718 const GLfloat *value)
5719{
5720 return ValidateUniformMatrix(context, GL_FLOAT_MAT2, location, count, transpose);
5721}
5722
Jamie Madill5b772312018-03-08 20:28:32 -05005723bool ValidateUniformMatrix3fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005724 GLint location,
5725 GLsizei count,
5726 GLboolean transpose,
5727 const GLfloat *value)
5728{
5729 return ValidateUniformMatrix(context, GL_FLOAT_MAT3, location, count, transpose);
5730}
5731
Jamie Madill5b772312018-03-08 20:28:32 -05005732bool ValidateUniformMatrix4fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005733 GLint location,
5734 GLsizei count,
5735 GLboolean transpose,
5736 const GLfloat *value)
5737{
5738 return ValidateUniformMatrix(context, GL_FLOAT_MAT4, location, count, transpose);
5739}
5740
Jamie Madill5b772312018-03-08 20:28:32 -05005741bool ValidateValidateProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005742{
5743 Program *programObject = GetValidProgram(context, program);
5744
5745 if (!programObject)
5746 {
5747 return false;
5748 }
5749
5750 return true;
5751}
5752
Jamie Madill5b772312018-03-08 20:28:32 -05005753bool ValidateVertexAttrib1f(Context *context, GLuint index, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005754{
5755 return ValidateVertexAttribIndex(context, index);
5756}
5757
Jamie Madill5b772312018-03-08 20:28:32 -05005758bool ValidateVertexAttrib1fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005759{
5760 return ValidateVertexAttribIndex(context, index);
5761}
5762
Jamie Madill5b772312018-03-08 20:28:32 -05005763bool ValidateVertexAttrib2f(Context *context, GLuint index, GLfloat x, GLfloat y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005764{
5765 return ValidateVertexAttribIndex(context, index);
5766}
5767
Jamie Madill5b772312018-03-08 20:28:32 -05005768bool ValidateVertexAttrib2fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005769{
5770 return ValidateVertexAttribIndex(context, index);
5771}
5772
Jamie Madill5b772312018-03-08 20:28:32 -05005773bool ValidateVertexAttrib3f(Context *context, GLuint index, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005774{
5775 return ValidateVertexAttribIndex(context, index);
5776}
5777
Jamie Madill5b772312018-03-08 20:28:32 -05005778bool ValidateVertexAttrib3fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005779{
5780 return ValidateVertexAttribIndex(context, index);
5781}
5782
Jamie Madill5b772312018-03-08 20:28:32 -05005783bool ValidateVertexAttrib4f(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005784 GLuint index,
5785 GLfloat x,
5786 GLfloat y,
5787 GLfloat z,
5788 GLfloat w)
5789{
5790 return ValidateVertexAttribIndex(context, index);
5791}
5792
Jamie Madill5b772312018-03-08 20:28:32 -05005793bool ValidateVertexAttrib4fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005794{
5795 return ValidateVertexAttribIndex(context, index);
5796}
5797
Jamie Madill5b772312018-03-08 20:28:32 -05005798bool ValidateViewport(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005799{
5800 if (width < 0 || height < 0)
5801 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005802 ANGLE_VALIDATION_ERR(context, InvalidValue(), ViewportNegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005803 return false;
5804 }
5805
5806 return true;
5807}
5808
Jamie Madill5b772312018-03-08 20:28:32 -05005809bool ValidateDrawElements(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -04005810 PrimitiveMode mode,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005811 GLsizei count,
5812 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04005813 const void *indices)
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005814{
5815 return ValidateDrawElementsCommon(context, mode, count, type, indices, 1);
5816}
5817
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08005818bool ValidateGetFramebufferAttachmentParameteriv(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04005819 GLenum target,
5820 GLenum attachment,
5821 GLenum pname,
5822 GLint *params)
5823{
5824 return ValidateGetFramebufferAttachmentParameterivBase(context, target, attachment, pname,
5825 nullptr);
5826}
5827
Jamie Madill5b772312018-03-08 20:28:32 -05005828bool ValidateGetProgramiv(Context *context, GLuint program, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04005829{
5830 return ValidateGetProgramivBase(context, program, pname, nullptr);
5831}
5832
Jamie Madill5b772312018-03-08 20:28:32 -05005833bool ValidateCopyTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005834 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005835 GLint level,
5836 GLenum internalformat,
5837 GLint x,
5838 GLint y,
5839 GLsizei width,
5840 GLsizei height,
5841 GLint border)
5842{
5843 if (context->getClientMajorVersion() < 3)
5844 {
5845 return ValidateES2CopyTexImageParameters(context, target, level, internalformat, false, 0,
5846 0, x, y, width, height, border);
5847 }
5848
5849 ASSERT(context->getClientMajorVersion() == 3);
5850 return ValidateES3CopyTexImage2DParameters(context, target, level, internalformat, false, 0, 0,
5851 0, x, y, width, height, border);
5852}
5853
5854bool ValidateCopyTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005855 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005856 GLint level,
5857 GLint xoffset,
5858 GLint yoffset,
5859 GLint x,
5860 GLint y,
5861 GLsizei width,
5862 GLsizei height)
5863{
5864 if (context->getClientMajorVersion() < 3)
5865 {
5866 return ValidateES2CopyTexImageParameters(context, target, level, GL_NONE, true, xoffset,
5867 yoffset, x, y, width, height, 0);
5868 }
5869
5870 return ValidateES3CopyTexImage2DParameters(context, target, level, GL_NONE, true, xoffset,
5871 yoffset, 0, x, y, width, height, 0);
5872}
5873
5874bool ValidateDeleteBuffers(Context *context, GLint n, const GLuint *)
5875{
5876 return ValidateGenOrDelete(context, n);
5877}
5878
5879bool ValidateDeleteFramebuffers(Context *context, GLint n, const GLuint *)
5880{
5881 return ValidateGenOrDelete(context, n);
5882}
5883
5884bool ValidateDeleteRenderbuffers(Context *context, GLint n, const GLuint *)
5885{
5886 return ValidateGenOrDelete(context, n);
5887}
5888
5889bool ValidateDeleteTextures(Context *context, GLint n, const GLuint *)
5890{
5891 return ValidateGenOrDelete(context, n);
5892}
5893
5894bool ValidateDisable(Context *context, GLenum cap)
5895{
5896 if (!ValidCap(context, cap, false))
5897 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005898 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005899 return false;
5900 }
5901
5902 return true;
5903}
5904
5905bool ValidateEnable(Context *context, GLenum cap)
5906{
5907 if (!ValidCap(context, cap, false))
5908 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005909 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005910 return false;
5911 }
5912
5913 if (context->getLimitations().noSampleAlphaToCoverageSupport &&
5914 cap == GL_SAMPLE_ALPHA_TO_COVERAGE)
5915 {
5916 const char *errorMessage = "Current renderer doesn't support alpha-to-coverage";
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005917 context->handleError(InvalidOperation() << errorMessage);
Jamie Madillbe849e42017-05-02 15:49:00 -04005918
5919 // We also output an error message to the debugger window if tracing is active, so that
5920 // developers can see the error message.
5921 ERR() << errorMessage;
5922 return false;
5923 }
5924
5925 return true;
5926}
5927
5928bool ValidateFramebufferRenderbuffer(Context *context,
5929 GLenum target,
5930 GLenum attachment,
5931 GLenum renderbuffertarget,
5932 GLuint renderbuffer)
5933{
Geoff Lange8afa902017-09-27 15:00:43 -04005934 if (!ValidFramebufferTarget(context, target))
Jamie Madillbe849e42017-05-02 15:49:00 -04005935 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005936 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
5937 return false;
5938 }
5939
5940 if (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0)
5941 {
5942 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005943 return false;
5944 }
5945
5946 return ValidateFramebufferRenderbufferParameters(context, target, attachment,
5947 renderbuffertarget, renderbuffer);
5948}
5949
5950bool ValidateFramebufferTexture2D(Context *context,
5951 GLenum target,
5952 GLenum attachment,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005953 TextureTarget textarget,
Jamie Madillbe849e42017-05-02 15:49:00 -04005954 GLuint texture,
5955 GLint level)
5956{
5957 // Attachments are required to be bound to level 0 without ES3 or the GL_OES_fbo_render_mipmap
5958 // extension
5959 if (context->getClientMajorVersion() < 3 && !context->getExtensions().fboRenderMipmap &&
5960 level != 0)
5961 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005962 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidFramebufferTextureLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04005963 return false;
5964 }
5965
5966 if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
5967 {
5968 return false;
5969 }
5970
5971 if (texture != 0)
5972 {
5973 gl::Texture *tex = context->getTexture(texture);
5974 ASSERT(tex);
5975
5976 const gl::Caps &caps = context->getCaps();
5977
5978 switch (textarget)
5979 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005980 case TextureTarget::_2D:
Jamie Madillbe849e42017-05-02 15:49:00 -04005981 {
5982 if (level > gl::log2(caps.max2DTextureSize))
5983 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005984 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04005985 return false;
5986 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05005987 if (tex->getType() != TextureType::_2D)
Jamie Madillbe849e42017-05-02 15:49:00 -04005988 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005989 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005990 return false;
5991 }
5992 }
5993 break;
5994
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005995 case TextureTarget::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04005996 {
5997 if (level != 0)
5998 {
5999 context->handleError(InvalidValue());
6000 return false;
6001 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006002 if (tex->getType() != TextureType::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006003 {
6004 context->handleError(InvalidOperation()
6005 << "Textarget must match the texture target type.");
6006 return false;
6007 }
6008 }
6009 break;
6010
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006011 case TextureTarget::CubeMapNegativeX:
6012 case TextureTarget::CubeMapNegativeY:
6013 case TextureTarget::CubeMapNegativeZ:
6014 case TextureTarget::CubeMapPositiveX:
6015 case TextureTarget::CubeMapPositiveY:
6016 case TextureTarget::CubeMapPositiveZ:
Jamie Madillbe849e42017-05-02 15:49:00 -04006017 {
6018 if (level > gl::log2(caps.maxCubeMapTextureSize))
6019 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006020 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04006021 return false;
6022 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006023 if (tex->getType() != TextureType::CubeMap)
Jamie Madillbe849e42017-05-02 15:49:00 -04006024 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006025 context->handleError(InvalidOperation()
6026 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006027 return false;
6028 }
6029 }
6030 break;
6031
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006032 case TextureTarget::_2DMultisample:
Jamie Madillbe849e42017-05-02 15:49:00 -04006033 {
6034 if (context->getClientVersion() < ES_3_1)
6035 {
Brandon Jonesafa75152017-07-21 13:11:29 -07006036 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
Jamie Madillbe849e42017-05-02 15:49:00 -04006037 return false;
6038 }
6039
6040 if (level != 0)
6041 {
Brandon Jonesafa75152017-07-21 13:11:29 -07006042 ANGLE_VALIDATION_ERR(context, InvalidValue(), LevelNotZero);
Jamie Madillbe849e42017-05-02 15:49:00 -04006043 return false;
6044 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006045 if (tex->getType() != TextureType::_2DMultisample)
Jamie Madillbe849e42017-05-02 15:49:00 -04006046 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006047 context->handleError(InvalidOperation()
6048 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006049 return false;
6050 }
6051 }
6052 break;
6053
6054 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07006055 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006056 return false;
6057 }
Jamie Madillbe849e42017-05-02 15:49:00 -04006058 }
6059
6060 return true;
6061}
6062
6063bool ValidateGenBuffers(Context *context, GLint n, GLuint *)
6064{
6065 return ValidateGenOrDelete(context, n);
6066}
6067
6068bool ValidateGenFramebuffers(Context *context, GLint n, GLuint *)
6069{
6070 return ValidateGenOrDelete(context, n);
6071}
6072
6073bool ValidateGenRenderbuffers(Context *context, GLint n, GLuint *)
6074{
6075 return ValidateGenOrDelete(context, n);
6076}
6077
6078bool ValidateGenTextures(Context *context, GLint n, GLuint *)
6079{
6080 return ValidateGenOrDelete(context, n);
6081}
6082
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006083bool ValidateGenerateMipmap(Context *context, TextureType target)
Jamie Madillbe849e42017-05-02 15:49:00 -04006084{
6085 if (!ValidTextureTarget(context, target))
6086 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006087 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006088 return false;
6089 }
6090
6091 Texture *texture = context->getTargetTexture(target);
6092
6093 if (texture == nullptr)
6094 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006095 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04006096 return false;
6097 }
6098
6099 const GLuint effectiveBaseLevel = texture->getTextureState().getEffectiveBaseLevel();
6100
6101 // This error isn't spelled out in the spec in a very explicit way, but we interpret the spec so
6102 // that out-of-range base level has a non-color-renderable / non-texture-filterable format.
6103 if (effectiveBaseLevel >= gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
6104 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006105 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -04006106 return false;
6107 }
6108
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006109 TextureTarget baseTarget = (target == TextureType::CubeMap)
6110 ? TextureTarget::CubeMapPositiveX
6111 : NonCubeTextureTypeToTarget(target);
Geoff Lang536eca12017-09-13 11:23:35 -04006112 const auto &format = *(texture->getFormat(baseTarget, effectiveBaseLevel).info);
6113 if (format.sizedInternalFormat == GL_NONE || format.compressed || format.depthBits > 0 ||
6114 format.stencilBits > 0)
Brandon Jones6cad5662017-06-14 13:25:13 -07006115 {
6116 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
6117 return false;
6118 }
6119
Geoff Lang536eca12017-09-13 11:23:35 -04006120 // GenerateMipmap accepts formats that are unsized or both color renderable and filterable.
6121 bool formatUnsized = !format.sized;
6122 bool formatColorRenderableAndFilterable =
6123 format.filterSupport(context->getClientVersion(), context->getExtensions()) &&
Yuly Novikovf15f8862018-06-04 18:59:41 -04006124 format.textureAttachmentSupport(context->getClientVersion(), context->getExtensions());
Geoff Lang536eca12017-09-13 11:23:35 -04006125 if (!formatUnsized && !formatColorRenderableAndFilterable)
Jamie Madillbe849e42017-05-02 15:49:00 -04006126 {
Geoff Lang536eca12017-09-13 11:23:35 -04006127 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006128 return false;
6129 }
6130
Geoff Lang536eca12017-09-13 11:23:35 -04006131 // GL_EXT_sRGB adds an unsized SRGB (no alpha) format which has explicitly disabled mipmap
6132 // generation
6133 if (format.colorEncoding == GL_SRGB && format.format == GL_RGB)
6134 {
6135 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
6136 return false;
6137 }
6138
Jiange2c00842018-07-13 16:50:49 +08006139 // According to the OpenGL extension spec EXT_sRGB.txt, EXT_SRGB is based on ES 2.0 and
6140 // generateMipmap is not allowed if texture format is SRGB_EXT or SRGB_ALPHA_EXT.
6141 if (context->getClientVersion() < Version(3, 0) && format.colorEncoding == GL_SRGB)
Jamie Madillbe849e42017-05-02 15:49:00 -04006142 {
Geoff Lang536eca12017-09-13 11:23:35 -04006143 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006144 return false;
6145 }
6146
6147 // Non-power of 2 ES2 check
6148 if (context->getClientVersion() < Version(3, 0) && !context->getExtensions().textureNPOT &&
6149 (!isPow2(static_cast<int>(texture->getWidth(baseTarget, 0))) ||
6150 !isPow2(static_cast<int>(texture->getHeight(baseTarget, 0)))))
6151 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006152 ASSERT(target == TextureType::_2D || target == TextureType::Rectangle ||
6153 target == TextureType::CubeMap);
Brandon Jones6cad5662017-06-14 13:25:13 -07006154 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotPow2);
Jamie Madillbe849e42017-05-02 15:49:00 -04006155 return false;
6156 }
6157
6158 // Cube completeness check
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006159 if (target == TextureType::CubeMap && !texture->getTextureState().isCubeComplete())
Jamie Madillbe849e42017-05-02 15:49:00 -04006160 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006161 ANGLE_VALIDATION_ERR(context, InvalidOperation(), CubemapIncomplete);
Jamie Madillbe849e42017-05-02 15:49:00 -04006162 return false;
6163 }
6164
6165 return true;
6166}
6167
Jamie Madill5b772312018-03-08 20:28:32 -05006168bool ValidateGetBufferParameteriv(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04006169 BufferBinding target,
Jamie Madillbe849e42017-05-02 15:49:00 -04006170 GLenum pname,
6171 GLint *params)
6172{
6173 return ValidateGetBufferParameterBase(context, target, pname, false, nullptr);
6174}
6175
6176bool ValidateGetRenderbufferParameteriv(Context *context,
6177 GLenum target,
6178 GLenum pname,
6179 GLint *params)
6180{
6181 return ValidateGetRenderbufferParameterivBase(context, target, pname, nullptr);
6182}
6183
6184bool ValidateGetShaderiv(Context *context, GLuint shader, GLenum pname, GLint *params)
6185{
6186 return ValidateGetShaderivBase(context, shader, pname, nullptr);
6187}
6188
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006189bool ValidateGetTexParameterfv(Context *context, TextureType target, GLenum pname, GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006190{
6191 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6192}
6193
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006194bool ValidateGetTexParameteriv(Context *context, TextureType target, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006195{
6196 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6197}
6198
6199bool ValidateGetUniformfv(Context *context, GLuint program, GLint location, GLfloat *params)
6200{
6201 return ValidateGetUniformBase(context, program, location);
6202}
6203
6204bool ValidateGetUniformiv(Context *context, GLuint program, GLint location, GLint *params)
6205{
6206 return ValidateGetUniformBase(context, program, location);
6207}
6208
6209bool ValidateGetVertexAttribfv(Context *context, GLuint index, GLenum pname, GLfloat *params)
6210{
6211 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6212}
6213
6214bool ValidateGetVertexAttribiv(Context *context, GLuint index, GLenum pname, GLint *params)
6215{
6216 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6217}
6218
6219bool ValidateGetVertexAttribPointerv(Context *context, GLuint index, GLenum pname, void **pointer)
6220{
6221 return ValidateGetVertexAttribBase(context, index, pname, nullptr, true, false);
6222}
6223
6224bool ValidateIsEnabled(Context *context, GLenum cap)
6225{
6226 if (!ValidCap(context, cap, true))
6227 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006228 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006229 return false;
6230 }
6231
6232 return true;
6233}
6234
6235bool ValidateLinkProgram(Context *context, GLuint program)
6236{
6237 if (context->hasActiveTransformFeedback(program))
6238 {
6239 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006240 context->handleError(InvalidOperation() << "Cannot link program while program is "
6241 "associated with an active transform "
6242 "feedback object.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006243 return false;
6244 }
6245
6246 Program *programObject = GetValidProgram(context, program);
6247 if (!programObject)
6248 {
6249 return false;
6250 }
6251
6252 return true;
6253}
6254
Jamie Madill4928b7c2017-06-20 12:57:39 -04006255bool ValidateReadPixels(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04006256 GLint x,
6257 GLint y,
6258 GLsizei width,
6259 GLsizei height,
6260 GLenum format,
6261 GLenum type,
6262 void *pixels)
6263{
6264 return ValidateReadPixelsBase(context, x, y, width, height, format, type, -1, nullptr, nullptr,
6265 nullptr, pixels);
6266}
6267
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006268bool ValidateTexParameterf(Context *context, TextureType target, GLenum pname, GLfloat param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006269{
Lingfeng Yangf97641c2018-06-21 19:22:45 -07006270 return ValidateTexParameterBase(context, target, pname, 1, &param);
Jamie Madillbe849e42017-05-02 15:49:00 -04006271}
6272
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006273bool ValidateTexParameterfv(Context *context,
6274 TextureType target,
6275 GLenum pname,
6276 const GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006277{
6278 return ValidateTexParameterBase(context, target, pname, -1, params);
6279}
6280
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006281bool ValidateTexParameteri(Context *context, TextureType target, GLenum pname, GLint param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006282{
Lingfeng Yangf97641c2018-06-21 19:22:45 -07006283 return ValidateTexParameterBase(context, target, pname, 1, &param);
Jamie Madillbe849e42017-05-02 15:49:00 -04006284}
6285
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006286bool ValidateTexParameteriv(Context *context, TextureType target, GLenum pname, const GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006287{
6288 return ValidateTexParameterBase(context, target, pname, -1, params);
6289}
6290
6291bool ValidateUseProgram(Context *context, GLuint program)
6292{
6293 if (program != 0)
6294 {
Jamie Madill44a6fbf2018-10-02 13:38:56 -04006295 Program *programObject = context->getProgramResolveLink(program);
Jamie Madillbe849e42017-05-02 15:49:00 -04006296 if (!programObject)
6297 {
6298 // ES 3.1.0 section 7.3 page 72
6299 if (context->getShader(program))
6300 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006301 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006302 return false;
6303 }
6304 else
6305 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006306 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006307 return false;
6308 }
6309 }
6310 if (!programObject->isLinked())
6311 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006312 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillbe849e42017-05-02 15:49:00 -04006313 return false;
6314 }
6315 }
6316 if (context->getGLState().isTransformFeedbackActiveUnpaused())
6317 {
6318 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006319 context
6320 ->handleError(InvalidOperation()
6321 << "Cannot change active program while transform feedback is unpaused.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006322 return false;
6323 }
6324
6325 return true;
6326}
6327
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006328bool ValidateDeleteFencesNV(Context *context, GLsizei n, const GLuint *fences)
6329{
6330 if (!context->getExtensions().fence)
6331 {
6332 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6333 return false;
6334 }
6335
6336 if (n < 0)
6337 {
6338 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
6339 return false;
6340 }
6341
6342 return true;
6343}
6344
6345bool ValidateFinishFenceNV(Context *context, GLuint fence)
6346{
6347 if (!context->getExtensions().fence)
6348 {
6349 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6350 return false;
6351 }
6352
6353 FenceNV *fenceObject = context->getFenceNV(fence);
6354
6355 if (fenceObject == nullptr)
6356 {
6357 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6358 return false;
6359 }
6360
6361 if (!fenceObject->isSet())
6362 {
6363 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6364 return false;
6365 }
6366
6367 return true;
6368}
6369
6370bool ValidateGenFencesNV(Context *context, GLsizei n, GLuint *fences)
6371{
6372 if (!context->getExtensions().fence)
6373 {
6374 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6375 return false;
6376 }
6377
6378 if (n < 0)
6379 {
6380 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
6381 return false;
6382 }
6383
6384 return true;
6385}
6386
6387bool ValidateGetFenceivNV(Context *context, GLuint fence, GLenum pname, GLint *params)
6388{
6389 if (!context->getExtensions().fence)
6390 {
6391 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6392 return false;
6393 }
6394
6395 FenceNV *fenceObject = context->getFenceNV(fence);
6396
6397 if (fenceObject == nullptr)
6398 {
6399 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6400 return false;
6401 }
6402
6403 if (!fenceObject->isSet())
6404 {
6405 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6406 return false;
6407 }
6408
6409 switch (pname)
6410 {
6411 case GL_FENCE_STATUS_NV:
6412 case GL_FENCE_CONDITION_NV:
6413 break;
6414
6415 default:
6416 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPname);
6417 return false;
6418 }
6419
6420 return true;
6421}
6422
6423bool ValidateGetGraphicsResetStatusEXT(Context *context)
6424{
6425 if (!context->getExtensions().robustness)
6426 {
6427 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6428 return false;
6429 }
6430
6431 return true;
6432}
6433
6434bool ValidateGetTranslatedShaderSourceANGLE(Context *context,
6435 GLuint shader,
6436 GLsizei bufsize,
6437 GLsizei *length,
6438 GLchar *source)
6439{
6440 if (!context->getExtensions().translatedShaderSource)
6441 {
6442 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6443 return false;
6444 }
6445
6446 if (bufsize < 0)
6447 {
6448 context->handleError(InvalidValue());
6449 return false;
6450 }
6451
6452 Shader *shaderObject = context->getShader(shader);
6453
6454 if (!shaderObject)
6455 {
6456 context->handleError(InvalidOperation());
6457 return false;
6458 }
6459
6460 return true;
6461}
6462
6463bool ValidateIsFenceNV(Context *context, GLuint fence)
6464{
6465 if (!context->getExtensions().fence)
6466 {
6467 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6468 return false;
6469 }
6470
6471 return true;
6472}
6473
Jamie Madill007530e2017-12-28 14:27:04 -05006474bool ValidateSetFenceNV(Context *context, GLuint fence, GLenum condition)
6475{
6476 if (!context->getExtensions().fence)
6477 {
6478 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6479 return false;
6480 }
6481
6482 if (condition != GL_ALL_COMPLETED_NV)
6483 {
6484 context->handleError(InvalidEnum());
6485 return false;
6486 }
6487
6488 FenceNV *fenceObject = context->getFenceNV(fence);
6489
6490 if (fenceObject == nullptr)
6491 {
6492 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6493 return false;
6494 }
6495
6496 return true;
6497}
6498
6499bool ValidateTestFenceNV(Context *context, GLuint fence)
6500{
6501 if (!context->getExtensions().fence)
6502 {
6503 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6504 return false;
6505 }
6506
6507 FenceNV *fenceObject = context->getFenceNV(fence);
6508
6509 if (fenceObject == nullptr)
6510 {
6511 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6512 return false;
6513 }
6514
6515 if (fenceObject->isSet() != GL_TRUE)
6516 {
6517 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6518 return false;
6519 }
6520
6521 return true;
6522}
6523
6524bool ValidateTexStorage2DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006525 TextureType type,
Jamie Madill007530e2017-12-28 14:27:04 -05006526 GLsizei levels,
6527 GLenum internalformat,
6528 GLsizei width,
6529 GLsizei height)
6530{
6531 if (!context->getExtensions().textureStorage)
6532 {
6533 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6534 return false;
6535 }
6536
6537 if (context->getClientMajorVersion() < 3)
6538 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006539 return ValidateES2TexStorageParameters(context, type, levels, internalformat, width,
Jamie Madill007530e2017-12-28 14:27:04 -05006540 height);
6541 }
6542
6543 ASSERT(context->getClientMajorVersion() >= 3);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006544 return ValidateES3TexStorage2DParameters(context, type, levels, internalformat, width, height,
Jamie Madill007530e2017-12-28 14:27:04 -05006545 1);
6546}
6547
6548bool ValidateVertexAttribDivisorANGLE(Context *context, GLuint index, GLuint divisor)
6549{
6550 if (!context->getExtensions().instancedArrays)
6551 {
6552 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6553 return false;
6554 }
6555
6556 if (index >= MAX_VERTEX_ATTRIBS)
6557 {
6558 context->handleError(InvalidValue());
6559 return false;
6560 }
6561
6562 if (context->getLimitations().attributeZeroRequiresZeroDivisorInEXT)
6563 {
6564 if (index == 0 && divisor != 0)
6565 {
6566 const char *errorMessage =
6567 "The current context doesn't support setting a non-zero divisor on the "
6568 "attribute with index zero. "
6569 "Please reorder the attributes in your vertex shader so that attribute zero "
6570 "can have a zero divisor.";
6571 context->handleError(InvalidOperation() << errorMessage);
6572
6573 // We also output an error message to the debugger window if tracing is active, so
6574 // that developers can see the error message.
6575 ERR() << errorMessage;
6576 return false;
6577 }
6578 }
6579
6580 return true;
6581}
6582
6583bool ValidateTexImage3DOES(Context *context,
6584 GLenum target,
6585 GLint level,
6586 GLenum internalformat,
6587 GLsizei width,
6588 GLsizei height,
6589 GLsizei depth,
6590 GLint border,
6591 GLenum format,
6592 GLenum type,
6593 const void *pixels)
6594{
6595 UNIMPLEMENTED(); // FIXME
6596 return false;
6597}
6598
6599bool ValidatePopGroupMarkerEXT(Context *context)
6600{
6601 if (!context->getExtensions().debugMarker)
6602 {
6603 // The debug marker calls should not set error state
6604 // However, it seems reasonable to set an error state if the extension is not enabled
6605 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6606 return false;
6607 }
6608
6609 return true;
6610}
6611
Jamie Madillfa920eb2018-01-04 11:45:50 -05006612bool ValidateTexStorage1DEXT(Context *context,
6613 GLenum target,
6614 GLsizei levels,
6615 GLenum internalformat,
6616 GLsizei width)
6617{
6618 UNIMPLEMENTED();
6619 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6620 return false;
6621}
6622
6623bool ValidateTexStorage3DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006624 TextureType target,
Jamie Madillfa920eb2018-01-04 11:45:50 -05006625 GLsizei levels,
6626 GLenum internalformat,
6627 GLsizei width,
6628 GLsizei height,
6629 GLsizei depth)
6630{
6631 if (!context->getExtensions().textureStorage)
6632 {
6633 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6634 return false;
6635 }
6636
6637 if (context->getClientMajorVersion() < 3)
6638 {
6639 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6640 return false;
6641 }
6642
6643 return ValidateES3TexStorage3DParameters(context, target, levels, internalformat, width, height,
6644 depth);
6645}
6646
jchen1082af6202018-06-22 10:59:52 +08006647bool ValidateMaxShaderCompilerThreadsKHR(Context *context, GLuint count)
6648{
6649 if (!context->getExtensions().parallelShaderCompile)
6650 {
6651 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6652 return false;
6653 }
6654 return true;
6655}
6656
Jamie Madillc29968b2016-01-20 11:17:23 -05006657} // namespace gl