blob: b35dbdf4beb3d2d584333791bc8b8b14cbcff83e [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;
78 if (context->hasPath(pathName) && !context->hasPathData(pathName))
79 {
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 {
Geoff Lang4f0e0032017-05-01 16:04:35 -0400291 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700292 }
293
Geoff Langc0094ec2017-08-16 14:16:24 -0400294 if (!ValidES3FormatCombination(GetUnsizedFormat(internalFormat), type, internalFormat))
295 {
296 context->handleError(InvalidOperation()
297 << "Invalid combination of type and internalFormat.");
298 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 {
Geoff Lang4f0e0032017-05-01 16:04:35 -0400304 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700305 }
306
307 return true;
308}
309
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800310bool IsValidCopyTextureDestinationTargetEnum(Context *context, TextureTarget target)
Geoff Lang97073d12016-04-20 10:42:34 -0700311{
312 switch (target)
313 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800314 case TextureTarget::_2D:
315 case TextureTarget::CubeMapNegativeX:
316 case TextureTarget::CubeMapNegativeY:
317 case TextureTarget::CubeMapNegativeZ:
318 case TextureTarget::CubeMapPositiveX:
319 case TextureTarget::CubeMapPositiveY:
320 case TextureTarget::CubeMapPositiveZ:
Geoff Lang63458a32017-10-30 15:16:53 -0400321 return true;
Geoff Lang97073d12016-04-20 10:42:34 -0700322
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800323 case TextureTarget::Rectangle:
Geoff Lang63458a32017-10-30 15:16:53 -0400324 return context->getExtensions().textureRectangle;
Geoff Lang97073d12016-04-20 10:42:34 -0700325
326 default:
327 return false;
328 }
329}
330
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800331bool IsValidCopyTextureDestinationTarget(Context *context,
332 TextureType textureType,
333 TextureTarget target)
Geoff Lang63458a32017-10-30 15:16:53 -0400334{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800335 return TextureTargetToType(target) == textureType;
Geoff Lang63458a32017-10-30 15:16:53 -0400336}
337
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800338bool IsValidCopyTextureSourceTarget(Context *context, TextureType type)
Geoff Lang97073d12016-04-20 10:42:34 -0700339{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800340 switch (type)
Geoff Lang97073d12016-04-20 10:42:34 -0700341 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800342 case TextureType::_2D:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400343 return true;
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800344 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400345 return context->getExtensions().textureRectangle;
Geoff Lang4f0e0032017-05-01 16:04:35 -0400346
347 // TODO(geofflang): accept GL_TEXTURE_EXTERNAL_OES if the texture_external extension is
348 // supported
349
350 default:
351 return false;
352 }
353}
354
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800355bool IsValidCopyTextureSourceLevel(Context *context, TextureType type, GLint level)
Geoff Lang4f0e0032017-05-01 16:04:35 -0400356{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800357 if (!ValidMipLevel(context, type, level))
Geoff Lang4f0e0032017-05-01 16:04:35 -0400358 {
359 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700360 }
361
Geoff Lang4f0e0032017-05-01 16:04:35 -0400362 if (level > 0 && context->getClientVersion() < ES_3_0)
363 {
364 return false;
365 }
Geoff Lang97073d12016-04-20 10:42:34 -0700366
Geoff Lang4f0e0032017-05-01 16:04:35 -0400367 return true;
368}
369
370bool IsValidCopyTextureDestinationLevel(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800371 TextureType type,
Geoff Lang4f0e0032017-05-01 16:04:35 -0400372 GLint level,
373 GLsizei width,
Yuly Novikove3688d22018-03-07 22:14:54 +0000374 GLsizei height)
Geoff Lang4f0e0032017-05-01 16:04:35 -0400375{
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800376 if (!ValidMipLevel(context, type, level))
Geoff Lang4f0e0032017-05-01 16:04:35 -0400377 {
378 return false;
379 }
380
Geoff Lang4f0e0032017-05-01 16:04:35 -0400381 const Caps &caps = context->getCaps();
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800382 switch (type)
Geoff Lang4f0e0032017-05-01 16:04:35 -0400383 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800384 case TextureType::_2D:
385 return static_cast<GLuint>(width) <= (caps.max2DTextureSize >> level) &&
386 static_cast<GLuint>(height) <= (caps.max2DTextureSize >> level);
387 case TextureType::Rectangle:
388 ASSERT(level == 0);
389 return static_cast<GLuint>(width) <= (caps.max2DTextureSize >> level) &&
390 static_cast<GLuint>(height) <= (caps.max2DTextureSize >> level);
Geoff Lang4f0e0032017-05-01 16:04:35 -0400391
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800392 case TextureType::CubeMap:
393 return static_cast<GLuint>(width) <= (caps.maxCubeMapTextureSize >> level) &&
394 static_cast<GLuint>(height) <= (caps.maxCubeMapTextureSize >> level);
395 default:
396 return true;
397 }
Geoff Lang97073d12016-04-20 10:42:34 -0700398}
399
Jamie Madillc1d770e2017-04-13 17:31:24 -0400400bool IsValidStencilFunc(GLenum func)
401{
402 switch (func)
403 {
404 case GL_NEVER:
405 case GL_ALWAYS:
406 case GL_LESS:
407 case GL_LEQUAL:
408 case GL_EQUAL:
409 case GL_GEQUAL:
410 case GL_GREATER:
411 case GL_NOTEQUAL:
412 return true;
413
414 default:
415 return false;
416 }
417}
418
419bool IsValidStencilFace(GLenum face)
420{
421 switch (face)
422 {
423 case GL_FRONT:
424 case GL_BACK:
425 case GL_FRONT_AND_BACK:
426 return true;
427
428 default:
429 return false;
430 }
431}
432
433bool IsValidStencilOp(GLenum op)
434{
435 switch (op)
436 {
437 case GL_ZERO:
438 case GL_KEEP:
439 case GL_REPLACE:
440 case GL_INCR:
441 case GL_DECR:
442 case GL_INVERT:
443 case GL_INCR_WRAP:
444 case GL_DECR_WRAP:
445 return true;
446
447 default:
448 return false;
449 }
450}
451
Jamie Madillbe849e42017-05-02 15:49:00 -0400452bool ValidateES2CopyTexImageParameters(ValidationContext *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800453 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -0400454 GLint level,
455 GLenum internalformat,
456 bool isSubImage,
457 GLint xoffset,
458 GLint yoffset,
459 GLint x,
460 GLint y,
461 GLsizei width,
462 GLsizei height,
463 GLint border)
464{
465 if (!ValidTexture2DDestinationTarget(context, target))
466 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700467 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -0400468 return false;
469 }
470
Corentin Wallezf0e89be2017-11-08 14:00:32 -0800471 TextureType texType = TextureTargetToType(target);
472 if (!ValidImageSizeParameters(context, texType, level, width, height, 1, isSubImage))
Jamie Madillbe849e42017-05-02 15:49:00 -0400473 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500474 context->handleError(InvalidValue() << "Invalid texture dimensions.");
Jamie Madillbe849e42017-05-02 15:49:00 -0400475 return false;
476 }
477
478 Format textureFormat = Format::Invalid();
479 if (!ValidateCopyTexImageParametersBase(context, target, level, internalformat, isSubImage,
480 xoffset, yoffset, 0, x, y, width, height, border,
481 &textureFormat))
482 {
483 return false;
484 }
485
486 const gl::Framebuffer *framebuffer = context->getGLState().getReadFramebuffer();
487 GLenum colorbufferFormat =
488 framebuffer->getReadColorbuffer()->getFormat().info->sizedInternalFormat;
489 const auto &formatInfo = *textureFormat.info;
490
491 // [OpenGL ES 2.0.24] table 3.9
492 if (isSubImage)
493 {
494 switch (formatInfo.format)
495 {
496 case GL_ALPHA:
497 if (colorbufferFormat != GL_ALPHA8_EXT && colorbufferFormat != GL_RGBA4 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400498 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGBA8_OES &&
499 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400500 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700501 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400502 return false;
503 }
504 break;
505 case GL_LUMINANCE:
506 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
507 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
508 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400509 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGRA8_EXT &&
510 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400511 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700512 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400513 return false;
514 }
515 break;
516 case GL_RED_EXT:
517 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
518 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
519 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
520 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_R32F &&
521 colorbufferFormat != GL_RG32F && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400522 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
523 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400524 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700525 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400526 return false;
527 }
528 break;
529 case GL_RG_EXT:
530 if (colorbufferFormat != GL_RG8_EXT && colorbufferFormat != GL_RGB565 &&
531 colorbufferFormat != GL_RGB8_OES && colorbufferFormat != GL_RGBA4 &&
532 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGBA8_OES &&
533 colorbufferFormat != GL_RG32F && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400534 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
535 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400536 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700537 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400538 return false;
539 }
540 break;
541 case GL_RGB:
542 if (colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
543 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
544 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400545 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
546 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400547 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700548 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400549 return false;
550 }
551 break;
552 case GL_LUMINANCE_ALPHA:
553 case GL_RGBA:
554 if (colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400555 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_RGBA32F &&
556 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400557 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700558 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400559 return false;
560 }
561 break;
562 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
563 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
564 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
565 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
566 case GL_ETC1_RGB8_OES:
567 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
568 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
569 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
570 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
571 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
Brandon Jones6cad5662017-06-14 13:25:13 -0700572 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400573 return false;
574 case GL_DEPTH_COMPONENT:
575 case GL_DEPTH_STENCIL_OES:
Brandon Jones6cad5662017-06-14 13:25:13 -0700576 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400577 return false;
578 default:
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 }
582
583 if (formatInfo.type == GL_FLOAT && !context->getExtensions().textureFloat)
584 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700585 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400586 return false;
587 }
588 }
589 else
590 {
591 switch (internalformat)
592 {
593 case GL_ALPHA:
594 if (colorbufferFormat != GL_ALPHA8_EXT && colorbufferFormat != GL_RGBA4 &&
595 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_BGRA8_EXT &&
596 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGR5_A1_ANGLEX)
597 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700598 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400599 return false;
600 }
601 break;
602 case GL_LUMINANCE:
603 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
604 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
605 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
606 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
607 colorbufferFormat != GL_BGR5_A1_ANGLEX)
608 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700609 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400610 return false;
611 }
612 break;
613 case GL_RED_EXT:
614 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
615 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
616 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
617 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
618 colorbufferFormat != GL_BGR5_A1_ANGLEX)
619 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700620 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400621 return false;
622 }
623 break;
624 case GL_RG_EXT:
625 if (colorbufferFormat != GL_RG8_EXT && colorbufferFormat != GL_RGB565 &&
626 colorbufferFormat != GL_RGB8_OES && colorbufferFormat != GL_RGBA4 &&
627 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_BGRA8_EXT &&
628 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGR5_A1_ANGLEX)
629 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700630 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400631 return false;
632 }
633 break;
634 case GL_RGB:
635 if (colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
636 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
637 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
638 colorbufferFormat != GL_BGR5_A1_ANGLEX)
639 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700640 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400641 return false;
642 }
643 break;
644 case GL_LUMINANCE_ALPHA:
645 case GL_RGBA:
646 if (colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
647 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
648 colorbufferFormat != GL_BGR5_A1_ANGLEX)
649 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700650 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400651 return false;
652 }
653 break;
654 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
655 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
656 if (context->getExtensions().textureCompressionDXT1)
657 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700658 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400659 return false;
660 }
661 else
662 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700663 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400664 return false;
665 }
666 break;
667 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
668 if (context->getExtensions().textureCompressionDXT3)
669 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700670 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400671 return false;
672 }
673 else
674 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700675 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400676 return false;
677 }
678 break;
679 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
680 if (context->getExtensions().textureCompressionDXT5)
681 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700682 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400683 return false;
684 }
685 else
686 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700687 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400688 return false;
689 }
690 break;
691 case GL_ETC1_RGB8_OES:
692 if (context->getExtensions().compressedETC1RGB8Texture)
693 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500694 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -0400695 return false;
696 }
697 else
698 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500699 context->handleError(InvalidEnum());
Jamie Madillbe849e42017-05-02 15:49:00 -0400700 return false;
701 }
702 break;
703 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
704 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
705 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
706 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
707 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
708 if (context->getExtensions().lossyETCDecode)
709 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500710 context->handleError(InvalidOperation()
711 << "ETC lossy decode formats can't be copied to.");
Jamie Madillbe849e42017-05-02 15:49:00 -0400712 return false;
713 }
714 else
715 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500716 context->handleError(InvalidEnum()
717 << "ANGLE_lossy_etc_decode extension is not supported.");
Jamie Madillbe849e42017-05-02 15:49:00 -0400718 return false;
719 }
720 break;
721 case GL_DEPTH_COMPONENT:
722 case GL_DEPTH_COMPONENT16:
723 case GL_DEPTH_COMPONENT32_OES:
724 case GL_DEPTH_STENCIL_OES:
725 case GL_DEPTH24_STENCIL8_OES:
726 if (context->getExtensions().depthTextures)
727 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500728 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -0400729 return false;
730 }
731 else
732 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500733 context->handleError(InvalidEnum());
Jamie Madillbe849e42017-05-02 15:49:00 -0400734 return false;
735 }
736 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500737 context->handleError(InvalidEnum());
Jamie Madillbe849e42017-05-02 15:49:00 -0400738 return false;
739 }
740 }
741
742 // If width or height is zero, it is a no-op. Return false without setting an error.
743 return (width > 0 && height > 0);
744}
745
746bool ValidCap(const Context *context, GLenum cap, bool queryOnly)
747{
748 switch (cap)
749 {
750 // EXT_multisample_compatibility
751 case GL_MULTISAMPLE_EXT:
752 case GL_SAMPLE_ALPHA_TO_ONE_EXT:
753 return context->getExtensions().multisampleCompatibility;
754
755 case GL_CULL_FACE:
756 case GL_POLYGON_OFFSET_FILL:
757 case GL_SAMPLE_ALPHA_TO_COVERAGE:
758 case GL_SAMPLE_COVERAGE:
759 case GL_SCISSOR_TEST:
760 case GL_STENCIL_TEST:
761 case GL_DEPTH_TEST:
762 case GL_BLEND:
763 case GL_DITHER:
764 return true;
765
766 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
767 case GL_RASTERIZER_DISCARD:
768 return (context->getClientMajorVersion() >= 3);
769
770 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
771 case GL_DEBUG_OUTPUT:
772 return context->getExtensions().debug;
773
774 case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
775 return queryOnly && context->getExtensions().bindGeneratesResource;
776
777 case GL_CLIENT_ARRAYS_ANGLE:
778 return queryOnly && context->getExtensions().clientArrays;
779
780 case GL_FRAMEBUFFER_SRGB_EXT:
781 return context->getExtensions().sRGBWriteControl;
782
783 case GL_SAMPLE_MASK:
784 return context->getClientVersion() >= Version(3, 1);
785
Geoff Langb433e872017-10-05 14:01:47 -0400786 case GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
Jamie Madillbe849e42017-05-02 15:49:00 -0400787 return queryOnly && context->getExtensions().robustResourceInitialization;
788
789 default:
790 return false;
791 }
792}
793
Geoff Langfc32e8b2017-05-31 14:16:59 -0400794// Return true if a character belongs to the ASCII subset as defined in GLSL ES 1.0 spec section
795// 3.1.
Geoff Langcab92ee2017-07-19 17:32:07 -0400796bool IsValidESSLCharacter(unsigned char c)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400797{
798 // Printing characters are valid except " $ ` @ \ ' DEL.
Geoff Langcab92ee2017-07-19 17:32:07 -0400799 if (c >= 32 && c <= 126 && c != '"' && c != '$' && c != '`' && c != '@' && c != '\\' &&
800 c != '\'')
Geoff Langfc32e8b2017-05-31 14:16:59 -0400801 {
802 return true;
803 }
804
805 // Horizontal tab, line feed, vertical tab, form feed, carriage return are also valid.
806 if (c >= 9 && c <= 13)
807 {
808 return true;
809 }
810
811 return false;
812}
813
Geoff Langcab92ee2017-07-19 17:32:07 -0400814bool IsValidESSLString(const char *str, size_t len)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400815{
Geoff Langa71a98e2017-06-19 15:15:00 -0400816 for (size_t i = 0; i < len; i++)
817 {
Geoff Langcab92ee2017-07-19 17:32:07 -0400818 if (!IsValidESSLCharacter(str[i]))
Geoff Langa71a98e2017-06-19 15:15:00 -0400819 {
820 return false;
821 }
822 }
823
824 return true;
Geoff Langfc32e8b2017-05-31 14:16:59 -0400825}
826
Geoff Langcab92ee2017-07-19 17:32:07 -0400827bool IsValidESSLShaderSourceString(const char *str, size_t len, bool lineContinuationAllowed)
828{
829 enum class ParseState
830 {
831 // Have not seen an ASCII non-whitespace character yet on
832 // this line. Possible that we might see a preprocessor
833 // directive.
834 BEGINING_OF_LINE,
835
836 // Have seen at least one ASCII non-whitespace character
837 // on this line.
838 MIDDLE_OF_LINE,
839
840 // Handling a preprocessor directive. Passes through all
841 // characters up to the end of the line. Disables comment
842 // processing.
843 IN_PREPROCESSOR_DIRECTIVE,
844
845 // Handling a single-line comment. The comment text is
846 // replaced with a single space.
847 IN_SINGLE_LINE_COMMENT,
848
849 // Handling a multi-line comment. Newlines are passed
850 // through to preserve line numbers.
851 IN_MULTI_LINE_COMMENT
852 };
853
854 ParseState state = ParseState::BEGINING_OF_LINE;
855 size_t pos = 0;
856
857 while (pos < len)
858 {
859 char c = str[pos];
860 char next = pos + 1 < len ? str[pos + 1] : 0;
861
862 // Check for newlines
863 if (c == '\n' || c == '\r')
864 {
865 if (state != ParseState::IN_MULTI_LINE_COMMENT)
866 {
867 state = ParseState::BEGINING_OF_LINE;
868 }
869
870 pos++;
871 continue;
872 }
873
874 switch (state)
875 {
876 case ParseState::BEGINING_OF_LINE:
877 if (c == ' ')
878 {
879 // Maintain the BEGINING_OF_LINE state until a non-space is seen
880 pos++;
881 }
882 else if (c == '#')
883 {
884 state = ParseState::IN_PREPROCESSOR_DIRECTIVE;
885 pos++;
886 }
887 else
888 {
889 // Don't advance, re-process this character with the MIDDLE_OF_LINE state
890 state = ParseState::MIDDLE_OF_LINE;
891 }
892 break;
893
894 case ParseState::MIDDLE_OF_LINE:
895 if (c == '/' && next == '/')
896 {
897 state = ParseState::IN_SINGLE_LINE_COMMENT;
898 pos++;
899 }
900 else if (c == '/' && next == '*')
901 {
902 state = ParseState::IN_MULTI_LINE_COMMENT;
903 pos++;
904 }
905 else if (lineContinuationAllowed && c == '\\' && (next == '\n' || next == '\r'))
906 {
907 // Skip line continuation characters
908 }
909 else if (!IsValidESSLCharacter(c))
910 {
911 return false;
912 }
913 pos++;
914 break;
915
916 case ParseState::IN_PREPROCESSOR_DIRECTIVE:
Bryan Bernhart (Intel Americas Inc)335d8bf2017-10-23 15:41:43 -0700917 // Line-continuation characters may not be permitted.
918 // Otherwise, just pass it through. Do not parse comments in this state.
919 if (!lineContinuationAllowed && c == '\\')
920 {
921 return false;
922 }
Geoff Langcab92ee2017-07-19 17:32:07 -0400923 pos++;
924 break;
925
926 case ParseState::IN_SINGLE_LINE_COMMENT:
927 // Line-continuation characters are processed before comment processing.
928 // Advance string if a new line character is immediately behind
929 // line-continuation character.
930 if (c == '\\' && (next == '\n' || next == '\r'))
931 {
932 pos++;
933 }
934 pos++;
935 break;
936
937 case ParseState::IN_MULTI_LINE_COMMENT:
938 if (c == '*' && next == '/')
939 {
940 state = ParseState::MIDDLE_OF_LINE;
941 pos++;
942 }
943 pos++;
944 break;
945 }
946 }
947
948 return true;
949}
950
Brandon Jonesed5b46f2017-07-21 08:39:17 -0700951bool ValidateWebGLNamePrefix(ValidationContext *context, const GLchar *name)
952{
953 ASSERT(context->isWebGL());
954
955 // WebGL 1.0 [Section 6.16] GLSL Constructs
956 // Identifiers starting with "webgl_" and "_webgl_" are reserved for use by WebGL.
957 if (strncmp(name, "webgl_", 6) == 0 || strncmp(name, "_webgl_", 7) == 0)
958 {
959 ANGLE_VALIDATION_ERR(context, InvalidOperation(), WebglBindAttribLocationReservedPrefix);
960 return false;
961 }
962
963 return true;
964}
965
966bool ValidateWebGLNameLength(ValidationContext *context, size_t length)
967{
968 ASSERT(context->isWebGL());
969
970 if (context->isWebGL1() && length > 256)
971 {
972 // WebGL 1.0 [Section 6.21] Maxmimum Uniform and Attribute Location Lengths
973 // WebGL imposes a limit of 256 characters on the lengths of uniform and attribute
974 // locations.
975 ANGLE_VALIDATION_ERR(context, InvalidValue(), WebglNameLengthLimitExceeded);
976
977 return false;
978 }
979 else if (length > 1024)
980 {
981 // WebGL 2.0 [Section 4.3.2] WebGL 2.0 imposes a limit of 1024 characters on the lengths of
982 // uniform and attribute locations.
983 ANGLE_VALIDATION_ERR(context, InvalidValue(), Webgl2NameLengthLimitExceeded);
984 return false;
985 }
986
987 return true;
988}
989
Jamie Madill007530e2017-12-28 14:27:04 -0500990bool ValidateMatrixMode(Context *context, GLenum matrixMode)
991{
992 if (!context->getExtensions().pathRendering)
993 {
994 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
995 return false;
996 }
997
998 if (matrixMode != GL_PATH_MODELVIEW_CHROMIUM && matrixMode != GL_PATH_PROJECTION_CHROMIUM)
999 {
1000 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidMatrixMode);
1001 return false;
1002 }
1003 return true;
1004}
Jamie Madillc29968b2016-01-20 11:17:23 -05001005} // anonymous namespace
1006
Geoff Langff5b2d52016-09-07 11:32:23 -04001007bool ValidateES2TexImageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001008 TextureTarget target,
Geoff Langff5b2d52016-09-07 11:32:23 -04001009 GLint level,
1010 GLenum internalformat,
1011 bool isCompressed,
1012 bool isSubImage,
1013 GLint xoffset,
1014 GLint yoffset,
1015 GLsizei width,
1016 GLsizei height,
1017 GLint border,
1018 GLenum format,
1019 GLenum type,
1020 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04001021 const void *pixels)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001022{
Jamie Madill6f38f822014-06-06 17:12:20 -04001023 if (!ValidTexture2DDestinationTarget(context, target))
1024 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001025 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001026 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -04001027 }
1028
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001029 TextureType texType = TextureTargetToType(target);
1030 if (!ValidImageSizeParameters(context, texType, level, width, height, 1, isSubImage))
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001031 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001032 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001033 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001034 }
1035
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001036 if (!ValidMipLevel(context, texType, level))
Brandon Jones6cad5662017-06-14 13:25:13 -07001037 {
1038 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
1039 return false;
1040 }
1041
1042 if (xoffset < 0 || std::numeric_limits<GLsizei>::max() - xoffset < width ||
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001043 std::numeric_limits<GLsizei>::max() - yoffset < height)
1044 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001045 ANGLE_VALIDATION_ERR(context, InvalidValue(), ResourceMaxTextureSize);
Geoff Langb1196682014-07-23 13:47:29 -04001046 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001047 }
1048
Geoff Lang6e898aa2017-06-02 11:17:26 -04001049 // From GL_CHROMIUM_color_buffer_float_rgb[a]:
1050 // GL_RGB[A] / GL_RGB[A]32F becomes an allowable format / internalformat parameter pair for
1051 // TexImage2D. The restriction in section 3.7.1 of the OpenGL ES 2.0 spec that the
1052 // internalformat parameter and format parameter of TexImage2D must match is lifted for this
1053 // case.
1054 bool nonEqualFormatsAllowed =
1055 (internalformat == GL_RGB32F && context->getExtensions().colorBufferFloatRGB) ||
1056 (internalformat == GL_RGBA32F && context->getExtensions().colorBufferFloatRGBA);
1057
1058 if (!isSubImage && !isCompressed && internalformat != format && !nonEqualFormatsAllowed)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001059 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001060 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001061 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001062 }
1063
Geoff Langaae65a42014-05-26 12:43:44 -04001064 const gl::Caps &caps = context->getCaps();
1065
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001066 switch (texType)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001067 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001068 case TextureType::_2D:
1069 if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
1070 static_cast<GLuint>(height) > (caps.max2DTextureSize >> level))
1071 {
1072 context->handleError(InvalidValue());
1073 return false;
1074 }
1075 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001076
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001077 case TextureType::Rectangle:
1078 ASSERT(level == 0);
1079 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1080 static_cast<GLuint>(height) > caps.maxRectangleTextureSize)
1081 {
1082 context->handleError(InvalidValue());
1083 return false;
1084 }
1085 if (isCompressed)
1086 {
1087 context->handleError(InvalidEnum()
1088 << "Rectangle texture cannot have a compressed format.");
1089 return false;
1090 }
1091 break;
1092
1093 case TextureType::CubeMap:
1094 if (!isSubImage && width != height)
1095 {
1096 ANGLE_VALIDATION_ERR(context, InvalidValue(), CubemapFacesEqualDimensions);
1097 return false;
1098 }
1099
1100 if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level) ||
1101 static_cast<GLuint>(height) > (caps.maxCubeMapTextureSize >> level))
1102 {
1103 context->handleError(InvalidValue());
1104 return false;
1105 }
1106 break;
1107
1108 default:
1109 context->handleError(InvalidEnum());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001110 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001111 }
1112
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001113 gl::Texture *texture = context->getTargetTexture(texType);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001114 if (!texture)
1115 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001116 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Geoff Langb1196682014-07-23 13:47:29 -04001117 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001118 }
1119
Geoff Langa9be0dc2014-12-17 12:34:40 -05001120 if (isSubImage)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001121 {
Geoff Langca271392017-04-05 12:30:00 -04001122 const InternalFormat &textureInternalFormat = *texture->getFormat(target, level).info;
1123 if (textureInternalFormat.internalFormat == GL_NONE)
Geoff Langc51642b2016-11-14 16:18:26 -05001124 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001125 context->handleError(InvalidOperation() << "Texture level does not exist.");
Geoff Langc51642b2016-11-14 16:18:26 -05001126 return false;
1127 }
1128
Geoff Langa9be0dc2014-12-17 12:34:40 -05001129 if (format != GL_NONE)
1130 {
Geoff Langca271392017-04-05 12:30:00 -04001131 if (GetInternalFormatInfo(format, type).sizedInternalFormat !=
1132 textureInternalFormat.sizedInternalFormat)
Geoff Langa9be0dc2014-12-17 12:34:40 -05001133 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001134 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TypeMismatch);
Geoff Langa9be0dc2014-12-17 12:34:40 -05001135 return false;
1136 }
1137 }
1138
1139 if (static_cast<size_t>(xoffset + width) > texture->getWidth(target, level) ||
1140 static_cast<size_t>(yoffset + height) > texture->getHeight(target, level))
1141 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001142 context->handleError(InvalidValue());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001143 return false;
1144 }
Geoff Langfb052642017-10-24 13:42:09 -04001145
1146 if (width > 0 && height > 0 && pixels == nullptr &&
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001147 context->getGLState().getTargetBuffer(BufferBinding::PixelUnpack) == nullptr)
Geoff Langfb052642017-10-24 13:42:09 -04001148 {
1149 ANGLE_VALIDATION_ERR(context, InvalidValue(), PixelDataNull);
1150 return false;
1151 }
Geoff Langa9be0dc2014-12-17 12:34:40 -05001152 }
1153 else
1154 {
Geoff Lang69cce582015-09-17 13:20:36 -04001155 if (texture->getImmutableFormat())
Geoff Langa9be0dc2014-12-17 12:34:40 -05001156 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001157 context->handleError(InvalidOperation());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001158 return false;
1159 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001160 }
1161
1162 // Verify zero border
1163 if (border != 0)
1164 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001165 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidBorder);
Geoff Langb1196682014-07-23 13:47:29 -04001166 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001167 }
1168
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001169 if (isCompressed)
1170 {
tmartino0ccd5ae2015-10-01 14:33:14 -04001171 GLenum actualInternalFormat =
Geoff Langca271392017-04-05 12:30:00 -04001172 isSubImage ? texture->getFormat(target, level).info->sizedInternalFormat
1173 : internalformat;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001174 switch (actualInternalFormat)
1175 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001176 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1177 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1178 if (!context->getExtensions().textureCompressionDXT1)
1179 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001180 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001181 return false;
1182 }
1183 break;
1184 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
Geoff Lang86f81162017-10-30 15:10:45 -04001185 if (!context->getExtensions().textureCompressionDXT3)
He Yunchaoced53ae2016-11-29 15:00:51 +08001186 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001187 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001188 return false;
1189 }
1190 break;
1191 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1192 if (!context->getExtensions().textureCompressionDXT5)
1193 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001194 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001195 return false;
1196 }
1197 break;
Kai Ninomiya02f075c2016-12-22 14:55:46 -08001198 case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
1199 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
1200 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
1201 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
1202 if (!context->getExtensions().textureCompressionS3TCsRGB)
1203 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001204 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
Kai Ninomiya02f075c2016-12-22 14:55:46 -08001205 return false;
1206 }
1207 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001208 case GL_ETC1_RGB8_OES:
1209 if (!context->getExtensions().compressedETC1RGB8Texture)
1210 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001211 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001212 return false;
1213 }
Geoff Lang86f81162017-10-30 15:10:45 -04001214 if (isSubImage)
1215 {
1216 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
1217 return false;
1218 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001219 break;
1220 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001221 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1222 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1223 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1224 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001225 if (!context->getExtensions().lossyETCDecode)
1226 {
Geoff Lang86f81162017-10-30 15:10:45 -04001227 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001228 return false;
1229 }
1230 break;
1231 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001232 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
Geoff Langb1196682014-07-23 13:47:29 -04001233 return false;
tmartino0ccd5ae2015-10-01 14:33:14 -04001234 }
Geoff Lang966c9402017-04-18 12:38:27 -04001235
1236 if (isSubImage)
tmartino0ccd5ae2015-10-01 14:33:14 -04001237 {
Geoff Lang966c9402017-04-18 12:38:27 -04001238 if (!ValidCompressedSubImageSize(context, actualInternalFormat, xoffset, yoffset, width,
1239 height, texture->getWidth(target, level),
1240 texture->getHeight(target, level)))
1241 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001242 context->handleError(InvalidOperation() << "Invalid compressed format dimension.");
Geoff Lang966c9402017-04-18 12:38:27 -04001243 return false;
1244 }
1245
1246 if (format != actualInternalFormat)
1247 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001248 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Geoff Lang966c9402017-04-18 12:38:27 -04001249 return false;
1250 }
1251 }
1252 else
1253 {
1254 if (!ValidCompressedImageSize(context, actualInternalFormat, level, width, height))
1255 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001256 context->handleError(InvalidOperation() << "Invalid compressed format dimension.");
Geoff Lang966c9402017-04-18 12:38:27 -04001257 return false;
1258 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001259 }
1260 }
1261 else
1262 {
1263 // validate <type> by itself (used as secondary key below)
1264 switch (type)
1265 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001266 case GL_UNSIGNED_BYTE:
1267 case GL_UNSIGNED_SHORT_5_6_5:
1268 case GL_UNSIGNED_SHORT_4_4_4_4:
1269 case GL_UNSIGNED_SHORT_5_5_5_1:
1270 case GL_UNSIGNED_SHORT:
1271 case GL_UNSIGNED_INT:
1272 case GL_UNSIGNED_INT_24_8_OES:
1273 case GL_HALF_FLOAT_OES:
1274 case GL_FLOAT:
1275 break;
1276 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001277 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidType);
He Yunchaoced53ae2016-11-29 15:00:51 +08001278 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001279 }
1280
1281 // validate <format> + <type> combinations
1282 // - invalid <format> -> sets INVALID_ENUM
1283 // - invalid <format>+<type> combination -> sets INVALID_OPERATION
1284 switch (format)
1285 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001286 case GL_ALPHA:
1287 case GL_LUMINANCE:
1288 case GL_LUMINANCE_ALPHA:
1289 switch (type)
1290 {
1291 case GL_UNSIGNED_BYTE:
1292 case GL_FLOAT:
1293 case GL_HALF_FLOAT_OES:
1294 break;
1295 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001296 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001297 return false;
1298 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001299 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001300 case GL_RED:
1301 case GL_RG:
1302 if (!context->getExtensions().textureRG)
1303 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001304 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001305 return false;
1306 }
1307 switch (type)
1308 {
1309 case GL_UNSIGNED_BYTE:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001310 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001311 case GL_FLOAT:
1312 case GL_HALF_FLOAT_OES:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001313 if (!context->getExtensions().textureFloat)
1314 {
1315 context->handleError(InvalidEnum());
1316 return false;
1317 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001318 break;
1319 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001320 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001321 return false;
1322 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001323 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001324 case GL_RGB:
1325 switch (type)
1326 {
1327 case GL_UNSIGNED_BYTE:
1328 case GL_UNSIGNED_SHORT_5_6_5:
1329 case GL_FLOAT:
1330 case GL_HALF_FLOAT_OES:
1331 break;
1332 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001333 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001334 return false;
1335 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001336 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001337 case GL_RGBA:
1338 switch (type)
1339 {
1340 case GL_UNSIGNED_BYTE:
1341 case GL_UNSIGNED_SHORT_4_4_4_4:
1342 case GL_UNSIGNED_SHORT_5_5_5_1:
1343 case GL_FLOAT:
1344 case GL_HALF_FLOAT_OES:
1345 break;
1346 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001347 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001348 return false;
1349 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001350 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001351 case GL_BGRA_EXT:
Bryan Bernhart (Intel Americas Inc)2a357412017-09-05 10:42:47 -07001352 if (!context->getExtensions().textureFormatBGRA8888)
1353 {
1354 context->handleError(InvalidEnum());
1355 return false;
1356 }
He Yunchaoced53ae2016-11-29 15:00:51 +08001357 switch (type)
1358 {
1359 case GL_UNSIGNED_BYTE:
1360 break;
1361 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001362 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001363 return false;
1364 }
1365 break;
1366 case GL_SRGB_EXT:
1367 case GL_SRGB_ALPHA_EXT:
1368 if (!context->getExtensions().sRGB)
1369 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001370 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001371 return false;
1372 }
1373 switch (type)
1374 {
1375 case GL_UNSIGNED_BYTE:
1376 break;
1377 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001378 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001379 return false;
1380 }
1381 break;
1382 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are
1383 // handled below
1384 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1385 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1386 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1387 break;
1388 case GL_DEPTH_COMPONENT:
1389 switch (type)
1390 {
1391 case GL_UNSIGNED_SHORT:
1392 case GL_UNSIGNED_INT:
1393 break;
1394 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001395 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001396 return false;
1397 }
1398 break;
1399 case GL_DEPTH_STENCIL_OES:
1400 switch (type)
1401 {
1402 case GL_UNSIGNED_INT_24_8_OES:
1403 break;
1404 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001405 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001406 return false;
1407 }
1408 break;
1409 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001410 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001411 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001412 }
1413
1414 switch (format)
1415 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001416 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1417 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1418 if (context->getExtensions().textureCompressionDXT1)
1419 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001420 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001421 return false;
1422 }
1423 else
1424 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001425 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001426 return false;
1427 }
1428 break;
1429 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1430 if (context->getExtensions().textureCompressionDXT3)
1431 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001432 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001433 return false;
1434 }
1435 else
1436 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001437 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001438 return false;
1439 }
1440 break;
1441 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1442 if (context->getExtensions().textureCompressionDXT5)
1443 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001444 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001445 return false;
1446 }
1447 else
1448 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001449 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001450 return false;
1451 }
1452 break;
1453 case GL_ETC1_RGB8_OES:
1454 if (context->getExtensions().compressedETC1RGB8Texture)
1455 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001456 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001457 return false;
1458 }
1459 else
1460 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001461 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001462 return false;
1463 }
1464 break;
1465 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001466 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1467 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1468 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1469 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001470 if (context->getExtensions().lossyETCDecode)
1471 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001472 context->handleError(InvalidOperation()
1473 << "ETC lossy decode formats can't work with this type.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001474 return false;
1475 }
1476 else
1477 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001478 context->handleError(InvalidEnum()
1479 << "ANGLE_lossy_etc_decode extension is not supported.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001480 return false;
1481 }
1482 break;
1483 case GL_DEPTH_COMPONENT:
1484 case GL_DEPTH_STENCIL_OES:
1485 if (!context->getExtensions().depthTextures)
1486 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001487 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001488 return false;
1489 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001490 if (target != TextureTarget::_2D)
He Yunchaoced53ae2016-11-29 15:00:51 +08001491 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001492 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTargetAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001493 return false;
1494 }
1495 // OES_depth_texture supports loading depth data and multiple levels,
1496 // but ANGLE_depth_texture does not
Brandon Jonesafa75152017-07-21 13:11:29 -07001497 if (pixels != nullptr)
He Yunchaoced53ae2016-11-29 15:00:51 +08001498 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001499 ANGLE_VALIDATION_ERR(context, InvalidOperation(), PixelDataNotNull);
1500 return false;
1501 }
1502 if (level != 0)
1503 {
1504 ANGLE_VALIDATION_ERR(context, InvalidOperation(), LevelNotZero);
He Yunchaoced53ae2016-11-29 15:00:51 +08001505 return false;
1506 }
1507 break;
1508 default:
1509 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001510 }
1511
Geoff Lang6e898aa2017-06-02 11:17:26 -04001512 if (!isSubImage)
1513 {
1514 switch (internalformat)
1515 {
1516 case GL_RGBA32F:
1517 if (!context->getExtensions().colorBufferFloatRGBA)
1518 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001519 context->handleError(InvalidValue()
1520 << "Sized GL_RGBA32F internal format requires "
1521 "GL_CHROMIUM_color_buffer_float_rgba");
Geoff Lang6e898aa2017-06-02 11:17:26 -04001522 return false;
1523 }
1524 if (type != GL_FLOAT)
1525 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001526 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001527 return false;
1528 }
1529 if (format != GL_RGBA)
1530 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001531 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001532 return false;
1533 }
1534 break;
1535
1536 case GL_RGB32F:
1537 if (!context->getExtensions().colorBufferFloatRGB)
1538 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001539 context->handleError(InvalidValue()
1540 << "Sized GL_RGB32F internal format requires "
1541 "GL_CHROMIUM_color_buffer_float_rgb");
Geoff Lang6e898aa2017-06-02 11:17:26 -04001542 return false;
1543 }
1544 if (type != GL_FLOAT)
1545 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001546 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001547 return false;
1548 }
1549 if (format != GL_RGB)
1550 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001551 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001552 return false;
1553 }
1554 break;
1555
1556 default:
1557 break;
1558 }
1559 }
1560
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001561 if (type == GL_FLOAT)
1562 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001563 if (!context->getExtensions().textureFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001564 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001565 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001566 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001567 }
1568 }
1569 else if (type == GL_HALF_FLOAT_OES)
1570 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001571 if (!context->getExtensions().textureHalfFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001572 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001573 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001574 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001575 }
1576 }
1577 }
1578
Geoff Langdbcced82017-06-06 15:55:54 -04001579 GLenum sizeCheckFormat = isSubImage ? format : internalformat;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001580 if (!ValidImageDataSize(context, texType, width, height, 1, sizeCheckFormat, type, pixels,
Geoff Langff5b2d52016-09-07 11:32:23 -04001581 imageSize))
1582 {
1583 return false;
1584 }
1585
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001586 return true;
1587}
1588
He Yunchaoced53ae2016-11-29 15:00:51 +08001589bool ValidateES2TexStorageParameters(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001590 TextureType target,
He Yunchaoced53ae2016-11-29 15:00:51 +08001591 GLsizei levels,
1592 GLenum internalformat,
1593 GLsizei width,
1594 GLsizei height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001595{
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001596 if (target != TextureType::_2D && target != TextureType::CubeMap &&
1597 target != TextureType::Rectangle)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001598 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001599 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001600 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001601 }
1602
1603 if (width < 1 || height < 1 || levels < 1)
1604 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001605 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001606 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001607 }
1608
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001609 if (target == TextureType::CubeMap && width != height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001610 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001611 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001612 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001613 }
1614
1615 if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1)
1616 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001617 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001618 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001619 }
1620
Geoff Langca271392017-04-05 12:30:00 -04001621 const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalformat);
Geoff Lang5d601382014-07-22 15:14:06 -04001622 if (formatInfo.format == GL_NONE || formatInfo.type == GL_NONE)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001623 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001624 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001625 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001626 }
1627
Geoff Langaae65a42014-05-26 12:43:44 -04001628 const gl::Caps &caps = context->getCaps();
1629
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001630 switch (target)
1631 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001632 case TextureType::_2D:
He Yunchaoced53ae2016-11-29 15:00:51 +08001633 if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
1634 static_cast<GLuint>(height) > caps.max2DTextureSize)
1635 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001636 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001637 return false;
1638 }
1639 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001640 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001641 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1642 static_cast<GLuint>(height) > caps.maxRectangleTextureSize || levels != 1)
1643 {
1644 context->handleError(InvalidValue());
1645 return false;
1646 }
1647 if (formatInfo.compressed)
1648 {
1649 context->handleError(InvalidEnum()
1650 << "Rectangle texture cannot have a compressed format.");
1651 return false;
1652 }
1653 break;
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001654 case TextureType::CubeMap:
He Yunchaoced53ae2016-11-29 15:00:51 +08001655 if (static_cast<GLuint>(width) > caps.maxCubeMapTextureSize ||
1656 static_cast<GLuint>(height) > caps.maxCubeMapTextureSize)
1657 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001658 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001659 return false;
1660 }
1661 break;
1662 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001663 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001664 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001665 }
1666
Geoff Langc0b9ef42014-07-02 10:02:37 -04001667 if (levels != 1 && !context->getExtensions().textureNPOT)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001668 {
1669 if (!gl::isPow2(width) || !gl::isPow2(height))
1670 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001671 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001672 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001673 }
1674 }
1675
1676 switch (internalformat)
1677 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001678 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1679 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1680 if (!context->getExtensions().textureCompressionDXT1)
1681 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001682 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001683 return false;
1684 }
1685 break;
1686 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1687 if (!context->getExtensions().textureCompressionDXT3)
1688 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001689 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001690 return false;
1691 }
1692 break;
1693 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1694 if (!context->getExtensions().textureCompressionDXT5)
1695 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001696 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001697 return false;
1698 }
1699 break;
1700 case GL_ETC1_RGB8_OES:
1701 if (!context->getExtensions().compressedETC1RGB8Texture)
1702 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001703 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001704 return false;
1705 }
1706 break;
1707 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001708 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1709 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1710 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1711 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001712 if (!context->getExtensions().lossyETCDecode)
1713 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001714 context->handleError(InvalidEnum()
1715 << "ANGLE_lossy_etc_decode extension is not supported.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001716 return false;
1717 }
1718 break;
1719 case GL_RGBA32F_EXT:
1720 case GL_RGB32F_EXT:
1721 case GL_ALPHA32F_EXT:
1722 case GL_LUMINANCE32F_EXT:
1723 case GL_LUMINANCE_ALPHA32F_EXT:
1724 if (!context->getExtensions().textureFloat)
1725 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001726 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001727 return false;
1728 }
1729 break;
1730 case GL_RGBA16F_EXT:
1731 case GL_RGB16F_EXT:
1732 case GL_ALPHA16F_EXT:
1733 case GL_LUMINANCE16F_EXT:
1734 case GL_LUMINANCE_ALPHA16F_EXT:
1735 if (!context->getExtensions().textureHalfFloat)
1736 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001737 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001738 return false;
1739 }
1740 break;
1741 case GL_R8_EXT:
1742 case GL_RG8_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001743 if (!context->getExtensions().textureRG)
1744 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001745 context->handleError(InvalidEnum());
Geoff Lang677bb6f2017-04-05 12:40:40 -04001746 return false;
1747 }
1748 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001749 case GL_R16F_EXT:
1750 case GL_RG16F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001751 if (!context->getExtensions().textureRG || !context->getExtensions().textureHalfFloat)
1752 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001753 context->handleError(InvalidEnum());
Geoff Lang677bb6f2017-04-05 12:40:40 -04001754 return false;
1755 }
1756 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001757 case GL_R32F_EXT:
1758 case GL_RG32F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001759 if (!context->getExtensions().textureRG || !context->getExtensions().textureFloat)
He Yunchaoced53ae2016-11-29 15:00:51 +08001760 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001761 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001762 return false;
1763 }
1764 break;
1765 case GL_DEPTH_COMPONENT16:
1766 case GL_DEPTH_COMPONENT32_OES:
1767 case GL_DEPTH24_STENCIL8_OES:
1768 if (!context->getExtensions().depthTextures)
1769 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001770 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001771 return false;
1772 }
Corentin Wallezf0e89be2017-11-08 14:00:32 -08001773 if (target != TextureType::_2D)
He Yunchaoced53ae2016-11-29 15:00:51 +08001774 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001775 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001776 return false;
1777 }
1778 // ANGLE_depth_texture only supports 1-level textures
1779 if (levels != 1)
1780 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001781 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001782 return false;
1783 }
1784 break;
1785 default:
1786 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001787 }
1788
Geoff Lang691e58c2014-12-19 17:03:25 -05001789 gl::Texture *texture = context->getTargetTexture(target);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001790 if (!texture || texture->id() == 0)
1791 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001792 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001793 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001794 }
1795
Geoff Lang69cce582015-09-17 13:20:36 -04001796 if (texture->getImmutableFormat())
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001797 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001798 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001799 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001800 }
1801
1802 return true;
1803}
1804
He Yunchaoced53ae2016-11-29 15:00:51 +08001805bool ValidateDiscardFramebufferEXT(Context *context,
1806 GLenum target,
1807 GLsizei numAttachments,
Austin Kinross08332632015-05-05 13:35:47 -07001808 const GLenum *attachments)
1809{
Jamie Madillc29968b2016-01-20 11:17:23 -05001810 if (!context->getExtensions().discardFramebuffer)
1811 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001812 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Jamie Madillc29968b2016-01-20 11:17:23 -05001813 return false;
1814 }
1815
Austin Kinross08332632015-05-05 13:35:47 -07001816 bool defaultFramebuffer = false;
1817
1818 switch (target)
1819 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001820 case GL_FRAMEBUFFER:
1821 defaultFramebuffer =
1822 (context->getGLState().getTargetFramebuffer(GL_FRAMEBUFFER)->id() == 0);
1823 break;
1824 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001825 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
He Yunchaoced53ae2016-11-29 15:00:51 +08001826 return false;
Austin Kinross08332632015-05-05 13:35:47 -07001827 }
1828
He Yunchaoced53ae2016-11-29 15:00:51 +08001829 return ValidateDiscardFramebufferBase(context, target, numAttachments, attachments,
1830 defaultFramebuffer);
Austin Kinross08332632015-05-05 13:35:47 -07001831}
1832
Austin Kinrossbc781f32015-10-26 09:27:38 -07001833bool ValidateBindVertexArrayOES(Context *context, GLuint array)
1834{
1835 if (!context->getExtensions().vertexArrayObject)
1836 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001837 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001838 return false;
1839 }
1840
1841 return ValidateBindVertexArrayBase(context, array);
1842}
1843
Jamie Madilld7576732017-08-26 18:49:50 -04001844bool ValidateDeleteVertexArraysOES(Context *context, GLsizei n, const GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001845{
1846 if (!context->getExtensions().vertexArrayObject)
1847 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001848 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001849 return false;
1850 }
1851
Olli Etuaho41997e72016-03-10 13:38:39 +02001852 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001853}
1854
Jamie Madilld7576732017-08-26 18:49:50 -04001855bool ValidateGenVertexArraysOES(Context *context, GLsizei n, GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001856{
1857 if (!context->getExtensions().vertexArrayObject)
1858 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001859 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001860 return false;
1861 }
1862
Olli Etuaho41997e72016-03-10 13:38:39 +02001863 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001864}
1865
Jamie Madilld7576732017-08-26 18:49:50 -04001866bool ValidateIsVertexArrayOES(Context *context, GLuint array)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001867{
1868 if (!context->getExtensions().vertexArrayObject)
1869 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001870 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001871 return false;
1872 }
1873
1874 return true;
1875}
Geoff Langc5629752015-12-07 16:29:04 -05001876
1877bool ValidateProgramBinaryOES(Context *context,
1878 GLuint program,
1879 GLenum binaryFormat,
1880 const void *binary,
1881 GLint length)
1882{
1883 if (!context->getExtensions().getProgramBinary)
1884 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001885 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05001886 return false;
1887 }
1888
1889 return ValidateProgramBinaryBase(context, program, binaryFormat, binary, length);
1890}
1891
1892bool ValidateGetProgramBinaryOES(Context *context,
1893 GLuint program,
1894 GLsizei bufSize,
1895 GLsizei *length,
1896 GLenum *binaryFormat,
1897 void *binary)
1898{
1899 if (!context->getExtensions().getProgramBinary)
1900 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001901 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05001902 return false;
1903 }
1904
1905 return ValidateGetProgramBinaryBase(context, program, bufSize, length, binaryFormat, binary);
1906}
Geoff Lange102fee2015-12-10 11:23:30 -05001907
Geoff Lang70d0f492015-12-10 17:45:46 -05001908static bool ValidDebugSource(GLenum source, bool mustBeThirdPartyOrApplication)
1909{
1910 switch (source)
1911 {
1912 case GL_DEBUG_SOURCE_API:
1913 case GL_DEBUG_SOURCE_SHADER_COMPILER:
1914 case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
1915 case GL_DEBUG_SOURCE_OTHER:
1916 // Only THIRD_PARTY and APPLICATION sources are allowed to be manually inserted
1917 return !mustBeThirdPartyOrApplication;
1918
1919 case GL_DEBUG_SOURCE_THIRD_PARTY:
1920 case GL_DEBUG_SOURCE_APPLICATION:
1921 return true;
1922
1923 default:
1924 return false;
1925 }
1926}
1927
1928static bool ValidDebugType(GLenum type)
1929{
1930 switch (type)
1931 {
1932 case GL_DEBUG_TYPE_ERROR:
1933 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
1934 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
1935 case GL_DEBUG_TYPE_PERFORMANCE:
1936 case GL_DEBUG_TYPE_PORTABILITY:
1937 case GL_DEBUG_TYPE_OTHER:
1938 case GL_DEBUG_TYPE_MARKER:
1939 case GL_DEBUG_TYPE_PUSH_GROUP:
1940 case GL_DEBUG_TYPE_POP_GROUP:
1941 return true;
1942
1943 default:
1944 return false;
1945 }
1946}
1947
1948static bool ValidDebugSeverity(GLenum severity)
1949{
1950 switch (severity)
1951 {
1952 case GL_DEBUG_SEVERITY_HIGH:
1953 case GL_DEBUG_SEVERITY_MEDIUM:
1954 case GL_DEBUG_SEVERITY_LOW:
1955 case GL_DEBUG_SEVERITY_NOTIFICATION:
1956 return true;
1957
1958 default:
1959 return false;
1960 }
1961}
1962
Geoff Lange102fee2015-12-10 11:23:30 -05001963bool ValidateDebugMessageControlKHR(Context *context,
1964 GLenum source,
1965 GLenum type,
1966 GLenum severity,
1967 GLsizei count,
1968 const GLuint *ids,
1969 GLboolean enabled)
1970{
1971 if (!context->getExtensions().debug)
1972 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001973 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05001974 return false;
1975 }
1976
Geoff Lang70d0f492015-12-10 17:45:46 -05001977 if (!ValidDebugSource(source, false) && source != GL_DONT_CARE)
1978 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001979 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05001980 return false;
1981 }
1982
1983 if (!ValidDebugType(type) && type != GL_DONT_CARE)
1984 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001985 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05001986 return false;
1987 }
1988
1989 if (!ValidDebugSeverity(severity) && severity != GL_DONT_CARE)
1990 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001991 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSeverity);
Geoff Lang70d0f492015-12-10 17:45:46 -05001992 return false;
1993 }
1994
1995 if (count > 0)
1996 {
1997 if (source == GL_DONT_CARE || type == GL_DONT_CARE)
1998 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001999 context->handleError(
2000 InvalidOperation()
2001 << "If count is greater than zero, source and severity cannot be GL_DONT_CARE.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002002 return false;
2003 }
2004
2005 if (severity != GL_DONT_CARE)
2006 {
Jamie Madill437fa652016-05-03 15:13:24 -04002007 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002008 InvalidOperation()
2009 << "If count is greater than zero, severity must be GL_DONT_CARE.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002010 return false;
2011 }
2012 }
2013
Geoff Lange102fee2015-12-10 11:23:30 -05002014 return true;
2015}
2016
2017bool ValidateDebugMessageInsertKHR(Context *context,
2018 GLenum source,
2019 GLenum type,
2020 GLuint id,
2021 GLenum severity,
2022 GLsizei length,
2023 const GLchar *buf)
2024{
2025 if (!context->getExtensions().debug)
2026 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002027 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002028 return false;
2029 }
2030
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002031 if (!context->getGLState().getDebug().isOutputEnabled())
Geoff Lang70d0f492015-12-10 17:45:46 -05002032 {
2033 // If the DEBUG_OUTPUT state is disabled calls to DebugMessageInsert are discarded and do
2034 // not generate an error.
2035 return false;
2036 }
2037
2038 if (!ValidDebugSeverity(severity))
2039 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002040 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002041 return false;
2042 }
2043
2044 if (!ValidDebugType(type))
2045 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002046 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05002047 return false;
2048 }
2049
2050 if (!ValidDebugSource(source, true))
2051 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002052 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002053 return false;
2054 }
2055
2056 size_t messageLength = (length < 0) ? strlen(buf) : length;
2057 if (messageLength > context->getExtensions().maxDebugMessageLength)
2058 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002059 context->handleError(InvalidValue()
2060 << "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002061 return false;
2062 }
2063
Geoff Lange102fee2015-12-10 11:23:30 -05002064 return true;
2065}
2066
2067bool ValidateDebugMessageCallbackKHR(Context *context,
2068 GLDEBUGPROCKHR callback,
2069 const void *userParam)
2070{
2071 if (!context->getExtensions().debug)
2072 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002073 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002074 return false;
2075 }
2076
Geoff Lange102fee2015-12-10 11:23:30 -05002077 return true;
2078}
2079
2080bool ValidateGetDebugMessageLogKHR(Context *context,
2081 GLuint count,
2082 GLsizei bufSize,
2083 GLenum *sources,
2084 GLenum *types,
2085 GLuint *ids,
2086 GLenum *severities,
2087 GLsizei *lengths,
2088 GLchar *messageLog)
2089{
2090 if (!context->getExtensions().debug)
2091 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002092 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002093 return false;
2094 }
2095
Geoff Lang70d0f492015-12-10 17:45:46 -05002096 if (bufSize < 0 && messageLog != nullptr)
2097 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002098 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002099 return false;
2100 }
2101
Geoff Lange102fee2015-12-10 11:23:30 -05002102 return true;
2103}
2104
2105bool ValidatePushDebugGroupKHR(Context *context,
2106 GLenum source,
2107 GLuint id,
2108 GLsizei length,
2109 const GLchar *message)
2110{
2111 if (!context->getExtensions().debug)
2112 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002113 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002114 return false;
2115 }
2116
Geoff Lang70d0f492015-12-10 17:45:46 -05002117 if (!ValidDebugSource(source, true))
2118 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002119 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002120 return false;
2121 }
2122
2123 size_t messageLength = (length < 0) ? strlen(message) : length;
2124 if (messageLength > context->getExtensions().maxDebugMessageLength)
2125 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002126 context->handleError(InvalidValue()
2127 << "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002128 return false;
2129 }
2130
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002131 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002132 if (currentStackSize >= context->getExtensions().maxDebugGroupStackDepth)
2133 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002134 context
2135 ->handleError(StackOverflow()
2136 << "Cannot push more than GL_MAX_DEBUG_GROUP_STACK_DEPTH debug groups.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002137 return false;
2138 }
2139
Geoff Lange102fee2015-12-10 11:23:30 -05002140 return true;
2141}
2142
2143bool ValidatePopDebugGroupKHR(Context *context)
2144{
2145 if (!context->getExtensions().debug)
2146 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002147 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002148 return false;
2149 }
2150
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002151 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002152 if (currentStackSize <= 1)
2153 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002154 context->handleError(StackUnderflow() << "Cannot pop the default debug group.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002155 return false;
2156 }
2157
2158 return true;
2159}
2160
2161static bool ValidateObjectIdentifierAndName(Context *context, GLenum identifier, GLuint name)
2162{
2163 switch (identifier)
2164 {
2165 case GL_BUFFER:
2166 if (context->getBuffer(name) == nullptr)
2167 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002168 context->handleError(InvalidValue() << "name is not a valid buffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002169 return false;
2170 }
2171 return true;
2172
2173 case GL_SHADER:
2174 if (context->getShader(name) == nullptr)
2175 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002176 context->handleError(InvalidValue() << "name is not a valid shader.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002177 return false;
2178 }
2179 return true;
2180
2181 case GL_PROGRAM:
2182 if (context->getProgram(name) == nullptr)
2183 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002184 context->handleError(InvalidValue() << "name is not a valid program.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002185 return false;
2186 }
2187 return true;
2188
2189 case GL_VERTEX_ARRAY:
2190 if (context->getVertexArray(name) == nullptr)
2191 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002192 context->handleError(InvalidValue() << "name is not a valid vertex array.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002193 return false;
2194 }
2195 return true;
2196
2197 case GL_QUERY:
2198 if (context->getQuery(name) == nullptr)
2199 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002200 context->handleError(InvalidValue() << "name is not a valid query.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002201 return false;
2202 }
2203 return true;
2204
2205 case GL_TRANSFORM_FEEDBACK:
2206 if (context->getTransformFeedback(name) == nullptr)
2207 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002208 context->handleError(InvalidValue() << "name is not a valid transform feedback.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002209 return false;
2210 }
2211 return true;
2212
2213 case GL_SAMPLER:
2214 if (context->getSampler(name) == nullptr)
2215 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002216 context->handleError(InvalidValue() << "name is not a valid sampler.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002217 return false;
2218 }
2219 return true;
2220
2221 case GL_TEXTURE:
2222 if (context->getTexture(name) == nullptr)
2223 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002224 context->handleError(InvalidValue() << "name is not a valid texture.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002225 return false;
2226 }
2227 return true;
2228
2229 case GL_RENDERBUFFER:
2230 if (context->getRenderbuffer(name) == nullptr)
2231 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002232 context->handleError(InvalidValue() << "name is not a valid renderbuffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002233 return false;
2234 }
2235 return true;
2236
2237 case GL_FRAMEBUFFER:
2238 if (context->getFramebuffer(name) == nullptr)
2239 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002240 context->handleError(InvalidValue() << "name is not a valid framebuffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002241 return false;
2242 }
2243 return true;
2244
2245 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002246 context->handleError(InvalidEnum() << "Invalid identifier.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002247 return false;
2248 }
Geoff Lange102fee2015-12-10 11:23:30 -05002249}
2250
Martin Radev9d901792016-07-15 15:58:58 +03002251static bool ValidateLabelLength(Context *context, GLsizei length, const GLchar *label)
2252{
2253 size_t labelLength = 0;
2254
2255 if (length < 0)
2256 {
2257 if (label != nullptr)
2258 {
2259 labelLength = strlen(label);
2260 }
2261 }
2262 else
2263 {
2264 labelLength = static_cast<size_t>(length);
2265 }
2266
2267 if (labelLength > context->getExtensions().maxLabelLength)
2268 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002269 context->handleError(InvalidValue() << "Label length is larger than GL_MAX_LABEL_LENGTH.");
Martin Radev9d901792016-07-15 15:58:58 +03002270 return false;
2271 }
2272
2273 return true;
2274}
2275
Geoff Lange102fee2015-12-10 11:23:30 -05002276bool ValidateObjectLabelKHR(Context *context,
2277 GLenum identifier,
2278 GLuint name,
2279 GLsizei length,
2280 const GLchar *label)
2281{
2282 if (!context->getExtensions().debug)
2283 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002284 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002285 return false;
2286 }
2287
Geoff Lang70d0f492015-12-10 17:45:46 -05002288 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2289 {
2290 return false;
2291 }
2292
Martin Radev9d901792016-07-15 15:58:58 +03002293 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002294 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002295 return false;
2296 }
2297
Geoff Lange102fee2015-12-10 11:23:30 -05002298 return true;
2299}
2300
2301bool ValidateGetObjectLabelKHR(Context *context,
2302 GLenum identifier,
2303 GLuint name,
2304 GLsizei bufSize,
2305 GLsizei *length,
2306 GLchar *label)
2307{
2308 if (!context->getExtensions().debug)
2309 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002310 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002311 return false;
2312 }
2313
Geoff Lang70d0f492015-12-10 17:45:46 -05002314 if (bufSize < 0)
2315 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002316 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002317 return false;
2318 }
2319
2320 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2321 {
2322 return false;
2323 }
2324
Martin Radev9d901792016-07-15 15:58:58 +03002325 return true;
Geoff Lang70d0f492015-12-10 17:45:46 -05002326}
2327
2328static bool ValidateObjectPtrName(Context *context, const void *ptr)
2329{
Jamie Madill70b5bb02017-08-28 13:32:37 -04002330 if (context->getSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr))) == nullptr)
Geoff Lang70d0f492015-12-10 17:45:46 -05002331 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002332 context->handleError(InvalidValue() << "name is not a valid sync.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002333 return false;
2334 }
2335
Geoff Lange102fee2015-12-10 11:23:30 -05002336 return true;
2337}
2338
2339bool ValidateObjectPtrLabelKHR(Context *context,
2340 const void *ptr,
2341 GLsizei length,
2342 const GLchar *label)
2343{
2344 if (!context->getExtensions().debug)
2345 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002346 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002347 return false;
2348 }
2349
Geoff Lang70d0f492015-12-10 17:45:46 -05002350 if (!ValidateObjectPtrName(context, ptr))
2351 {
2352 return false;
2353 }
2354
Martin Radev9d901792016-07-15 15:58:58 +03002355 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002356 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002357 return false;
2358 }
2359
Geoff Lange102fee2015-12-10 11:23:30 -05002360 return true;
2361}
2362
2363bool ValidateGetObjectPtrLabelKHR(Context *context,
2364 const void *ptr,
2365 GLsizei bufSize,
2366 GLsizei *length,
2367 GLchar *label)
2368{
2369 if (!context->getExtensions().debug)
2370 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002371 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002372 return false;
2373 }
2374
Geoff Lang70d0f492015-12-10 17:45:46 -05002375 if (bufSize < 0)
2376 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002377 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002378 return false;
2379 }
2380
2381 if (!ValidateObjectPtrName(context, ptr))
2382 {
2383 return false;
2384 }
2385
Martin Radev9d901792016-07-15 15:58:58 +03002386 return true;
Geoff Lange102fee2015-12-10 11:23:30 -05002387}
2388
2389bool ValidateGetPointervKHR(Context *context, GLenum pname, void **params)
2390{
2391 if (!context->getExtensions().debug)
2392 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002393 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002394 return false;
2395 }
2396
Geoff Lang70d0f492015-12-10 17:45:46 -05002397 // TODO: represent this in Context::getQueryParameterInfo.
2398 switch (pname)
2399 {
2400 case GL_DEBUG_CALLBACK_FUNCTION:
2401 case GL_DEBUG_CALLBACK_USER_PARAM:
2402 break;
2403
2404 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07002405 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Geoff Lang70d0f492015-12-10 17:45:46 -05002406 return false;
2407 }
2408
Geoff Lange102fee2015-12-10 11:23:30 -05002409 return true;
2410}
Jamie Madillc29968b2016-01-20 11:17:23 -05002411
2412bool ValidateBlitFramebufferANGLE(Context *context,
2413 GLint srcX0,
2414 GLint srcY0,
2415 GLint srcX1,
2416 GLint srcY1,
2417 GLint dstX0,
2418 GLint dstY0,
2419 GLint dstX1,
2420 GLint dstY1,
2421 GLbitfield mask,
2422 GLenum filter)
2423{
2424 if (!context->getExtensions().framebufferBlit)
2425 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002426 context->handleError(InvalidOperation() << "Blit extension not available.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002427 return false;
2428 }
2429
2430 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
2431 {
2432 // TODO(jmadill): Determine if this should be available on other implementations.
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002433 context->handleError(InvalidOperation() << "Scaling and flipping in "
2434 "BlitFramebufferANGLE not supported by this "
2435 "implementation.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002436 return false;
2437 }
2438
2439 if (filter == GL_LINEAR)
2440 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002441 context->handleError(InvalidEnum() << "Linear blit not supported in this extension");
Jamie Madillc29968b2016-01-20 11:17:23 -05002442 return false;
2443 }
2444
Jamie Madill51f40ec2016-06-15 14:06:00 -04002445 Framebuffer *readFramebuffer = context->getGLState().getReadFramebuffer();
2446 Framebuffer *drawFramebuffer = context->getGLState().getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002447
2448 if (mask & GL_COLOR_BUFFER_BIT)
2449 {
2450 const FramebufferAttachment *readColorAttachment = readFramebuffer->getReadColorbuffer();
2451 const FramebufferAttachment *drawColorAttachment = drawFramebuffer->getFirstColorbuffer();
2452
2453 if (readColorAttachment && drawColorAttachment)
2454 {
2455 if (!(readColorAttachment->type() == GL_TEXTURE &&
Corentin Wallez99d492c2018-02-27 15:17:10 -05002456 readColorAttachment->getTextureImageIndex().type == TextureType::_2D) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002457 readColorAttachment->type() != GL_RENDERBUFFER &&
2458 readColorAttachment->type() != GL_FRAMEBUFFER_DEFAULT)
2459 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002460 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002461 return false;
2462 }
2463
Geoff Langa15472a2015-08-11 11:48:03 -04002464 for (size_t drawbufferIdx = 0;
2465 drawbufferIdx < drawFramebuffer->getDrawbufferStateCount(); ++drawbufferIdx)
Jamie Madillc29968b2016-01-20 11:17:23 -05002466 {
Geoff Langa15472a2015-08-11 11:48:03 -04002467 const FramebufferAttachment *attachment =
2468 drawFramebuffer->getDrawBuffer(drawbufferIdx);
2469 if (attachment)
Jamie Madillc29968b2016-01-20 11:17:23 -05002470 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002471 if (!(attachment->type() == GL_TEXTURE &&
Corentin Wallez99d492c2018-02-27 15:17:10 -05002472 attachment->getTextureImageIndex().type == TextureType::_2D) &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002473 attachment->type() != GL_RENDERBUFFER &&
2474 attachment->type() != GL_FRAMEBUFFER_DEFAULT)
2475 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002476 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002477 return false;
2478 }
2479
2480 // Return an error if the destination formats do not match
Kenneth Russell69382852017-07-21 16:38:44 -04002481 if (!Format::EquivalentForBlit(attachment->getFormat(),
2482 readColorAttachment->getFormat()))
Jamie Madillc29968b2016-01-20 11:17:23 -05002483 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002484 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002485 return false;
2486 }
2487 }
2488 }
2489
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002490 if (readFramebuffer->getSamples(context) != 0 &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002491 IsPartialBlit(context, readColorAttachment, drawColorAttachment, srcX0, srcY0,
2492 srcX1, srcY1, dstX0, dstY0, dstX1, dstY1))
2493 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002494 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002495 return false;
2496 }
2497 }
2498 }
2499
2500 GLenum masks[] = {GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT};
2501 GLenum attachments[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
2502 for (size_t i = 0; i < 2; i++)
2503 {
2504 if (mask & masks[i])
2505 {
2506 const FramebufferAttachment *readBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002507 readFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002508 const FramebufferAttachment *drawBuffer =
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08002509 drawFramebuffer->getAttachment(context, attachments[i]);
Jamie Madillc29968b2016-01-20 11:17:23 -05002510
2511 if (readBuffer && drawBuffer)
2512 {
2513 if (IsPartialBlit(context, readBuffer, drawBuffer, srcX0, srcY0, srcX1, srcY1,
2514 dstX0, dstY0, dstX1, dstY1))
2515 {
2516 // only whole-buffer copies are permitted
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002517 context->handleError(InvalidOperation() << "Only whole-buffer depth and "
2518 "stencil blits are supported by "
2519 "this extension.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002520 return false;
2521 }
2522
2523 if (readBuffer->getSamples() != 0 || drawBuffer->getSamples() != 0)
2524 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002525 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002526 return false;
2527 }
2528 }
2529 }
2530 }
2531
2532 return ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0,
2533 dstX1, dstY1, mask, filter);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04002534}
Jamie Madillc29968b2016-01-20 11:17:23 -05002535
2536bool ValidateClear(ValidationContext *context, GLbitfield mask)
2537{
Jamie Madillacf2f3a2017-11-21 19:22:44 -05002538 Framebuffer *fbo = context->getGLState().getDrawFramebuffer();
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002539 if (fbo->checkStatus(context) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002540 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002541 context->handleError(InvalidFramebufferOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002542 return false;
2543 }
2544
2545 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
2546 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002547 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidClearMask);
Jamie Madillc29968b2016-01-20 11:17:23 -05002548 return false;
2549 }
2550
Geoff Lang76e65652017-03-27 14:58:02 -04002551 if (context->getExtensions().webglCompatibility && (mask & GL_COLOR_BUFFER_BIT) != 0)
2552 {
2553 constexpr GLenum validComponentTypes[] = {GL_FLOAT, GL_UNSIGNED_NORMALIZED,
2554 GL_SIGNED_NORMALIZED};
2555
Corentin Wallez59c41592017-07-11 13:19:54 -04002556 for (GLuint drawBufferIdx = 0; drawBufferIdx < fbo->getDrawbufferStateCount();
Geoff Lang76e65652017-03-27 14:58:02 -04002557 drawBufferIdx++)
2558 {
2559 if (!ValidateWebGLFramebufferAttachmentClearType(
2560 context, drawBufferIdx, validComponentTypes, ArraySize(validComponentTypes)))
2561 {
2562 return false;
2563 }
2564 }
2565 }
2566
Jamie Madillc29968b2016-01-20 11:17:23 -05002567 return true;
2568}
2569
2570bool ValidateDrawBuffersEXT(ValidationContext *context, GLsizei n, const GLenum *bufs)
2571{
2572 if (!context->getExtensions().drawBuffers)
2573 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002574 context->handleError(InvalidOperation() << "Extension not supported.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002575 return false;
2576 }
2577
2578 return ValidateDrawBuffersBase(context, n, bufs);
2579}
2580
Jamie Madill73a84962016-02-12 09:27:23 -05002581bool ValidateTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002582 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002583 GLint level,
2584 GLint internalformat,
2585 GLsizei width,
2586 GLsizei height,
2587 GLint border,
2588 GLenum format,
2589 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002590 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002591{
Martin Radev1be913c2016-07-11 17:59:16 +03002592 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002593 {
2594 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
Geoff Langff5b2d52016-09-07 11:32:23 -04002595 0, 0, width, height, border, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002596 }
2597
Martin Radev1be913c2016-07-11 17:59:16 +03002598 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002599 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002600 0, 0, width, height, 1, border, format, type, -1,
2601 pixels);
2602}
2603
2604bool ValidateTexImage2DRobust(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002605 TextureTarget target,
Geoff Langff5b2d52016-09-07 11:32:23 -04002606 GLint level,
2607 GLint internalformat,
2608 GLsizei width,
2609 GLsizei height,
2610 GLint border,
2611 GLenum format,
2612 GLenum type,
2613 GLsizei bufSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002614 const void *pixels)
Geoff Langff5b2d52016-09-07 11:32:23 -04002615{
2616 if (!ValidateRobustEntryPoint(context, bufSize))
2617 {
2618 return false;
2619 }
2620
2621 if (context->getClientMajorVersion() < 3)
2622 {
2623 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
2624 0, 0, width, height, border, format, type, bufSize,
2625 pixels);
2626 }
2627
2628 ASSERT(context->getClientMajorVersion() >= 3);
2629 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
2630 0, 0, width, height, 1, border, format, type, bufSize,
2631 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002632}
2633
2634bool ValidateTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002635 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002636 GLint level,
2637 GLint xoffset,
2638 GLint yoffset,
2639 GLsizei width,
2640 GLsizei height,
2641 GLenum format,
2642 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002643 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002644{
2645
Martin Radev1be913c2016-07-11 17:59:16 +03002646 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002647 {
2648 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002649 yoffset, width, height, 0, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002650 }
2651
Martin Radev1be913c2016-07-11 17:59:16 +03002652 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002653 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002654 yoffset, 0, width, height, 1, 0, format, type, -1,
2655 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002656}
2657
Geoff Langc52f6f12016-10-14 10:18:00 -04002658bool ValidateTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002659 TextureTarget target,
Geoff Langc52f6f12016-10-14 10:18:00 -04002660 GLint level,
2661 GLint xoffset,
2662 GLint yoffset,
2663 GLsizei width,
2664 GLsizei height,
2665 GLenum format,
2666 GLenum type,
2667 GLsizei bufSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002668 const void *pixels)
Geoff Langc52f6f12016-10-14 10:18:00 -04002669{
2670 if (!ValidateRobustEntryPoint(context, bufSize))
2671 {
2672 return false;
2673 }
2674
2675 if (context->getClientMajorVersion() < 3)
2676 {
2677 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
2678 yoffset, width, height, 0, format, type, bufSize,
2679 pixels);
2680 }
2681
2682 ASSERT(context->getClientMajorVersion() >= 3);
2683 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
2684 yoffset, 0, width, height, 1, 0, format, type, bufSize,
2685 pixels);
2686}
2687
Jamie Madill73a84962016-02-12 09:27:23 -05002688bool ValidateCompressedTexImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002689 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002690 GLint level,
2691 GLenum internalformat,
2692 GLsizei width,
2693 GLsizei height,
2694 GLint border,
2695 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002696 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002697{
Martin Radev1be913c2016-07-11 17:59:16 +03002698 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002699 {
2700 if (!ValidateES2TexImageParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002701 0, width, height, border, GL_NONE, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002702 {
2703 return false;
2704 }
2705 }
2706 else
2707 {
Martin Radev1be913c2016-07-11 17:59:16 +03002708 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002709 if (!ValidateES3TexImage2DParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002710 0, 0, width, height, 1, border, GL_NONE, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002711 data))
2712 {
2713 return false;
2714 }
2715 }
2716
Geoff Langca271392017-04-05 12:30:00 -04002717 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalformat);
Jeff Gilbert48590352017-11-07 16:03:38 -08002718 auto blockSizeOrErr = formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1));
Jamie Madille2e406c2016-06-02 13:04:10 -04002719 if (blockSizeOrErr.isError())
2720 {
2721 context->handleError(blockSizeOrErr.getError());
2722 return false;
2723 }
2724
2725 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSizeOrErr.getResult())
Jamie Madill73a84962016-02-12 09:27:23 -05002726 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002727 ANGLE_VALIDATION_ERR(context, InvalidValue(), CompressedTextureDimensionsMustMatchData);
Jamie Madill73a84962016-02-12 09:27:23 -05002728 return false;
2729 }
2730
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002731 if (target == TextureTarget::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002732 {
2733 context->handleError(InvalidEnum() << "Rectangle texture cannot have a compressed format.");
2734 return false;
2735 }
2736
Jamie Madill73a84962016-02-12 09:27:23 -05002737 return true;
2738}
2739
Corentin Wallezb2931602017-04-11 15:58:57 -04002740bool ValidateCompressedTexImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002741 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04002742 GLint level,
2743 GLenum internalformat,
2744 GLsizei width,
2745 GLsizei height,
2746 GLint border,
2747 GLsizei imageSize,
2748 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002749 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002750{
2751 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2752 {
2753 return false;
2754 }
2755
2756 return ValidateCompressedTexImage2D(context, target, level, internalformat, width, height,
2757 border, imageSize, data);
2758}
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002759
Corentin Wallezb2931602017-04-11 15:58:57 -04002760bool ValidateCompressedTexSubImage2DRobustANGLE(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002761 TextureTarget target,
Corentin Wallezb2931602017-04-11 15:58:57 -04002762 GLint level,
2763 GLint xoffset,
2764 GLint yoffset,
2765 GLsizei width,
2766 GLsizei height,
2767 GLenum format,
2768 GLsizei imageSize,
2769 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002770 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002771{
2772 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2773 {
2774 return false;
2775 }
2776
2777 return ValidateCompressedTexSubImage2D(context, target, level, xoffset, yoffset, width, height,
2778 format, imageSize, data);
2779}
2780
Jamie Madill73a84962016-02-12 09:27:23 -05002781bool ValidateCompressedTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002782 TextureTarget target,
Jamie Madill73a84962016-02-12 09:27:23 -05002783 GLint level,
2784 GLint xoffset,
2785 GLint yoffset,
2786 GLsizei width,
2787 GLsizei height,
2788 GLenum format,
2789 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002790 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002791{
Martin Radev1be913c2016-07-11 17:59:16 +03002792 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002793 {
2794 if (!ValidateES2TexImageParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002795 yoffset, width, height, 0, format, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002796 {
2797 return false;
2798 }
2799 }
2800 else
2801 {
Martin Radev1be913c2016-07-11 17:59:16 +03002802 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002803 if (!ValidateES3TexImage2DParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002804 yoffset, 0, width, height, 1, 0, format, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002805 data))
2806 {
2807 return false;
2808 }
2809 }
2810
Geoff Langca271392017-04-05 12:30:00 -04002811 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(format);
Jeff Gilbert48590352017-11-07 16:03:38 -08002812 auto blockSizeOrErr = formatInfo.computeCompressedImageSize(gl::Extents(width, height, 1));
Jamie Madille2e406c2016-06-02 13:04:10 -04002813 if (blockSizeOrErr.isError())
2814 {
2815 context->handleError(blockSizeOrErr.getError());
2816 return false;
2817 }
2818
2819 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSizeOrErr.getResult())
Jamie Madill73a84962016-02-12 09:27:23 -05002820 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002821 context->handleError(InvalidValue());
Jamie Madill73a84962016-02-12 09:27:23 -05002822 return false;
2823 }
2824
2825 return true;
2826}
2827
Corentin Wallez336129f2017-10-17 15:55:40 -04002828bool ValidateGetBufferPointervOES(Context *context,
2829 BufferBinding target,
2830 GLenum pname,
2831 void **params)
Olli Etuaho4f667482016-03-30 15:56:35 +03002832{
Geoff Lang496c02d2016-10-20 11:38:11 -07002833 return ValidateGetBufferPointervBase(context, target, pname, nullptr, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03002834}
2835
Corentin Wallez336129f2017-10-17 15:55:40 -04002836bool ValidateMapBufferOES(Context *context, BufferBinding target, GLenum access)
Olli Etuaho4f667482016-03-30 15:56:35 +03002837{
2838 if (!context->getExtensions().mapBuffer)
2839 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002840 context->handleError(InvalidOperation() << "Map buffer extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002841 return false;
2842 }
2843
Corentin Walleze4477002017-12-01 14:39:58 -05002844 if (!context->isValidBufferBinding(target))
Olli Etuaho4f667482016-03-30 15:56:35 +03002845 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002846 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03002847 return false;
2848 }
2849
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002850 Buffer *buffer = context->getGLState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002851
2852 if (buffer == nullptr)
2853 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002854 context->handleError(InvalidOperation() << "Attempted to map buffer object zero.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002855 return false;
2856 }
2857
2858 if (access != GL_WRITE_ONLY_OES)
2859 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002860 context->handleError(InvalidEnum() << "Non-write buffer mapping not supported.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002861 return false;
2862 }
2863
2864 if (buffer->isMapped())
2865 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002866 context->handleError(InvalidOperation() << "Buffer is already mapped.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002867 return false;
2868 }
2869
Geoff Lang79f71042017-08-14 16:43:43 -04002870 return ValidateMapBufferBase(context, target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002871}
2872
Corentin Wallez336129f2017-10-17 15:55:40 -04002873bool ValidateUnmapBufferOES(Context *context, BufferBinding target)
Olli Etuaho4f667482016-03-30 15:56:35 +03002874{
2875 if (!context->getExtensions().mapBuffer)
2876 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002877 context->handleError(InvalidOperation() << "Map buffer extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002878 return false;
2879 }
2880
2881 return ValidateUnmapBufferBase(context, target);
2882}
2883
2884bool ValidateMapBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04002885 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03002886 GLintptr offset,
2887 GLsizeiptr length,
2888 GLbitfield access)
2889{
2890 if (!context->getExtensions().mapBufferRange)
2891 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002892 context->handleError(InvalidOperation() << "Map buffer range extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002893 return false;
2894 }
2895
2896 return ValidateMapBufferRangeBase(context, target, offset, length, access);
2897}
2898
Corentin Wallez336129f2017-10-17 15:55:40 -04002899bool ValidateMapBufferBase(Context *context, BufferBinding target)
Geoff Lang79f71042017-08-14 16:43:43 -04002900{
2901 Buffer *buffer = context->getGLState().getTargetBuffer(target);
2902 ASSERT(buffer != nullptr);
2903
2904 // Check if this buffer is currently being used as a transform feedback output buffer
2905 TransformFeedback *transformFeedback = context->getGLState().getCurrentTransformFeedback();
2906 if (transformFeedback != nullptr && transformFeedback->isActive())
2907 {
2908 for (size_t i = 0; i < transformFeedback->getIndexedBufferCount(); i++)
2909 {
2910 const auto &transformFeedbackBuffer = transformFeedback->getIndexedBuffer(i);
2911 if (transformFeedbackBuffer.get() == buffer)
2912 {
2913 context->handleError(InvalidOperation()
2914 << "Buffer is currently bound for transform feedback.");
2915 return false;
2916 }
2917 }
2918 }
2919
2920 return true;
2921}
2922
Olli Etuaho4f667482016-03-30 15:56:35 +03002923bool ValidateFlushMappedBufferRangeEXT(Context *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04002924 BufferBinding target,
Olli Etuaho4f667482016-03-30 15:56:35 +03002925 GLintptr offset,
2926 GLsizeiptr length)
2927{
2928 if (!context->getExtensions().mapBufferRange)
2929 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002930 context->handleError(InvalidOperation() << "Map buffer range extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002931 return false;
2932 }
2933
2934 return ValidateFlushMappedBufferRangeBase(context, target, offset, length);
2935}
2936
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002937bool ValidateBindTexture(Context *context, TextureType target, GLuint texture)
Ian Ewell54f87462016-03-10 13:47:21 -05002938{
2939 Texture *textureObject = context->getTexture(texture);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002940 if (textureObject && textureObject->getType() != target && texture != 0)
Ian Ewell54f87462016-03-10 13:47:21 -05002941 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002942 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TypeMismatch);
Ian Ewell54f87462016-03-10 13:47:21 -05002943 return false;
2944 }
2945
Geoff Langf41a7152016-09-19 15:11:17 -04002946 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
2947 !context->isTextureGenerated(texture))
2948 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002949 context->handleError(InvalidOperation() << "Texture was not generated");
Geoff Langf41a7152016-09-19 15:11:17 -04002950 return false;
2951 }
2952
Ian Ewell54f87462016-03-10 13:47:21 -05002953 switch (target)
2954 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002955 case TextureType::_2D:
2956 case TextureType::CubeMap:
Ian Ewell54f87462016-03-10 13:47:21 -05002957 break;
2958
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002959 case TextureType::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002960 if (!context->getExtensions().textureRectangle)
2961 {
2962 context->handleError(InvalidEnum()
2963 << "Context does not support GL_ANGLE_texture_rectangle");
2964 return false;
2965 }
2966 break;
2967
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002968 case TextureType::_3D:
2969 case TextureType::_2DArray:
Martin Radev1be913c2016-07-11 17:59:16 +03002970 if (context->getClientMajorVersion() < 3)
Ian Ewell54f87462016-03-10 13:47:21 -05002971 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002972 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES3Required);
Ian Ewell54f87462016-03-10 13:47:21 -05002973 return false;
2974 }
2975 break;
Geoff Lang3b573612016-10-31 14:08:10 -04002976
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002977 case TextureType::_2DMultisample:
Geoff Lang3b573612016-10-31 14:08:10 -04002978 if (context->getClientVersion() < Version(3, 1))
2979 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002980 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
Geoff Lang3b573612016-10-31 14:08:10 -04002981 return false;
2982 }
Geoff Lang3b573612016-10-31 14:08:10 -04002983 break;
2984
Corentin Wallezf0e89be2017-11-08 14:00:32 -08002985 case TextureType::External:
Geoff Langb66a9092016-05-16 15:59:14 -04002986 if (!context->getExtensions().eglImageExternal &&
2987 !context->getExtensions().eglStreamConsumerExternal)
Ian Ewell54f87462016-03-10 13:47:21 -05002988 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002989 context->handleError(InvalidEnum() << "External texture extension not enabled");
Ian Ewell54f87462016-03-10 13:47:21 -05002990 return false;
2991 }
2992 break;
2993 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07002994 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Ian Ewell54f87462016-03-10 13:47:21 -05002995 return false;
2996 }
2997
2998 return true;
2999}
3000
Geoff Langd8605522016-04-13 10:19:12 -04003001bool ValidateBindUniformLocationCHROMIUM(Context *context,
3002 GLuint program,
3003 GLint location,
3004 const GLchar *name)
3005{
3006 if (!context->getExtensions().bindUniformLocation)
3007 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003008 context->handleError(InvalidOperation()
3009 << "GL_CHROMIUM_bind_uniform_location is not available.");
Geoff Langd8605522016-04-13 10:19:12 -04003010 return false;
3011 }
3012
3013 Program *programObject = GetValidProgram(context, program);
3014 if (!programObject)
3015 {
3016 return false;
3017 }
3018
3019 if (location < 0)
3020 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003021 context->handleError(InvalidValue() << "Location cannot be less than 0.");
Geoff Langd8605522016-04-13 10:19:12 -04003022 return false;
3023 }
3024
3025 const Caps &caps = context->getCaps();
3026 if (static_cast<size_t>(location) >=
3027 (caps.maxVertexUniformVectors + caps.maxFragmentUniformVectors) * 4)
3028 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003029 context->handleError(InvalidValue() << "Location must be less than "
3030 "(MAX_VERTEX_UNIFORM_VECTORS + "
3031 "MAX_FRAGMENT_UNIFORM_VECTORS) * 4");
Geoff Langd8605522016-04-13 10:19:12 -04003032 return false;
3033 }
3034
Geoff Langfc32e8b2017-05-31 14:16:59 -04003035 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
3036 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04003037 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04003038 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003039 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04003040 return false;
3041 }
3042
Geoff Langd8605522016-04-13 10:19:12 -04003043 if (strncmp(name, "gl_", 3) == 0)
3044 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003045 ANGLE_VALIDATION_ERR(context, InvalidValue(), NameBeginsWithGL);
Geoff Langd8605522016-04-13 10:19:12 -04003046 return false;
3047 }
3048
3049 return true;
3050}
3051
Jamie Madille2e406c2016-06-02 13:04:10 -04003052bool ValidateCoverageModulationCHROMIUM(Context *context, GLenum components)
Sami Väisänena797e062016-05-12 15:23:40 +03003053{
3054 if (!context->getExtensions().framebufferMixedSamples)
3055 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003056 context->handleError(InvalidOperation()
3057 << "GL_CHROMIUM_framebuffer_mixed_samples is not available.");
Sami Väisänena797e062016-05-12 15:23:40 +03003058 return false;
3059 }
3060 switch (components)
3061 {
3062 case GL_RGB:
3063 case GL_RGBA:
3064 case GL_ALPHA:
3065 case GL_NONE:
3066 break;
3067 default:
3068 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003069 InvalidEnum()
3070 << "GLenum components is not one of GL_RGB, GL_RGBA, GL_ALPHA or GL_NONE.");
Sami Väisänena797e062016-05-12 15:23:40 +03003071 return false;
3072 }
3073
3074 return true;
3075}
3076
Sami Väisänene45e53b2016-05-25 10:36:04 +03003077// CHROMIUM_path_rendering
3078
Jamie Madill007530e2017-12-28 14:27:04 -05003079bool ValidateMatrixLoadfCHROMIUM(Context *context, GLenum matrixMode, const GLfloat *matrix)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003080{
Jamie Madill007530e2017-12-28 14:27:04 -05003081 if (!ValidateMatrixMode(context, matrixMode))
Sami Väisänene45e53b2016-05-25 10:36:04 +03003082 {
Sami Väisänene45e53b2016-05-25 10:36:04 +03003083 return false;
3084 }
Jamie Madill007530e2017-12-28 14:27:04 -05003085
Sami Väisänene45e53b2016-05-25 10:36:04 +03003086 if (matrix == nullptr)
3087 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003088 context->handleError(InvalidOperation() << "Invalid matrix.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003089 return false;
3090 }
Jamie Madill007530e2017-12-28 14:27:04 -05003091
Sami Väisänene45e53b2016-05-25 10:36:04 +03003092 return true;
3093}
3094
Jamie Madill007530e2017-12-28 14:27:04 -05003095bool ValidateMatrixLoadIdentityCHROMIUM(Context *context, GLenum matrixMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003096{
Jamie Madill007530e2017-12-28 14:27:04 -05003097 return ValidateMatrixMode(context, matrixMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003098}
3099
Jamie Madill007530e2017-12-28 14:27:04 -05003100bool ValidateGenPathsCHROMIUM(Context *context, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003101{
3102 if (!context->getExtensions().pathRendering)
3103 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003104 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003105 return false;
3106 }
3107
3108 // range = 0 is undefined in NV_path_rendering.
3109 // we add stricter semantic check here and require a non zero positive range.
3110 if (range <= 0)
3111 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003112 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003113 return false;
3114 }
3115
3116 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range))
3117 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003118 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003119 return false;
3120 }
3121
3122 return true;
3123}
3124
Jamie Madill007530e2017-12-28 14:27:04 -05003125bool ValidateDeletePathsCHROMIUM(Context *context, GLuint path, GLsizei range)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003126{
3127 if (!context->getExtensions().pathRendering)
3128 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003129 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003130 return false;
3131 }
3132
3133 // range = 0 is undefined in NV_path_rendering.
3134 // we add stricter semantic check here and require a non zero positive range.
3135 if (range <= 0)
3136 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003137 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003138 return false;
3139 }
3140
3141 angle::CheckedNumeric<std::uint32_t> checkedRange(path);
3142 checkedRange += range;
3143
3144 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range) || !checkedRange.IsValid())
3145 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003146 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003147 return false;
3148 }
3149 return true;
3150}
3151
Jamie Madill007530e2017-12-28 14:27:04 -05003152bool ValidatePathCommandsCHROMIUM(Context *context,
3153 GLuint path,
3154 GLsizei numCommands,
3155 const GLubyte *commands,
3156 GLsizei numCoords,
3157 GLenum coordType,
3158 const void *coords)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003159{
3160 if (!context->getExtensions().pathRendering)
3161 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003162 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003163 return false;
3164 }
3165 if (!context->hasPath(path))
3166 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003167 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003168 return false;
3169 }
3170
3171 if (numCommands < 0)
3172 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003173 context->handleError(InvalidValue() << "Invalid number of commands.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003174 return false;
3175 }
3176 else if (numCommands > 0)
3177 {
3178 if (!commands)
3179 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003180 context->handleError(InvalidValue() << "No commands array given.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003181 return false;
3182 }
3183 }
3184
3185 if (numCoords < 0)
3186 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003187 context->handleError(InvalidValue() << "Invalid number of coordinates.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003188 return false;
3189 }
3190 else if (numCoords > 0)
3191 {
3192 if (!coords)
3193 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003194 context->handleError(InvalidValue() << "No coordinate array given.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003195 return false;
3196 }
3197 }
3198
3199 std::uint32_t coordTypeSize = 0;
3200 switch (coordType)
3201 {
3202 case GL_BYTE:
3203 coordTypeSize = sizeof(GLbyte);
3204 break;
3205
3206 case GL_UNSIGNED_BYTE:
3207 coordTypeSize = sizeof(GLubyte);
3208 break;
3209
3210 case GL_SHORT:
3211 coordTypeSize = sizeof(GLshort);
3212 break;
3213
3214 case GL_UNSIGNED_SHORT:
3215 coordTypeSize = sizeof(GLushort);
3216 break;
3217
3218 case GL_FLOAT:
3219 coordTypeSize = sizeof(GLfloat);
3220 break;
3221
3222 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003223 context->handleError(InvalidEnum() << "Invalid coordinate type.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003224 return false;
3225 }
3226
3227 angle::CheckedNumeric<std::uint32_t> checkedSize(numCommands);
3228 checkedSize += (coordTypeSize * numCoords);
3229 if (!checkedSize.IsValid())
3230 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003231 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003232 return false;
3233 }
3234
3235 // early return skips command data validation when it doesn't exist.
3236 if (!commands)
3237 return true;
3238
3239 GLsizei expectedNumCoords = 0;
3240 for (GLsizei i = 0; i < numCommands; ++i)
3241 {
3242 switch (commands[i])
3243 {
3244 case GL_CLOSE_PATH_CHROMIUM: // no coordinates.
3245 break;
3246 case GL_MOVE_TO_CHROMIUM:
3247 case GL_LINE_TO_CHROMIUM:
3248 expectedNumCoords += 2;
3249 break;
3250 case GL_QUADRATIC_CURVE_TO_CHROMIUM:
3251 expectedNumCoords += 4;
3252 break;
3253 case GL_CUBIC_CURVE_TO_CHROMIUM:
3254 expectedNumCoords += 6;
3255 break;
3256 case GL_CONIC_CURVE_TO_CHROMIUM:
3257 expectedNumCoords += 5;
3258 break;
3259 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003260 context->handleError(InvalidEnum() << "Invalid command.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003261 return false;
3262 }
3263 }
3264 if (expectedNumCoords != numCoords)
3265 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003266 context->handleError(InvalidValue() << "Invalid number of coordinates.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003267 return false;
3268 }
3269
3270 return true;
3271}
3272
Jamie Madill007530e2017-12-28 14:27:04 -05003273bool ValidatePathParameterfCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003274{
3275 if (!context->getExtensions().pathRendering)
3276 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003277 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003278 return false;
3279 }
3280 if (!context->hasPath(path))
3281 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003282 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003283 return false;
3284 }
3285
3286 switch (pname)
3287 {
3288 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3289 if (value < 0.0f)
3290 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003291 context->handleError(InvalidValue() << "Invalid stroke width.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003292 return false;
3293 }
3294 break;
3295 case GL_PATH_END_CAPS_CHROMIUM:
3296 switch (static_cast<GLenum>(value))
3297 {
3298 case GL_FLAT_CHROMIUM:
3299 case GL_SQUARE_CHROMIUM:
3300 case GL_ROUND_CHROMIUM:
3301 break;
3302 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003303 context->handleError(InvalidEnum() << "Invalid end caps.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003304 return false;
3305 }
3306 break;
3307 case GL_PATH_JOIN_STYLE_CHROMIUM:
3308 switch (static_cast<GLenum>(value))
3309 {
3310 case GL_MITER_REVERT_CHROMIUM:
3311 case GL_BEVEL_CHROMIUM:
3312 case GL_ROUND_CHROMIUM:
3313 break;
3314 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003315 context->handleError(InvalidEnum() << "Invalid join style.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003316 return false;
3317 }
Nico Weber41b072b2018-02-09 10:01:32 -05003318 break;
Sami Väisänene45e53b2016-05-25 10:36:04 +03003319 case GL_PATH_MITER_LIMIT_CHROMIUM:
3320 if (value < 0.0f)
3321 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003322 context->handleError(InvalidValue() << "Invalid miter limit.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003323 return false;
3324 }
3325 break;
3326
3327 case GL_PATH_STROKE_BOUND_CHROMIUM:
3328 // no errors, only clamping.
3329 break;
3330
3331 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003332 context->handleError(InvalidEnum() << "Invalid path parameter.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003333 return false;
3334 }
3335 return true;
3336}
3337
Jamie Madill007530e2017-12-28 14:27:04 -05003338bool ValidatePathParameteriCHROMIUM(Context *context, GLuint path, GLenum pname, GLint value)
3339{
3340 // TODO(jmadill): Use proper clamping cast.
3341 return ValidatePathParameterfCHROMIUM(context, path, pname, static_cast<GLfloat>(value));
3342}
3343
3344bool ValidateGetPathParameterfvCHROMIUM(Context *context, GLuint path, GLenum pname, GLfloat *value)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003345{
3346 if (!context->getExtensions().pathRendering)
3347 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003348 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003349 return false;
3350 }
3351
3352 if (!context->hasPath(path))
3353 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003354 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003355 return false;
3356 }
3357 if (!value)
3358 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003359 context->handleError(InvalidValue() << "No value array.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003360 return false;
3361 }
3362
3363 switch (pname)
3364 {
3365 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3366 case GL_PATH_END_CAPS_CHROMIUM:
3367 case GL_PATH_JOIN_STYLE_CHROMIUM:
3368 case GL_PATH_MITER_LIMIT_CHROMIUM:
3369 case GL_PATH_STROKE_BOUND_CHROMIUM:
3370 break;
3371
3372 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003373 context->handleError(InvalidEnum() << "Invalid path parameter.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003374 return false;
3375 }
3376
3377 return true;
3378}
3379
Jamie Madill007530e2017-12-28 14:27:04 -05003380bool ValidateGetPathParameterivCHROMIUM(Context *context, GLuint path, GLenum pname, GLint *value)
3381{
3382 return ValidateGetPathParameterfvCHROMIUM(context, path, pname,
3383 reinterpret_cast<GLfloat *>(value));
3384}
3385
3386bool ValidatePathStencilFuncCHROMIUM(Context *context, GLenum func, GLint ref, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003387{
3388 if (!context->getExtensions().pathRendering)
3389 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003390 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003391 return false;
3392 }
3393
3394 switch (func)
3395 {
3396 case GL_NEVER:
3397 case GL_ALWAYS:
3398 case GL_LESS:
3399 case GL_LEQUAL:
3400 case GL_EQUAL:
3401 case GL_GEQUAL:
3402 case GL_GREATER:
3403 case GL_NOTEQUAL:
3404 break;
3405 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07003406 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003407 return false;
3408 }
3409
3410 return true;
3411}
3412
3413// Note that the spec specifies that for the path drawing commands
3414// if the path object is not an existing path object the command
3415// does nothing and no error is generated.
3416// However if the path object exists but has not been specified any
3417// commands then an error is generated.
3418
Jamie Madill007530e2017-12-28 14:27:04 -05003419bool ValidateStencilFillPathCHROMIUM(Context *context, GLuint path, GLenum fillMode, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003420{
3421 if (!context->getExtensions().pathRendering)
3422 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003423 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003424 return false;
3425 }
3426 if (context->hasPath(path) && !context->hasPathData(path))
3427 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003428 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003429 return false;
3430 }
3431
3432 switch (fillMode)
3433 {
3434 case GL_COUNT_UP_CHROMIUM:
3435 case GL_COUNT_DOWN_CHROMIUM:
3436 break;
3437 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003438 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003439 return false;
3440 }
3441
3442 if (!isPow2(mask + 1))
3443 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003444 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003445 return false;
3446 }
3447
3448 return true;
3449}
3450
Jamie Madill007530e2017-12-28 14:27:04 -05003451bool ValidateStencilStrokePathCHROMIUM(Context *context, GLuint path, GLint reference, GLuint mask)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003452{
3453 if (!context->getExtensions().pathRendering)
3454 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003455 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003456 return false;
3457 }
3458 if (context->hasPath(path) && !context->hasPathData(path))
3459 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003460 context->handleError(InvalidOperation() << "No such path or path has no data.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003461 return false;
3462 }
3463
3464 return true;
3465}
3466
Jamie Madill007530e2017-12-28 14:27:04 -05003467bool ValidateCoverPathCHROMIUM(Context *context, GLuint path, GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003468{
3469 if (!context->getExtensions().pathRendering)
3470 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003471 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003472 return false;
3473 }
3474 if (context->hasPath(path) && !context->hasPathData(path))
3475 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003476 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003477 return false;
3478 }
3479
3480 switch (coverMode)
3481 {
3482 case GL_CONVEX_HULL_CHROMIUM:
3483 case GL_BOUNDING_BOX_CHROMIUM:
3484 break;
3485 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003486 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003487 return false;
3488 }
3489 return true;
3490}
3491
Jamie Madill007530e2017-12-28 14:27:04 -05003492bool ValidateStencilThenCoverFillPathCHROMIUM(Context *context,
3493 GLuint path,
3494 GLenum fillMode,
3495 GLuint mask,
3496 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003497{
Jamie Madill007530e2017-12-28 14:27:04 -05003498 return ValidateStencilFillPathCHROMIUM(context, path, fillMode, mask) &&
3499 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003500}
3501
Jamie Madill007530e2017-12-28 14:27:04 -05003502bool ValidateStencilThenCoverStrokePathCHROMIUM(Context *context,
3503 GLuint path,
3504 GLint reference,
3505 GLuint mask,
3506 GLenum coverMode)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003507{
Jamie Madill007530e2017-12-28 14:27:04 -05003508 return ValidateStencilStrokePathCHROMIUM(context, path, reference, mask) &&
3509 ValidateCoverPathCHROMIUM(context, path, coverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003510}
3511
Jamie Madill007530e2017-12-28 14:27:04 -05003512bool ValidateIsPathCHROMIUM(Context *context)
Sami Väisänene45e53b2016-05-25 10:36:04 +03003513{
3514 if (!context->getExtensions().pathRendering)
3515 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003516 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003517 return false;
3518 }
3519 return true;
3520}
3521
Jamie Madill007530e2017-12-28 14:27:04 -05003522bool ValidateCoverFillPathInstancedCHROMIUM(Context *context,
3523 GLsizei numPaths,
3524 GLenum pathNameType,
3525 const void *paths,
3526 GLuint pathBase,
3527 GLenum coverMode,
3528 GLenum transformType,
3529 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003530{
3531 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3532 transformType, transformValues))
3533 return false;
3534
3535 switch (coverMode)
3536 {
3537 case GL_CONVEX_HULL_CHROMIUM:
3538 case GL_BOUNDING_BOX_CHROMIUM:
3539 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3540 break;
3541 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003542 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003543 return false;
3544 }
3545
3546 return true;
3547}
3548
Jamie Madill007530e2017-12-28 14:27:04 -05003549bool ValidateCoverStrokePathInstancedCHROMIUM(Context *context,
3550 GLsizei numPaths,
3551 GLenum pathNameType,
3552 const void *paths,
3553 GLuint pathBase,
3554 GLenum coverMode,
3555 GLenum transformType,
3556 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003557{
3558 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3559 transformType, transformValues))
3560 return false;
3561
3562 switch (coverMode)
3563 {
3564 case GL_CONVEX_HULL_CHROMIUM:
3565 case GL_BOUNDING_BOX_CHROMIUM:
3566 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3567 break;
3568 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003569 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003570 return false;
3571 }
3572
3573 return true;
3574}
3575
Jamie Madill007530e2017-12-28 14:27:04 -05003576bool ValidateStencilFillPathInstancedCHROMIUM(Context *context,
3577 GLsizei numPaths,
3578 GLenum pathNameType,
3579 const void *paths,
3580 GLuint pathBase,
3581 GLenum fillMode,
3582 GLuint mask,
3583 GLenum transformType,
3584 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003585{
3586
3587 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3588 transformType, transformValues))
3589 return false;
3590
3591 switch (fillMode)
3592 {
3593 case GL_COUNT_UP_CHROMIUM:
3594 case GL_COUNT_DOWN_CHROMIUM:
3595 break;
3596 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003597 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003598 return false;
3599 }
3600 if (!isPow2(mask + 1))
3601 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003602 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003603 return false;
3604 }
3605 return true;
3606}
3607
Jamie Madill007530e2017-12-28 14:27:04 -05003608bool ValidateStencilStrokePathInstancedCHROMIUM(Context *context,
3609 GLsizei numPaths,
3610 GLenum pathNameType,
3611 const void *paths,
3612 GLuint pathBase,
3613 GLint reference,
3614 GLuint mask,
3615 GLenum transformType,
3616 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003617{
3618 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3619 transformType, transformValues))
3620 return false;
3621
3622 // no more validation here.
3623
3624 return true;
3625}
3626
Jamie Madill007530e2017-12-28 14:27:04 -05003627bool ValidateStencilThenCoverFillPathInstancedCHROMIUM(Context *context,
3628 GLsizei numPaths,
3629 GLenum pathNameType,
3630 const void *paths,
3631 GLuint pathBase,
3632 GLenum fillMode,
3633 GLuint mask,
3634 GLenum coverMode,
3635 GLenum transformType,
3636 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003637{
3638 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3639 transformType, transformValues))
3640 return false;
3641
3642 switch (coverMode)
3643 {
3644 case GL_CONVEX_HULL_CHROMIUM:
3645 case GL_BOUNDING_BOX_CHROMIUM:
3646 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3647 break;
3648 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003649 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003650 return false;
3651 }
3652
3653 switch (fillMode)
3654 {
3655 case GL_COUNT_UP_CHROMIUM:
3656 case GL_COUNT_DOWN_CHROMIUM:
3657 break;
3658 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003659 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003660 return false;
3661 }
3662 if (!isPow2(mask + 1))
3663 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003664 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
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 ValidateStencilThenCoverStrokePathInstancedCHROMIUM(Context *context,
3672 GLsizei numPaths,
3673 GLenum pathNameType,
3674 const void *paths,
3675 GLuint pathBase,
3676 GLint reference,
3677 GLuint mask,
3678 GLenum coverMode,
3679 GLenum transformType,
3680 const GLfloat *transformValues)
Sami Väisänend59ca052016-06-21 16:10:00 +03003681{
3682 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3683 transformType, transformValues))
3684 return false;
3685
3686 switch (coverMode)
3687 {
3688 case GL_CONVEX_HULL_CHROMIUM:
3689 case GL_BOUNDING_BOX_CHROMIUM:
3690 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3691 break;
3692 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003693 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003694 return false;
3695 }
3696
3697 return true;
3698}
3699
Jamie Madill007530e2017-12-28 14:27:04 -05003700bool ValidateBindFragmentInputLocationCHROMIUM(Context *context,
3701 GLuint program,
3702 GLint location,
3703 const GLchar *name)
Sami Väisänen46eaa942016-06-29 10:26:37 +03003704{
3705 if (!context->getExtensions().pathRendering)
3706 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003707 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003708 return false;
3709 }
3710
3711 const GLint MaxLocation = context->getCaps().maxVaryingVectors * 4;
3712 if (location >= MaxLocation)
3713 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003714 context->handleError(InvalidValue() << "Location exceeds max varying.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003715 return false;
3716 }
3717
3718 const auto *programObject = context->getProgram(program);
3719 if (!programObject)
3720 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003721 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003722 return false;
3723 }
3724
3725 if (!name)
3726 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003727 context->handleError(InvalidValue() << "No name given.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003728 return false;
3729 }
3730
3731 if (angle::BeginsWith(name, "gl_"))
3732 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003733 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003734 return false;
3735 }
3736
3737 return true;
3738}
3739
Jamie Madill007530e2017-12-28 14:27:04 -05003740bool ValidateProgramPathFragmentInputGenCHROMIUM(Context *context,
3741 GLuint program,
3742 GLint location,
3743 GLenum genMode,
3744 GLint components,
3745 const GLfloat *coeffs)
Sami Väisänen46eaa942016-06-29 10:26:37 +03003746{
3747 if (!context->getExtensions().pathRendering)
3748 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003749 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003750 return false;
3751 }
3752
3753 const auto *programObject = context->getProgram(program);
3754 if (!programObject || programObject->isFlaggedForDeletion())
3755 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003756 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramDoesNotExist);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003757 return false;
3758 }
3759
3760 if (!programObject->isLinked())
3761 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003762 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003763 return false;
3764 }
3765
3766 switch (genMode)
3767 {
3768 case GL_NONE:
3769 if (components != 0)
3770 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003771 context->handleError(InvalidValue() << "Invalid components.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003772 return false;
3773 }
3774 break;
3775
3776 case GL_OBJECT_LINEAR_CHROMIUM:
3777 case GL_EYE_LINEAR_CHROMIUM:
3778 case GL_CONSTANT_CHROMIUM:
3779 if (components < 1 || components > 4)
3780 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003781 context->handleError(InvalidValue() << "Invalid components.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003782 return false;
3783 }
3784 if (!coeffs)
3785 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003786 context->handleError(InvalidValue() << "No coefficients array given.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003787 return false;
3788 }
3789 break;
3790
3791 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003792 context->handleError(InvalidEnum() << "Invalid gen mode.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003793 return false;
3794 }
3795
3796 // If the location is -1 then the command is silently ignored
3797 // and no further validation is needed.
3798 if (location == -1)
3799 return true;
3800
Jamie Madillbd044ed2017-06-05 12:59:21 -04003801 const auto &binding = programObject->getFragmentInputBindingInfo(context, location);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003802
3803 if (!binding.valid)
3804 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003805 context->handleError(InvalidOperation() << "No such binding.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003806 return false;
3807 }
3808
3809 if (binding.type != GL_NONE)
3810 {
3811 GLint expectedComponents = 0;
3812 switch (binding.type)
3813 {
3814 case GL_FLOAT:
3815 expectedComponents = 1;
3816 break;
3817 case GL_FLOAT_VEC2:
3818 expectedComponents = 2;
3819 break;
3820 case GL_FLOAT_VEC3:
3821 expectedComponents = 3;
3822 break;
3823 case GL_FLOAT_VEC4:
3824 expectedComponents = 4;
3825 break;
3826 default:
He Yunchaoced53ae2016-11-29 15:00:51 +08003827 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003828 InvalidOperation()
3829 << "Fragment input type is not a floating point scalar or vector.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003830 return false;
3831 }
3832 if (expectedComponents != components && genMode != GL_NONE)
3833 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003834 context->handleError(InvalidOperation() << "Unexpected number of components");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003835 return false;
3836 }
3837 }
3838 return true;
3839}
3840
Geoff Lang97073d12016-04-20 10:42:34 -07003841bool ValidateCopyTextureCHROMIUM(Context *context,
3842 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003843 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003844 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003845 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003846 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003847 GLint internalFormat,
3848 GLenum destType,
3849 GLboolean unpackFlipY,
3850 GLboolean unpackPremultiplyAlpha,
3851 GLboolean unpackUnmultiplyAlpha)
3852{
3853 if (!context->getExtensions().copyTexture)
3854 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003855 context->handleError(InvalidOperation()
3856 << "GL_CHROMIUM_copy_texture extension not available.");
Geoff Lang97073d12016-04-20 10:42:34 -07003857 return false;
3858 }
3859
Geoff Lang4f0e0032017-05-01 16:04:35 -04003860 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07003861 if (source == nullptr)
3862 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003863 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003864 return false;
3865 }
3866
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003867 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07003868 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003869 context->handleError(InvalidValue() << "Source texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07003870 return false;
3871 }
3872
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003873 TextureType sourceType = source->getType();
3874 ASSERT(sourceType != TextureType::CubeMap);
3875 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003876
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003877 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07003878 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003879 context->handleError(InvalidValue() << "Source texture level is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07003880 return false;
3881 }
3882
Geoff Lang4f0e0032017-05-01 16:04:35 -04003883 GLsizei sourceWidth = static_cast<GLsizei>(source->getWidth(sourceTarget, sourceLevel));
3884 GLsizei sourceHeight = static_cast<GLsizei>(source->getHeight(sourceTarget, sourceLevel));
3885 if (sourceWidth == 0 || sourceHeight == 0)
3886 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003887 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003888 return false;
3889 }
3890
3891 const InternalFormat &sourceFormat = *source->getFormat(sourceTarget, sourceLevel).info;
3892 if (!IsValidCopyTextureSourceInternalFormatEnum(sourceFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07003893 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003894 context->handleError(InvalidOperation() << "Source texture internal format is invalid.");
Geoff Lang97073d12016-04-20 10:42:34 -07003895 return false;
3896 }
3897
Geoff Lang63458a32017-10-30 15:16:53 -04003898 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
3899 {
3900 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
3901 return false;
3902 }
3903
Geoff Lang4f0e0032017-05-01 16:04:35 -04003904 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07003905 if (dest == nullptr)
3906 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003907 context->handleError(InvalidValue()
3908 << "Destination texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003909 return false;
3910 }
3911
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003912 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07003913 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003914 context->handleError(InvalidValue() << "Destination texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07003915 return false;
3916 }
3917
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003918 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, sourceWidth,
Yuly Novikove3688d22018-03-07 22:14:54 +00003919 sourceHeight))
Geoff Lang4f0e0032017-05-01 16:04:35 -04003920 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003921 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003922 return false;
3923 }
3924
Geoff Lang97073d12016-04-20 10:42:34 -07003925 if (!IsValidCopyTextureDestinationFormatType(context, internalFormat, destType))
3926 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003927 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07003928 return false;
3929 }
3930
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003931 if (dest->getType() == TextureType::CubeMap && sourceWidth != sourceHeight)
Geoff Lang4f0e0032017-05-01 16:04:35 -04003932 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003933 context->handleError(
3934 InvalidValue() << "Destination width and height must be equal for cube map textures.");
Geoff Lang4f0e0032017-05-01 16:04:35 -04003935 return false;
3936 }
3937
Geoff Lang97073d12016-04-20 10:42:34 -07003938 if (dest->getImmutableFormat())
3939 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003940 context->handleError(InvalidOperation() << "Destination texture is immutable.");
Geoff Lang97073d12016-04-20 10:42:34 -07003941 return false;
3942 }
3943
3944 return true;
3945}
3946
3947bool ValidateCopySubTextureCHROMIUM(Context *context,
3948 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003949 GLint sourceLevel,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003950 TextureTarget destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003951 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003952 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003953 GLint xoffset,
3954 GLint yoffset,
3955 GLint x,
3956 GLint y,
3957 GLsizei width,
3958 GLsizei height,
3959 GLboolean unpackFlipY,
3960 GLboolean unpackPremultiplyAlpha,
3961 GLboolean unpackUnmultiplyAlpha)
3962{
3963 if (!context->getExtensions().copyTexture)
3964 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003965 context->handleError(InvalidOperation()
3966 << "GL_CHROMIUM_copy_texture extension not available.");
Geoff Lang97073d12016-04-20 10:42:34 -07003967 return false;
3968 }
3969
Geoff Lang4f0e0032017-05-01 16:04:35 -04003970 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07003971 if (source == nullptr)
3972 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003973 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003974 return false;
3975 }
3976
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003977 if (!IsValidCopyTextureSourceTarget(context, source->getType()))
Geoff Lang97073d12016-04-20 10:42:34 -07003978 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003979 context->handleError(InvalidValue() << "Source texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07003980 return false;
3981 }
3982
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003983 TextureType sourceType = source->getType();
3984 ASSERT(sourceType != TextureType::CubeMap);
3985 TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003986
Corentin Wallezf0e89be2017-11-08 14:00:32 -08003987 if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
Geoff Lang4f0e0032017-05-01 16:04:35 -04003988 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003989 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003990 return false;
3991 }
3992
3993 if (source->getWidth(sourceTarget, sourceLevel) == 0 ||
3994 source->getHeight(sourceTarget, sourceLevel) == 0)
Geoff Lang97073d12016-04-20 10:42:34 -07003995 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003996 context->handleError(InvalidValue()
3997 << "The source level of the source texture must be defined.");
Geoff Lang97073d12016-04-20 10:42:34 -07003998 return false;
3999 }
4000
4001 if (x < 0 || y < 0)
4002 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004003 context->handleError(InvalidValue() << "x and y cannot be negative.");
Geoff Lang97073d12016-04-20 10:42:34 -07004004 return false;
4005 }
4006
4007 if (width < 0 || height < 0)
4008 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004009 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Geoff Lang97073d12016-04-20 10:42:34 -07004010 return false;
4011 }
4012
Geoff Lang4f0e0032017-05-01 16:04:35 -04004013 if (static_cast<size_t>(x + width) > source->getWidth(sourceTarget, sourceLevel) ||
4014 static_cast<size_t>(y + height) > source->getHeight(sourceTarget, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004015 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004016 ANGLE_VALIDATION_ERR(context, InvalidValue(), SourceTextureTooSmall);
Geoff Lang97073d12016-04-20 10:42:34 -07004017 return false;
4018 }
4019
Geoff Lang4f0e0032017-05-01 16:04:35 -04004020 const Format &sourceFormat = source->getFormat(sourceTarget, sourceLevel);
4021 if (!IsValidCopySubTextureSourceInternalFormat(sourceFormat.info->internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004022 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004023 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07004024 return false;
4025 }
4026
Geoff Lang63458a32017-10-30 15:16:53 -04004027 if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
4028 {
4029 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
4030 return false;
4031 }
4032
Geoff Lang4f0e0032017-05-01 16:04:35 -04004033 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07004034 if (dest == nullptr)
4035 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004036 context->handleError(InvalidValue()
4037 << "Destination texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07004038 return false;
4039 }
4040
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004041 if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07004042 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004043 context->handleError(InvalidValue() << "Destination texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07004044 return false;
4045 }
4046
Yuly Novikove3688d22018-03-07 22:14:54 +00004047 if (!IsValidCopyTextureDestinationLevel(context, dest->getType(), destLevel, width, height))
Geoff Lang97073d12016-04-20 10:42:34 -07004048 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004049 context->handleError(InvalidValue() << "Destination texture level is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004050 return false;
4051 }
4052
Geoff Lang4f0e0032017-05-01 16:04:35 -04004053 if (dest->getWidth(destTarget, destLevel) == 0 || dest->getHeight(destTarget, destLevel) == 0)
4054 {
Geoff Langbb1b19b2017-06-16 16:59:00 -04004055 context
4056 ->handleError(InvalidOperation()
4057 << "The destination level of the destination texture must be defined.");
Geoff Lang4f0e0032017-05-01 16:04:35 -04004058 return false;
4059 }
4060
4061 const InternalFormat &destFormat = *dest->getFormat(destTarget, destLevel).info;
4062 if (!IsValidCopySubTextureDestionationInternalFormat(destFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004063 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004064 context->handleError(InvalidOperation()
4065 << "Destination internal format and type combination is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004066 return false;
4067 }
4068
4069 if (xoffset < 0 || yoffset < 0)
4070 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004071 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Geoff Lang97073d12016-04-20 10:42:34 -07004072 return false;
4073 }
4074
Geoff Lang4f0e0032017-05-01 16:04:35 -04004075 if (static_cast<size_t>(xoffset + width) > dest->getWidth(destTarget, destLevel) ||
4076 static_cast<size_t>(yoffset + height) > dest->getHeight(destTarget, destLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004077 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004078 context->handleError(InvalidValue() << "Destination texture not large enough to copy to.");
Geoff Lang97073d12016-04-20 10:42:34 -07004079 return false;
4080 }
4081
4082 return true;
4083}
4084
Geoff Lang47110bf2016-04-20 11:13:22 -07004085bool ValidateCompressedCopyTextureCHROMIUM(Context *context, GLuint sourceId, GLuint destId)
4086{
4087 if (!context->getExtensions().copyCompressedTexture)
4088 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004089 context->handleError(InvalidOperation()
4090 << "GL_CHROMIUM_copy_compressed_texture extension not available.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004091 return false;
4092 }
4093
4094 const gl::Texture *source = context->getTexture(sourceId);
4095 if (source == nullptr)
4096 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004097 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004098 return false;
4099 }
4100
Corentin Wallez99d492c2018-02-27 15:17:10 -05004101 if (source->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004102 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004103 context->handleError(InvalidValue() << "Source texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004104 return false;
4105 }
4106
Corentin Wallez99d492c2018-02-27 15:17:10 -05004107 if (source->getWidth(TextureTarget::_2D, 0) == 0 ||
4108 source->getHeight(TextureTarget::_2D, 0) == 0)
Geoff Lang47110bf2016-04-20 11:13:22 -07004109 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004110 context->handleError(InvalidValue() << "Source texture must level 0 defined.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004111 return false;
4112 }
4113
Corentin Wallez99d492c2018-02-27 15:17:10 -05004114 const gl::Format &sourceFormat = source->getFormat(TextureTarget::_2D, 0);
Geoff Lang47110bf2016-04-20 11:13:22 -07004115 if (!sourceFormat.info->compressed)
4116 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004117 context->handleError(InvalidOperation()
4118 << "Source texture must have a compressed internal format.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004119 return false;
4120 }
4121
4122 const gl::Texture *dest = context->getTexture(destId);
4123 if (dest == nullptr)
4124 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004125 context->handleError(InvalidValue()
4126 << "Destination texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004127 return false;
4128 }
4129
Corentin Wallez99d492c2018-02-27 15:17:10 -05004130 if (dest->getType() != TextureType::_2D)
Geoff Lang47110bf2016-04-20 11:13:22 -07004131 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004132 context->handleError(InvalidValue()
4133 << "Destination texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004134 return false;
4135 }
4136
4137 if (dest->getImmutableFormat())
4138 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004139 context->handleError(InvalidOperation() << "Destination cannot be immutable.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004140 return false;
4141 }
4142
4143 return true;
4144}
4145
Martin Radev4c4c8e72016-08-04 12:25:34 +03004146bool ValidateCreateShader(Context *context, GLenum type)
4147{
4148 switch (type)
4149 {
4150 case GL_VERTEX_SHADER:
4151 case GL_FRAGMENT_SHADER:
4152 break;
Geoff Langeb66a6e2016-10-31 13:06:12 -04004153
Martin Radev4c4c8e72016-08-04 12:25:34 +03004154 case GL_COMPUTE_SHADER:
Geoff Langeb66a6e2016-10-31 13:06:12 -04004155 if (context->getClientVersion() < Version(3, 1))
Martin Radev4c4c8e72016-08-04 12:25:34 +03004156 {
Yunchao Hef0fd87d2017-09-12 04:55:05 +08004157 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
Geoff Langeb66a6e2016-10-31 13:06:12 -04004158 return false;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004159 }
Geoff Langeb66a6e2016-10-31 13:06:12 -04004160 break;
4161
Jiawei Shao89be29a2017-11-06 14:36:45 +08004162 case GL_GEOMETRY_SHADER_EXT:
4163 if (!context->getExtensions().geometryShader)
4164 {
4165 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
4166 return false;
4167 }
4168 break;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004169 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004170 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Martin Radev4c4c8e72016-08-04 12:25:34 +03004171 return false;
4172 }
Jamie Madill29639852016-09-02 15:00:09 -04004173
4174 return true;
4175}
4176
4177bool ValidateBufferData(ValidationContext *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004178 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004179 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004180 const void *data,
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004181 BufferUsage usage)
Jamie Madill29639852016-09-02 15:00:09 -04004182{
4183 if (size < 0)
4184 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004185 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madill29639852016-09-02 15:00:09 -04004186 return false;
4187 }
4188
4189 switch (usage)
4190 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004191 case BufferUsage::StreamDraw:
4192 case BufferUsage::StaticDraw:
4193 case BufferUsage::DynamicDraw:
Jamie Madill29639852016-09-02 15:00:09 -04004194 break;
4195
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004196 case BufferUsage::StreamRead:
4197 case BufferUsage::StaticRead:
4198 case BufferUsage::DynamicRead:
4199 case BufferUsage::StreamCopy:
4200 case BufferUsage::StaticCopy:
4201 case BufferUsage::DynamicCopy:
Jamie Madill29639852016-09-02 15:00:09 -04004202 if (context->getClientMajorVersion() < 3)
4203 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004204 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004205 return false;
4206 }
4207 break;
4208
4209 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004210 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004211 return false;
4212 }
4213
Corentin Walleze4477002017-12-01 14:39:58 -05004214 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004215 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004216 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004217 return false;
4218 }
4219
4220 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4221
4222 if (!buffer)
4223 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004224 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004225 return false;
4226 }
4227
4228 return true;
4229}
4230
4231bool ValidateBufferSubData(ValidationContext *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004232 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004233 GLintptr offset,
4234 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004235 const void *data)
Jamie Madill29639852016-09-02 15:00:09 -04004236{
Brandon Jones6cad5662017-06-14 13:25:13 -07004237 if (size < 0)
Jamie Madill29639852016-09-02 15:00:09 -04004238 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004239 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
4240 return false;
4241 }
4242
4243 if (offset < 0)
4244 {
4245 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Jamie Madill29639852016-09-02 15:00:09 -04004246 return false;
4247 }
4248
Corentin Walleze4477002017-12-01 14:39:58 -05004249 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004250 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004251 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004252 return false;
4253 }
4254
4255 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4256
4257 if (!buffer)
4258 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004259 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004260 return false;
4261 }
4262
4263 if (buffer->isMapped())
4264 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004265 context->handleError(InvalidOperation());
Jamie Madill29639852016-09-02 15:00:09 -04004266 return false;
4267 }
4268
4269 // Check for possible overflow of size + offset
4270 angle::CheckedNumeric<size_t> checkedSize(size);
4271 checkedSize += offset;
4272 if (!checkedSize.IsValid())
4273 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004274 context->handleError(OutOfMemory());
Jamie Madill29639852016-09-02 15:00:09 -04004275 return false;
4276 }
4277
4278 if (size + offset > buffer->getSize())
4279 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004280 ANGLE_VALIDATION_ERR(context, InvalidValue(), InsufficientBufferSize);
Jamie Madill29639852016-09-02 15:00:09 -04004281 return false;
4282 }
4283
Martin Radev4c4c8e72016-08-04 12:25:34 +03004284 return true;
4285}
4286
Geoff Lang111a99e2017-10-17 10:58:41 -04004287bool ValidateRequestExtensionANGLE(Context *context, const GLchar *name)
Geoff Langc287ea62016-09-16 14:46:51 -04004288{
Geoff Langc339c4e2016-11-29 10:37:36 -05004289 if (!context->getExtensions().requestExtension)
Geoff Langc287ea62016-09-16 14:46:51 -04004290 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004291 context->handleError(InvalidOperation() << "GL_ANGLE_request_extension is not available.");
Geoff Langc287ea62016-09-16 14:46:51 -04004292 return false;
4293 }
4294
Geoff Lang111a99e2017-10-17 10:58:41 -04004295 if (!context->isExtensionRequestable(name))
Geoff Langc287ea62016-09-16 14:46:51 -04004296 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004297 context->handleError(InvalidOperation() << "Extension " << name << " is not requestable.");
Geoff Langc287ea62016-09-16 14:46:51 -04004298 return false;
4299 }
4300
4301 return true;
4302}
4303
Jamie Madillef300b12016-10-07 15:12:09 -04004304bool ValidateActiveTexture(ValidationContext *context, GLenum texture)
4305{
4306 if (texture < GL_TEXTURE0 ||
4307 texture > GL_TEXTURE0 + context->getCaps().maxCombinedTextureImageUnits - 1)
4308 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004309 context->handleError(InvalidEnum());
Jamie Madillef300b12016-10-07 15:12:09 -04004310 return false;
4311 }
4312
4313 return true;
4314}
4315
4316bool ValidateAttachShader(ValidationContext *context, GLuint program, GLuint shader)
4317{
4318 Program *programObject = GetValidProgram(context, program);
4319 if (!programObject)
4320 {
4321 return false;
4322 }
4323
4324 Shader *shaderObject = GetValidShader(context, shader);
4325 if (!shaderObject)
4326 {
4327 return false;
4328 }
4329
4330 switch (shaderObject->getType())
4331 {
4332 case GL_VERTEX_SHADER:
4333 {
4334 if (programObject->getAttachedVertexShader())
4335 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004336 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
Jamie Madillef300b12016-10-07 15:12:09 -04004337 return false;
4338 }
4339 break;
4340 }
4341 case GL_FRAGMENT_SHADER:
4342 {
4343 if (programObject->getAttachedFragmentShader())
4344 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004345 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
Jamie Madillef300b12016-10-07 15:12:09 -04004346 return false;
4347 }
4348 break;
4349 }
4350 case GL_COMPUTE_SHADER:
4351 {
4352 if (programObject->getAttachedComputeShader())
4353 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004354 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
Jamie Madillef300b12016-10-07 15:12:09 -04004355 return false;
4356 }
4357 break;
4358 }
Jiawei Shao89be29a2017-11-06 14:36:45 +08004359 case GL_GEOMETRY_SHADER_EXT:
4360 {
4361 if (programObject->getAttachedGeometryShader())
4362 {
4363 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
4364 return false;
4365 }
4366 break;
4367 }
Jamie Madillef300b12016-10-07 15:12:09 -04004368 default:
4369 UNREACHABLE();
4370 break;
4371 }
4372
4373 return true;
4374}
4375
Jamie Madill01a80ee2016-11-07 12:06:18 -05004376bool ValidateBindAttribLocation(ValidationContext *context,
4377 GLuint program,
4378 GLuint index,
4379 const GLchar *name)
4380{
4381 if (index >= MAX_VERTEX_ATTRIBS)
4382 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004383 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004384 return false;
4385 }
4386
4387 if (strncmp(name, "gl_", 3) == 0)
4388 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004389 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004390 return false;
4391 }
4392
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004393 if (context->isWebGL())
Geoff Langfc32e8b2017-05-31 14:16:59 -04004394 {
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004395 const size_t length = strlen(name);
4396
4397 if (!IsValidESSLString(name, length))
4398 {
4399 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters
4400 // for shader-related entry points
4401 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
4402 return false;
4403 }
4404
4405 if (!ValidateWebGLNameLength(context, length) || !ValidateWebGLNamePrefix(context, name))
4406 {
4407 return false;
4408 }
Geoff Langfc32e8b2017-05-31 14:16:59 -04004409 }
4410
Jamie Madill01a80ee2016-11-07 12:06:18 -05004411 return GetValidProgram(context, program) != nullptr;
4412}
4413
Corentin Wallez336129f2017-10-17 15:55:40 -04004414bool ValidateBindBuffer(ValidationContext *context, BufferBinding target, GLuint buffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004415{
Corentin Walleze4477002017-12-01 14:39:58 -05004416 if (!context->isValidBufferBinding(target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004417 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004418 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004419 return false;
4420 }
4421
4422 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4423 !context->isBufferGenerated(buffer))
4424 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004425 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004426 return false;
4427 }
4428
4429 return true;
4430}
4431
4432bool ValidateBindFramebuffer(ValidationContext *context, GLenum target, GLuint framebuffer)
4433{
Geoff Lange8afa902017-09-27 15:00:43 -04004434 if (!ValidFramebufferTarget(context, target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004435 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004436 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004437 return false;
4438 }
4439
4440 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4441 !context->isFramebufferGenerated(framebuffer))
4442 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004443 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004444 return false;
4445 }
4446
4447 return true;
4448}
4449
4450bool ValidateBindRenderbuffer(ValidationContext *context, GLenum target, GLuint renderbuffer)
4451{
4452 if (target != GL_RENDERBUFFER)
4453 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004454 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004455 return false;
4456 }
4457
4458 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4459 !context->isRenderbufferGenerated(renderbuffer))
4460 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004461 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004462 return false;
4463 }
4464
4465 return true;
4466}
4467
Geoff Lang50cac572017-09-26 17:37:43 -04004468static bool ValidBlendEquationMode(const ValidationContext *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004469{
4470 switch (mode)
4471 {
4472 case GL_FUNC_ADD:
4473 case GL_FUNC_SUBTRACT:
4474 case GL_FUNC_REVERSE_SUBTRACT:
Geoff Lang50cac572017-09-26 17:37:43 -04004475 return true;
4476
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004477 case GL_MIN:
4478 case GL_MAX:
Geoff Lang50cac572017-09-26 17:37:43 -04004479 return context->getClientVersion() >= ES_3_0 || context->getExtensions().blendMinMax;
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004480
4481 default:
4482 return false;
4483 }
4484}
4485
Jamie Madillc1d770e2017-04-13 17:31:24 -04004486bool ValidateBlendColor(ValidationContext *context,
Jamie Madill876429b2017-04-20 15:46:24 -04004487 GLfloat red,
4488 GLfloat green,
4489 GLfloat blue,
4490 GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004491{
4492 return true;
4493}
4494
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004495bool ValidateBlendEquation(ValidationContext *context, GLenum mode)
4496{
Geoff Lang50cac572017-09-26 17:37:43 -04004497 if (!ValidBlendEquationMode(context, mode))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004498 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004499 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004500 return false;
4501 }
4502
4503 return true;
4504}
4505
4506bool ValidateBlendEquationSeparate(ValidationContext *context, GLenum modeRGB, GLenum modeAlpha)
4507{
Geoff Lang50cac572017-09-26 17:37:43 -04004508 if (!ValidBlendEquationMode(context, modeRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004509 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004510 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004511 return false;
4512 }
4513
Geoff Lang50cac572017-09-26 17:37:43 -04004514 if (!ValidBlendEquationMode(context, modeAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004515 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004516 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004517 return false;
4518 }
4519
4520 return true;
4521}
4522
4523bool ValidateBlendFunc(ValidationContext *context, GLenum sfactor, GLenum dfactor)
4524{
4525 return ValidateBlendFuncSeparate(context, sfactor, dfactor, sfactor, dfactor);
4526}
4527
4528static bool ValidSrcBlendFunc(GLenum srcBlend)
4529{
4530 switch (srcBlend)
4531 {
4532 case GL_ZERO:
4533 case GL_ONE:
4534 case GL_SRC_COLOR:
4535 case GL_ONE_MINUS_SRC_COLOR:
4536 case GL_DST_COLOR:
4537 case GL_ONE_MINUS_DST_COLOR:
4538 case GL_SRC_ALPHA:
4539 case GL_ONE_MINUS_SRC_ALPHA:
4540 case GL_DST_ALPHA:
4541 case GL_ONE_MINUS_DST_ALPHA:
4542 case GL_CONSTANT_COLOR:
4543 case GL_ONE_MINUS_CONSTANT_COLOR:
4544 case GL_CONSTANT_ALPHA:
4545 case GL_ONE_MINUS_CONSTANT_ALPHA:
4546 case GL_SRC_ALPHA_SATURATE:
4547 return true;
4548
4549 default:
4550 return false;
4551 }
4552}
4553
4554static bool ValidDstBlendFunc(GLenum dstBlend, GLint contextMajorVersion)
4555{
4556 switch (dstBlend)
4557 {
4558 case GL_ZERO:
4559 case GL_ONE:
4560 case GL_SRC_COLOR:
4561 case GL_ONE_MINUS_SRC_COLOR:
4562 case GL_DST_COLOR:
4563 case GL_ONE_MINUS_DST_COLOR:
4564 case GL_SRC_ALPHA:
4565 case GL_ONE_MINUS_SRC_ALPHA:
4566 case GL_DST_ALPHA:
4567 case GL_ONE_MINUS_DST_ALPHA:
4568 case GL_CONSTANT_COLOR:
4569 case GL_ONE_MINUS_CONSTANT_COLOR:
4570 case GL_CONSTANT_ALPHA:
4571 case GL_ONE_MINUS_CONSTANT_ALPHA:
4572 return true;
4573
4574 case GL_SRC_ALPHA_SATURATE:
4575 return (contextMajorVersion >= 3);
4576
4577 default:
4578 return false;
4579 }
4580}
4581
4582bool ValidateBlendFuncSeparate(ValidationContext *context,
4583 GLenum srcRGB,
4584 GLenum dstRGB,
4585 GLenum srcAlpha,
4586 GLenum dstAlpha)
4587{
4588 if (!ValidSrcBlendFunc(srcRGB))
4589 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004590 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004591 return false;
4592 }
4593
4594 if (!ValidDstBlendFunc(dstRGB, context->getClientMajorVersion()))
4595 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004596 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004597 return false;
4598 }
4599
4600 if (!ValidSrcBlendFunc(srcAlpha))
4601 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004602 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004603 return false;
4604 }
4605
4606 if (!ValidDstBlendFunc(dstAlpha, context->getClientMajorVersion()))
4607 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004608 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004609 return false;
4610 }
4611
Frank Henigman146e8a12017-03-02 23:22:37 -05004612 if (context->getLimitations().noSimultaneousConstantColorAndAlphaBlendFunc ||
4613 context->getExtensions().webglCompatibility)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004614 {
4615 bool constantColorUsed =
4616 (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
4617 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
4618
4619 bool constantAlphaUsed =
4620 (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
4621 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
4622
4623 if (constantColorUsed && constantAlphaUsed)
4624 {
Frank Henigman146e8a12017-03-02 23:22:37 -05004625 const char *msg;
4626 if (context->getExtensions().webglCompatibility)
4627 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004628 msg = kErrorInvalidConstantColor;
Frank Henigman146e8a12017-03-02 23:22:37 -05004629 }
4630 else
4631 {
4632 msg =
4633 "Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and "
4634 "GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR not supported by this "
4635 "implementation.";
4636 ERR() << msg;
4637 }
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004638 context->handleError(InvalidOperation() << msg);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004639 return false;
4640 }
4641 }
4642
4643 return true;
4644}
4645
Geoff Langc339c4e2016-11-29 10:37:36 -05004646bool ValidateGetString(Context *context, GLenum name)
4647{
4648 switch (name)
4649 {
4650 case GL_VENDOR:
4651 case GL_RENDERER:
4652 case GL_VERSION:
4653 case GL_SHADING_LANGUAGE_VERSION:
4654 case GL_EXTENSIONS:
4655 break;
4656
4657 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
4658 if (!context->getExtensions().requestExtension)
4659 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004660 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004661 return false;
4662 }
4663 break;
4664
4665 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07004666 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004667 return false;
4668 }
4669
4670 return true;
4671}
4672
Geoff Lang47c48082016-12-07 15:38:13 -05004673bool ValidateLineWidth(ValidationContext *context, GLfloat width)
4674{
4675 if (width <= 0.0f || isNaN(width))
4676 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004677 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidWidth);
Geoff Lang47c48082016-12-07 15:38:13 -05004678 return false;
4679 }
4680
4681 return true;
4682}
4683
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004684bool ValidateVertexAttribPointer(ValidationContext *context,
4685 GLuint index,
4686 GLint size,
4687 GLenum type,
4688 GLboolean normalized,
4689 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04004690 const void *ptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004691{
Shao80957d92017-02-20 21:25:59 +08004692 if (!ValidateVertexFormatBase(context, index, size, type, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004693 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004694 return false;
4695 }
4696
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004697 if (stride < 0)
4698 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004699 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeStride);
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004700 return false;
4701 }
4702
Shao80957d92017-02-20 21:25:59 +08004703 const Caps &caps = context->getCaps();
4704 if (context->getClientVersion() >= ES_3_1)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004705 {
Shao80957d92017-02-20 21:25:59 +08004706 if (stride > caps.maxVertexAttribStride)
4707 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004708 context->handleError(InvalidValue()
4709 << "stride cannot be greater than MAX_VERTEX_ATTRIB_STRIDE.");
Shao80957d92017-02-20 21:25:59 +08004710 return false;
4711 }
4712
4713 if (index >= caps.maxVertexAttribBindings)
4714 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004715 context->handleError(InvalidValue()
4716 << "index must be smaller than MAX_VERTEX_ATTRIB_BINDINGS.");
Shao80957d92017-02-20 21:25:59 +08004717 return false;
4718 }
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004719 }
4720
4721 // [OpenGL ES 3.0.2] Section 2.8 page 24:
4722 // An INVALID_OPERATION error is generated when a non-zero vertex array object
4723 // is bound, zero is bound to the ARRAY_BUFFER buffer object binding point,
4724 // and the pointer argument is not NULL.
Geoff Langfeb8c682017-02-13 16:07:35 -05004725 bool nullBufferAllowed = context->getGLState().areClientArraysEnabled() &&
4726 context->getGLState().getVertexArray()->id() == 0;
Corentin Wallez336129f2017-10-17 15:55:40 -04004727 if (!nullBufferAllowed && context->getGLState().getTargetBuffer(BufferBinding::Array) == 0 &&
4728 ptr != nullptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004729 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004730 context
4731 ->handleError(InvalidOperation()
4732 << "Client data cannot be used with a non-default vertex array object.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004733 return false;
4734 }
4735
4736 if (context->getExtensions().webglCompatibility)
4737 {
4738 // WebGL 1.0 [Section 6.14] Fixed point support
4739 // The WebGL API does not support the GL_FIXED data type.
4740 if (type == GL_FIXED)
4741 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004742 context->handleError(InvalidEnum() << "GL_FIXED is not supported in WebGL.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004743 return false;
4744 }
4745
Geoff Lang2d62ab72017-03-23 16:54:40 -04004746 if (!ValidateWebGLVertexAttribPointer(context, type, normalized, stride, ptr, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004747 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004748 return false;
4749 }
4750 }
4751
4752 return true;
4753}
4754
Jamie Madill876429b2017-04-20 15:46:24 -04004755bool ValidateDepthRangef(ValidationContext *context, GLfloat zNear, GLfloat zFar)
Frank Henigman6137ddc2017-02-10 18:55:07 -05004756{
4757 if (context->getExtensions().webglCompatibility && zNear > zFar)
4758 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004759 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidDepthRange);
Frank Henigman6137ddc2017-02-10 18:55:07 -05004760 return false;
4761 }
4762
4763 return true;
4764}
4765
Jamie Madille8fb6402017-02-14 17:56:40 -05004766bool ValidateRenderbufferStorage(ValidationContext *context,
4767 GLenum target,
4768 GLenum internalformat,
4769 GLsizei width,
4770 GLsizei height)
4771{
4772 return ValidateRenderbufferStorageParametersBase(context, target, 0, internalformat, width,
4773 height);
4774}
4775
4776bool ValidateRenderbufferStorageMultisampleANGLE(ValidationContext *context,
4777 GLenum target,
4778 GLsizei samples,
4779 GLenum internalformat,
4780 GLsizei width,
4781 GLsizei height)
4782{
4783 if (!context->getExtensions().framebufferMultisample)
4784 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004785 context->handleError(InvalidOperation()
4786 << "GL_ANGLE_framebuffer_multisample not available");
Jamie Madille8fb6402017-02-14 17:56:40 -05004787 return false;
4788 }
4789
4790 // ANGLE_framebuffer_multisample states that the value of samples must be less than or equal
4791 // to MAX_SAMPLES_ANGLE (Context::getCaps().maxSamples) otherwise GL_INVALID_OPERATION is
4792 // generated.
4793 if (static_cast<GLuint>(samples) > context->getCaps().maxSamples)
4794 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004795 context->handleError(InvalidValue());
Jamie Madille8fb6402017-02-14 17:56:40 -05004796 return false;
4797 }
4798
4799 // ANGLE_framebuffer_multisample states GL_OUT_OF_MEMORY is generated on a failure to create
4800 // the specified storage. This is different than ES 3.0 in which a sample number higher
4801 // than the maximum sample number supported by this format generates a GL_INVALID_VALUE.
4802 // The TextureCaps::getMaxSamples method is only guarenteed to be valid when the context is ES3.
4803 if (context->getClientMajorVersion() >= 3)
4804 {
4805 const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
4806 if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
4807 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004808 context->handleError(OutOfMemory());
Jamie Madille8fb6402017-02-14 17:56:40 -05004809 return false;
4810 }
4811 }
4812
4813 return ValidateRenderbufferStorageParametersBase(context, target, samples, internalformat,
4814 width, height);
4815}
4816
Jamie Madillc1d770e2017-04-13 17:31:24 -04004817bool ValidateCheckFramebufferStatus(ValidationContext *context, GLenum target)
4818{
Geoff Lange8afa902017-09-27 15:00:43 -04004819 if (!ValidFramebufferTarget(context, target))
Jamie Madillc1d770e2017-04-13 17:31:24 -04004820 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004821 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004822 return false;
4823 }
4824
4825 return true;
4826}
4827
4828bool ValidateClearColor(ValidationContext *context,
Jamie Madill876429b2017-04-20 15:46:24 -04004829 GLfloat red,
4830 GLfloat green,
4831 GLfloat blue,
4832 GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004833{
4834 return true;
4835}
4836
Jamie Madill876429b2017-04-20 15:46:24 -04004837bool ValidateClearDepthf(ValidationContext *context, GLfloat depth)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004838{
4839 return true;
4840}
4841
4842bool ValidateClearStencil(ValidationContext *context, GLint s)
4843{
4844 return true;
4845}
4846
4847bool ValidateColorMask(ValidationContext *context,
4848 GLboolean red,
4849 GLboolean green,
4850 GLboolean blue,
4851 GLboolean alpha)
4852{
4853 return true;
4854}
4855
4856bool ValidateCompileShader(ValidationContext *context, GLuint shader)
4857{
4858 return true;
4859}
4860
4861bool ValidateCreateProgram(ValidationContext *context)
4862{
4863 return true;
4864}
4865
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004866bool ValidateCullFace(ValidationContext *context, CullFaceMode mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004867{
4868 switch (mode)
4869 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004870 case CullFaceMode::Front:
4871 case CullFaceMode::Back:
4872 case CullFaceMode::FrontAndBack:
Jamie Madillc1d770e2017-04-13 17:31:24 -04004873 break;
4874
4875 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004876 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCullMode);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004877 return false;
4878 }
4879
4880 return true;
4881}
4882
4883bool ValidateDeleteProgram(ValidationContext *context, GLuint program)
4884{
4885 if (program == 0)
4886 {
4887 return false;
4888 }
4889
4890 if (!context->getProgram(program))
4891 {
4892 if (context->getShader(program))
4893 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004894 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004895 return false;
4896 }
4897 else
4898 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004899 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004900 return false;
4901 }
4902 }
4903
4904 return true;
4905}
4906
4907bool ValidateDeleteShader(ValidationContext *context, GLuint shader)
4908{
4909 if (shader == 0)
4910 {
4911 return false;
4912 }
4913
4914 if (!context->getShader(shader))
4915 {
4916 if (context->getProgram(shader))
4917 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004918 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004919 return false;
4920 }
4921 else
4922 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004923 ANGLE_VALIDATION_ERR(context, InvalidValue(), ExpectedShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004924 return false;
4925 }
4926 }
4927
4928 return true;
4929}
4930
4931bool ValidateDepthFunc(ValidationContext *context, GLenum func)
4932{
4933 switch (func)
4934 {
4935 case GL_NEVER:
4936 case GL_ALWAYS:
4937 case GL_LESS:
4938 case GL_LEQUAL:
4939 case GL_EQUAL:
4940 case GL_GREATER:
4941 case GL_GEQUAL:
4942 case GL_NOTEQUAL:
4943 break;
4944
4945 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004946 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004947 return false;
4948 }
4949
4950 return true;
4951}
4952
4953bool ValidateDepthMask(ValidationContext *context, GLboolean flag)
4954{
4955 return true;
4956}
4957
4958bool ValidateDetachShader(ValidationContext *context, GLuint program, GLuint shader)
4959{
4960 Program *programObject = GetValidProgram(context, program);
4961 if (!programObject)
4962 {
4963 return false;
4964 }
4965
4966 Shader *shaderObject = GetValidShader(context, shader);
4967 if (!shaderObject)
4968 {
4969 return false;
4970 }
4971
4972 const Shader *attachedShader = nullptr;
4973
4974 switch (shaderObject->getType())
4975 {
4976 case GL_VERTEX_SHADER:
4977 {
4978 attachedShader = programObject->getAttachedVertexShader();
4979 break;
4980 }
4981 case GL_FRAGMENT_SHADER:
4982 {
4983 attachedShader = programObject->getAttachedFragmentShader();
4984 break;
4985 }
4986 case GL_COMPUTE_SHADER:
4987 {
4988 attachedShader = programObject->getAttachedComputeShader();
4989 break;
4990 }
Jiawei Shao89be29a2017-11-06 14:36:45 +08004991 case GL_GEOMETRY_SHADER_EXT:
4992 {
4993 attachedShader = programObject->getAttachedGeometryShader();
4994 break;
4995 }
Jamie Madillc1d770e2017-04-13 17:31:24 -04004996 default:
4997 UNREACHABLE();
4998 return false;
4999 }
5000
5001 if (attachedShader != shaderObject)
5002 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005003 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderToDetachMustBeAttached);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005004 return false;
5005 }
5006
5007 return true;
5008}
5009
5010bool ValidateDisableVertexAttribArray(ValidationContext *context, GLuint index)
5011{
5012 if (index >= MAX_VERTEX_ATTRIBS)
5013 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005014 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005015 return false;
5016 }
5017
5018 return true;
5019}
5020
5021bool ValidateEnableVertexAttribArray(ValidationContext *context, GLuint index)
5022{
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
5032bool ValidateFinish(ValidationContext *context)
5033{
5034 return true;
5035}
5036
5037bool ValidateFlush(ValidationContext *context)
5038{
5039 return true;
5040}
5041
5042bool ValidateFrontFace(ValidationContext *context, GLenum mode)
5043{
5044 switch (mode)
5045 {
5046 case GL_CW:
5047 case GL_CCW:
5048 break;
5049 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005050 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005051 return false;
5052 }
5053
5054 return true;
5055}
5056
5057bool ValidateGetActiveAttrib(ValidationContext *context,
5058 GLuint program,
5059 GLuint index,
5060 GLsizei bufsize,
5061 GLsizei *length,
5062 GLint *size,
5063 GLenum *type,
5064 GLchar *name)
5065{
5066 if (bufsize < 0)
5067 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005068 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005069 return false;
5070 }
5071
5072 Program *programObject = GetValidProgram(context, program);
5073
5074 if (!programObject)
5075 {
5076 return false;
5077 }
5078
5079 if (index >= static_cast<GLuint>(programObject->getActiveAttributeCount()))
5080 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005081 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005082 return false;
5083 }
5084
5085 return true;
5086}
5087
5088bool ValidateGetActiveUniform(ValidationContext *context,
5089 GLuint program,
5090 GLuint index,
5091 GLsizei bufsize,
5092 GLsizei *length,
5093 GLint *size,
5094 GLenum *type,
5095 GLchar *name)
5096{
5097 if (bufsize < 0)
5098 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005099 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005100 return false;
5101 }
5102
5103 Program *programObject = GetValidProgram(context, program);
5104
5105 if (!programObject)
5106 {
5107 return false;
5108 }
5109
5110 if (index >= static_cast<GLuint>(programObject->getActiveUniformCount()))
5111 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005112 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005113 return false;
5114 }
5115
5116 return true;
5117}
5118
5119bool ValidateGetAttachedShaders(ValidationContext *context,
5120 GLuint program,
5121 GLsizei maxcount,
5122 GLsizei *count,
5123 GLuint *shaders)
5124{
5125 if (maxcount < 0)
5126 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005127 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeMaxCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005128 return false;
5129 }
5130
5131 Program *programObject = GetValidProgram(context, program);
5132
5133 if (!programObject)
5134 {
5135 return false;
5136 }
5137
5138 return true;
5139}
5140
5141bool ValidateGetAttribLocation(ValidationContext *context, GLuint program, const GLchar *name)
5142{
Geoff Langfc32e8b2017-05-31 14:16:59 -04005143 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5144 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005145 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005146 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005147 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005148 return false;
5149 }
5150
Jamie Madillc1d770e2017-04-13 17:31:24 -04005151 Program *programObject = GetValidProgram(context, program);
5152
5153 if (!programObject)
5154 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005155 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005156 return false;
5157 }
5158
5159 if (!programObject->isLinked())
5160 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005161 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005162 return false;
5163 }
5164
5165 return true;
5166}
5167
5168bool ValidateGetBooleanv(ValidationContext *context, GLenum pname, GLboolean *params)
5169{
5170 GLenum nativeType;
5171 unsigned int numParams = 0;
5172 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5173}
5174
5175bool ValidateGetError(ValidationContext *context)
5176{
5177 return true;
5178}
5179
5180bool ValidateGetFloatv(ValidationContext *context, GLenum pname, GLfloat *params)
5181{
5182 GLenum nativeType;
5183 unsigned int numParams = 0;
5184 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5185}
5186
5187bool ValidateGetIntegerv(ValidationContext *context, GLenum pname, GLint *params)
5188{
5189 GLenum nativeType;
5190 unsigned int numParams = 0;
5191 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5192}
5193
5194bool ValidateGetProgramInfoLog(ValidationContext *context,
5195 GLuint program,
5196 GLsizei bufsize,
5197 GLsizei *length,
5198 GLchar *infolog)
5199{
5200 if (bufsize < 0)
5201 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005202 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005203 return false;
5204 }
5205
5206 Program *programObject = GetValidProgram(context, program);
5207 if (!programObject)
5208 {
5209 return false;
5210 }
5211
5212 return true;
5213}
5214
5215bool ValidateGetShaderInfoLog(ValidationContext *context,
5216 GLuint shader,
5217 GLsizei bufsize,
5218 GLsizei *length,
5219 GLchar *infolog)
5220{
5221 if (bufsize < 0)
5222 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005223 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005224 return false;
5225 }
5226
5227 Shader *shaderObject = GetValidShader(context, shader);
5228 if (!shaderObject)
5229 {
5230 return false;
5231 }
5232
5233 return true;
5234}
5235
5236bool ValidateGetShaderPrecisionFormat(ValidationContext *context,
5237 GLenum shadertype,
5238 GLenum precisiontype,
5239 GLint *range,
5240 GLint *precision)
5241{
5242 switch (shadertype)
5243 {
5244 case GL_VERTEX_SHADER:
5245 case GL_FRAGMENT_SHADER:
5246 break;
5247 case GL_COMPUTE_SHADER:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005248 context->handleError(InvalidOperation()
5249 << "compute shader precision not yet implemented.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005250 return false;
5251 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005252 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005253 return false;
5254 }
5255
5256 switch (precisiontype)
5257 {
5258 case GL_LOW_FLOAT:
5259 case GL_MEDIUM_FLOAT:
5260 case GL_HIGH_FLOAT:
5261 case GL_LOW_INT:
5262 case GL_MEDIUM_INT:
5263 case GL_HIGH_INT:
5264 break;
5265
5266 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005267 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPrecision);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005268 return false;
5269 }
5270
5271 return true;
5272}
5273
5274bool ValidateGetShaderSource(ValidationContext *context,
5275 GLuint shader,
5276 GLsizei bufsize,
5277 GLsizei *length,
5278 GLchar *source)
5279{
5280 if (bufsize < 0)
5281 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005282 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005283 return false;
5284 }
5285
5286 Shader *shaderObject = GetValidShader(context, shader);
5287 if (!shaderObject)
5288 {
5289 return false;
5290 }
5291
5292 return true;
5293}
5294
5295bool ValidateGetUniformLocation(ValidationContext *context, GLuint program, const GLchar *name)
5296{
5297 if (strstr(name, "gl_") == name)
5298 {
5299 return false;
5300 }
5301
Geoff Langfc32e8b2017-05-31 14:16:59 -04005302 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5303 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005304 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005305 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005306 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005307 return false;
5308 }
5309
Jamie Madillc1d770e2017-04-13 17:31:24 -04005310 Program *programObject = GetValidProgram(context, program);
5311
5312 if (!programObject)
5313 {
5314 return false;
5315 }
5316
5317 if (!programObject->isLinked())
5318 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005319 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005320 return false;
5321 }
5322
5323 return true;
5324}
5325
5326bool ValidateHint(ValidationContext *context, GLenum target, GLenum mode)
5327{
5328 switch (mode)
5329 {
5330 case GL_FASTEST:
5331 case GL_NICEST:
5332 case GL_DONT_CARE:
5333 break;
5334
5335 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005336 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005337 return false;
5338 }
5339
5340 switch (target)
5341 {
5342 case GL_GENERATE_MIPMAP_HINT:
5343 break;
5344
Geoff Lange7bd2182017-06-16 16:13:13 -04005345 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
5346 if (context->getClientVersion() < ES_3_0 &&
5347 !context->getExtensions().standardDerivatives)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005348 {
Brandon Jones72f58fa2017-09-19 10:47:41 -07005349 context->handleError(InvalidEnum() << "hint requires OES_standard_derivatives.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005350 return false;
5351 }
5352 break;
5353
5354 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005355 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005356 return false;
5357 }
5358
5359 return true;
5360}
5361
5362bool ValidateIsBuffer(ValidationContext *context, GLuint buffer)
5363{
5364 return true;
5365}
5366
5367bool ValidateIsFramebuffer(ValidationContext *context, GLuint framebuffer)
5368{
5369 return true;
5370}
5371
5372bool ValidateIsProgram(ValidationContext *context, GLuint program)
5373{
5374 return true;
5375}
5376
5377bool ValidateIsRenderbuffer(ValidationContext *context, GLuint renderbuffer)
5378{
5379 return true;
5380}
5381
5382bool ValidateIsShader(ValidationContext *context, GLuint shader)
5383{
5384 return true;
5385}
5386
5387bool ValidateIsTexture(ValidationContext *context, GLuint texture)
5388{
5389 return true;
5390}
5391
5392bool ValidatePixelStorei(ValidationContext *context, GLenum pname, GLint param)
5393{
5394 if (context->getClientMajorVersion() < 3)
5395 {
5396 switch (pname)
5397 {
5398 case GL_UNPACK_IMAGE_HEIGHT:
5399 case GL_UNPACK_SKIP_IMAGES:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005400 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005401 return false;
5402
5403 case GL_UNPACK_ROW_LENGTH:
5404 case GL_UNPACK_SKIP_ROWS:
5405 case GL_UNPACK_SKIP_PIXELS:
5406 if (!context->getExtensions().unpackSubimage)
5407 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005408 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005409 return false;
5410 }
5411 break;
5412
5413 case GL_PACK_ROW_LENGTH:
5414 case GL_PACK_SKIP_ROWS:
5415 case GL_PACK_SKIP_PIXELS:
5416 if (!context->getExtensions().packSubimage)
5417 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005418 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005419 return false;
5420 }
5421 break;
5422 }
5423 }
5424
5425 if (param < 0)
5426 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005427 context->handleError(InvalidValue() << "Cannot use negative values in PixelStorei");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005428 return false;
5429 }
5430
5431 switch (pname)
5432 {
5433 case GL_UNPACK_ALIGNMENT:
5434 if (param != 1 && param != 2 && param != 4 && param != 8)
5435 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005436 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005437 return false;
5438 }
5439 break;
5440
5441 case GL_PACK_ALIGNMENT:
5442 if (param != 1 && param != 2 && param != 4 && param != 8)
5443 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005444 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005445 return false;
5446 }
5447 break;
5448
5449 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Geoff Lang000dab82017-09-27 14:27:07 -04005450 if (!context->getExtensions().packReverseRowOrder)
5451 {
5452 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
5453 }
5454 break;
5455
Jamie Madillc1d770e2017-04-13 17:31:24 -04005456 case GL_UNPACK_ROW_LENGTH:
5457 case GL_UNPACK_IMAGE_HEIGHT:
5458 case GL_UNPACK_SKIP_IMAGES:
5459 case GL_UNPACK_SKIP_ROWS:
5460 case GL_UNPACK_SKIP_PIXELS:
5461 case GL_PACK_ROW_LENGTH:
5462 case GL_PACK_SKIP_ROWS:
5463 case GL_PACK_SKIP_PIXELS:
5464 break;
5465
5466 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005467 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005468 return false;
5469 }
5470
5471 return true;
5472}
5473
5474bool ValidatePolygonOffset(ValidationContext *context, GLfloat factor, GLfloat units)
5475{
5476 return true;
5477}
5478
5479bool ValidateReleaseShaderCompiler(ValidationContext *context)
5480{
5481 return true;
5482}
5483
Jamie Madill876429b2017-04-20 15:46:24 -04005484bool ValidateSampleCoverage(ValidationContext *context, GLfloat value, GLboolean invert)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005485{
5486 return true;
5487}
5488
5489bool ValidateScissor(ValidationContext *context, GLint x, GLint y, GLsizei width, GLsizei height)
5490{
5491 if (width < 0 || height < 0)
5492 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005493 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005494 return false;
5495 }
5496
5497 return true;
5498}
5499
5500bool ValidateShaderBinary(ValidationContext *context,
5501 GLsizei n,
5502 const GLuint *shaders,
5503 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04005504 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005505 GLsizei length)
5506{
5507 const std::vector<GLenum> &shaderBinaryFormats = context->getCaps().shaderBinaryFormats;
5508 if (std::find(shaderBinaryFormats.begin(), shaderBinaryFormats.end(), binaryformat) ==
5509 shaderBinaryFormats.end())
5510 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005511 context->handleError(InvalidEnum() << "Invalid shader binary format.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005512 return false;
5513 }
5514
5515 return true;
5516}
5517
5518bool ValidateShaderSource(ValidationContext *context,
5519 GLuint shader,
5520 GLsizei count,
5521 const GLchar *const *string,
5522 const GLint *length)
5523{
5524 if (count < 0)
5525 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005526 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005527 return false;
5528 }
5529
Geoff Langfc32e8b2017-05-31 14:16:59 -04005530 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5531 // shader-related entry points
5532 if (context->getExtensions().webglCompatibility)
5533 {
5534 for (GLsizei i = 0; i < count; i++)
5535 {
Geoff Langcab92ee2017-07-19 17:32:07 -04005536 size_t len =
5537 (length && length[i] >= 0) ? static_cast<size_t>(length[i]) : strlen(string[i]);
Geoff Langa71a98e2017-06-19 15:15:00 -04005538
5539 // Backslash as line-continuation is allowed in WebGL 2.0.
Geoff Langcab92ee2017-07-19 17:32:07 -04005540 if (!IsValidESSLShaderSourceString(string[i], len,
5541 context->getClientVersion() >= ES_3_0))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005542 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005543 ANGLE_VALIDATION_ERR(context, InvalidValue(), ShaderSourceInvalidCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005544 return false;
5545 }
5546 }
5547 }
5548
Jamie Madillc1d770e2017-04-13 17:31:24 -04005549 Shader *shaderObject = GetValidShader(context, shader);
5550 if (!shaderObject)
5551 {
5552 return false;
5553 }
5554
5555 return true;
5556}
5557
5558bool ValidateStencilFunc(ValidationContext *context, GLenum func, GLint ref, GLuint mask)
5559{
5560 if (!IsValidStencilFunc(func))
5561 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005562 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005563 return false;
5564 }
5565
5566 return true;
5567}
5568
5569bool ValidateStencilFuncSeparate(ValidationContext *context,
5570 GLenum face,
5571 GLenum func,
5572 GLint ref,
5573 GLuint mask)
5574{
5575 if (!IsValidStencilFace(face))
5576 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005577 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005578 return false;
5579 }
5580
5581 if (!IsValidStencilFunc(func))
5582 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005583 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005584 return false;
5585 }
5586
5587 return true;
5588}
5589
5590bool ValidateStencilMask(ValidationContext *context, GLuint mask)
5591{
5592 return true;
5593}
5594
5595bool ValidateStencilMaskSeparate(ValidationContext *context, GLenum face, GLuint mask)
5596{
5597 if (!IsValidStencilFace(face))
5598 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005599 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005600 return false;
5601 }
5602
5603 return true;
5604}
5605
5606bool ValidateStencilOp(ValidationContext *context, GLenum fail, GLenum zfail, GLenum zpass)
5607{
5608 if (!IsValidStencilOp(fail))
5609 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005610 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005611 return false;
5612 }
5613
5614 if (!IsValidStencilOp(zfail))
5615 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005616 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005617 return false;
5618 }
5619
5620 if (!IsValidStencilOp(zpass))
5621 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005622 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005623 return false;
5624 }
5625
5626 return true;
5627}
5628
5629bool ValidateStencilOpSeparate(ValidationContext *context,
5630 GLenum face,
5631 GLenum fail,
5632 GLenum zfail,
5633 GLenum zpass)
5634{
5635 if (!IsValidStencilFace(face))
5636 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005637 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005638 return false;
5639 }
5640
5641 return ValidateStencilOp(context, fail, zfail, zpass);
5642}
5643
5644bool ValidateUniform1f(ValidationContext *context, GLint location, GLfloat x)
5645{
5646 return ValidateUniform(context, GL_FLOAT, location, 1);
5647}
5648
5649bool ValidateUniform1fv(ValidationContext *context, GLint location, GLsizei count, const GLfloat *v)
5650{
5651 return ValidateUniform(context, GL_FLOAT, location, count);
5652}
5653
Jamie Madillbe849e42017-05-02 15:49:00 -04005654bool ValidateUniform1i(ValidationContext *context, GLint location, GLint x)
5655{
5656 return ValidateUniform1iv(context, location, 1, &x);
5657}
5658
Jamie Madillc1d770e2017-04-13 17:31:24 -04005659bool ValidateUniform2f(ValidationContext *context, GLint location, GLfloat x, GLfloat y)
5660{
5661 return ValidateUniform(context, GL_FLOAT_VEC2, location, 1);
5662}
5663
5664bool ValidateUniform2fv(ValidationContext *context, GLint location, GLsizei count, const GLfloat *v)
5665{
5666 return ValidateUniform(context, GL_FLOAT_VEC2, location, count);
5667}
5668
5669bool ValidateUniform2i(ValidationContext *context, GLint location, GLint x, GLint y)
5670{
5671 return ValidateUniform(context, GL_INT_VEC2, location, 1);
5672}
5673
5674bool ValidateUniform2iv(ValidationContext *context, GLint location, GLsizei count, const GLint *v)
5675{
5676 return ValidateUniform(context, GL_INT_VEC2, location, count);
5677}
5678
5679bool ValidateUniform3f(ValidationContext *context, GLint location, GLfloat x, GLfloat y, GLfloat z)
5680{
5681 return ValidateUniform(context, GL_FLOAT_VEC3, location, 1);
5682}
5683
5684bool ValidateUniform3fv(ValidationContext *context, GLint location, GLsizei count, const GLfloat *v)
5685{
5686 return ValidateUniform(context, GL_FLOAT_VEC3, location, count);
5687}
5688
5689bool ValidateUniform3i(ValidationContext *context, GLint location, GLint x, GLint y, GLint z)
5690{
5691 return ValidateUniform(context, GL_INT_VEC3, location, 1);
5692}
5693
5694bool ValidateUniform3iv(ValidationContext *context, GLint location, GLsizei count, const GLint *v)
5695{
5696 return ValidateUniform(context, GL_INT_VEC3, location, count);
5697}
5698
5699bool ValidateUniform4f(ValidationContext *context,
5700 GLint location,
5701 GLfloat x,
5702 GLfloat y,
5703 GLfloat z,
5704 GLfloat w)
5705{
5706 return ValidateUniform(context, GL_FLOAT_VEC4, location, 1);
5707}
5708
5709bool ValidateUniform4fv(ValidationContext *context, GLint location, GLsizei count, const GLfloat *v)
5710{
5711 return ValidateUniform(context, GL_FLOAT_VEC4, location, count);
5712}
5713
5714bool ValidateUniform4i(ValidationContext *context,
5715 GLint location,
5716 GLint x,
5717 GLint y,
5718 GLint z,
5719 GLint w)
5720{
5721 return ValidateUniform(context, GL_INT_VEC4, location, 1);
5722}
5723
5724bool ValidateUniform4iv(ValidationContext *context, GLint location, GLsizei count, const GLint *v)
5725{
5726 return ValidateUniform(context, GL_INT_VEC4, location, count);
5727}
5728
5729bool ValidateUniformMatrix2fv(ValidationContext *context,
5730 GLint location,
5731 GLsizei count,
5732 GLboolean transpose,
5733 const GLfloat *value)
5734{
5735 return ValidateUniformMatrix(context, GL_FLOAT_MAT2, location, count, transpose);
5736}
5737
5738bool ValidateUniformMatrix3fv(ValidationContext *context,
5739 GLint location,
5740 GLsizei count,
5741 GLboolean transpose,
5742 const GLfloat *value)
5743{
5744 return ValidateUniformMatrix(context, GL_FLOAT_MAT3, location, count, transpose);
5745}
5746
5747bool ValidateUniformMatrix4fv(ValidationContext *context,
5748 GLint location,
5749 GLsizei count,
5750 GLboolean transpose,
5751 const GLfloat *value)
5752{
5753 return ValidateUniformMatrix(context, GL_FLOAT_MAT4, location, count, transpose);
5754}
5755
5756bool ValidateValidateProgram(ValidationContext *context, GLuint program)
5757{
5758 Program *programObject = GetValidProgram(context, program);
5759
5760 if (!programObject)
5761 {
5762 return false;
5763 }
5764
5765 return true;
5766}
5767
Jamie Madillc1d770e2017-04-13 17:31:24 -04005768bool ValidateVertexAttrib1f(ValidationContext *context, GLuint index, GLfloat x)
5769{
5770 return ValidateVertexAttribIndex(context, index);
5771}
5772
5773bool ValidateVertexAttrib1fv(ValidationContext *context, GLuint index, const GLfloat *values)
5774{
5775 return ValidateVertexAttribIndex(context, index);
5776}
5777
5778bool ValidateVertexAttrib2f(ValidationContext *context, GLuint index, GLfloat x, GLfloat y)
5779{
5780 return ValidateVertexAttribIndex(context, index);
5781}
5782
5783bool ValidateVertexAttrib2fv(ValidationContext *context, GLuint index, const GLfloat *values)
5784{
5785 return ValidateVertexAttribIndex(context, index);
5786}
5787
5788bool ValidateVertexAttrib3f(ValidationContext *context,
5789 GLuint index,
5790 GLfloat x,
5791 GLfloat y,
5792 GLfloat z)
5793{
5794 return ValidateVertexAttribIndex(context, index);
5795}
5796
5797bool ValidateVertexAttrib3fv(ValidationContext *context, GLuint index, const GLfloat *values)
5798{
5799 return ValidateVertexAttribIndex(context, index);
5800}
5801
5802bool ValidateVertexAttrib4f(ValidationContext *context,
5803 GLuint index,
5804 GLfloat x,
5805 GLfloat y,
5806 GLfloat z,
5807 GLfloat w)
5808{
5809 return ValidateVertexAttribIndex(context, index);
5810}
5811
5812bool ValidateVertexAttrib4fv(ValidationContext *context, GLuint index, const GLfloat *values)
5813{
5814 return ValidateVertexAttribIndex(context, index);
5815}
5816
5817bool ValidateViewport(ValidationContext *context, GLint x, GLint y, GLsizei width, GLsizei height)
5818{
5819 if (width < 0 || height < 0)
5820 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005821 ANGLE_VALIDATION_ERR(context, InvalidValue(), ViewportNegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005822 return false;
5823 }
5824
5825 return true;
5826}
5827
5828bool ValidateDrawArrays(ValidationContext *context, GLenum mode, GLint first, GLsizei count)
5829{
5830 return ValidateDrawArraysCommon(context, mode, first, count, 1);
5831}
5832
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005833bool ValidateDrawElements(ValidationContext *context,
5834 GLenum mode,
5835 GLsizei count,
5836 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04005837 const void *indices)
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005838{
5839 return ValidateDrawElementsCommon(context, mode, count, type, indices, 1);
5840}
5841
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08005842bool ValidateGetFramebufferAttachmentParameteriv(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04005843 GLenum target,
5844 GLenum attachment,
5845 GLenum pname,
5846 GLint *params)
5847{
5848 return ValidateGetFramebufferAttachmentParameterivBase(context, target, attachment, pname,
5849 nullptr);
5850}
5851
5852bool ValidateGetProgramiv(ValidationContext *context, GLuint program, GLenum pname, GLint *params)
5853{
5854 return ValidateGetProgramivBase(context, program, pname, nullptr);
5855}
5856
5857bool ValidateCopyTexImage2D(ValidationContext *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005858 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005859 GLint level,
5860 GLenum internalformat,
5861 GLint x,
5862 GLint y,
5863 GLsizei width,
5864 GLsizei height,
5865 GLint border)
5866{
5867 if (context->getClientMajorVersion() < 3)
5868 {
5869 return ValidateES2CopyTexImageParameters(context, target, level, internalformat, false, 0,
5870 0, x, y, width, height, border);
5871 }
5872
5873 ASSERT(context->getClientMajorVersion() == 3);
5874 return ValidateES3CopyTexImage2DParameters(context, target, level, internalformat, false, 0, 0,
5875 0, x, y, width, height, border);
5876}
5877
5878bool ValidateCopyTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005879 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005880 GLint level,
5881 GLint xoffset,
5882 GLint yoffset,
5883 GLint x,
5884 GLint y,
5885 GLsizei width,
5886 GLsizei height)
5887{
5888 if (context->getClientMajorVersion() < 3)
5889 {
5890 return ValidateES2CopyTexImageParameters(context, target, level, GL_NONE, true, xoffset,
5891 yoffset, x, y, width, height, 0);
5892 }
5893
5894 return ValidateES3CopyTexImage2DParameters(context, target, level, GL_NONE, true, xoffset,
5895 yoffset, 0, x, y, width, height, 0);
5896}
5897
5898bool ValidateDeleteBuffers(Context *context, GLint n, const GLuint *)
5899{
5900 return ValidateGenOrDelete(context, n);
5901}
5902
5903bool ValidateDeleteFramebuffers(Context *context, GLint n, const GLuint *)
5904{
5905 return ValidateGenOrDelete(context, n);
5906}
5907
5908bool ValidateDeleteRenderbuffers(Context *context, GLint n, const GLuint *)
5909{
5910 return ValidateGenOrDelete(context, n);
5911}
5912
5913bool ValidateDeleteTextures(Context *context, GLint n, const GLuint *)
5914{
5915 return ValidateGenOrDelete(context, n);
5916}
5917
5918bool ValidateDisable(Context *context, GLenum cap)
5919{
5920 if (!ValidCap(context, cap, false))
5921 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005922 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005923 return false;
5924 }
5925
5926 return true;
5927}
5928
5929bool ValidateEnable(Context *context, GLenum cap)
5930{
5931 if (!ValidCap(context, cap, false))
5932 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005933 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005934 return false;
5935 }
5936
5937 if (context->getLimitations().noSampleAlphaToCoverageSupport &&
5938 cap == GL_SAMPLE_ALPHA_TO_COVERAGE)
5939 {
5940 const char *errorMessage = "Current renderer doesn't support alpha-to-coverage";
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005941 context->handleError(InvalidOperation() << errorMessage);
Jamie Madillbe849e42017-05-02 15:49:00 -04005942
5943 // We also output an error message to the debugger window if tracing is active, so that
5944 // developers can see the error message.
5945 ERR() << errorMessage;
5946 return false;
5947 }
5948
5949 return true;
5950}
5951
5952bool ValidateFramebufferRenderbuffer(Context *context,
5953 GLenum target,
5954 GLenum attachment,
5955 GLenum renderbuffertarget,
5956 GLuint renderbuffer)
5957{
Geoff Lange8afa902017-09-27 15:00:43 -04005958 if (!ValidFramebufferTarget(context, target))
Jamie Madillbe849e42017-05-02 15:49:00 -04005959 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005960 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
5961 return false;
5962 }
5963
5964 if (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0)
5965 {
5966 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005967 return false;
5968 }
5969
5970 return ValidateFramebufferRenderbufferParameters(context, target, attachment,
5971 renderbuffertarget, renderbuffer);
5972}
5973
5974bool ValidateFramebufferTexture2D(Context *context,
5975 GLenum target,
5976 GLenum attachment,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005977 TextureTarget textarget,
Jamie Madillbe849e42017-05-02 15:49:00 -04005978 GLuint texture,
5979 GLint level)
5980{
5981 // Attachments are required to be bound to level 0 without ES3 or the GL_OES_fbo_render_mipmap
5982 // extension
5983 if (context->getClientMajorVersion() < 3 && !context->getExtensions().fboRenderMipmap &&
5984 level != 0)
5985 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005986 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidFramebufferTextureLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04005987 return false;
5988 }
5989
5990 if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
5991 {
5992 return false;
5993 }
5994
5995 if (texture != 0)
5996 {
5997 gl::Texture *tex = context->getTexture(texture);
5998 ASSERT(tex);
5999
6000 const gl::Caps &caps = context->getCaps();
6001
6002 switch (textarget)
6003 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006004 case TextureTarget::_2D:
Jamie Madillbe849e42017-05-02 15:49:00 -04006005 {
6006 if (level > gl::log2(caps.max2DTextureSize))
6007 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006008 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04006009 return false;
6010 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006011 if (tex->getType() != TextureType::_2D)
Jamie Madillbe849e42017-05-02 15:49:00 -04006012 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006013 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006014 return false;
6015 }
6016 }
6017 break;
6018
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006019 case TextureTarget::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006020 {
6021 if (level != 0)
6022 {
6023 context->handleError(InvalidValue());
6024 return false;
6025 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006026 if (tex->getType() != TextureType::Rectangle)
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006027 {
6028 context->handleError(InvalidOperation()
6029 << "Textarget must match the texture target type.");
6030 return false;
6031 }
6032 }
6033 break;
6034
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006035 case TextureTarget::CubeMapNegativeX:
6036 case TextureTarget::CubeMapNegativeY:
6037 case TextureTarget::CubeMapNegativeZ:
6038 case TextureTarget::CubeMapPositiveX:
6039 case TextureTarget::CubeMapPositiveY:
6040 case TextureTarget::CubeMapPositiveZ:
Jamie Madillbe849e42017-05-02 15:49:00 -04006041 {
6042 if (level > gl::log2(caps.maxCubeMapTextureSize))
6043 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006044 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04006045 return false;
6046 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006047 if (tex->getType() != TextureType::CubeMap)
Jamie Madillbe849e42017-05-02 15:49:00 -04006048 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006049 context->handleError(InvalidOperation()
6050 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006051 return false;
6052 }
6053 }
6054 break;
6055
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006056 case TextureTarget::_2DMultisample:
Jamie Madillbe849e42017-05-02 15:49:00 -04006057 {
6058 if (context->getClientVersion() < ES_3_1)
6059 {
Brandon Jonesafa75152017-07-21 13:11:29 -07006060 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
Jamie Madillbe849e42017-05-02 15:49:00 -04006061 return false;
6062 }
6063
6064 if (level != 0)
6065 {
Brandon Jonesafa75152017-07-21 13:11:29 -07006066 ANGLE_VALIDATION_ERR(context, InvalidValue(), LevelNotZero);
Jamie Madillbe849e42017-05-02 15:49:00 -04006067 return false;
6068 }
Corentin Wallez99d492c2018-02-27 15:17:10 -05006069 if (tex->getType() != TextureType::_2DMultisample)
Jamie Madillbe849e42017-05-02 15:49:00 -04006070 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006071 context->handleError(InvalidOperation()
6072 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006073 return false;
6074 }
6075 }
6076 break;
6077
6078 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07006079 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006080 return false;
6081 }
6082
6083 const Format &format = tex->getFormat(textarget, level);
6084 if (format.info->compressed)
6085 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006086 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -04006087 return false;
6088 }
6089 }
6090
6091 return true;
6092}
6093
6094bool ValidateGenBuffers(Context *context, GLint n, GLuint *)
6095{
6096 return ValidateGenOrDelete(context, n);
6097}
6098
6099bool ValidateGenFramebuffers(Context *context, GLint n, GLuint *)
6100{
6101 return ValidateGenOrDelete(context, n);
6102}
6103
6104bool ValidateGenRenderbuffers(Context *context, GLint n, GLuint *)
6105{
6106 return ValidateGenOrDelete(context, n);
6107}
6108
6109bool ValidateGenTextures(Context *context, GLint n, GLuint *)
6110{
6111 return ValidateGenOrDelete(context, n);
6112}
6113
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006114bool ValidateGenerateMipmap(Context *context, TextureType target)
Jamie Madillbe849e42017-05-02 15:49:00 -04006115{
6116 if (!ValidTextureTarget(context, target))
6117 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006118 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006119 return false;
6120 }
6121
6122 Texture *texture = context->getTargetTexture(target);
6123
6124 if (texture == nullptr)
6125 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006126 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04006127 return false;
6128 }
6129
6130 const GLuint effectiveBaseLevel = texture->getTextureState().getEffectiveBaseLevel();
6131
6132 // This error isn't spelled out in the spec in a very explicit way, but we interpret the spec so
6133 // that out-of-range base level has a non-color-renderable / non-texture-filterable format.
6134 if (effectiveBaseLevel >= gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
6135 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006136 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -04006137 return false;
6138 }
6139
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006140 TextureTarget baseTarget = (target == TextureType::CubeMap)
6141 ? TextureTarget::CubeMapPositiveX
6142 : NonCubeTextureTypeToTarget(target);
Geoff Lang536eca12017-09-13 11:23:35 -04006143 const auto &format = *(texture->getFormat(baseTarget, effectiveBaseLevel).info);
6144 if (format.sizedInternalFormat == GL_NONE || format.compressed || format.depthBits > 0 ||
6145 format.stencilBits > 0)
Brandon Jones6cad5662017-06-14 13:25:13 -07006146 {
6147 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
6148 return false;
6149 }
6150
Geoff Lang536eca12017-09-13 11:23:35 -04006151 // GenerateMipmap accepts formats that are unsized or both color renderable and filterable.
6152 bool formatUnsized = !format.sized;
6153 bool formatColorRenderableAndFilterable =
6154 format.filterSupport(context->getClientVersion(), context->getExtensions()) &&
6155 format.renderSupport(context->getClientVersion(), context->getExtensions());
6156 if (!formatUnsized && !formatColorRenderableAndFilterable)
Jamie Madillbe849e42017-05-02 15:49:00 -04006157 {
Geoff Lang536eca12017-09-13 11:23:35 -04006158 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006159 return false;
6160 }
6161
Geoff Lang536eca12017-09-13 11:23:35 -04006162 // GL_EXT_sRGB adds an unsized SRGB (no alpha) format which has explicitly disabled mipmap
6163 // generation
6164 if (format.colorEncoding == GL_SRGB && format.format == GL_RGB)
6165 {
6166 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
6167 return false;
6168 }
6169
6170 // ES3 and WebGL grant mipmap generation for sRGBA (with alpha) textures but GL_EXT_sRGB does
6171 // not.
Geoff Lang65ac5b92017-05-01 13:16:30 -04006172 bool supportsSRGBMipmapGeneration =
6173 context->getClientVersion() >= ES_3_0 || context->getExtensions().webglCompatibility;
Geoff Lang536eca12017-09-13 11:23:35 -04006174 if (!supportsSRGBMipmapGeneration && format.colorEncoding == GL_SRGB)
Jamie Madillbe849e42017-05-02 15:49:00 -04006175 {
Geoff Lang536eca12017-09-13 11:23:35 -04006176 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006177 return false;
6178 }
6179
6180 // Non-power of 2 ES2 check
6181 if (context->getClientVersion() < Version(3, 0) && !context->getExtensions().textureNPOT &&
6182 (!isPow2(static_cast<int>(texture->getWidth(baseTarget, 0))) ||
6183 !isPow2(static_cast<int>(texture->getHeight(baseTarget, 0)))))
6184 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006185 ASSERT(target == TextureType::_2D || target == TextureType::Rectangle ||
6186 target == TextureType::CubeMap);
Brandon Jones6cad5662017-06-14 13:25:13 -07006187 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotPow2);
Jamie Madillbe849e42017-05-02 15:49:00 -04006188 return false;
6189 }
6190
6191 // Cube completeness check
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006192 if (target == TextureType::CubeMap && !texture->getTextureState().isCubeComplete())
Jamie Madillbe849e42017-05-02 15:49:00 -04006193 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006194 ANGLE_VALIDATION_ERR(context, InvalidOperation(), CubemapIncomplete);
Jamie Madillbe849e42017-05-02 15:49:00 -04006195 return false;
6196 }
6197
6198 return true;
6199}
6200
6201bool ValidateGetBufferParameteriv(ValidationContext *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04006202 BufferBinding target,
Jamie Madillbe849e42017-05-02 15:49:00 -04006203 GLenum pname,
6204 GLint *params)
6205{
6206 return ValidateGetBufferParameterBase(context, target, pname, false, nullptr);
6207}
6208
6209bool ValidateGetRenderbufferParameteriv(Context *context,
6210 GLenum target,
6211 GLenum pname,
6212 GLint *params)
6213{
6214 return ValidateGetRenderbufferParameterivBase(context, target, pname, nullptr);
6215}
6216
6217bool ValidateGetShaderiv(Context *context, GLuint shader, GLenum pname, GLint *params)
6218{
6219 return ValidateGetShaderivBase(context, shader, pname, nullptr);
6220}
6221
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006222bool ValidateGetTexParameterfv(Context *context, TextureType target, GLenum pname, GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006223{
6224 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6225}
6226
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006227bool ValidateGetTexParameteriv(Context *context, TextureType target, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006228{
6229 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6230}
6231
6232bool ValidateGetUniformfv(Context *context, GLuint program, GLint location, GLfloat *params)
6233{
6234 return ValidateGetUniformBase(context, program, location);
6235}
6236
6237bool ValidateGetUniformiv(Context *context, GLuint program, GLint location, GLint *params)
6238{
6239 return ValidateGetUniformBase(context, program, location);
6240}
6241
6242bool ValidateGetVertexAttribfv(Context *context, GLuint index, GLenum pname, GLfloat *params)
6243{
6244 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6245}
6246
6247bool ValidateGetVertexAttribiv(Context *context, GLuint index, GLenum pname, GLint *params)
6248{
6249 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6250}
6251
6252bool ValidateGetVertexAttribPointerv(Context *context, GLuint index, GLenum pname, void **pointer)
6253{
6254 return ValidateGetVertexAttribBase(context, index, pname, nullptr, true, false);
6255}
6256
6257bool ValidateIsEnabled(Context *context, GLenum cap)
6258{
6259 if (!ValidCap(context, cap, true))
6260 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006261 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006262 return false;
6263 }
6264
6265 return true;
6266}
6267
6268bool ValidateLinkProgram(Context *context, GLuint program)
6269{
6270 if (context->hasActiveTransformFeedback(program))
6271 {
6272 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006273 context->handleError(InvalidOperation() << "Cannot link program while program is "
6274 "associated with an active transform "
6275 "feedback object.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006276 return false;
6277 }
6278
6279 Program *programObject = GetValidProgram(context, program);
6280 if (!programObject)
6281 {
6282 return false;
6283 }
6284
6285 return true;
6286}
6287
Jamie Madill4928b7c2017-06-20 12:57:39 -04006288bool ValidateReadPixels(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04006289 GLint x,
6290 GLint y,
6291 GLsizei width,
6292 GLsizei height,
6293 GLenum format,
6294 GLenum type,
6295 void *pixels)
6296{
6297 return ValidateReadPixelsBase(context, x, y, width, height, format, type, -1, nullptr, nullptr,
6298 nullptr, pixels);
6299}
6300
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006301bool ValidateTexParameterf(Context *context, TextureType target, GLenum pname, GLfloat param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006302{
6303 return ValidateTexParameterBase(context, target, pname, -1, &param);
6304}
6305
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006306bool ValidateTexParameterfv(Context *context,
6307 TextureType target,
6308 GLenum pname,
6309 const GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006310{
6311 return ValidateTexParameterBase(context, target, pname, -1, params);
6312}
6313
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006314bool ValidateTexParameteri(Context *context, TextureType target, GLenum pname, GLint param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006315{
6316 return ValidateTexParameterBase(context, target, pname, -1, &param);
6317}
6318
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006319bool ValidateTexParameteriv(Context *context, TextureType target, GLenum pname, const GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006320{
6321 return ValidateTexParameterBase(context, target, pname, -1, params);
6322}
6323
6324bool ValidateUseProgram(Context *context, GLuint program)
6325{
6326 if (program != 0)
6327 {
6328 Program *programObject = context->getProgram(program);
6329 if (!programObject)
6330 {
6331 // ES 3.1.0 section 7.3 page 72
6332 if (context->getShader(program))
6333 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006334 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006335 return false;
6336 }
6337 else
6338 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006339 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006340 return false;
6341 }
6342 }
6343 if (!programObject->isLinked())
6344 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006345 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillbe849e42017-05-02 15:49:00 -04006346 return false;
6347 }
6348 }
6349 if (context->getGLState().isTransformFeedbackActiveUnpaused())
6350 {
6351 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006352 context
6353 ->handleError(InvalidOperation()
6354 << "Cannot change active program while transform feedback is unpaused.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006355 return false;
6356 }
6357
6358 return true;
6359}
6360
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006361bool ValidateDeleteFencesNV(Context *context, GLsizei n, const GLuint *fences)
6362{
6363 if (!context->getExtensions().fence)
6364 {
6365 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6366 return false;
6367 }
6368
6369 if (n < 0)
6370 {
6371 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
6372 return false;
6373 }
6374
6375 return true;
6376}
6377
6378bool ValidateFinishFenceNV(Context *context, GLuint fence)
6379{
6380 if (!context->getExtensions().fence)
6381 {
6382 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6383 return false;
6384 }
6385
6386 FenceNV *fenceObject = context->getFenceNV(fence);
6387
6388 if (fenceObject == nullptr)
6389 {
6390 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6391 return false;
6392 }
6393
6394 if (!fenceObject->isSet())
6395 {
6396 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6397 return false;
6398 }
6399
6400 return true;
6401}
6402
6403bool ValidateGenFencesNV(Context *context, GLsizei n, GLuint *fences)
6404{
6405 if (!context->getExtensions().fence)
6406 {
6407 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6408 return false;
6409 }
6410
6411 if (n < 0)
6412 {
6413 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
6414 return false;
6415 }
6416
6417 return true;
6418}
6419
6420bool ValidateGetFenceivNV(Context *context, GLuint fence, GLenum pname, GLint *params)
6421{
6422 if (!context->getExtensions().fence)
6423 {
6424 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6425 return false;
6426 }
6427
6428 FenceNV *fenceObject = context->getFenceNV(fence);
6429
6430 if (fenceObject == nullptr)
6431 {
6432 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6433 return false;
6434 }
6435
6436 if (!fenceObject->isSet())
6437 {
6438 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6439 return false;
6440 }
6441
6442 switch (pname)
6443 {
6444 case GL_FENCE_STATUS_NV:
6445 case GL_FENCE_CONDITION_NV:
6446 break;
6447
6448 default:
6449 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPname);
6450 return false;
6451 }
6452
6453 return true;
6454}
6455
6456bool ValidateGetGraphicsResetStatusEXT(Context *context)
6457{
6458 if (!context->getExtensions().robustness)
6459 {
6460 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6461 return false;
6462 }
6463
6464 return true;
6465}
6466
6467bool ValidateGetTranslatedShaderSourceANGLE(Context *context,
6468 GLuint shader,
6469 GLsizei bufsize,
6470 GLsizei *length,
6471 GLchar *source)
6472{
6473 if (!context->getExtensions().translatedShaderSource)
6474 {
6475 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6476 return false;
6477 }
6478
6479 if (bufsize < 0)
6480 {
6481 context->handleError(InvalidValue());
6482 return false;
6483 }
6484
6485 Shader *shaderObject = context->getShader(shader);
6486
6487 if (!shaderObject)
6488 {
6489 context->handleError(InvalidOperation());
6490 return false;
6491 }
6492
6493 return true;
6494}
6495
6496bool ValidateIsFenceNV(Context *context, GLuint fence)
6497{
6498 if (!context->getExtensions().fence)
6499 {
6500 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6501 return false;
6502 }
6503
6504 return true;
6505}
6506
Jamie Madill007530e2017-12-28 14:27:04 -05006507bool ValidateSetFenceNV(Context *context, GLuint fence, GLenum condition)
6508{
6509 if (!context->getExtensions().fence)
6510 {
6511 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6512 return false;
6513 }
6514
6515 if (condition != GL_ALL_COMPLETED_NV)
6516 {
6517 context->handleError(InvalidEnum());
6518 return false;
6519 }
6520
6521 FenceNV *fenceObject = context->getFenceNV(fence);
6522
6523 if (fenceObject == nullptr)
6524 {
6525 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6526 return false;
6527 }
6528
6529 return true;
6530}
6531
6532bool ValidateTestFenceNV(Context *context, GLuint fence)
6533{
6534 if (!context->getExtensions().fence)
6535 {
6536 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6537 return false;
6538 }
6539
6540 FenceNV *fenceObject = context->getFenceNV(fence);
6541
6542 if (fenceObject == nullptr)
6543 {
6544 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6545 return false;
6546 }
6547
6548 if (fenceObject->isSet() != GL_TRUE)
6549 {
6550 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6551 return false;
6552 }
6553
6554 return true;
6555}
6556
6557bool ValidateTexStorage2DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006558 TextureType type,
Jamie Madill007530e2017-12-28 14:27:04 -05006559 GLsizei levels,
6560 GLenum internalformat,
6561 GLsizei width,
6562 GLsizei height)
6563{
6564 if (!context->getExtensions().textureStorage)
6565 {
6566 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6567 return false;
6568 }
6569
6570 if (context->getClientMajorVersion() < 3)
6571 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006572 return ValidateES2TexStorageParameters(context, type, levels, internalformat, width,
Jamie Madill007530e2017-12-28 14:27:04 -05006573 height);
6574 }
6575
6576 ASSERT(context->getClientMajorVersion() >= 3);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006577 return ValidateES3TexStorage2DParameters(context, type, levels, internalformat, width, height,
Jamie Madill007530e2017-12-28 14:27:04 -05006578 1);
6579}
6580
6581bool ValidateVertexAttribDivisorANGLE(Context *context, GLuint index, GLuint divisor)
6582{
6583 if (!context->getExtensions().instancedArrays)
6584 {
6585 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6586 return false;
6587 }
6588
6589 if (index >= MAX_VERTEX_ATTRIBS)
6590 {
6591 context->handleError(InvalidValue());
6592 return false;
6593 }
6594
6595 if (context->getLimitations().attributeZeroRequiresZeroDivisorInEXT)
6596 {
6597 if (index == 0 && divisor != 0)
6598 {
6599 const char *errorMessage =
6600 "The current context doesn't support setting a non-zero divisor on the "
6601 "attribute with index zero. "
6602 "Please reorder the attributes in your vertex shader so that attribute zero "
6603 "can have a zero divisor.";
6604 context->handleError(InvalidOperation() << errorMessage);
6605
6606 // We also output an error message to the debugger window if tracing is active, so
6607 // that developers can see the error message.
6608 ERR() << errorMessage;
6609 return false;
6610 }
6611 }
6612
6613 return true;
6614}
6615
6616bool ValidateTexImage3DOES(Context *context,
6617 GLenum target,
6618 GLint level,
6619 GLenum internalformat,
6620 GLsizei width,
6621 GLsizei height,
6622 GLsizei depth,
6623 GLint border,
6624 GLenum format,
6625 GLenum type,
6626 const void *pixels)
6627{
6628 UNIMPLEMENTED(); // FIXME
6629 return false;
6630}
6631
6632bool ValidatePopGroupMarkerEXT(Context *context)
6633{
6634 if (!context->getExtensions().debugMarker)
6635 {
6636 // The debug marker calls should not set error state
6637 // However, it seems reasonable to set an error state if the extension is not enabled
6638 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6639 return false;
6640 }
6641
6642 return true;
6643}
6644
Jamie Madillfa920eb2018-01-04 11:45:50 -05006645bool ValidateTexStorage1DEXT(Context *context,
6646 GLenum target,
6647 GLsizei levels,
6648 GLenum internalformat,
6649 GLsizei width)
6650{
6651 UNIMPLEMENTED();
6652 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6653 return false;
6654}
6655
6656bool ValidateTexStorage3DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006657 TextureType target,
Jamie Madillfa920eb2018-01-04 11:45:50 -05006658 GLsizei levels,
6659 GLenum internalformat,
6660 GLsizei width,
6661 GLsizei height,
6662 GLsizei depth)
6663{
6664 if (!context->getExtensions().textureStorage)
6665 {
6666 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6667 return false;
6668 }
6669
6670 if (context->getClientMajorVersion() < 3)
6671 {
6672 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6673 return false;
6674 }
6675
6676 return ValidateES3TexStorage3DParameters(context, target, levels, internalformat, width, height,
6677 depth);
6678}
6679
Jamie Madillc29968b2016-01-20 11:17:23 -05006680} // namespace gl