blob: 15730176c765aacb96df1f2406288f3e8e29ce92 [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 ValidateBindBuffer(Context *context, BufferBinding target, GLuint buffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004516{
Corentin Walleze4477002017-12-01 14:39:58 -05004517 if (!context->isValidBufferBinding(target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004518 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004519 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004520 return false;
4521 }
4522
4523 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4524 !context->isBufferGenerated(buffer))
4525 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004526 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
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 ValidateBindFramebuffer(Context *context, GLenum target, GLuint framebuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004534{
Geoff Lange8afa902017-09-27 15:00:43 -04004535 if (!ValidFramebufferTarget(context, target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004536 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004537 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004538 return false;
4539 }
4540
4541 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4542 !context->isFramebufferGenerated(framebuffer))
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 -05004551bool ValidateBindRenderbuffer(Context *context, GLenum target, GLuint renderbuffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004552{
4553 if (target != GL_RENDERBUFFER)
4554 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004555 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004556 return false;
4557 }
4558
4559 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4560 !context->isRenderbufferGenerated(renderbuffer))
4561 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004562 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004563 return false;
4564 }
4565
4566 return true;
4567}
4568
Jamie Madill5b772312018-03-08 20:28:32 -05004569static bool ValidBlendEquationMode(const Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004570{
4571 switch (mode)
4572 {
4573 case GL_FUNC_ADD:
4574 case GL_FUNC_SUBTRACT:
4575 case GL_FUNC_REVERSE_SUBTRACT:
Geoff Lang50cac572017-09-26 17:37:43 -04004576 return true;
4577
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004578 case GL_MIN:
4579 case GL_MAX:
Geoff Lang50cac572017-09-26 17:37:43 -04004580 return context->getClientVersion() >= ES_3_0 || context->getExtensions().blendMinMax;
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004581
4582 default:
4583 return false;
4584 }
4585}
4586
Jamie Madill5b772312018-03-08 20:28:32 -05004587bool ValidateBlendColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004588{
4589 return true;
4590}
4591
Jamie Madill5b772312018-03-08 20:28:32 -05004592bool ValidateBlendEquation(Context *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004593{
Geoff Lang50cac572017-09-26 17:37:43 -04004594 if (!ValidBlendEquationMode(context, mode))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004595 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004596 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004597 return false;
4598 }
4599
4600 return true;
4601}
4602
Jamie Madill5b772312018-03-08 20:28:32 -05004603bool ValidateBlendEquationSeparate(Context *context, GLenum modeRGB, GLenum modeAlpha)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004604{
Geoff Lang50cac572017-09-26 17:37:43 -04004605 if (!ValidBlendEquationMode(context, modeRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004606 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004607 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004608 return false;
4609 }
4610
Geoff Lang50cac572017-09-26 17:37:43 -04004611 if (!ValidBlendEquationMode(context, modeAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004612 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004613 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004614 return false;
4615 }
4616
4617 return true;
4618}
4619
Jamie Madill5b772312018-03-08 20:28:32 -05004620bool ValidateBlendFunc(Context *context, GLenum sfactor, GLenum dfactor)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004621{
4622 return ValidateBlendFuncSeparate(context, sfactor, dfactor, sfactor, dfactor);
4623}
4624
Jamie Madill5b772312018-03-08 20:28:32 -05004625bool ValidateBlendFuncSeparate(Context *context,
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004626 GLenum srcRGB,
4627 GLenum dstRGB,
4628 GLenum srcAlpha,
4629 GLenum dstAlpha)
4630{
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03004631 if (!ValidSrcBlendFunc(context, srcRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004632 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004633 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004634 return false;
4635 }
4636
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03004637 if (!ValidDstBlendFunc(context, dstRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004638 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004639 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004640 return false;
4641 }
4642
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03004643 if (!ValidSrcBlendFunc(context, srcAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004644 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004645 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004646 return false;
4647 }
4648
Olli Etuahoab5fb5e2018-09-18 17:23:28 +03004649 if (!ValidDstBlendFunc(context, dstAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004650 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004651 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004652 return false;
4653 }
4654
Frank Henigman146e8a12017-03-02 23:22:37 -05004655 if (context->getLimitations().noSimultaneousConstantColorAndAlphaBlendFunc ||
4656 context->getExtensions().webglCompatibility)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004657 {
4658 bool constantColorUsed =
4659 (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
4660 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
4661
4662 bool constantAlphaUsed =
4663 (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
4664 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
4665
4666 if (constantColorUsed && constantAlphaUsed)
4667 {
Frank Henigman146e8a12017-03-02 23:22:37 -05004668 const char *msg;
4669 if (context->getExtensions().webglCompatibility)
4670 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004671 msg = kErrorInvalidConstantColor;
Frank Henigman146e8a12017-03-02 23:22:37 -05004672 }
4673 else
4674 {
4675 msg =
4676 "Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and "
4677 "GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR not supported by this "
4678 "implementation.";
Jamie Madilla2f043d2018-07-10 17:21:20 -04004679 WARN() << msg;
Frank Henigman146e8a12017-03-02 23:22:37 -05004680 }
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004681 context->handleError(InvalidOperation() << msg);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004682 return false;
4683 }
4684 }
4685
4686 return true;
4687}
4688
Geoff Langc339c4e2016-11-29 10:37:36 -05004689bool ValidateGetString(Context *context, GLenum name)
4690{
4691 switch (name)
4692 {
4693 case GL_VENDOR:
4694 case GL_RENDERER:
4695 case GL_VERSION:
4696 case GL_SHADING_LANGUAGE_VERSION:
4697 case GL_EXTENSIONS:
4698 break;
4699
4700 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
4701 if (!context->getExtensions().requestExtension)
4702 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004703 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004704 return false;
4705 }
4706 break;
4707
4708 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07004709 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004710 return false;
4711 }
4712
4713 return true;
4714}
4715
Jamie Madill5b772312018-03-08 20:28:32 -05004716bool ValidateLineWidth(Context *context, GLfloat width)
Geoff Lang47c48082016-12-07 15:38:13 -05004717{
4718 if (width <= 0.0f || isNaN(width))
4719 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004720 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidWidth);
Geoff Lang47c48082016-12-07 15:38:13 -05004721 return false;
4722 }
4723
4724 return true;
4725}
4726
Jamie Madill5b772312018-03-08 20:28:32 -05004727bool ValidateVertexAttribPointer(Context *context,
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004728 GLuint index,
4729 GLint size,
4730 GLenum type,
4731 GLboolean normalized,
4732 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04004733 const void *ptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004734{
Shao80957d92017-02-20 21:25:59 +08004735 if (!ValidateVertexFormatBase(context, index, size, type, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004736 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004737 return false;
4738 }
4739
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004740 if (stride < 0)
4741 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004742 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeStride);
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004743 return false;
4744 }
4745
Shao80957d92017-02-20 21:25:59 +08004746 const Caps &caps = context->getCaps();
4747 if (context->getClientVersion() >= ES_3_1)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004748 {
Shao80957d92017-02-20 21:25:59 +08004749 if (stride > caps.maxVertexAttribStride)
4750 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004751 context->handleError(InvalidValue()
4752 << "stride cannot be greater than MAX_VERTEX_ATTRIB_STRIDE.");
Shao80957d92017-02-20 21:25:59 +08004753 return false;
4754 }
4755
4756 if (index >= caps.maxVertexAttribBindings)
4757 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004758 context->handleError(InvalidValue()
4759 << "index must be smaller than MAX_VERTEX_ATTRIB_BINDINGS.");
Shao80957d92017-02-20 21:25:59 +08004760 return false;
4761 }
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004762 }
4763
4764 // [OpenGL ES 3.0.2] Section 2.8 page 24:
4765 // An INVALID_OPERATION error is generated when a non-zero vertex array object
4766 // is bound, zero is bound to the ARRAY_BUFFER buffer object binding point,
4767 // and the pointer argument is not NULL.
Geoff Langfeb8c682017-02-13 16:07:35 -05004768 bool nullBufferAllowed = context->getGLState().areClientArraysEnabled() &&
4769 context->getGLState().getVertexArray()->id() == 0;
Corentin Wallez336129f2017-10-17 15:55:40 -04004770 if (!nullBufferAllowed && context->getGLState().getTargetBuffer(BufferBinding::Array) == 0 &&
4771 ptr != nullptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004772 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004773 context
4774 ->handleError(InvalidOperation()
4775 << "Client data cannot be used with a non-default vertex array object.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004776 return false;
4777 }
4778
4779 if (context->getExtensions().webglCompatibility)
4780 {
4781 // WebGL 1.0 [Section 6.14] Fixed point support
4782 // The WebGL API does not support the GL_FIXED data type.
4783 if (type == GL_FIXED)
4784 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004785 context->handleError(InvalidEnum() << "GL_FIXED is not supported in WebGL.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004786 return false;
4787 }
4788
Geoff Lang2d62ab72017-03-23 16:54:40 -04004789 if (!ValidateWebGLVertexAttribPointer(context, type, normalized, stride, ptr, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004790 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004791 return false;
4792 }
4793 }
4794
4795 return true;
4796}
4797
Jamie Madill5b772312018-03-08 20:28:32 -05004798bool ValidateDepthRangef(Context *context, GLfloat zNear, GLfloat zFar)
Frank Henigman6137ddc2017-02-10 18:55:07 -05004799{
4800 if (context->getExtensions().webglCompatibility && zNear > zFar)
4801 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004802 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidDepthRange);
Frank Henigman6137ddc2017-02-10 18:55:07 -05004803 return false;
4804 }
4805
4806 return true;
4807}
4808
Jamie Madill5b772312018-03-08 20:28:32 -05004809bool ValidateRenderbufferStorage(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05004810 GLenum target,
4811 GLenum internalformat,
4812 GLsizei width,
4813 GLsizei height)
4814{
4815 return ValidateRenderbufferStorageParametersBase(context, target, 0, internalformat, width,
4816 height);
4817}
4818
Jamie Madill5b772312018-03-08 20:28:32 -05004819bool ValidateRenderbufferStorageMultisampleANGLE(Context *context,
Jamie Madille8fb6402017-02-14 17:56:40 -05004820 GLenum target,
4821 GLsizei samples,
4822 GLenum internalformat,
4823 GLsizei width,
4824 GLsizei height)
4825{
4826 if (!context->getExtensions().framebufferMultisample)
4827 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004828 context->handleError(InvalidOperation()
4829 << "GL_ANGLE_framebuffer_multisample not available");
Jamie Madille8fb6402017-02-14 17:56:40 -05004830 return false;
4831 }
4832
4833 // ANGLE_framebuffer_multisample states that the value of samples must be less than or equal
4834 // to MAX_SAMPLES_ANGLE (Context::getCaps().maxSamples) otherwise GL_INVALID_OPERATION is
4835 // generated.
4836 if (static_cast<GLuint>(samples) > context->getCaps().maxSamples)
4837 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004838 context->handleError(InvalidValue());
Jamie Madille8fb6402017-02-14 17:56:40 -05004839 return false;
4840 }
4841
4842 // ANGLE_framebuffer_multisample states GL_OUT_OF_MEMORY is generated on a failure to create
4843 // the specified storage. This is different than ES 3.0 in which a sample number higher
4844 // than the maximum sample number supported by this format generates a GL_INVALID_VALUE.
4845 // The TextureCaps::getMaxSamples method is only guarenteed to be valid when the context is ES3.
4846 if (context->getClientMajorVersion() >= 3)
4847 {
4848 const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
4849 if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
4850 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004851 context->handleError(OutOfMemory());
Jamie Madille8fb6402017-02-14 17:56:40 -05004852 return false;
4853 }
4854 }
4855
4856 return ValidateRenderbufferStorageParametersBase(context, target, samples, internalformat,
4857 width, height);
4858}
4859
Jamie Madill5b772312018-03-08 20:28:32 -05004860bool ValidateCheckFramebufferStatus(Context *context, GLenum target)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004861{
Geoff Lange8afa902017-09-27 15:00:43 -04004862 if (!ValidFramebufferTarget(context, target))
Jamie Madillc1d770e2017-04-13 17:31:24 -04004863 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004864 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004865 return false;
4866 }
4867
4868 return true;
4869}
4870
Jamie Madill5b772312018-03-08 20:28:32 -05004871bool ValidateClearColor(Context *context, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004872{
4873 return true;
4874}
4875
Jamie Madill5b772312018-03-08 20:28:32 -05004876bool ValidateClearDepthf(Context *context, GLfloat depth)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004877{
4878 return true;
4879}
4880
Jamie Madill5b772312018-03-08 20:28:32 -05004881bool ValidateClearStencil(Context *context, GLint s)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004882{
4883 return true;
4884}
4885
Jamie Madill5b772312018-03-08 20:28:32 -05004886bool ValidateColorMask(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04004887 GLboolean red,
4888 GLboolean green,
4889 GLboolean blue,
4890 GLboolean alpha)
4891{
4892 return true;
4893}
4894
Jamie Madill5b772312018-03-08 20:28:32 -05004895bool ValidateCompileShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004896{
4897 return true;
4898}
4899
Jamie Madill5b772312018-03-08 20:28:32 -05004900bool ValidateCreateProgram(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004901{
4902 return true;
4903}
4904
Jamie Madill5b772312018-03-08 20:28:32 -05004905bool ValidateCullFace(Context *context, CullFaceMode mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004906{
4907 switch (mode)
4908 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004909 case CullFaceMode::Front:
4910 case CullFaceMode::Back:
4911 case CullFaceMode::FrontAndBack:
Jamie Madillc1d770e2017-04-13 17:31:24 -04004912 break;
4913
4914 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004915 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCullMode);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004916 return false;
4917 }
4918
4919 return true;
4920}
4921
Jamie Madill5b772312018-03-08 20:28:32 -05004922bool ValidateDeleteProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004923{
4924 if (program == 0)
4925 {
4926 return false;
4927 }
4928
Jamie Madill44a6fbf2018-10-02 13:38:56 -04004929 if (!context->getProgramResolveLink(program))
Jamie Madillc1d770e2017-04-13 17:31:24 -04004930 {
4931 if (context->getShader(program))
4932 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004933 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004934 return false;
4935 }
4936 else
4937 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004938 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004939 return false;
4940 }
4941 }
4942
4943 return true;
4944}
4945
Jamie Madill5b772312018-03-08 20:28:32 -05004946bool ValidateDeleteShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004947{
4948 if (shader == 0)
4949 {
4950 return false;
4951 }
4952
4953 if (!context->getShader(shader))
4954 {
Jamie Madill44a6fbf2018-10-02 13:38:56 -04004955 if (context->getProgramResolveLink(shader))
Jamie Madillc1d770e2017-04-13 17:31:24 -04004956 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004957 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004958 return false;
4959 }
4960 else
4961 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004962 ANGLE_VALIDATION_ERR(context, InvalidValue(), ExpectedShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004963 return false;
4964 }
4965 }
4966
4967 return true;
4968}
4969
Jamie Madill5b772312018-03-08 20:28:32 -05004970bool ValidateDepthFunc(Context *context, GLenum func)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004971{
4972 switch (func)
4973 {
4974 case GL_NEVER:
4975 case GL_ALWAYS:
4976 case GL_LESS:
4977 case GL_LEQUAL:
4978 case GL_EQUAL:
4979 case GL_GREATER:
4980 case GL_GEQUAL:
4981 case GL_NOTEQUAL:
4982 break;
4983
4984 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004985 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004986 return false;
4987 }
4988
4989 return true;
4990}
4991
Jamie Madill5b772312018-03-08 20:28:32 -05004992bool ValidateDepthMask(Context *context, GLboolean flag)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004993{
4994 return true;
4995}
4996
Jamie Madill5b772312018-03-08 20:28:32 -05004997bool ValidateDetachShader(Context *context, GLuint program, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004998{
4999 Program *programObject = GetValidProgram(context, program);
5000 if (!programObject)
5001 {
5002 return false;
5003 }
5004
5005 Shader *shaderObject = GetValidShader(context, shader);
5006 if (!shaderObject)
5007 {
5008 return false;
5009 }
5010
Jiawei Shao385b3e02018-03-21 09:43:28 +08005011 const Shader *attachedShader = programObject->getAttachedShader(shaderObject->getType());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005012 if (attachedShader != shaderObject)
5013 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005014 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderToDetachMustBeAttached);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005015 return false;
5016 }
5017
5018 return true;
5019}
5020
Jamie Madill5b772312018-03-08 20:28:32 -05005021bool ValidateDisableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005022{
5023 if (index >= MAX_VERTEX_ATTRIBS)
5024 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005025 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005026 return false;
5027 }
5028
5029 return true;
5030}
5031
Jamie Madill5b772312018-03-08 20:28:32 -05005032bool ValidateEnableVertexAttribArray(Context *context, GLuint index)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005033{
5034 if (index >= MAX_VERTEX_ATTRIBS)
5035 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005036 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005037 return false;
5038 }
5039
5040 return true;
5041}
5042
Jamie Madill5b772312018-03-08 20:28:32 -05005043bool ValidateFinish(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005044{
5045 return true;
5046}
5047
Jamie Madill5b772312018-03-08 20:28:32 -05005048bool ValidateFlush(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005049{
5050 return true;
5051}
5052
Jamie Madill5b772312018-03-08 20:28:32 -05005053bool ValidateFrontFace(Context *context, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005054{
5055 switch (mode)
5056 {
5057 case GL_CW:
5058 case GL_CCW:
5059 break;
5060 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005061 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005062 return false;
5063 }
5064
5065 return true;
5066}
5067
Jamie Madill5b772312018-03-08 20:28:32 -05005068bool ValidateGetActiveAttrib(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005069 GLuint program,
5070 GLuint index,
5071 GLsizei bufsize,
5072 GLsizei *length,
5073 GLint *size,
5074 GLenum *type,
5075 GLchar *name)
5076{
5077 if (bufsize < 0)
5078 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005079 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005080 return false;
5081 }
5082
5083 Program *programObject = GetValidProgram(context, program);
5084
5085 if (!programObject)
5086 {
5087 return false;
5088 }
5089
5090 if (index >= static_cast<GLuint>(programObject->getActiveAttributeCount()))
5091 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005092 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005093 return false;
5094 }
5095
5096 return true;
5097}
5098
Jamie Madill5b772312018-03-08 20:28:32 -05005099bool ValidateGetActiveUniform(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005100 GLuint program,
5101 GLuint index,
5102 GLsizei bufsize,
5103 GLsizei *length,
5104 GLint *size,
5105 GLenum *type,
5106 GLchar *name)
5107{
5108 if (bufsize < 0)
5109 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005110 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005111 return false;
5112 }
5113
5114 Program *programObject = GetValidProgram(context, program);
5115
5116 if (!programObject)
5117 {
5118 return false;
5119 }
5120
5121 if (index >= static_cast<GLuint>(programObject->getActiveUniformCount()))
5122 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005123 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005124 return false;
5125 }
5126
5127 return true;
5128}
5129
Jamie Madill5b772312018-03-08 20:28:32 -05005130bool ValidateGetAttachedShaders(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005131 GLuint program,
5132 GLsizei maxcount,
5133 GLsizei *count,
5134 GLuint *shaders)
5135{
5136 if (maxcount < 0)
5137 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005138 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeMaxCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005139 return false;
5140 }
5141
5142 Program *programObject = GetValidProgram(context, program);
5143
5144 if (!programObject)
5145 {
5146 return false;
5147 }
5148
5149 return true;
5150}
5151
Jamie Madill5b772312018-03-08 20:28:32 -05005152bool ValidateGetAttribLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005153{
Geoff Langfc32e8b2017-05-31 14:16:59 -04005154 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5155 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005156 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005157 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005158 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005159 return false;
5160 }
5161
Jamie Madillc1d770e2017-04-13 17:31:24 -04005162 Program *programObject = GetValidProgram(context, program);
5163
5164 if (!programObject)
5165 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005166 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005167 return false;
5168 }
5169
5170 if (!programObject->isLinked())
5171 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005172 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005173 return false;
5174 }
5175
5176 return true;
5177}
5178
Jamie Madill5b772312018-03-08 20:28:32 -05005179bool ValidateGetBooleanv(Context *context, GLenum pname, GLboolean *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005180{
5181 GLenum nativeType;
5182 unsigned int numParams = 0;
5183 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5184}
5185
Jamie Madill5b772312018-03-08 20:28:32 -05005186bool ValidateGetError(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005187{
5188 return true;
5189}
5190
Jamie Madill5b772312018-03-08 20:28:32 -05005191bool ValidateGetFloatv(Context *context, GLenum pname, GLfloat *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005192{
5193 GLenum nativeType;
5194 unsigned int numParams = 0;
5195 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5196}
5197
Jamie Madill5b772312018-03-08 20:28:32 -05005198bool ValidateGetIntegerv(Context *context, GLenum pname, GLint *params)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005199{
5200 GLenum nativeType;
5201 unsigned int numParams = 0;
5202 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5203}
5204
Jamie Madill5b772312018-03-08 20:28:32 -05005205bool ValidateGetProgramInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005206 GLuint program,
5207 GLsizei bufsize,
5208 GLsizei *length,
5209 GLchar *infolog)
5210{
5211 if (bufsize < 0)
5212 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005213 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005214 return false;
5215 }
5216
5217 Program *programObject = GetValidProgram(context, program);
5218 if (!programObject)
5219 {
5220 return false;
5221 }
5222
5223 return true;
5224}
5225
Jamie Madill5b772312018-03-08 20:28:32 -05005226bool ValidateGetShaderInfoLog(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005227 GLuint shader,
5228 GLsizei bufsize,
5229 GLsizei *length,
5230 GLchar *infolog)
5231{
5232 if (bufsize < 0)
5233 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005234 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005235 return false;
5236 }
5237
5238 Shader *shaderObject = GetValidShader(context, shader);
5239 if (!shaderObject)
5240 {
5241 return false;
5242 }
5243
5244 return true;
5245}
5246
Jamie Madill5b772312018-03-08 20:28:32 -05005247bool ValidateGetShaderPrecisionFormat(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005248 GLenum shadertype,
5249 GLenum precisiontype,
5250 GLint *range,
5251 GLint *precision)
5252{
5253 switch (shadertype)
5254 {
5255 case GL_VERTEX_SHADER:
5256 case GL_FRAGMENT_SHADER:
5257 break;
5258 case GL_COMPUTE_SHADER:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005259 context->handleError(InvalidOperation()
5260 << "compute shader precision not yet implemented.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005261 return false;
5262 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005263 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005264 return false;
5265 }
5266
5267 switch (precisiontype)
5268 {
5269 case GL_LOW_FLOAT:
5270 case GL_MEDIUM_FLOAT:
5271 case GL_HIGH_FLOAT:
5272 case GL_LOW_INT:
5273 case GL_MEDIUM_INT:
5274 case GL_HIGH_INT:
5275 break;
5276
5277 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005278 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPrecision);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005279 return false;
5280 }
5281
5282 return true;
5283}
5284
Jamie Madill5b772312018-03-08 20:28:32 -05005285bool ValidateGetShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005286 GLuint shader,
5287 GLsizei bufsize,
5288 GLsizei *length,
5289 GLchar *source)
5290{
5291 if (bufsize < 0)
5292 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005293 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005294 return false;
5295 }
5296
5297 Shader *shaderObject = GetValidShader(context, shader);
5298 if (!shaderObject)
5299 {
5300 return false;
5301 }
5302
5303 return true;
5304}
5305
Jamie Madill5b772312018-03-08 20:28:32 -05005306bool ValidateGetUniformLocation(Context *context, GLuint program, const GLchar *name)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005307{
5308 if (strstr(name, "gl_") == name)
5309 {
5310 return false;
5311 }
5312
Geoff Langfc32e8b2017-05-31 14:16:59 -04005313 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5314 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005315 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005316 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005317 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005318 return false;
5319 }
5320
Jamie Madillc1d770e2017-04-13 17:31:24 -04005321 Program *programObject = GetValidProgram(context, program);
5322
5323 if (!programObject)
5324 {
5325 return false;
5326 }
5327
5328 if (!programObject->isLinked())
5329 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005330 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005331 return false;
5332 }
5333
5334 return true;
5335}
5336
Jamie Madill5b772312018-03-08 20:28:32 -05005337bool ValidateHint(Context *context, GLenum target, GLenum mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005338{
5339 switch (mode)
5340 {
5341 case GL_FASTEST:
5342 case GL_NICEST:
5343 case GL_DONT_CARE:
5344 break;
5345
5346 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005347 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005348 return false;
5349 }
5350
5351 switch (target)
5352 {
5353 case GL_GENERATE_MIPMAP_HINT:
5354 break;
5355
Geoff Lange7bd2182017-06-16 16:13:13 -04005356 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
5357 if (context->getClientVersion() < ES_3_0 &&
5358 !context->getExtensions().standardDerivatives)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005359 {
Brandon Jones72f58fa2017-09-19 10:47:41 -07005360 context->handleError(InvalidEnum() << "hint requires OES_standard_derivatives.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005361 return false;
5362 }
5363 break;
5364
Lingfeng Yang6e5bf362018-08-15 09:53:17 -07005365 case GL_PERSPECTIVE_CORRECTION_HINT:
5366 case GL_POINT_SMOOTH_HINT:
5367 case GL_LINE_SMOOTH_HINT:
5368 case GL_FOG_HINT:
5369 if (context->getClientMajorVersion() >= 2)
5370 {
5371 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
5372 return false;
5373 }
5374 break;
5375
Jamie Madillc1d770e2017-04-13 17:31:24 -04005376 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005377 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005378 return false;
5379 }
5380
5381 return true;
5382}
5383
Jamie Madill5b772312018-03-08 20:28:32 -05005384bool ValidateIsBuffer(Context *context, GLuint buffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005385{
5386 return true;
5387}
5388
Jamie Madill5b772312018-03-08 20:28:32 -05005389bool ValidateIsFramebuffer(Context *context, GLuint framebuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005390{
5391 return true;
5392}
5393
Jamie Madill5b772312018-03-08 20:28:32 -05005394bool ValidateIsProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005395{
5396 return true;
5397}
5398
Jamie Madill5b772312018-03-08 20:28:32 -05005399bool ValidateIsRenderbuffer(Context *context, GLuint renderbuffer)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005400{
5401 return true;
5402}
5403
Jamie Madill5b772312018-03-08 20:28:32 -05005404bool ValidateIsShader(Context *context, GLuint shader)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005405{
5406 return true;
5407}
5408
Jamie Madill5b772312018-03-08 20:28:32 -05005409bool ValidateIsTexture(Context *context, GLuint texture)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005410{
5411 return true;
5412}
5413
Jamie Madill5b772312018-03-08 20:28:32 -05005414bool ValidatePixelStorei(Context *context, GLenum pname, GLint param)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005415{
5416 if (context->getClientMajorVersion() < 3)
5417 {
5418 switch (pname)
5419 {
5420 case GL_UNPACK_IMAGE_HEIGHT:
5421 case GL_UNPACK_SKIP_IMAGES:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005422 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005423 return false;
5424
5425 case GL_UNPACK_ROW_LENGTH:
5426 case GL_UNPACK_SKIP_ROWS:
5427 case GL_UNPACK_SKIP_PIXELS:
5428 if (!context->getExtensions().unpackSubimage)
5429 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005430 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005431 return false;
5432 }
5433 break;
5434
5435 case GL_PACK_ROW_LENGTH:
5436 case GL_PACK_SKIP_ROWS:
5437 case GL_PACK_SKIP_PIXELS:
5438 if (!context->getExtensions().packSubimage)
5439 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005440 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005441 return false;
5442 }
5443 break;
5444 }
5445 }
5446
5447 if (param < 0)
5448 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005449 context->handleError(InvalidValue() << "Cannot use negative values in PixelStorei");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005450 return false;
5451 }
5452
5453 switch (pname)
5454 {
5455 case GL_UNPACK_ALIGNMENT:
5456 if (param != 1 && param != 2 && param != 4 && param != 8)
5457 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005458 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005459 return false;
5460 }
5461 break;
5462
5463 case GL_PACK_ALIGNMENT:
5464 if (param != 1 && param != 2 && param != 4 && param != 8)
5465 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005466 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005467 return false;
5468 }
5469 break;
5470
5471 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Geoff Lang000dab82017-09-27 14:27:07 -04005472 if (!context->getExtensions().packReverseRowOrder)
5473 {
5474 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
5475 }
5476 break;
5477
Jamie Madillc1d770e2017-04-13 17:31:24 -04005478 case GL_UNPACK_ROW_LENGTH:
5479 case GL_UNPACK_IMAGE_HEIGHT:
5480 case GL_UNPACK_SKIP_IMAGES:
5481 case GL_UNPACK_SKIP_ROWS:
5482 case GL_UNPACK_SKIP_PIXELS:
5483 case GL_PACK_ROW_LENGTH:
5484 case GL_PACK_SKIP_ROWS:
5485 case GL_PACK_SKIP_PIXELS:
5486 break;
5487
5488 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005489 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005490 return false;
5491 }
5492
5493 return true;
5494}
5495
Jamie Madill5b772312018-03-08 20:28:32 -05005496bool ValidatePolygonOffset(Context *context, GLfloat factor, GLfloat units)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005497{
5498 return true;
5499}
5500
Jamie Madill5b772312018-03-08 20:28:32 -05005501bool ValidateReleaseShaderCompiler(Context *context)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005502{
5503 return true;
5504}
5505
Jamie Madill5b772312018-03-08 20:28:32 -05005506bool ValidateSampleCoverage(Context *context, GLfloat value, GLboolean invert)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005507{
5508 return true;
5509}
5510
Jamie Madill5b772312018-03-08 20:28:32 -05005511bool ValidateScissor(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005512{
5513 if (width < 0 || height < 0)
5514 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005515 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
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 ValidateShaderBinary(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005523 GLsizei n,
5524 const GLuint *shaders,
5525 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04005526 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005527 GLsizei length)
5528{
5529 const std::vector<GLenum> &shaderBinaryFormats = context->getCaps().shaderBinaryFormats;
5530 if (std::find(shaderBinaryFormats.begin(), shaderBinaryFormats.end(), binaryformat) ==
5531 shaderBinaryFormats.end())
5532 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005533 context->handleError(InvalidEnum() << "Invalid shader binary format.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005534 return false;
5535 }
5536
5537 return true;
5538}
5539
Jamie Madill5b772312018-03-08 20:28:32 -05005540bool ValidateShaderSource(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005541 GLuint shader,
5542 GLsizei count,
5543 const GLchar *const *string,
5544 const GLint *length)
5545{
5546 if (count < 0)
5547 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005548 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005549 return false;
5550 }
5551
Geoff Langfc32e8b2017-05-31 14:16:59 -04005552 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5553 // shader-related entry points
5554 if (context->getExtensions().webglCompatibility)
5555 {
5556 for (GLsizei i = 0; i < count; i++)
5557 {
Geoff Langcab92ee2017-07-19 17:32:07 -04005558 size_t len =
5559 (length && length[i] >= 0) ? static_cast<size_t>(length[i]) : strlen(string[i]);
Geoff Langa71a98e2017-06-19 15:15:00 -04005560
5561 // Backslash as line-continuation is allowed in WebGL 2.0.
Geoff Langcab92ee2017-07-19 17:32:07 -04005562 if (!IsValidESSLShaderSourceString(string[i], len,
5563 context->getClientVersion() >= ES_3_0))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005564 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005565 ANGLE_VALIDATION_ERR(context, InvalidValue(), ShaderSourceInvalidCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005566 return false;
5567 }
5568 }
5569 }
5570
Jamie Madillc1d770e2017-04-13 17:31:24 -04005571 Shader *shaderObject = GetValidShader(context, shader);
5572 if (!shaderObject)
5573 {
5574 return false;
5575 }
5576
5577 return true;
5578}
5579
Jamie Madill5b772312018-03-08 20:28:32 -05005580bool ValidateStencilFunc(Context *context, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005581{
5582 if (!IsValidStencilFunc(func))
5583 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005584 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005585 return false;
5586 }
5587
5588 return true;
5589}
5590
Jamie Madill5b772312018-03-08 20:28:32 -05005591bool ValidateStencilFuncSeparate(Context *context, GLenum face, GLenum func, GLint ref, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005592{
5593 if (!IsValidStencilFace(face))
5594 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005595 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005596 return false;
5597 }
5598
5599 if (!IsValidStencilFunc(func))
5600 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005601 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005602 return false;
5603 }
5604
5605 return true;
5606}
5607
Jamie Madill5b772312018-03-08 20:28:32 -05005608bool ValidateStencilMask(Context *context, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005609{
5610 return true;
5611}
5612
Jamie Madill5b772312018-03-08 20:28:32 -05005613bool ValidateStencilMaskSeparate(Context *context, GLenum face, GLuint mask)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005614{
5615 if (!IsValidStencilFace(face))
5616 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005617 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005618 return false;
5619 }
5620
5621 return true;
5622}
5623
Jamie Madill5b772312018-03-08 20:28:32 -05005624bool ValidateStencilOp(Context *context, GLenum fail, GLenum zfail, GLenum zpass)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005625{
5626 if (!IsValidStencilOp(fail))
5627 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005628 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005629 return false;
5630 }
5631
5632 if (!IsValidStencilOp(zfail))
5633 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005634 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005635 return false;
5636 }
5637
5638 if (!IsValidStencilOp(zpass))
5639 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005640 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005641 return false;
5642 }
5643
5644 return true;
5645}
5646
Jamie Madill5b772312018-03-08 20:28:32 -05005647bool ValidateStencilOpSeparate(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005648 GLenum face,
5649 GLenum fail,
5650 GLenum zfail,
5651 GLenum zpass)
5652{
5653 if (!IsValidStencilFace(face))
5654 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005655 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005656 return false;
5657 }
5658
5659 return ValidateStencilOp(context, fail, zfail, zpass);
5660}
5661
Jamie Madill5b772312018-03-08 20:28:32 -05005662bool ValidateUniform1f(Context *context, GLint location, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005663{
5664 return ValidateUniform(context, GL_FLOAT, location, 1);
5665}
5666
Jamie Madill5b772312018-03-08 20:28:32 -05005667bool ValidateUniform1fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005668{
5669 return ValidateUniform(context, GL_FLOAT, location, count);
5670}
5671
Jamie Madill5b772312018-03-08 20:28:32 -05005672bool ValidateUniform1i(Context *context, GLint location, GLint x)
Jamie Madillbe849e42017-05-02 15:49:00 -04005673{
5674 return ValidateUniform1iv(context, location, 1, &x);
5675}
5676
Jamie Madill5b772312018-03-08 20:28:32 -05005677bool ValidateUniform2fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005678{
5679 return ValidateUniform(context, GL_FLOAT_VEC2, location, count);
5680}
5681
Jamie Madill5b772312018-03-08 20:28:32 -05005682bool ValidateUniform2i(Context *context, GLint location, GLint x, GLint y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005683{
5684 return ValidateUniform(context, GL_INT_VEC2, location, 1);
5685}
5686
Jamie Madill5b772312018-03-08 20:28:32 -05005687bool ValidateUniform2iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005688{
5689 return ValidateUniform(context, GL_INT_VEC2, location, count);
5690}
5691
Jamie Madill5b772312018-03-08 20:28:32 -05005692bool ValidateUniform3f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005693{
5694 return ValidateUniform(context, GL_FLOAT_VEC3, location, 1);
5695}
5696
Jamie Madill5b772312018-03-08 20:28:32 -05005697bool ValidateUniform3fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005698{
5699 return ValidateUniform(context, GL_FLOAT_VEC3, location, count);
5700}
5701
Jamie Madill5b772312018-03-08 20:28:32 -05005702bool ValidateUniform3i(Context *context, GLint location, GLint x, GLint y, GLint z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005703{
5704 return ValidateUniform(context, GL_INT_VEC3, location, 1);
5705}
5706
Jamie Madill5b772312018-03-08 20:28:32 -05005707bool ValidateUniform3iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005708{
5709 return ValidateUniform(context, GL_INT_VEC3, location, count);
5710}
5711
Jamie Madill5b772312018-03-08 20:28:32 -05005712bool ValidateUniform4f(Context *context, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005713{
5714 return ValidateUniform(context, GL_FLOAT_VEC4, location, 1);
5715}
5716
Jamie Madill5b772312018-03-08 20:28:32 -05005717bool ValidateUniform4fv(Context *context, GLint location, GLsizei count, const GLfloat *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005718{
5719 return ValidateUniform(context, GL_FLOAT_VEC4, location, count);
5720}
5721
Jamie Madill5b772312018-03-08 20:28:32 -05005722bool ValidateUniform4i(Context *context, GLint location, GLint x, GLint y, GLint z, GLint w)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005723{
5724 return ValidateUniform(context, GL_INT_VEC4, location, 1);
5725}
5726
Jamie Madill5b772312018-03-08 20:28:32 -05005727bool ValidateUniform4iv(Context *context, GLint location, GLsizei count, const GLint *v)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005728{
5729 return ValidateUniform(context, GL_INT_VEC4, location, count);
5730}
5731
Jamie Madill5b772312018-03-08 20:28:32 -05005732bool ValidateUniformMatrix2fv(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_MAT2, location, count, transpose);
5739}
5740
Jamie Madill5b772312018-03-08 20:28:32 -05005741bool ValidateUniformMatrix3fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005742 GLint location,
5743 GLsizei count,
5744 GLboolean transpose,
5745 const GLfloat *value)
5746{
5747 return ValidateUniformMatrix(context, GL_FLOAT_MAT3, location, count, transpose);
5748}
5749
Jamie Madill5b772312018-03-08 20:28:32 -05005750bool ValidateUniformMatrix4fv(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005751 GLint location,
5752 GLsizei count,
5753 GLboolean transpose,
5754 const GLfloat *value)
5755{
5756 return ValidateUniformMatrix(context, GL_FLOAT_MAT4, location, count, transpose);
5757}
5758
Jamie Madill5b772312018-03-08 20:28:32 -05005759bool ValidateValidateProgram(Context *context, GLuint program)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005760{
5761 Program *programObject = GetValidProgram(context, program);
5762
5763 if (!programObject)
5764 {
5765 return false;
5766 }
5767
5768 return true;
5769}
5770
Jamie Madill5b772312018-03-08 20:28:32 -05005771bool ValidateVertexAttrib1f(Context *context, GLuint index, GLfloat x)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005772{
5773 return ValidateVertexAttribIndex(context, index);
5774}
5775
Jamie Madill5b772312018-03-08 20:28:32 -05005776bool ValidateVertexAttrib1fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005777{
5778 return ValidateVertexAttribIndex(context, index);
5779}
5780
Jamie Madill5b772312018-03-08 20:28:32 -05005781bool ValidateVertexAttrib2f(Context *context, GLuint index, GLfloat x, GLfloat y)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005782{
5783 return ValidateVertexAttribIndex(context, index);
5784}
5785
Jamie Madill5b772312018-03-08 20:28:32 -05005786bool ValidateVertexAttrib2fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005787{
5788 return ValidateVertexAttribIndex(context, index);
5789}
5790
Jamie Madill5b772312018-03-08 20:28:32 -05005791bool ValidateVertexAttrib3f(Context *context, GLuint index, GLfloat x, GLfloat y, GLfloat z)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005792{
5793 return ValidateVertexAttribIndex(context, index);
5794}
5795
Jamie Madill5b772312018-03-08 20:28:32 -05005796bool ValidateVertexAttrib3fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005797{
5798 return ValidateVertexAttribIndex(context, index);
5799}
5800
Jamie Madill5b772312018-03-08 20:28:32 -05005801bool ValidateVertexAttrib4f(Context *context,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005802 GLuint index,
5803 GLfloat x,
5804 GLfloat y,
5805 GLfloat z,
5806 GLfloat w)
5807{
5808 return ValidateVertexAttribIndex(context, index);
5809}
5810
Jamie Madill5b772312018-03-08 20:28:32 -05005811bool ValidateVertexAttrib4fv(Context *context, GLuint index, const GLfloat *values)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005812{
5813 return ValidateVertexAttribIndex(context, index);
5814}
5815
Jamie Madill5b772312018-03-08 20:28:32 -05005816bool ValidateViewport(Context *context, GLint x, GLint y, GLsizei width, GLsizei height)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005817{
5818 if (width < 0 || height < 0)
5819 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005820 ANGLE_VALIDATION_ERR(context, InvalidValue(), ViewportNegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005821 return false;
5822 }
5823
5824 return true;
5825}
5826
Jamie Madill5b772312018-03-08 20:28:32 -05005827bool ValidateDrawElements(Context *context,
Jamie Madill493f9572018-05-24 19:52:15 -04005828 PrimitiveMode mode,
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005829 GLsizei count,
5830 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04005831 const void *indices)
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005832{
5833 return ValidateDrawElementsCommon(context, mode, count, type, indices, 1);
5834}
5835
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08005836bool ValidateGetFramebufferAttachmentParameteriv(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04005837 GLenum target,
5838 GLenum attachment,
5839 GLenum pname,
5840 GLint *params)
5841{
5842 return ValidateGetFramebufferAttachmentParameterivBase(context, target, attachment, pname,
5843 nullptr);
5844}
5845
Jamie Madill5b772312018-03-08 20:28:32 -05005846bool ValidateGetProgramiv(Context *context, GLuint program, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04005847{
5848 return ValidateGetProgramivBase(context, program, pname, nullptr);
5849}
5850
Jamie Madill5b772312018-03-08 20:28:32 -05005851bool ValidateCopyTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005852 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005853 GLint level,
5854 GLenum internalformat,
5855 GLint x,
5856 GLint y,
5857 GLsizei width,
5858 GLsizei height,
5859 GLint border)
5860{
5861 if (context->getClientMajorVersion() < 3)
5862 {
5863 return ValidateES2CopyTexImageParameters(context, target, level, internalformat, false, 0,
5864 0, x, y, width, height, border);
5865 }
5866
5867 ASSERT(context->getClientMajorVersion() == 3);
5868 return ValidateES3CopyTexImage2DParameters(context, target, level, internalformat, false, 0, 0,
5869 0, x, y, width, height, border);
5870}
5871
5872bool ValidateCopyTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005873 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005874 GLint level,
5875 GLint xoffset,
5876 GLint yoffset,
5877 GLint x,
5878 GLint y,
5879 GLsizei width,
5880 GLsizei height)
5881{
5882 if (context->getClientMajorVersion() < 3)
5883 {
5884 return ValidateES2CopyTexImageParameters(context, target, level, GL_NONE, true, xoffset,
5885 yoffset, x, y, width, height, 0);
5886 }
5887
5888 return ValidateES3CopyTexImage2DParameters(context, target, level, GL_NONE, true, xoffset,
5889 yoffset, 0, x, y, width, height, 0);
5890}
5891
5892bool ValidateDeleteBuffers(Context *context, GLint n, const GLuint *)
5893{
5894 return ValidateGenOrDelete(context, n);
5895}
5896
5897bool ValidateDeleteFramebuffers(Context *context, GLint n, const GLuint *)
5898{
5899 return ValidateGenOrDelete(context, n);
5900}
5901
5902bool ValidateDeleteRenderbuffers(Context *context, GLint n, const GLuint *)
5903{
5904 return ValidateGenOrDelete(context, n);
5905}
5906
5907bool ValidateDeleteTextures(Context *context, GLint n, const GLuint *)
5908{
5909 return ValidateGenOrDelete(context, n);
5910}
5911
5912bool ValidateDisable(Context *context, GLenum cap)
5913{
5914 if (!ValidCap(context, cap, false))
5915 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005916 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005917 return false;
5918 }
5919
5920 return true;
5921}
5922
5923bool ValidateEnable(Context *context, GLenum cap)
5924{
5925 if (!ValidCap(context, cap, false))
5926 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005927 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005928 return false;
5929 }
5930
5931 if (context->getLimitations().noSampleAlphaToCoverageSupport &&
5932 cap == GL_SAMPLE_ALPHA_TO_COVERAGE)
5933 {
5934 const char *errorMessage = "Current renderer doesn't support alpha-to-coverage";
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005935 context->handleError(InvalidOperation() << errorMessage);
Jamie Madillbe849e42017-05-02 15:49:00 -04005936
5937 // We also output an error message to the debugger window if tracing is active, so that
5938 // developers can see the error message.
5939 ERR() << errorMessage;
5940 return false;
5941 }
5942
5943 return true;
5944}
5945
5946bool ValidateFramebufferRenderbuffer(Context *context,
5947 GLenum target,
5948 GLenum attachment,
5949 GLenum renderbuffertarget,
5950 GLuint renderbuffer)
5951{
Geoff Lange8afa902017-09-27 15:00:43 -04005952 if (!ValidFramebufferTarget(context, target))
Jamie Madillbe849e42017-05-02 15:49:00 -04005953 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005954 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
5955 return false;
5956 }
5957
5958 if (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0)
5959 {
5960 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005961 return false;
5962 }
5963
5964 return ValidateFramebufferRenderbufferParameters(context, target, attachment,
5965 renderbuffertarget, renderbuffer);
5966}
5967
5968bool ValidateFramebufferTexture2D(Context *context,
5969 GLenum target,
5970 GLenum attachment,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005971 TextureTarget textarget,
Jamie Madillbe849e42017-05-02 15:49:00 -04005972 GLuint texture,
5973 GLint level)
5974{
5975 // Attachments are required to be bound to level 0 without ES3 or the GL_OES_fbo_render_mipmap
5976 // extension
5977 if (context->getClientMajorVersion() < 3 && !context->getExtensions().fboRenderMipmap &&
5978 level != 0)
5979 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005980 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidFramebufferTextureLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04005981 return false;
5982 }
5983
5984 if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
5985 {
5986 return false;
5987 }
5988
5989 if (texture != 0)
5990 {
5991 gl::Texture *tex = context->getTexture(texture);
5992 ASSERT(tex);
5993
5994 const gl::Caps &caps = context->getCaps();
5995
5996 switch (textarget)
5997 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005998 case TextureTarget::_2D:
Jamie Madillbe849e42017-05-02 15:49:00 -04005999 {
6000 if (level > gl::log2(caps.max2DTextureSize))
6001 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006002 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04006003 return false;
6004 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006005 if (tex->getType() != TextureType::_2D)
Jamie Madillbe849e42017-05-02 15:49:00 -04006006 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006007 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006008 return false;
6009 }
6010 }
6011 break;
6012
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006013 case TextureTarget::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006014 {
6015 if (level != 0)
6016 {
6017 context->handleError(InvalidValue());
6018 return false;
6019 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006020 if (tex->getType() != TextureType::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006021 {
6022 context->handleError(InvalidOperation()
6023 << "Textarget must match the texture target type.");
6024 return false;
6025 }
6026 }
6027 break;
6028
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006029 case TextureTarget::CubeMapNegativeX:
6030 case TextureTarget::CubeMapNegativeY:
6031 case TextureTarget::CubeMapNegativeZ:
6032 case TextureTarget::CubeMapPositiveX:
6033 case TextureTarget::CubeMapPositiveY:
6034 case TextureTarget::CubeMapPositiveZ:
Jamie Madillbe849e42017-05-02 15:49:00 -04006035 {
6036 if (level > gl::log2(caps.maxCubeMapTextureSize))
6037 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006038 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04006039 return false;
6040 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006041 if (tex->getType() != TextureType::CubeMap)
Jamie Madillbe849e42017-05-02 15:49:00 -04006042 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006043 context->handleError(InvalidOperation()
6044 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006045 return false;
6046 }
6047 }
6048 break;
6049
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006050 case TextureTarget::_2DMultisample:
Jamie Madillbe849e42017-05-02 15:49:00 -04006051 {
6052 if (context->getClientVersion() < ES_3_1)
6053 {
Brandon Jonesafa75152017-07-21 13:11:29 -07006054 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
Jamie Madillbe849e42017-05-02 15:49:00 -04006055 return false;
6056 }
6057
6058 if (level != 0)
6059 {
Brandon Jonesafa75152017-07-21 13:11:29 -07006060 ANGLE_VALIDATION_ERR(context, InvalidValue(), LevelNotZero);
Jamie Madillbe849e42017-05-02 15:49:00 -04006061 return false;
6062 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006063 if (tex->getType() != TextureType::_2DMultisample)
Jamie Madillbe849e42017-05-02 15:49:00 -04006064 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006065 context->handleError(InvalidOperation()
6066 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006067 return false;
6068 }
6069 }
6070 break;
6071
6072 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07006073 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006074 return false;
6075 }
Jamie Madillbe849e42017-05-02 15:49:00 -04006076 }
6077
6078 return true;
6079}
6080
6081bool ValidateGenBuffers(Context *context, GLint n, GLuint *)
6082{
6083 return ValidateGenOrDelete(context, n);
6084}
6085
6086bool ValidateGenFramebuffers(Context *context, GLint n, GLuint *)
6087{
6088 return ValidateGenOrDelete(context, n);
6089}
6090
6091bool ValidateGenRenderbuffers(Context *context, GLint n, GLuint *)
6092{
6093 return ValidateGenOrDelete(context, n);
6094}
6095
6096bool ValidateGenTextures(Context *context, GLint n, GLuint *)
6097{
6098 return ValidateGenOrDelete(context, n);
6099}
6100
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006101bool ValidateGenerateMipmap(Context *context, TextureType target)
Jamie Madillbe849e42017-05-02 15:49:00 -04006102{
6103 if (!ValidTextureTarget(context, target))
6104 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006105 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006106 return false;
6107 }
6108
6109 Texture *texture = context->getTargetTexture(target);
6110
6111 if (texture == nullptr)
6112 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006113 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04006114 return false;
6115 }
6116
6117 const GLuint effectiveBaseLevel = texture->getTextureState().getEffectiveBaseLevel();
6118
6119 // This error isn't spelled out in the spec in a very explicit way, but we interpret the spec so
6120 // that out-of-range base level has a non-color-renderable / non-texture-filterable format.
6121 if (effectiveBaseLevel >= gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
6122 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006123 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -04006124 return false;
6125 }
6126
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006127 TextureTarget baseTarget = (target == TextureType::CubeMap)
6128 ? TextureTarget::CubeMapPositiveX
6129 : NonCubeTextureTypeToTarget(target);
Geoff Lang536eca12017-09-13 11:23:35 -04006130 const auto &format = *(texture->getFormat(baseTarget, effectiveBaseLevel).info);
6131 if (format.sizedInternalFormat == GL_NONE || format.compressed || format.depthBits > 0 ||
6132 format.stencilBits > 0)
Brandon Jones6cad5662017-06-14 13:25:13 -07006133 {
6134 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
6135 return false;
6136 }
6137
Geoff Lang536eca12017-09-13 11:23:35 -04006138 // GenerateMipmap accepts formats that are unsized or both color renderable and filterable.
6139 bool formatUnsized = !format.sized;
6140 bool formatColorRenderableAndFilterable =
6141 format.filterSupport(context->getClientVersion(), context->getExtensions()) &&
Yuly Novikovf15f8862018-06-04 18:59:41 -04006142 format.textureAttachmentSupport(context->getClientVersion(), context->getExtensions());
Geoff Lang536eca12017-09-13 11:23:35 -04006143 if (!formatUnsized && !formatColorRenderableAndFilterable)
Jamie Madillbe849e42017-05-02 15:49:00 -04006144 {
Geoff Lang536eca12017-09-13 11:23:35 -04006145 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006146 return false;
6147 }
6148
Geoff Lang536eca12017-09-13 11:23:35 -04006149 // GL_EXT_sRGB adds an unsized SRGB (no alpha) format which has explicitly disabled mipmap
6150 // generation
6151 if (format.colorEncoding == GL_SRGB && format.format == GL_RGB)
6152 {
6153 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
6154 return false;
6155 }
6156
Jiange2c00842018-07-13 16:50:49 +08006157 // According to the OpenGL extension spec EXT_sRGB.txt, EXT_SRGB is based on ES 2.0 and
6158 // generateMipmap is not allowed if texture format is SRGB_EXT or SRGB_ALPHA_EXT.
6159 if (context->getClientVersion() < Version(3, 0) && format.colorEncoding == GL_SRGB)
Jamie Madillbe849e42017-05-02 15:49:00 -04006160 {
Geoff Lang536eca12017-09-13 11:23:35 -04006161 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006162 return false;
6163 }
6164
6165 // Non-power of 2 ES2 check
6166 if (context->getClientVersion() < Version(3, 0) && !context->getExtensions().textureNPOT &&
6167 (!isPow2(static_cast<int>(texture->getWidth(baseTarget, 0))) ||
6168 !isPow2(static_cast<int>(texture->getHeight(baseTarget, 0)))))
6169 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006170 ASSERT(target == TextureType::_2D || target == TextureType::Rectangle ||
6171 target == TextureType::CubeMap);
Brandon Jones6cad5662017-06-14 13:25:13 -07006172 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotPow2);
Jamie Madillbe849e42017-05-02 15:49:00 -04006173 return false;
6174 }
6175
6176 // Cube completeness check
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006177 if (target == TextureType::CubeMap && !texture->getTextureState().isCubeComplete())
Jamie Madillbe849e42017-05-02 15:49:00 -04006178 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006179 ANGLE_VALIDATION_ERR(context, InvalidOperation(), CubemapIncomplete);
Jamie Madillbe849e42017-05-02 15:49:00 -04006180 return false;
6181 }
6182
6183 return true;
6184}
6185
Jamie Madill5b772312018-03-08 20:28:32 -05006186bool ValidateGetBufferParameteriv(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04006187 BufferBinding target,
Jamie Madillbe849e42017-05-02 15:49:00 -04006188 GLenum pname,
6189 GLint *params)
6190{
6191 return ValidateGetBufferParameterBase(context, target, pname, false, nullptr);
6192}
6193
6194bool ValidateGetRenderbufferParameteriv(Context *context,
6195 GLenum target,
6196 GLenum pname,
6197 GLint *params)
6198{
6199 return ValidateGetRenderbufferParameterivBase(context, target, pname, nullptr);
6200}
6201
6202bool ValidateGetShaderiv(Context *context, GLuint shader, GLenum pname, GLint *params)
6203{
6204 return ValidateGetShaderivBase(context, shader, pname, nullptr);
6205}
6206
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006207bool ValidateGetTexParameterfv(Context *context, TextureType target, GLenum pname, GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006208{
6209 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6210}
6211
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006212bool ValidateGetTexParameteriv(Context *context, TextureType target, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006213{
6214 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6215}
6216
6217bool ValidateGetUniformfv(Context *context, GLuint program, GLint location, GLfloat *params)
6218{
6219 return ValidateGetUniformBase(context, program, location);
6220}
6221
6222bool ValidateGetUniformiv(Context *context, GLuint program, GLint location, GLint *params)
6223{
6224 return ValidateGetUniformBase(context, program, location);
6225}
6226
6227bool ValidateGetVertexAttribfv(Context *context, GLuint index, GLenum pname, GLfloat *params)
6228{
6229 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6230}
6231
6232bool ValidateGetVertexAttribiv(Context *context, GLuint index, GLenum pname, GLint *params)
6233{
6234 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6235}
6236
6237bool ValidateGetVertexAttribPointerv(Context *context, GLuint index, GLenum pname, void **pointer)
6238{
6239 return ValidateGetVertexAttribBase(context, index, pname, nullptr, true, false);
6240}
6241
6242bool ValidateIsEnabled(Context *context, GLenum cap)
6243{
6244 if (!ValidCap(context, cap, true))
6245 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006246 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006247 return false;
6248 }
6249
6250 return true;
6251}
6252
6253bool ValidateLinkProgram(Context *context, GLuint program)
6254{
6255 if (context->hasActiveTransformFeedback(program))
6256 {
6257 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006258 context->handleError(InvalidOperation() << "Cannot link program while program is "
6259 "associated with an active transform "
6260 "feedback object.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006261 return false;
6262 }
6263
6264 Program *programObject = GetValidProgram(context, program);
6265 if (!programObject)
6266 {
6267 return false;
6268 }
6269
6270 return true;
6271}
6272
Jamie Madill4928b7c2017-06-20 12:57:39 -04006273bool ValidateReadPixels(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04006274 GLint x,
6275 GLint y,
6276 GLsizei width,
6277 GLsizei height,
6278 GLenum format,
6279 GLenum type,
6280 void *pixels)
6281{
6282 return ValidateReadPixelsBase(context, x, y, width, height, format, type, -1, nullptr, nullptr,
6283 nullptr, pixels);
6284}
6285
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006286bool ValidateTexParameterf(Context *context, TextureType target, GLenum pname, GLfloat param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006287{
Lingfeng Yangf97641c2018-06-21 19:22:45 -07006288 return ValidateTexParameterBase(context, target, pname, 1, &param);
Jamie Madillbe849e42017-05-02 15:49:00 -04006289}
6290
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006291bool ValidateTexParameterfv(Context *context,
6292 TextureType target,
6293 GLenum pname,
6294 const GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006295{
6296 return ValidateTexParameterBase(context, target, pname, -1, params);
6297}
6298
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006299bool ValidateTexParameteri(Context *context, TextureType target, GLenum pname, GLint param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006300{
Lingfeng Yangf97641c2018-06-21 19:22:45 -07006301 return ValidateTexParameterBase(context, target, pname, 1, &param);
Jamie Madillbe849e42017-05-02 15:49:00 -04006302}
6303
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006304bool ValidateTexParameteriv(Context *context, TextureType target, GLenum pname, const GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006305{
6306 return ValidateTexParameterBase(context, target, pname, -1, params);
6307}
6308
6309bool ValidateUseProgram(Context *context, GLuint program)
6310{
6311 if (program != 0)
6312 {
Jamie Madill44a6fbf2018-10-02 13:38:56 -04006313 Program *programObject = context->getProgramResolveLink(program);
Jamie Madillbe849e42017-05-02 15:49:00 -04006314 if (!programObject)
6315 {
6316 // ES 3.1.0 section 7.3 page 72
6317 if (context->getShader(program))
6318 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006319 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006320 return false;
6321 }
6322 else
6323 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006324 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006325 return false;
6326 }
6327 }
6328 if (!programObject->isLinked())
6329 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006330 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillbe849e42017-05-02 15:49:00 -04006331 return false;
6332 }
6333 }
6334 if (context->getGLState().isTransformFeedbackActiveUnpaused())
6335 {
6336 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006337 context
6338 ->handleError(InvalidOperation()
6339 << "Cannot change active program while transform feedback is unpaused.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006340 return false;
6341 }
6342
6343 return true;
6344}
6345
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006346bool ValidateDeleteFencesNV(Context *context, GLsizei n, const GLuint *fences)
6347{
6348 if (!context->getExtensions().fence)
6349 {
6350 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6351 return false;
6352 }
6353
6354 if (n < 0)
6355 {
6356 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
6357 return false;
6358 }
6359
6360 return true;
6361}
6362
6363bool ValidateFinishFenceNV(Context *context, GLuint fence)
6364{
6365 if (!context->getExtensions().fence)
6366 {
6367 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6368 return false;
6369 }
6370
6371 FenceNV *fenceObject = context->getFenceNV(fence);
6372
6373 if (fenceObject == nullptr)
6374 {
6375 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6376 return false;
6377 }
6378
6379 if (!fenceObject->isSet())
6380 {
6381 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6382 return false;
6383 }
6384
6385 return true;
6386}
6387
6388bool ValidateGenFencesNV(Context *context, GLsizei n, GLuint *fences)
6389{
6390 if (!context->getExtensions().fence)
6391 {
6392 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6393 return false;
6394 }
6395
6396 if (n < 0)
6397 {
6398 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
6399 return false;
6400 }
6401
6402 return true;
6403}
6404
6405bool ValidateGetFenceivNV(Context *context, GLuint fence, GLenum pname, GLint *params)
6406{
6407 if (!context->getExtensions().fence)
6408 {
6409 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6410 return false;
6411 }
6412
6413 FenceNV *fenceObject = context->getFenceNV(fence);
6414
6415 if (fenceObject == nullptr)
6416 {
6417 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6418 return false;
6419 }
6420
6421 if (!fenceObject->isSet())
6422 {
6423 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6424 return false;
6425 }
6426
6427 switch (pname)
6428 {
6429 case GL_FENCE_STATUS_NV:
6430 case GL_FENCE_CONDITION_NV:
6431 break;
6432
6433 default:
6434 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPname);
6435 return false;
6436 }
6437
6438 return true;
6439}
6440
6441bool ValidateGetGraphicsResetStatusEXT(Context *context)
6442{
6443 if (!context->getExtensions().robustness)
6444 {
6445 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6446 return false;
6447 }
6448
6449 return true;
6450}
6451
6452bool ValidateGetTranslatedShaderSourceANGLE(Context *context,
6453 GLuint shader,
6454 GLsizei bufsize,
6455 GLsizei *length,
6456 GLchar *source)
6457{
6458 if (!context->getExtensions().translatedShaderSource)
6459 {
6460 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6461 return false;
6462 }
6463
6464 if (bufsize < 0)
6465 {
6466 context->handleError(InvalidValue());
6467 return false;
6468 }
6469
6470 Shader *shaderObject = context->getShader(shader);
6471
6472 if (!shaderObject)
6473 {
6474 context->handleError(InvalidOperation());
6475 return false;
6476 }
6477
6478 return true;
6479}
6480
6481bool ValidateIsFenceNV(Context *context, GLuint fence)
6482{
6483 if (!context->getExtensions().fence)
6484 {
6485 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6486 return false;
6487 }
6488
6489 return true;
6490}
6491
Jamie Madill007530e2017-12-28 14:27:04 -05006492bool ValidateSetFenceNV(Context *context, GLuint fence, GLenum condition)
6493{
6494 if (!context->getExtensions().fence)
6495 {
6496 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6497 return false;
6498 }
6499
6500 if (condition != GL_ALL_COMPLETED_NV)
6501 {
6502 context->handleError(InvalidEnum());
6503 return false;
6504 }
6505
6506 FenceNV *fenceObject = context->getFenceNV(fence);
6507
6508 if (fenceObject == nullptr)
6509 {
6510 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6511 return false;
6512 }
6513
6514 return true;
6515}
6516
6517bool ValidateTestFenceNV(Context *context, GLuint fence)
6518{
6519 if (!context->getExtensions().fence)
6520 {
6521 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6522 return false;
6523 }
6524
6525 FenceNV *fenceObject = context->getFenceNV(fence);
6526
6527 if (fenceObject == nullptr)
6528 {
6529 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6530 return false;
6531 }
6532
6533 if (fenceObject->isSet() != GL_TRUE)
6534 {
6535 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6536 return false;
6537 }
6538
6539 return true;
6540}
6541
6542bool ValidateTexStorage2DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006543 TextureType type,
Jamie Madill007530e2017-12-28 14:27:04 -05006544 GLsizei levels,
6545 GLenum internalformat,
6546 GLsizei width,
6547 GLsizei height)
6548{
6549 if (!context->getExtensions().textureStorage)
6550 {
6551 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6552 return false;
6553 }
6554
6555 if (context->getClientMajorVersion() < 3)
6556 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006557 return ValidateES2TexStorageParameters(context, type, levels, internalformat, width,
Jamie Madill007530e2017-12-28 14:27:04 -05006558 height);
6559 }
6560
6561 ASSERT(context->getClientMajorVersion() >= 3);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006562 return ValidateES3TexStorage2DParameters(context, type, levels, internalformat, width, height,
Jamie Madill007530e2017-12-28 14:27:04 -05006563 1);
6564}
6565
6566bool ValidateVertexAttribDivisorANGLE(Context *context, GLuint index, GLuint divisor)
6567{
6568 if (!context->getExtensions().instancedArrays)
6569 {
6570 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6571 return false;
6572 }
6573
6574 if (index >= MAX_VERTEX_ATTRIBS)
6575 {
6576 context->handleError(InvalidValue());
6577 return false;
6578 }
6579
6580 if (context->getLimitations().attributeZeroRequiresZeroDivisorInEXT)
6581 {
6582 if (index == 0 && divisor != 0)
6583 {
6584 const char *errorMessage =
6585 "The current context doesn't support setting a non-zero divisor on the "
6586 "attribute with index zero. "
6587 "Please reorder the attributes in your vertex shader so that attribute zero "
6588 "can have a zero divisor.";
6589 context->handleError(InvalidOperation() << errorMessage);
6590
6591 // We also output an error message to the debugger window if tracing is active, so
6592 // that developers can see the error message.
6593 ERR() << errorMessage;
6594 return false;
6595 }
6596 }
6597
6598 return true;
6599}
6600
6601bool ValidateTexImage3DOES(Context *context,
6602 GLenum target,
6603 GLint level,
6604 GLenum internalformat,
6605 GLsizei width,
6606 GLsizei height,
6607 GLsizei depth,
6608 GLint border,
6609 GLenum format,
6610 GLenum type,
6611 const void *pixels)
6612{
6613 UNIMPLEMENTED(); // FIXME
6614 return false;
6615}
6616
6617bool ValidatePopGroupMarkerEXT(Context *context)
6618{
6619 if (!context->getExtensions().debugMarker)
6620 {
6621 // The debug marker calls should not set error state
6622 // However, it seems reasonable to set an error state if the extension is not enabled
6623 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6624 return false;
6625 }
6626
6627 return true;
6628}
6629
Jamie Madillfa920eb2018-01-04 11:45:50 -05006630bool ValidateTexStorage1DEXT(Context *context,
6631 GLenum target,
6632 GLsizei levels,
6633 GLenum internalformat,
6634 GLsizei width)
6635{
6636 UNIMPLEMENTED();
6637 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6638 return false;
6639}
6640
6641bool ValidateTexStorage3DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006642 TextureType target,
Jamie Madillfa920eb2018-01-04 11:45:50 -05006643 GLsizei levels,
6644 GLenum internalformat,
6645 GLsizei width,
6646 GLsizei height,
6647 GLsizei depth)
6648{
6649 if (!context->getExtensions().textureStorage)
6650 {
6651 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6652 return false;
6653 }
6654
6655 if (context->getClientMajorVersion() < 3)
6656 {
6657 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6658 return false;
6659 }
6660
6661 return ValidateES3TexStorage3DParameters(context, target, levels, internalformat, width, height,
6662 depth);
6663}
6664
jchen1082af6202018-06-22 10:59:52 +08006665bool ValidateMaxShaderCompilerThreadsKHR(Context *context, GLuint count)
6666{
6667 if (!context->getExtensions().parallelShaderCompile)
6668 {
6669 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6670 return false;
6671 }
6672 return true;
6673}
6674
Jamie Madillc29968b2016-01-20 11:17:23 -05006675} // namespace gl