blob: bd4d4799e78b8a36ece9184e289eeb42294bcf9a [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,
374 GLsizei height)
375{
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 &&
2456 readColorAttachment->getTextureImageIndex().type == GL_TEXTURE_2D) &&
2457 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 &&
2472 attachment->getTextureImageIndex().type == GL_TEXTURE_2D) &&
2473 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,
Geoff Lang4f0e0032017-05-01 16:04:35 -04003919 sourceHeight))
3920 {
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
Corentin Wallezf0e89be2017-11-08 14:00:32 -08004047 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
4101 if (source->getTarget() != GL_TEXTURE_2D)
4102 {
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
4107 if (source->getWidth(GL_TEXTURE_2D, 0) == 0 || source->getHeight(GL_TEXTURE_2D, 0) == 0)
4108 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004109 context->handleError(InvalidValue() << "Source texture must level 0 defined.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004110 return false;
4111 }
4112
4113 const gl::Format &sourceFormat = source->getFormat(GL_TEXTURE_2D, 0);
4114 if (!sourceFormat.info->compressed)
4115 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004116 context->handleError(InvalidOperation()
4117 << "Source texture must have a compressed internal format.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004118 return false;
4119 }
4120
4121 const gl::Texture *dest = context->getTexture(destId);
4122 if (dest == nullptr)
4123 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004124 context->handleError(InvalidValue()
4125 << "Destination texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004126 return false;
4127 }
4128
4129 if (dest->getTarget() != GL_TEXTURE_2D)
4130 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004131 context->handleError(InvalidValue()
4132 << "Destination texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004133 return false;
4134 }
4135
4136 if (dest->getImmutableFormat())
4137 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004138 context->handleError(InvalidOperation() << "Destination cannot be immutable.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004139 return false;
4140 }
4141
4142 return true;
4143}
4144
Martin Radev4c4c8e72016-08-04 12:25:34 +03004145bool ValidateCreateShader(Context *context, GLenum type)
4146{
4147 switch (type)
4148 {
4149 case GL_VERTEX_SHADER:
4150 case GL_FRAGMENT_SHADER:
4151 break;
Geoff Langeb66a6e2016-10-31 13:06:12 -04004152
Martin Radev4c4c8e72016-08-04 12:25:34 +03004153 case GL_COMPUTE_SHADER:
Geoff Langeb66a6e2016-10-31 13:06:12 -04004154 if (context->getClientVersion() < Version(3, 1))
Martin Radev4c4c8e72016-08-04 12:25:34 +03004155 {
Yunchao Hef0fd87d2017-09-12 04:55:05 +08004156 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
Geoff Langeb66a6e2016-10-31 13:06:12 -04004157 return false;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004158 }
Geoff Langeb66a6e2016-10-31 13:06:12 -04004159 break;
4160
Jiawei Shao89be29a2017-11-06 14:36:45 +08004161 case GL_GEOMETRY_SHADER_EXT:
4162 if (!context->getExtensions().geometryShader)
4163 {
4164 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
4165 return false;
4166 }
4167 break;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004168 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004169 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Martin Radev4c4c8e72016-08-04 12:25:34 +03004170 return false;
4171 }
Jamie Madill29639852016-09-02 15:00:09 -04004172
4173 return true;
4174}
4175
4176bool ValidateBufferData(ValidationContext *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004177 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004178 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004179 const void *data,
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004180 BufferUsage usage)
Jamie Madill29639852016-09-02 15:00:09 -04004181{
4182 if (size < 0)
4183 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004184 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madill29639852016-09-02 15:00:09 -04004185 return false;
4186 }
4187
4188 switch (usage)
4189 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004190 case BufferUsage::StreamDraw:
4191 case BufferUsage::StaticDraw:
4192 case BufferUsage::DynamicDraw:
Jamie Madill29639852016-09-02 15:00:09 -04004193 break;
4194
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004195 case BufferUsage::StreamRead:
4196 case BufferUsage::StaticRead:
4197 case BufferUsage::DynamicRead:
4198 case BufferUsage::StreamCopy:
4199 case BufferUsage::StaticCopy:
4200 case BufferUsage::DynamicCopy:
Jamie Madill29639852016-09-02 15:00:09 -04004201 if (context->getClientMajorVersion() < 3)
4202 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004203 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004204 return false;
4205 }
4206 break;
4207
4208 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004209 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004210 return false;
4211 }
4212
Corentin Walleze4477002017-12-01 14:39:58 -05004213 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004214 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004215 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004216 return false;
4217 }
4218
4219 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4220
4221 if (!buffer)
4222 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004223 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004224 return false;
4225 }
4226
4227 return true;
4228}
4229
4230bool ValidateBufferSubData(ValidationContext *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04004231 BufferBinding target,
Jamie Madill29639852016-09-02 15:00:09 -04004232 GLintptr offset,
4233 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004234 const void *data)
Jamie Madill29639852016-09-02 15:00:09 -04004235{
Brandon Jones6cad5662017-06-14 13:25:13 -07004236 if (size < 0)
Jamie Madill29639852016-09-02 15:00:09 -04004237 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004238 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
4239 return false;
4240 }
4241
4242 if (offset < 0)
4243 {
4244 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Jamie Madill29639852016-09-02 15:00:09 -04004245 return false;
4246 }
4247
Corentin Walleze4477002017-12-01 14:39:58 -05004248 if (!context->isValidBufferBinding(target))
Jamie Madill29639852016-09-02 15:00:09 -04004249 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004250 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004251 return false;
4252 }
4253
4254 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4255
4256 if (!buffer)
4257 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004258 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004259 return false;
4260 }
4261
4262 if (buffer->isMapped())
4263 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004264 context->handleError(InvalidOperation());
Jamie Madill29639852016-09-02 15:00:09 -04004265 return false;
4266 }
4267
4268 // Check for possible overflow of size + offset
4269 angle::CheckedNumeric<size_t> checkedSize(size);
4270 checkedSize += offset;
4271 if (!checkedSize.IsValid())
4272 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004273 context->handleError(OutOfMemory());
Jamie Madill29639852016-09-02 15:00:09 -04004274 return false;
4275 }
4276
4277 if (size + offset > buffer->getSize())
4278 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004279 ANGLE_VALIDATION_ERR(context, InvalidValue(), InsufficientBufferSize);
Jamie Madill29639852016-09-02 15:00:09 -04004280 return false;
4281 }
4282
Martin Radev4c4c8e72016-08-04 12:25:34 +03004283 return true;
4284}
4285
Geoff Lang111a99e2017-10-17 10:58:41 -04004286bool ValidateRequestExtensionANGLE(Context *context, const GLchar *name)
Geoff Langc287ea62016-09-16 14:46:51 -04004287{
Geoff Langc339c4e2016-11-29 10:37:36 -05004288 if (!context->getExtensions().requestExtension)
Geoff Langc287ea62016-09-16 14:46:51 -04004289 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004290 context->handleError(InvalidOperation() << "GL_ANGLE_request_extension is not available.");
Geoff Langc287ea62016-09-16 14:46:51 -04004291 return false;
4292 }
4293
Geoff Lang111a99e2017-10-17 10:58:41 -04004294 if (!context->isExtensionRequestable(name))
Geoff Langc287ea62016-09-16 14:46:51 -04004295 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004296 context->handleError(InvalidOperation() << "Extension " << name << " is not requestable.");
Geoff Langc287ea62016-09-16 14:46:51 -04004297 return false;
4298 }
4299
4300 return true;
4301}
4302
Jamie Madillef300b12016-10-07 15:12:09 -04004303bool ValidateActiveTexture(ValidationContext *context, GLenum texture)
4304{
4305 if (texture < GL_TEXTURE0 ||
4306 texture > GL_TEXTURE0 + context->getCaps().maxCombinedTextureImageUnits - 1)
4307 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004308 context->handleError(InvalidEnum());
Jamie Madillef300b12016-10-07 15:12:09 -04004309 return false;
4310 }
4311
4312 return true;
4313}
4314
4315bool ValidateAttachShader(ValidationContext *context, GLuint program, GLuint shader)
4316{
4317 Program *programObject = GetValidProgram(context, program);
4318 if (!programObject)
4319 {
4320 return false;
4321 }
4322
4323 Shader *shaderObject = GetValidShader(context, shader);
4324 if (!shaderObject)
4325 {
4326 return false;
4327 }
4328
4329 switch (shaderObject->getType())
4330 {
4331 case GL_VERTEX_SHADER:
4332 {
4333 if (programObject->getAttachedVertexShader())
4334 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004335 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
Jamie Madillef300b12016-10-07 15:12:09 -04004336 return false;
4337 }
4338 break;
4339 }
4340 case GL_FRAGMENT_SHADER:
4341 {
4342 if (programObject->getAttachedFragmentShader())
4343 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004344 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
Jamie Madillef300b12016-10-07 15:12:09 -04004345 return false;
4346 }
4347 break;
4348 }
4349 case GL_COMPUTE_SHADER:
4350 {
4351 if (programObject->getAttachedComputeShader())
4352 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004353 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
Jamie Madillef300b12016-10-07 15:12:09 -04004354 return false;
4355 }
4356 break;
4357 }
Jiawei Shao89be29a2017-11-06 14:36:45 +08004358 case GL_GEOMETRY_SHADER_EXT:
4359 {
4360 if (programObject->getAttachedGeometryShader())
4361 {
4362 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
4363 return false;
4364 }
4365 break;
4366 }
Jamie Madillef300b12016-10-07 15:12:09 -04004367 default:
4368 UNREACHABLE();
4369 break;
4370 }
4371
4372 return true;
4373}
4374
Jamie Madill01a80ee2016-11-07 12:06:18 -05004375bool ValidateBindAttribLocation(ValidationContext *context,
4376 GLuint program,
4377 GLuint index,
4378 const GLchar *name)
4379{
4380 if (index >= MAX_VERTEX_ATTRIBS)
4381 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004382 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004383 return false;
4384 }
4385
4386 if (strncmp(name, "gl_", 3) == 0)
4387 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004388 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004389 return false;
4390 }
4391
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004392 if (context->isWebGL())
Geoff Langfc32e8b2017-05-31 14:16:59 -04004393 {
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004394 const size_t length = strlen(name);
4395
4396 if (!IsValidESSLString(name, length))
4397 {
4398 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters
4399 // for shader-related entry points
4400 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
4401 return false;
4402 }
4403
4404 if (!ValidateWebGLNameLength(context, length) || !ValidateWebGLNamePrefix(context, name))
4405 {
4406 return false;
4407 }
Geoff Langfc32e8b2017-05-31 14:16:59 -04004408 }
4409
Jamie Madill01a80ee2016-11-07 12:06:18 -05004410 return GetValidProgram(context, program) != nullptr;
4411}
4412
Corentin Wallez336129f2017-10-17 15:55:40 -04004413bool ValidateBindBuffer(ValidationContext *context, BufferBinding target, GLuint buffer)
Jamie Madill01a80ee2016-11-07 12:06:18 -05004414{
Corentin Walleze4477002017-12-01 14:39:58 -05004415 if (!context->isValidBufferBinding(target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004416 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004417 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004418 return false;
4419 }
4420
4421 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4422 !context->isBufferGenerated(buffer))
4423 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004424 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004425 return false;
4426 }
4427
4428 return true;
4429}
4430
4431bool ValidateBindFramebuffer(ValidationContext *context, GLenum target, GLuint framebuffer)
4432{
Geoff Lange8afa902017-09-27 15:00:43 -04004433 if (!ValidFramebufferTarget(context, target))
Jamie Madill01a80ee2016-11-07 12:06:18 -05004434 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004435 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004436 return false;
4437 }
4438
4439 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4440 !context->isFramebufferGenerated(framebuffer))
4441 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004442 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004443 return false;
4444 }
4445
4446 return true;
4447}
4448
4449bool ValidateBindRenderbuffer(ValidationContext *context, GLenum target, GLuint renderbuffer)
4450{
4451 if (target != GL_RENDERBUFFER)
4452 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004453 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004454 return false;
4455 }
4456
4457 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4458 !context->isRenderbufferGenerated(renderbuffer))
4459 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004460 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004461 return false;
4462 }
4463
4464 return true;
4465}
4466
Geoff Lang50cac572017-09-26 17:37:43 -04004467static bool ValidBlendEquationMode(const ValidationContext *context, GLenum mode)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004468{
4469 switch (mode)
4470 {
4471 case GL_FUNC_ADD:
4472 case GL_FUNC_SUBTRACT:
4473 case GL_FUNC_REVERSE_SUBTRACT:
Geoff Lang50cac572017-09-26 17:37:43 -04004474 return true;
4475
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004476 case GL_MIN:
4477 case GL_MAX:
Geoff Lang50cac572017-09-26 17:37:43 -04004478 return context->getClientVersion() >= ES_3_0 || context->getExtensions().blendMinMax;
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004479
4480 default:
4481 return false;
4482 }
4483}
4484
Jamie Madillc1d770e2017-04-13 17:31:24 -04004485bool ValidateBlendColor(ValidationContext *context,
Jamie Madill876429b2017-04-20 15:46:24 -04004486 GLfloat red,
4487 GLfloat green,
4488 GLfloat blue,
4489 GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004490{
4491 return true;
4492}
4493
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004494bool ValidateBlendEquation(ValidationContext *context, GLenum mode)
4495{
Geoff Lang50cac572017-09-26 17:37:43 -04004496 if (!ValidBlendEquationMode(context, mode))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004497 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004498 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004499 return false;
4500 }
4501
4502 return true;
4503}
4504
4505bool ValidateBlendEquationSeparate(ValidationContext *context, GLenum modeRGB, GLenum modeAlpha)
4506{
Geoff Lang50cac572017-09-26 17:37:43 -04004507 if (!ValidBlendEquationMode(context, modeRGB))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004508 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004509 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004510 return false;
4511 }
4512
Geoff Lang50cac572017-09-26 17:37:43 -04004513 if (!ValidBlendEquationMode(context, modeAlpha))
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004514 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004515 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004516 return false;
4517 }
4518
4519 return true;
4520}
4521
4522bool ValidateBlendFunc(ValidationContext *context, GLenum sfactor, GLenum dfactor)
4523{
4524 return ValidateBlendFuncSeparate(context, sfactor, dfactor, sfactor, dfactor);
4525}
4526
4527static bool ValidSrcBlendFunc(GLenum srcBlend)
4528{
4529 switch (srcBlend)
4530 {
4531 case GL_ZERO:
4532 case GL_ONE:
4533 case GL_SRC_COLOR:
4534 case GL_ONE_MINUS_SRC_COLOR:
4535 case GL_DST_COLOR:
4536 case GL_ONE_MINUS_DST_COLOR:
4537 case GL_SRC_ALPHA:
4538 case GL_ONE_MINUS_SRC_ALPHA:
4539 case GL_DST_ALPHA:
4540 case GL_ONE_MINUS_DST_ALPHA:
4541 case GL_CONSTANT_COLOR:
4542 case GL_ONE_MINUS_CONSTANT_COLOR:
4543 case GL_CONSTANT_ALPHA:
4544 case GL_ONE_MINUS_CONSTANT_ALPHA:
4545 case GL_SRC_ALPHA_SATURATE:
4546 return true;
4547
4548 default:
4549 return false;
4550 }
4551}
4552
4553static bool ValidDstBlendFunc(GLenum dstBlend, GLint contextMajorVersion)
4554{
4555 switch (dstBlend)
4556 {
4557 case GL_ZERO:
4558 case GL_ONE:
4559 case GL_SRC_COLOR:
4560 case GL_ONE_MINUS_SRC_COLOR:
4561 case GL_DST_COLOR:
4562 case GL_ONE_MINUS_DST_COLOR:
4563 case GL_SRC_ALPHA:
4564 case GL_ONE_MINUS_SRC_ALPHA:
4565 case GL_DST_ALPHA:
4566 case GL_ONE_MINUS_DST_ALPHA:
4567 case GL_CONSTANT_COLOR:
4568 case GL_ONE_MINUS_CONSTANT_COLOR:
4569 case GL_CONSTANT_ALPHA:
4570 case GL_ONE_MINUS_CONSTANT_ALPHA:
4571 return true;
4572
4573 case GL_SRC_ALPHA_SATURATE:
4574 return (contextMajorVersion >= 3);
4575
4576 default:
4577 return false;
4578 }
4579}
4580
4581bool ValidateBlendFuncSeparate(ValidationContext *context,
4582 GLenum srcRGB,
4583 GLenum dstRGB,
4584 GLenum srcAlpha,
4585 GLenum dstAlpha)
4586{
4587 if (!ValidSrcBlendFunc(srcRGB))
4588 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004589 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004590 return false;
4591 }
4592
4593 if (!ValidDstBlendFunc(dstRGB, context->getClientMajorVersion()))
4594 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004595 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004596 return false;
4597 }
4598
4599 if (!ValidSrcBlendFunc(srcAlpha))
4600 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004601 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004602 return false;
4603 }
4604
4605 if (!ValidDstBlendFunc(dstAlpha, context->getClientMajorVersion()))
4606 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004607 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004608 return false;
4609 }
4610
Frank Henigman146e8a12017-03-02 23:22:37 -05004611 if (context->getLimitations().noSimultaneousConstantColorAndAlphaBlendFunc ||
4612 context->getExtensions().webglCompatibility)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004613 {
4614 bool constantColorUsed =
4615 (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
4616 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
4617
4618 bool constantAlphaUsed =
4619 (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
4620 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
4621
4622 if (constantColorUsed && constantAlphaUsed)
4623 {
Frank Henigman146e8a12017-03-02 23:22:37 -05004624 const char *msg;
4625 if (context->getExtensions().webglCompatibility)
4626 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004627 msg = kErrorInvalidConstantColor;
Frank Henigman146e8a12017-03-02 23:22:37 -05004628 }
4629 else
4630 {
4631 msg =
4632 "Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and "
4633 "GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR not supported by this "
4634 "implementation.";
4635 ERR() << msg;
4636 }
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004637 context->handleError(InvalidOperation() << msg);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004638 return false;
4639 }
4640 }
4641
4642 return true;
4643}
4644
Geoff Langc339c4e2016-11-29 10:37:36 -05004645bool ValidateGetString(Context *context, GLenum name)
4646{
4647 switch (name)
4648 {
4649 case GL_VENDOR:
4650 case GL_RENDERER:
4651 case GL_VERSION:
4652 case GL_SHADING_LANGUAGE_VERSION:
4653 case GL_EXTENSIONS:
4654 break;
4655
4656 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
4657 if (!context->getExtensions().requestExtension)
4658 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004659 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004660 return false;
4661 }
4662 break;
4663
4664 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07004665 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004666 return false;
4667 }
4668
4669 return true;
4670}
4671
Geoff Lang47c48082016-12-07 15:38:13 -05004672bool ValidateLineWidth(ValidationContext *context, GLfloat width)
4673{
4674 if (width <= 0.0f || isNaN(width))
4675 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004676 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidWidth);
Geoff Lang47c48082016-12-07 15:38:13 -05004677 return false;
4678 }
4679
4680 return true;
4681}
4682
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004683bool ValidateVertexAttribPointer(ValidationContext *context,
4684 GLuint index,
4685 GLint size,
4686 GLenum type,
4687 GLboolean normalized,
4688 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04004689 const void *ptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004690{
Shao80957d92017-02-20 21:25:59 +08004691 if (!ValidateVertexFormatBase(context, index, size, type, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004692 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004693 return false;
4694 }
4695
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004696 if (stride < 0)
4697 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004698 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeStride);
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004699 return false;
4700 }
4701
Shao80957d92017-02-20 21:25:59 +08004702 const Caps &caps = context->getCaps();
4703 if (context->getClientVersion() >= ES_3_1)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004704 {
Shao80957d92017-02-20 21:25:59 +08004705 if (stride > caps.maxVertexAttribStride)
4706 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004707 context->handleError(InvalidValue()
4708 << "stride cannot be greater than MAX_VERTEX_ATTRIB_STRIDE.");
Shao80957d92017-02-20 21:25:59 +08004709 return false;
4710 }
4711
4712 if (index >= caps.maxVertexAttribBindings)
4713 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004714 context->handleError(InvalidValue()
4715 << "index must be smaller than MAX_VERTEX_ATTRIB_BINDINGS.");
Shao80957d92017-02-20 21:25:59 +08004716 return false;
4717 }
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004718 }
4719
4720 // [OpenGL ES 3.0.2] Section 2.8 page 24:
4721 // An INVALID_OPERATION error is generated when a non-zero vertex array object
4722 // is bound, zero is bound to the ARRAY_BUFFER buffer object binding point,
4723 // and the pointer argument is not NULL.
Geoff Langfeb8c682017-02-13 16:07:35 -05004724 bool nullBufferAllowed = context->getGLState().areClientArraysEnabled() &&
4725 context->getGLState().getVertexArray()->id() == 0;
Corentin Wallez336129f2017-10-17 15:55:40 -04004726 if (!nullBufferAllowed && context->getGLState().getTargetBuffer(BufferBinding::Array) == 0 &&
4727 ptr != nullptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004728 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004729 context
4730 ->handleError(InvalidOperation()
4731 << "Client data cannot be used with a non-default vertex array object.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004732 return false;
4733 }
4734
4735 if (context->getExtensions().webglCompatibility)
4736 {
4737 // WebGL 1.0 [Section 6.14] Fixed point support
4738 // The WebGL API does not support the GL_FIXED data type.
4739 if (type == GL_FIXED)
4740 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004741 context->handleError(InvalidEnum() << "GL_FIXED is not supported in WebGL.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004742 return false;
4743 }
4744
Geoff Lang2d62ab72017-03-23 16:54:40 -04004745 if (!ValidateWebGLVertexAttribPointer(context, type, normalized, stride, ptr, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004746 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004747 return false;
4748 }
4749 }
4750
4751 return true;
4752}
4753
Jamie Madill876429b2017-04-20 15:46:24 -04004754bool ValidateDepthRangef(ValidationContext *context, GLfloat zNear, GLfloat zFar)
Frank Henigman6137ddc2017-02-10 18:55:07 -05004755{
4756 if (context->getExtensions().webglCompatibility && zNear > zFar)
4757 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004758 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidDepthRange);
Frank Henigman6137ddc2017-02-10 18:55:07 -05004759 return false;
4760 }
4761
4762 return true;
4763}
4764
Jamie Madille8fb6402017-02-14 17:56:40 -05004765bool ValidateRenderbufferStorage(ValidationContext *context,
4766 GLenum target,
4767 GLenum internalformat,
4768 GLsizei width,
4769 GLsizei height)
4770{
4771 return ValidateRenderbufferStorageParametersBase(context, target, 0, internalformat, width,
4772 height);
4773}
4774
4775bool ValidateRenderbufferStorageMultisampleANGLE(ValidationContext *context,
4776 GLenum target,
4777 GLsizei samples,
4778 GLenum internalformat,
4779 GLsizei width,
4780 GLsizei height)
4781{
4782 if (!context->getExtensions().framebufferMultisample)
4783 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004784 context->handleError(InvalidOperation()
4785 << "GL_ANGLE_framebuffer_multisample not available");
Jamie Madille8fb6402017-02-14 17:56:40 -05004786 return false;
4787 }
4788
4789 // ANGLE_framebuffer_multisample states that the value of samples must be less than or equal
4790 // to MAX_SAMPLES_ANGLE (Context::getCaps().maxSamples) otherwise GL_INVALID_OPERATION is
4791 // generated.
4792 if (static_cast<GLuint>(samples) > context->getCaps().maxSamples)
4793 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004794 context->handleError(InvalidValue());
Jamie Madille8fb6402017-02-14 17:56:40 -05004795 return false;
4796 }
4797
4798 // ANGLE_framebuffer_multisample states GL_OUT_OF_MEMORY is generated on a failure to create
4799 // the specified storage. This is different than ES 3.0 in which a sample number higher
4800 // than the maximum sample number supported by this format generates a GL_INVALID_VALUE.
4801 // The TextureCaps::getMaxSamples method is only guarenteed to be valid when the context is ES3.
4802 if (context->getClientMajorVersion() >= 3)
4803 {
4804 const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
4805 if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
4806 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004807 context->handleError(OutOfMemory());
Jamie Madille8fb6402017-02-14 17:56:40 -05004808 return false;
4809 }
4810 }
4811
4812 return ValidateRenderbufferStorageParametersBase(context, target, samples, internalformat,
4813 width, height);
4814}
4815
Jamie Madillc1d770e2017-04-13 17:31:24 -04004816bool ValidateCheckFramebufferStatus(ValidationContext *context, GLenum target)
4817{
Geoff Lange8afa902017-09-27 15:00:43 -04004818 if (!ValidFramebufferTarget(context, target))
Jamie Madillc1d770e2017-04-13 17:31:24 -04004819 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004820 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004821 return false;
4822 }
4823
4824 return true;
4825}
4826
4827bool ValidateClearColor(ValidationContext *context,
Jamie Madill876429b2017-04-20 15:46:24 -04004828 GLfloat red,
4829 GLfloat green,
4830 GLfloat blue,
4831 GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004832{
4833 return true;
4834}
4835
Jamie Madill876429b2017-04-20 15:46:24 -04004836bool ValidateClearDepthf(ValidationContext *context, GLfloat depth)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004837{
4838 return true;
4839}
4840
4841bool ValidateClearStencil(ValidationContext *context, GLint s)
4842{
4843 return true;
4844}
4845
4846bool ValidateColorMask(ValidationContext *context,
4847 GLboolean red,
4848 GLboolean green,
4849 GLboolean blue,
4850 GLboolean alpha)
4851{
4852 return true;
4853}
4854
4855bool ValidateCompileShader(ValidationContext *context, GLuint shader)
4856{
4857 return true;
4858}
4859
4860bool ValidateCreateProgram(ValidationContext *context)
4861{
4862 return true;
4863}
4864
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004865bool ValidateCullFace(ValidationContext *context, CullFaceMode mode)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004866{
4867 switch (mode)
4868 {
Corentin Wallez2e568cf2017-09-18 17:05:22 -04004869 case CullFaceMode::Front:
4870 case CullFaceMode::Back:
4871 case CullFaceMode::FrontAndBack:
Jamie Madillc1d770e2017-04-13 17:31:24 -04004872 break;
4873
4874 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004875 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCullMode);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004876 return false;
4877 }
4878
4879 return true;
4880}
4881
4882bool ValidateDeleteProgram(ValidationContext *context, GLuint program)
4883{
4884 if (program == 0)
4885 {
4886 return false;
4887 }
4888
4889 if (!context->getProgram(program))
4890 {
4891 if (context->getShader(program))
4892 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004893 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004894 return false;
4895 }
4896 else
4897 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004898 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004899 return false;
4900 }
4901 }
4902
4903 return true;
4904}
4905
4906bool ValidateDeleteShader(ValidationContext *context, GLuint shader)
4907{
4908 if (shader == 0)
4909 {
4910 return false;
4911 }
4912
4913 if (!context->getShader(shader))
4914 {
4915 if (context->getProgram(shader))
4916 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004917 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004918 return false;
4919 }
4920 else
4921 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004922 ANGLE_VALIDATION_ERR(context, InvalidValue(), ExpectedShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004923 return false;
4924 }
4925 }
4926
4927 return true;
4928}
4929
4930bool ValidateDepthFunc(ValidationContext *context, GLenum func)
4931{
4932 switch (func)
4933 {
4934 case GL_NEVER:
4935 case GL_ALWAYS:
4936 case GL_LESS:
4937 case GL_LEQUAL:
4938 case GL_EQUAL:
4939 case GL_GREATER:
4940 case GL_GEQUAL:
4941 case GL_NOTEQUAL:
4942 break;
4943
4944 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004945 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004946 return false;
4947 }
4948
4949 return true;
4950}
4951
4952bool ValidateDepthMask(ValidationContext *context, GLboolean flag)
4953{
4954 return true;
4955}
4956
4957bool ValidateDetachShader(ValidationContext *context, GLuint program, GLuint shader)
4958{
4959 Program *programObject = GetValidProgram(context, program);
4960 if (!programObject)
4961 {
4962 return false;
4963 }
4964
4965 Shader *shaderObject = GetValidShader(context, shader);
4966 if (!shaderObject)
4967 {
4968 return false;
4969 }
4970
4971 const Shader *attachedShader = nullptr;
4972
4973 switch (shaderObject->getType())
4974 {
4975 case GL_VERTEX_SHADER:
4976 {
4977 attachedShader = programObject->getAttachedVertexShader();
4978 break;
4979 }
4980 case GL_FRAGMENT_SHADER:
4981 {
4982 attachedShader = programObject->getAttachedFragmentShader();
4983 break;
4984 }
4985 case GL_COMPUTE_SHADER:
4986 {
4987 attachedShader = programObject->getAttachedComputeShader();
4988 break;
4989 }
Jiawei Shao89be29a2017-11-06 14:36:45 +08004990 case GL_GEOMETRY_SHADER_EXT:
4991 {
4992 attachedShader = programObject->getAttachedGeometryShader();
4993 break;
4994 }
Jamie Madillc1d770e2017-04-13 17:31:24 -04004995 default:
4996 UNREACHABLE();
4997 return false;
4998 }
4999
5000 if (attachedShader != shaderObject)
5001 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005002 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderToDetachMustBeAttached);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005003 return false;
5004 }
5005
5006 return true;
5007}
5008
5009bool ValidateDisableVertexAttribArray(ValidationContext *context, GLuint index)
5010{
5011 if (index >= MAX_VERTEX_ATTRIBS)
5012 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005013 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005014 return false;
5015 }
5016
5017 return true;
5018}
5019
5020bool ValidateEnableVertexAttribArray(ValidationContext *context, GLuint index)
5021{
5022 if (index >= MAX_VERTEX_ATTRIBS)
5023 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005024 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005025 return false;
5026 }
5027
5028 return true;
5029}
5030
5031bool ValidateFinish(ValidationContext *context)
5032{
5033 return true;
5034}
5035
5036bool ValidateFlush(ValidationContext *context)
5037{
5038 return true;
5039}
5040
5041bool ValidateFrontFace(ValidationContext *context, GLenum mode)
5042{
5043 switch (mode)
5044 {
5045 case GL_CW:
5046 case GL_CCW:
5047 break;
5048 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005049 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005050 return false;
5051 }
5052
5053 return true;
5054}
5055
5056bool ValidateGetActiveAttrib(ValidationContext *context,
5057 GLuint program,
5058 GLuint index,
5059 GLsizei bufsize,
5060 GLsizei *length,
5061 GLint *size,
5062 GLenum *type,
5063 GLchar *name)
5064{
5065 if (bufsize < 0)
5066 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005067 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005068 return false;
5069 }
5070
5071 Program *programObject = GetValidProgram(context, program);
5072
5073 if (!programObject)
5074 {
5075 return false;
5076 }
5077
5078 if (index >= static_cast<GLuint>(programObject->getActiveAttributeCount()))
5079 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005080 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005081 return false;
5082 }
5083
5084 return true;
5085}
5086
5087bool ValidateGetActiveUniform(ValidationContext *context,
5088 GLuint program,
5089 GLuint index,
5090 GLsizei bufsize,
5091 GLsizei *length,
5092 GLint *size,
5093 GLenum *type,
5094 GLchar *name)
5095{
5096 if (bufsize < 0)
5097 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005098 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005099 return false;
5100 }
5101
5102 Program *programObject = GetValidProgram(context, program);
5103
5104 if (!programObject)
5105 {
5106 return false;
5107 }
5108
5109 if (index >= static_cast<GLuint>(programObject->getActiveUniformCount()))
5110 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005111 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005112 return false;
5113 }
5114
5115 return true;
5116}
5117
5118bool ValidateGetAttachedShaders(ValidationContext *context,
5119 GLuint program,
5120 GLsizei maxcount,
5121 GLsizei *count,
5122 GLuint *shaders)
5123{
5124 if (maxcount < 0)
5125 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005126 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeMaxCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005127 return false;
5128 }
5129
5130 Program *programObject = GetValidProgram(context, program);
5131
5132 if (!programObject)
5133 {
5134 return false;
5135 }
5136
5137 return true;
5138}
5139
5140bool ValidateGetAttribLocation(ValidationContext *context, GLuint program, const GLchar *name)
5141{
Geoff Langfc32e8b2017-05-31 14:16:59 -04005142 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5143 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005144 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005145 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005146 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005147 return false;
5148 }
5149
Jamie Madillc1d770e2017-04-13 17:31:24 -04005150 Program *programObject = GetValidProgram(context, program);
5151
5152 if (!programObject)
5153 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005154 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005155 return false;
5156 }
5157
5158 if (!programObject->isLinked())
5159 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005160 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005161 return false;
5162 }
5163
5164 return true;
5165}
5166
5167bool ValidateGetBooleanv(ValidationContext *context, GLenum pname, GLboolean *params)
5168{
5169 GLenum nativeType;
5170 unsigned int numParams = 0;
5171 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5172}
5173
5174bool ValidateGetError(ValidationContext *context)
5175{
5176 return true;
5177}
5178
5179bool ValidateGetFloatv(ValidationContext *context, GLenum pname, GLfloat *params)
5180{
5181 GLenum nativeType;
5182 unsigned int numParams = 0;
5183 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5184}
5185
5186bool ValidateGetIntegerv(ValidationContext *context, GLenum pname, GLint *params)
5187{
5188 GLenum nativeType;
5189 unsigned int numParams = 0;
5190 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5191}
5192
5193bool ValidateGetProgramInfoLog(ValidationContext *context,
5194 GLuint program,
5195 GLsizei bufsize,
5196 GLsizei *length,
5197 GLchar *infolog)
5198{
5199 if (bufsize < 0)
5200 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005201 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005202 return false;
5203 }
5204
5205 Program *programObject = GetValidProgram(context, program);
5206 if (!programObject)
5207 {
5208 return false;
5209 }
5210
5211 return true;
5212}
5213
5214bool ValidateGetShaderInfoLog(ValidationContext *context,
5215 GLuint shader,
5216 GLsizei bufsize,
5217 GLsizei *length,
5218 GLchar *infolog)
5219{
5220 if (bufsize < 0)
5221 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005222 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005223 return false;
5224 }
5225
5226 Shader *shaderObject = GetValidShader(context, shader);
5227 if (!shaderObject)
5228 {
5229 return false;
5230 }
5231
5232 return true;
5233}
5234
5235bool ValidateGetShaderPrecisionFormat(ValidationContext *context,
5236 GLenum shadertype,
5237 GLenum precisiontype,
5238 GLint *range,
5239 GLint *precision)
5240{
5241 switch (shadertype)
5242 {
5243 case GL_VERTEX_SHADER:
5244 case GL_FRAGMENT_SHADER:
5245 break;
5246 case GL_COMPUTE_SHADER:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005247 context->handleError(InvalidOperation()
5248 << "compute shader precision not yet implemented.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005249 return false;
5250 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005251 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005252 return false;
5253 }
5254
5255 switch (precisiontype)
5256 {
5257 case GL_LOW_FLOAT:
5258 case GL_MEDIUM_FLOAT:
5259 case GL_HIGH_FLOAT:
5260 case GL_LOW_INT:
5261 case GL_MEDIUM_INT:
5262 case GL_HIGH_INT:
5263 break;
5264
5265 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005266 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPrecision);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005267 return false;
5268 }
5269
5270 return true;
5271}
5272
5273bool ValidateGetShaderSource(ValidationContext *context,
5274 GLuint shader,
5275 GLsizei bufsize,
5276 GLsizei *length,
5277 GLchar *source)
5278{
5279 if (bufsize < 0)
5280 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005281 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005282 return false;
5283 }
5284
5285 Shader *shaderObject = GetValidShader(context, shader);
5286 if (!shaderObject)
5287 {
5288 return false;
5289 }
5290
5291 return true;
5292}
5293
5294bool ValidateGetUniformLocation(ValidationContext *context, GLuint program, const GLchar *name)
5295{
5296 if (strstr(name, "gl_") == name)
5297 {
5298 return false;
5299 }
5300
Geoff Langfc32e8b2017-05-31 14:16:59 -04005301 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5302 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005303 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005304 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005305 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005306 return false;
5307 }
5308
Jamie Madillc1d770e2017-04-13 17:31:24 -04005309 Program *programObject = GetValidProgram(context, program);
5310
5311 if (!programObject)
5312 {
5313 return false;
5314 }
5315
5316 if (!programObject->isLinked())
5317 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005318 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005319 return false;
5320 }
5321
5322 return true;
5323}
5324
5325bool ValidateHint(ValidationContext *context, GLenum target, GLenum mode)
5326{
5327 switch (mode)
5328 {
5329 case GL_FASTEST:
5330 case GL_NICEST:
5331 case GL_DONT_CARE:
5332 break;
5333
5334 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005335 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005336 return false;
5337 }
5338
5339 switch (target)
5340 {
5341 case GL_GENERATE_MIPMAP_HINT:
5342 break;
5343
Geoff Lange7bd2182017-06-16 16:13:13 -04005344 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
5345 if (context->getClientVersion() < ES_3_0 &&
5346 !context->getExtensions().standardDerivatives)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005347 {
Brandon Jones72f58fa2017-09-19 10:47:41 -07005348 context->handleError(InvalidEnum() << "hint requires OES_standard_derivatives.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005349 return false;
5350 }
5351 break;
5352
5353 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005354 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005355 return false;
5356 }
5357
5358 return true;
5359}
5360
5361bool ValidateIsBuffer(ValidationContext *context, GLuint buffer)
5362{
5363 return true;
5364}
5365
5366bool ValidateIsFramebuffer(ValidationContext *context, GLuint framebuffer)
5367{
5368 return true;
5369}
5370
5371bool ValidateIsProgram(ValidationContext *context, GLuint program)
5372{
5373 return true;
5374}
5375
5376bool ValidateIsRenderbuffer(ValidationContext *context, GLuint renderbuffer)
5377{
5378 return true;
5379}
5380
5381bool ValidateIsShader(ValidationContext *context, GLuint shader)
5382{
5383 return true;
5384}
5385
5386bool ValidateIsTexture(ValidationContext *context, GLuint texture)
5387{
5388 return true;
5389}
5390
5391bool ValidatePixelStorei(ValidationContext *context, GLenum pname, GLint param)
5392{
5393 if (context->getClientMajorVersion() < 3)
5394 {
5395 switch (pname)
5396 {
5397 case GL_UNPACK_IMAGE_HEIGHT:
5398 case GL_UNPACK_SKIP_IMAGES:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005399 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005400 return false;
5401
5402 case GL_UNPACK_ROW_LENGTH:
5403 case GL_UNPACK_SKIP_ROWS:
5404 case GL_UNPACK_SKIP_PIXELS:
5405 if (!context->getExtensions().unpackSubimage)
5406 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005407 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005408 return false;
5409 }
5410 break;
5411
5412 case GL_PACK_ROW_LENGTH:
5413 case GL_PACK_SKIP_ROWS:
5414 case GL_PACK_SKIP_PIXELS:
5415 if (!context->getExtensions().packSubimage)
5416 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005417 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005418 return false;
5419 }
5420 break;
5421 }
5422 }
5423
5424 if (param < 0)
5425 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005426 context->handleError(InvalidValue() << "Cannot use negative values in PixelStorei");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005427 return false;
5428 }
5429
5430 switch (pname)
5431 {
5432 case GL_UNPACK_ALIGNMENT:
5433 if (param != 1 && param != 2 && param != 4 && param != 8)
5434 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005435 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005436 return false;
5437 }
5438 break;
5439
5440 case GL_PACK_ALIGNMENT:
5441 if (param != 1 && param != 2 && param != 4 && param != 8)
5442 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005443 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005444 return false;
5445 }
5446 break;
5447
5448 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
Geoff Lang000dab82017-09-27 14:27:07 -04005449 if (!context->getExtensions().packReverseRowOrder)
5450 {
5451 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
5452 }
5453 break;
5454
Jamie Madillc1d770e2017-04-13 17:31:24 -04005455 case GL_UNPACK_ROW_LENGTH:
5456 case GL_UNPACK_IMAGE_HEIGHT:
5457 case GL_UNPACK_SKIP_IMAGES:
5458 case GL_UNPACK_SKIP_ROWS:
5459 case GL_UNPACK_SKIP_PIXELS:
5460 case GL_PACK_ROW_LENGTH:
5461 case GL_PACK_SKIP_ROWS:
5462 case GL_PACK_SKIP_PIXELS:
5463 break;
5464
5465 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005466 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005467 return false;
5468 }
5469
5470 return true;
5471}
5472
5473bool ValidatePolygonOffset(ValidationContext *context, GLfloat factor, GLfloat units)
5474{
5475 return true;
5476}
5477
5478bool ValidateReleaseShaderCompiler(ValidationContext *context)
5479{
5480 return true;
5481}
5482
Jamie Madill876429b2017-04-20 15:46:24 -04005483bool ValidateSampleCoverage(ValidationContext *context, GLfloat value, GLboolean invert)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005484{
5485 return true;
5486}
5487
5488bool ValidateScissor(ValidationContext *context, GLint x, GLint y, GLsizei width, GLsizei height)
5489{
5490 if (width < 0 || height < 0)
5491 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005492 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005493 return false;
5494 }
5495
5496 return true;
5497}
5498
5499bool ValidateShaderBinary(ValidationContext *context,
5500 GLsizei n,
5501 const GLuint *shaders,
5502 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04005503 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005504 GLsizei length)
5505{
5506 const std::vector<GLenum> &shaderBinaryFormats = context->getCaps().shaderBinaryFormats;
5507 if (std::find(shaderBinaryFormats.begin(), shaderBinaryFormats.end(), binaryformat) ==
5508 shaderBinaryFormats.end())
5509 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005510 context->handleError(InvalidEnum() << "Invalid shader binary format.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005511 return false;
5512 }
5513
5514 return true;
5515}
5516
5517bool ValidateShaderSource(ValidationContext *context,
5518 GLuint shader,
5519 GLsizei count,
5520 const GLchar *const *string,
5521 const GLint *length)
5522{
5523 if (count < 0)
5524 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005525 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005526 return false;
5527 }
5528
Geoff Langfc32e8b2017-05-31 14:16:59 -04005529 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5530 // shader-related entry points
5531 if (context->getExtensions().webglCompatibility)
5532 {
5533 for (GLsizei i = 0; i < count; i++)
5534 {
Geoff Langcab92ee2017-07-19 17:32:07 -04005535 size_t len =
5536 (length && length[i] >= 0) ? static_cast<size_t>(length[i]) : strlen(string[i]);
Geoff Langa71a98e2017-06-19 15:15:00 -04005537
5538 // Backslash as line-continuation is allowed in WebGL 2.0.
Geoff Langcab92ee2017-07-19 17:32:07 -04005539 if (!IsValidESSLShaderSourceString(string[i], len,
5540 context->getClientVersion() >= ES_3_0))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005541 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005542 ANGLE_VALIDATION_ERR(context, InvalidValue(), ShaderSourceInvalidCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005543 return false;
5544 }
5545 }
5546 }
5547
Jamie Madillc1d770e2017-04-13 17:31:24 -04005548 Shader *shaderObject = GetValidShader(context, shader);
5549 if (!shaderObject)
5550 {
5551 return false;
5552 }
5553
5554 return true;
5555}
5556
5557bool ValidateStencilFunc(ValidationContext *context, GLenum func, GLint ref, GLuint mask)
5558{
5559 if (!IsValidStencilFunc(func))
5560 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005561 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005562 return false;
5563 }
5564
5565 return true;
5566}
5567
5568bool ValidateStencilFuncSeparate(ValidationContext *context,
5569 GLenum face,
5570 GLenum func,
5571 GLint ref,
5572 GLuint mask)
5573{
5574 if (!IsValidStencilFace(face))
5575 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005576 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005577 return false;
5578 }
5579
5580 if (!IsValidStencilFunc(func))
5581 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005582 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005583 return false;
5584 }
5585
5586 return true;
5587}
5588
5589bool ValidateStencilMask(ValidationContext *context, GLuint mask)
5590{
5591 return true;
5592}
5593
5594bool ValidateStencilMaskSeparate(ValidationContext *context, GLenum face, GLuint mask)
5595{
5596 if (!IsValidStencilFace(face))
5597 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005598 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005599 return false;
5600 }
5601
5602 return true;
5603}
5604
5605bool ValidateStencilOp(ValidationContext *context, GLenum fail, GLenum zfail, GLenum zpass)
5606{
5607 if (!IsValidStencilOp(fail))
5608 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005609 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005610 return false;
5611 }
5612
5613 if (!IsValidStencilOp(zfail))
5614 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005615 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005616 return false;
5617 }
5618
5619 if (!IsValidStencilOp(zpass))
5620 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005621 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005622 return false;
5623 }
5624
5625 return true;
5626}
5627
5628bool ValidateStencilOpSeparate(ValidationContext *context,
5629 GLenum face,
5630 GLenum fail,
5631 GLenum zfail,
5632 GLenum zpass)
5633{
5634 if (!IsValidStencilFace(face))
5635 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005636 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005637 return false;
5638 }
5639
5640 return ValidateStencilOp(context, fail, zfail, zpass);
5641}
5642
5643bool ValidateUniform1f(ValidationContext *context, GLint location, GLfloat x)
5644{
5645 return ValidateUniform(context, GL_FLOAT, location, 1);
5646}
5647
5648bool ValidateUniform1fv(ValidationContext *context, GLint location, GLsizei count, const GLfloat *v)
5649{
5650 return ValidateUniform(context, GL_FLOAT, location, count);
5651}
5652
Jamie Madillbe849e42017-05-02 15:49:00 -04005653bool ValidateUniform1i(ValidationContext *context, GLint location, GLint x)
5654{
5655 return ValidateUniform1iv(context, location, 1, &x);
5656}
5657
Jamie Madillc1d770e2017-04-13 17:31:24 -04005658bool ValidateUniform2f(ValidationContext *context, GLint location, GLfloat x, GLfloat y)
5659{
5660 return ValidateUniform(context, GL_FLOAT_VEC2, location, 1);
5661}
5662
5663bool ValidateUniform2fv(ValidationContext *context, GLint location, GLsizei count, const GLfloat *v)
5664{
5665 return ValidateUniform(context, GL_FLOAT_VEC2, location, count);
5666}
5667
5668bool ValidateUniform2i(ValidationContext *context, GLint location, GLint x, GLint y)
5669{
5670 return ValidateUniform(context, GL_INT_VEC2, location, 1);
5671}
5672
5673bool ValidateUniform2iv(ValidationContext *context, GLint location, GLsizei count, const GLint *v)
5674{
5675 return ValidateUniform(context, GL_INT_VEC2, location, count);
5676}
5677
5678bool ValidateUniform3f(ValidationContext *context, GLint location, GLfloat x, GLfloat y, GLfloat z)
5679{
5680 return ValidateUniform(context, GL_FLOAT_VEC3, location, 1);
5681}
5682
5683bool ValidateUniform3fv(ValidationContext *context, GLint location, GLsizei count, const GLfloat *v)
5684{
5685 return ValidateUniform(context, GL_FLOAT_VEC3, location, count);
5686}
5687
5688bool ValidateUniform3i(ValidationContext *context, GLint location, GLint x, GLint y, GLint z)
5689{
5690 return ValidateUniform(context, GL_INT_VEC3, location, 1);
5691}
5692
5693bool ValidateUniform3iv(ValidationContext *context, GLint location, GLsizei count, const GLint *v)
5694{
5695 return ValidateUniform(context, GL_INT_VEC3, location, count);
5696}
5697
5698bool ValidateUniform4f(ValidationContext *context,
5699 GLint location,
5700 GLfloat x,
5701 GLfloat y,
5702 GLfloat z,
5703 GLfloat w)
5704{
5705 return ValidateUniform(context, GL_FLOAT_VEC4, location, 1);
5706}
5707
5708bool ValidateUniform4fv(ValidationContext *context, GLint location, GLsizei count, const GLfloat *v)
5709{
5710 return ValidateUniform(context, GL_FLOAT_VEC4, location, count);
5711}
5712
5713bool ValidateUniform4i(ValidationContext *context,
5714 GLint location,
5715 GLint x,
5716 GLint y,
5717 GLint z,
5718 GLint w)
5719{
5720 return ValidateUniform(context, GL_INT_VEC4, location, 1);
5721}
5722
5723bool ValidateUniform4iv(ValidationContext *context, GLint location, GLsizei count, const GLint *v)
5724{
5725 return ValidateUniform(context, GL_INT_VEC4, location, count);
5726}
5727
5728bool ValidateUniformMatrix2fv(ValidationContext *context,
5729 GLint location,
5730 GLsizei count,
5731 GLboolean transpose,
5732 const GLfloat *value)
5733{
5734 return ValidateUniformMatrix(context, GL_FLOAT_MAT2, location, count, transpose);
5735}
5736
5737bool ValidateUniformMatrix3fv(ValidationContext *context,
5738 GLint location,
5739 GLsizei count,
5740 GLboolean transpose,
5741 const GLfloat *value)
5742{
5743 return ValidateUniformMatrix(context, GL_FLOAT_MAT3, location, count, transpose);
5744}
5745
5746bool ValidateUniformMatrix4fv(ValidationContext *context,
5747 GLint location,
5748 GLsizei count,
5749 GLboolean transpose,
5750 const GLfloat *value)
5751{
5752 return ValidateUniformMatrix(context, GL_FLOAT_MAT4, location, count, transpose);
5753}
5754
5755bool ValidateValidateProgram(ValidationContext *context, GLuint program)
5756{
5757 Program *programObject = GetValidProgram(context, program);
5758
5759 if (!programObject)
5760 {
5761 return false;
5762 }
5763
5764 return true;
5765}
5766
Jamie Madillc1d770e2017-04-13 17:31:24 -04005767bool ValidateVertexAttrib1f(ValidationContext *context, GLuint index, GLfloat x)
5768{
5769 return ValidateVertexAttribIndex(context, index);
5770}
5771
5772bool ValidateVertexAttrib1fv(ValidationContext *context, GLuint index, const GLfloat *values)
5773{
5774 return ValidateVertexAttribIndex(context, index);
5775}
5776
5777bool ValidateVertexAttrib2f(ValidationContext *context, GLuint index, GLfloat x, GLfloat y)
5778{
5779 return ValidateVertexAttribIndex(context, index);
5780}
5781
5782bool ValidateVertexAttrib2fv(ValidationContext *context, GLuint index, const GLfloat *values)
5783{
5784 return ValidateVertexAttribIndex(context, index);
5785}
5786
5787bool ValidateVertexAttrib3f(ValidationContext *context,
5788 GLuint index,
5789 GLfloat x,
5790 GLfloat y,
5791 GLfloat z)
5792{
5793 return ValidateVertexAttribIndex(context, index);
5794}
5795
5796bool ValidateVertexAttrib3fv(ValidationContext *context, GLuint index, const GLfloat *values)
5797{
5798 return ValidateVertexAttribIndex(context, index);
5799}
5800
5801bool ValidateVertexAttrib4f(ValidationContext *context,
5802 GLuint index,
5803 GLfloat x,
5804 GLfloat y,
5805 GLfloat z,
5806 GLfloat w)
5807{
5808 return ValidateVertexAttribIndex(context, index);
5809}
5810
5811bool ValidateVertexAttrib4fv(ValidationContext *context, GLuint index, const GLfloat *values)
5812{
5813 return ValidateVertexAttribIndex(context, index);
5814}
5815
5816bool ValidateViewport(ValidationContext *context, GLint x, GLint y, GLsizei width, GLsizei height)
5817{
5818 if (width < 0 || height < 0)
5819 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005820 ANGLE_VALIDATION_ERR(context, InvalidValue(), ViewportNegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005821 return false;
5822 }
5823
5824 return true;
5825}
5826
5827bool ValidateDrawArrays(ValidationContext *context, GLenum mode, GLint first, GLsizei count)
5828{
5829 return ValidateDrawArraysCommon(context, mode, first, count, 1);
5830}
5831
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005832bool ValidateDrawElements(ValidationContext *context,
5833 GLenum mode,
5834 GLsizei count,
5835 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04005836 const void *indices)
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005837{
5838 return ValidateDrawElementsCommon(context, mode, count, type, indices, 1);
5839}
5840
Bryan Bernhart (Intel Americas Inc)2eeb1b32017-11-29 16:06:43 -08005841bool ValidateGetFramebufferAttachmentParameteriv(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04005842 GLenum target,
5843 GLenum attachment,
5844 GLenum pname,
5845 GLint *params)
5846{
5847 return ValidateGetFramebufferAttachmentParameterivBase(context, target, attachment, pname,
5848 nullptr);
5849}
5850
5851bool ValidateGetProgramiv(ValidationContext *context, GLuint program, GLenum pname, GLint *params)
5852{
5853 return ValidateGetProgramivBase(context, program, pname, nullptr);
5854}
5855
5856bool ValidateCopyTexImage2D(ValidationContext *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005857 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005858 GLint level,
5859 GLenum internalformat,
5860 GLint x,
5861 GLint y,
5862 GLsizei width,
5863 GLsizei height,
5864 GLint border)
5865{
5866 if (context->getClientMajorVersion() < 3)
5867 {
5868 return ValidateES2CopyTexImageParameters(context, target, level, internalformat, false, 0,
5869 0, x, y, width, height, border);
5870 }
5871
5872 ASSERT(context->getClientMajorVersion() == 3);
5873 return ValidateES3CopyTexImage2DParameters(context, target, level, internalformat, false, 0, 0,
5874 0, x, y, width, height, border);
5875}
5876
5877bool ValidateCopyTexSubImage2D(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005878 TextureTarget target,
Jamie Madillbe849e42017-05-02 15:49:00 -04005879 GLint level,
5880 GLint xoffset,
5881 GLint yoffset,
5882 GLint x,
5883 GLint y,
5884 GLsizei width,
5885 GLsizei height)
5886{
5887 if (context->getClientMajorVersion() < 3)
5888 {
5889 return ValidateES2CopyTexImageParameters(context, target, level, GL_NONE, true, xoffset,
5890 yoffset, x, y, width, height, 0);
5891 }
5892
5893 return ValidateES3CopyTexImage2DParameters(context, target, level, GL_NONE, true, xoffset,
5894 yoffset, 0, x, y, width, height, 0);
5895}
5896
5897bool ValidateDeleteBuffers(Context *context, GLint n, const GLuint *)
5898{
5899 return ValidateGenOrDelete(context, n);
5900}
5901
5902bool ValidateDeleteFramebuffers(Context *context, GLint n, const GLuint *)
5903{
5904 return ValidateGenOrDelete(context, n);
5905}
5906
5907bool ValidateDeleteRenderbuffers(Context *context, GLint n, const GLuint *)
5908{
5909 return ValidateGenOrDelete(context, n);
5910}
5911
5912bool ValidateDeleteTextures(Context *context, GLint n, const GLuint *)
5913{
5914 return ValidateGenOrDelete(context, n);
5915}
5916
5917bool ValidateDisable(Context *context, GLenum cap)
5918{
5919 if (!ValidCap(context, cap, false))
5920 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005921 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005922 return false;
5923 }
5924
5925 return true;
5926}
5927
5928bool ValidateEnable(Context *context, GLenum cap)
5929{
5930 if (!ValidCap(context, cap, false))
5931 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005932 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005933 return false;
5934 }
5935
5936 if (context->getLimitations().noSampleAlphaToCoverageSupport &&
5937 cap == GL_SAMPLE_ALPHA_TO_COVERAGE)
5938 {
5939 const char *errorMessage = "Current renderer doesn't support alpha-to-coverage";
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005940 context->handleError(InvalidOperation() << errorMessage);
Jamie Madillbe849e42017-05-02 15:49:00 -04005941
5942 // We also output an error message to the debugger window if tracing is active, so that
5943 // developers can see the error message.
5944 ERR() << errorMessage;
5945 return false;
5946 }
5947
5948 return true;
5949}
5950
5951bool ValidateFramebufferRenderbuffer(Context *context,
5952 GLenum target,
5953 GLenum attachment,
5954 GLenum renderbuffertarget,
5955 GLuint renderbuffer)
5956{
Geoff Lange8afa902017-09-27 15:00:43 -04005957 if (!ValidFramebufferTarget(context, target))
Jamie Madillbe849e42017-05-02 15:49:00 -04005958 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005959 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
5960 return false;
5961 }
5962
5963 if (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0)
5964 {
5965 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005966 return false;
5967 }
5968
5969 return ValidateFramebufferRenderbufferParameters(context, target, attachment,
5970 renderbuffertarget, renderbuffer);
5971}
5972
5973bool ValidateFramebufferTexture2D(Context *context,
5974 GLenum target,
5975 GLenum attachment,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08005976 TextureTarget textarget,
Jamie Madillbe849e42017-05-02 15:49:00 -04005977 GLuint texture,
5978 GLint level)
5979{
5980 // Attachments are required to be bound to level 0 without ES3 or the GL_OES_fbo_render_mipmap
5981 // extension
5982 if (context->getClientMajorVersion() < 3 && !context->getExtensions().fboRenderMipmap &&
5983 level != 0)
5984 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005985 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidFramebufferTextureLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04005986 return false;
5987 }
5988
5989 if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
5990 {
5991 return false;
5992 }
5993
5994 if (texture != 0)
5995 {
5996 gl::Texture *tex = context->getTexture(texture);
5997 ASSERT(tex);
5998
5999 const gl::Caps &caps = context->getCaps();
6000
6001 switch (textarget)
6002 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006003 case TextureTarget::_2D:
Jamie Madillbe849e42017-05-02 15:49:00 -04006004 {
6005 if (level > gl::log2(caps.max2DTextureSize))
6006 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006007 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04006008 return false;
6009 }
6010 if (tex->getTarget() != GL_TEXTURE_2D)
6011 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006012 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006013 return false;
6014 }
6015 }
6016 break;
6017
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006018 case TextureTarget::Rectangle:
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006019 {
6020 if (level != 0)
6021 {
6022 context->handleError(InvalidValue());
6023 return false;
6024 }
6025 if (tex->getTarget() != GL_TEXTURE_RECTANGLE_ANGLE)
6026 {
6027 context->handleError(InvalidOperation()
6028 << "Textarget must match the texture target type.");
6029 return false;
6030 }
6031 }
6032 break;
6033
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006034 case TextureTarget::CubeMapNegativeX:
6035 case TextureTarget::CubeMapNegativeY:
6036 case TextureTarget::CubeMapNegativeZ:
6037 case TextureTarget::CubeMapPositiveX:
6038 case TextureTarget::CubeMapPositiveY:
6039 case TextureTarget::CubeMapPositiveZ:
Jamie Madillbe849e42017-05-02 15:49:00 -04006040 {
6041 if (level > gl::log2(caps.maxCubeMapTextureSize))
6042 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006043 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04006044 return false;
6045 }
6046 if (tex->getTarget() != GL_TEXTURE_CUBE_MAP)
6047 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006048 context->handleError(InvalidOperation()
6049 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006050 return false;
6051 }
6052 }
6053 break;
6054
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006055 case TextureTarget::_2DMultisample:
Jamie Madillbe849e42017-05-02 15:49:00 -04006056 {
6057 if (context->getClientVersion() < ES_3_1)
6058 {
Brandon Jonesafa75152017-07-21 13:11:29 -07006059 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
Jamie Madillbe849e42017-05-02 15:49:00 -04006060 return false;
6061 }
6062
6063 if (level != 0)
6064 {
Brandon Jonesafa75152017-07-21 13:11:29 -07006065 ANGLE_VALIDATION_ERR(context, InvalidValue(), LevelNotZero);
Jamie Madillbe849e42017-05-02 15:49:00 -04006066 return false;
6067 }
6068 if (tex->getTarget() != GL_TEXTURE_2D_MULTISAMPLE)
6069 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006070 context->handleError(InvalidOperation()
6071 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006072 return false;
6073 }
6074 }
6075 break;
6076
6077 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07006078 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006079 return false;
6080 }
6081
6082 const Format &format = tex->getFormat(textarget, level);
6083 if (format.info->compressed)
6084 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006085 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -04006086 return false;
6087 }
6088 }
6089
6090 return true;
6091}
6092
6093bool ValidateGenBuffers(Context *context, GLint n, GLuint *)
6094{
6095 return ValidateGenOrDelete(context, n);
6096}
6097
6098bool ValidateGenFramebuffers(Context *context, GLint n, GLuint *)
6099{
6100 return ValidateGenOrDelete(context, n);
6101}
6102
6103bool ValidateGenRenderbuffers(Context *context, GLint n, GLuint *)
6104{
6105 return ValidateGenOrDelete(context, n);
6106}
6107
6108bool ValidateGenTextures(Context *context, GLint n, GLuint *)
6109{
6110 return ValidateGenOrDelete(context, n);
6111}
6112
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006113bool ValidateGenerateMipmap(Context *context, TextureType target)
Jamie Madillbe849e42017-05-02 15:49:00 -04006114{
6115 if (!ValidTextureTarget(context, target))
6116 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006117 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006118 return false;
6119 }
6120
6121 Texture *texture = context->getTargetTexture(target);
6122
6123 if (texture == nullptr)
6124 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006125 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04006126 return false;
6127 }
6128
6129 const GLuint effectiveBaseLevel = texture->getTextureState().getEffectiveBaseLevel();
6130
6131 // This error isn't spelled out in the spec in a very explicit way, but we interpret the spec so
6132 // that out-of-range base level has a non-color-renderable / non-texture-filterable format.
6133 if (effectiveBaseLevel >= gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
6134 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006135 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -04006136 return false;
6137 }
6138
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006139 TextureTarget baseTarget = (target == TextureType::CubeMap)
6140 ? TextureTarget::CubeMapPositiveX
6141 : NonCubeTextureTypeToTarget(target);
Geoff Lang536eca12017-09-13 11:23:35 -04006142 const auto &format = *(texture->getFormat(baseTarget, effectiveBaseLevel).info);
6143 if (format.sizedInternalFormat == GL_NONE || format.compressed || format.depthBits > 0 ||
6144 format.stencilBits > 0)
Brandon Jones6cad5662017-06-14 13:25:13 -07006145 {
6146 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
6147 return false;
6148 }
6149
Geoff Lang536eca12017-09-13 11:23:35 -04006150 // GenerateMipmap accepts formats that are unsized or both color renderable and filterable.
6151 bool formatUnsized = !format.sized;
6152 bool formatColorRenderableAndFilterable =
6153 format.filterSupport(context->getClientVersion(), context->getExtensions()) &&
6154 format.renderSupport(context->getClientVersion(), context->getExtensions());
6155 if (!formatUnsized && !formatColorRenderableAndFilterable)
Jamie Madillbe849e42017-05-02 15:49:00 -04006156 {
Geoff Lang536eca12017-09-13 11:23:35 -04006157 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006158 return false;
6159 }
6160
Geoff Lang536eca12017-09-13 11:23:35 -04006161 // GL_EXT_sRGB adds an unsized SRGB (no alpha) format which has explicitly disabled mipmap
6162 // generation
6163 if (format.colorEncoding == GL_SRGB && format.format == GL_RGB)
6164 {
6165 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
6166 return false;
6167 }
6168
6169 // ES3 and WebGL grant mipmap generation for sRGBA (with alpha) textures but GL_EXT_sRGB does
6170 // not.
Geoff Lang65ac5b92017-05-01 13:16:30 -04006171 bool supportsSRGBMipmapGeneration =
6172 context->getClientVersion() >= ES_3_0 || context->getExtensions().webglCompatibility;
Geoff Lang536eca12017-09-13 11:23:35 -04006173 if (!supportsSRGBMipmapGeneration && format.colorEncoding == GL_SRGB)
Jamie Madillbe849e42017-05-02 15:49:00 -04006174 {
Geoff Lang536eca12017-09-13 11:23:35 -04006175 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
Jamie Madillbe849e42017-05-02 15:49:00 -04006176 return false;
6177 }
6178
6179 // Non-power of 2 ES2 check
6180 if (context->getClientVersion() < Version(3, 0) && !context->getExtensions().textureNPOT &&
6181 (!isPow2(static_cast<int>(texture->getWidth(baseTarget, 0))) ||
6182 !isPow2(static_cast<int>(texture->getHeight(baseTarget, 0)))))
6183 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006184 ASSERT(target == TextureType::_2D || target == TextureType::Rectangle ||
6185 target == TextureType::CubeMap);
Brandon Jones6cad5662017-06-14 13:25:13 -07006186 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotPow2);
Jamie Madillbe849e42017-05-02 15:49:00 -04006187 return false;
6188 }
6189
6190 // Cube completeness check
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006191 if (target == TextureType::CubeMap && !texture->getTextureState().isCubeComplete())
Jamie Madillbe849e42017-05-02 15:49:00 -04006192 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006193 ANGLE_VALIDATION_ERR(context, InvalidOperation(), CubemapIncomplete);
Jamie Madillbe849e42017-05-02 15:49:00 -04006194 return false;
6195 }
6196
6197 return true;
6198}
6199
6200bool ValidateGetBufferParameteriv(ValidationContext *context,
Corentin Wallez336129f2017-10-17 15:55:40 -04006201 BufferBinding target,
Jamie Madillbe849e42017-05-02 15:49:00 -04006202 GLenum pname,
6203 GLint *params)
6204{
6205 return ValidateGetBufferParameterBase(context, target, pname, false, nullptr);
6206}
6207
6208bool ValidateGetRenderbufferParameteriv(Context *context,
6209 GLenum target,
6210 GLenum pname,
6211 GLint *params)
6212{
6213 return ValidateGetRenderbufferParameterivBase(context, target, pname, nullptr);
6214}
6215
6216bool ValidateGetShaderiv(Context *context, GLuint shader, GLenum pname, GLint *params)
6217{
6218 return ValidateGetShaderivBase(context, shader, pname, nullptr);
6219}
6220
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006221bool ValidateGetTexParameterfv(Context *context, TextureType target, GLenum pname, GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006222{
6223 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6224}
6225
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006226bool ValidateGetTexParameteriv(Context *context, TextureType target, GLenum pname, GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006227{
6228 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6229}
6230
6231bool ValidateGetUniformfv(Context *context, GLuint program, GLint location, GLfloat *params)
6232{
6233 return ValidateGetUniformBase(context, program, location);
6234}
6235
6236bool ValidateGetUniformiv(Context *context, GLuint program, GLint location, GLint *params)
6237{
6238 return ValidateGetUniformBase(context, program, location);
6239}
6240
6241bool ValidateGetVertexAttribfv(Context *context, GLuint index, GLenum pname, GLfloat *params)
6242{
6243 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6244}
6245
6246bool ValidateGetVertexAttribiv(Context *context, GLuint index, GLenum pname, GLint *params)
6247{
6248 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6249}
6250
6251bool ValidateGetVertexAttribPointerv(Context *context, GLuint index, GLenum pname, void **pointer)
6252{
6253 return ValidateGetVertexAttribBase(context, index, pname, nullptr, true, false);
6254}
6255
6256bool ValidateIsEnabled(Context *context, GLenum cap)
6257{
6258 if (!ValidCap(context, cap, true))
6259 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006260 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006261 return false;
6262 }
6263
6264 return true;
6265}
6266
6267bool ValidateLinkProgram(Context *context, GLuint program)
6268{
6269 if (context->hasActiveTransformFeedback(program))
6270 {
6271 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006272 context->handleError(InvalidOperation() << "Cannot link program while program is "
6273 "associated with an active transform "
6274 "feedback object.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006275 return false;
6276 }
6277
6278 Program *programObject = GetValidProgram(context, program);
6279 if (!programObject)
6280 {
6281 return false;
6282 }
6283
6284 return true;
6285}
6286
Jamie Madill4928b7c2017-06-20 12:57:39 -04006287bool ValidateReadPixels(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04006288 GLint x,
6289 GLint y,
6290 GLsizei width,
6291 GLsizei height,
6292 GLenum format,
6293 GLenum type,
6294 void *pixels)
6295{
6296 return ValidateReadPixelsBase(context, x, y, width, height, format, type, -1, nullptr, nullptr,
6297 nullptr, pixels);
6298}
6299
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006300bool ValidateTexParameterf(Context *context, TextureType target, GLenum pname, GLfloat param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006301{
6302 return ValidateTexParameterBase(context, target, pname, -1, &param);
6303}
6304
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006305bool ValidateTexParameterfv(Context *context,
6306 TextureType target,
6307 GLenum pname,
6308 const GLfloat *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006309{
6310 return ValidateTexParameterBase(context, target, pname, -1, params);
6311}
6312
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006313bool ValidateTexParameteri(Context *context, TextureType target, GLenum pname, GLint param)
Jamie Madillbe849e42017-05-02 15:49:00 -04006314{
6315 return ValidateTexParameterBase(context, target, pname, -1, &param);
6316}
6317
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006318bool ValidateTexParameteriv(Context *context, TextureType target, GLenum pname, const GLint *params)
Jamie Madillbe849e42017-05-02 15:49:00 -04006319{
6320 return ValidateTexParameterBase(context, target, pname, -1, params);
6321}
6322
6323bool ValidateUseProgram(Context *context, GLuint program)
6324{
6325 if (program != 0)
6326 {
6327 Program *programObject = context->getProgram(program);
6328 if (!programObject)
6329 {
6330 // ES 3.1.0 section 7.3 page 72
6331 if (context->getShader(program))
6332 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006333 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006334 return false;
6335 }
6336 else
6337 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006338 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006339 return false;
6340 }
6341 }
6342 if (!programObject->isLinked())
6343 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006344 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillbe849e42017-05-02 15:49:00 -04006345 return false;
6346 }
6347 }
6348 if (context->getGLState().isTransformFeedbackActiveUnpaused())
6349 {
6350 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006351 context
6352 ->handleError(InvalidOperation()
6353 << "Cannot change active program while transform feedback is unpaused.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006354 return false;
6355 }
6356
6357 return true;
6358}
6359
Jamie Madill2b7bbc22017-12-21 17:30:38 -05006360bool ValidateDeleteFencesNV(Context *context, GLsizei n, const GLuint *fences)
6361{
6362 if (!context->getExtensions().fence)
6363 {
6364 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6365 return false;
6366 }
6367
6368 if (n < 0)
6369 {
6370 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
6371 return false;
6372 }
6373
6374 return true;
6375}
6376
6377bool ValidateFinishFenceNV(Context *context, GLuint fence)
6378{
6379 if (!context->getExtensions().fence)
6380 {
6381 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6382 return false;
6383 }
6384
6385 FenceNV *fenceObject = context->getFenceNV(fence);
6386
6387 if (fenceObject == nullptr)
6388 {
6389 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6390 return false;
6391 }
6392
6393 if (!fenceObject->isSet())
6394 {
6395 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6396 return false;
6397 }
6398
6399 return true;
6400}
6401
6402bool ValidateGenFencesNV(Context *context, GLsizei n, GLuint *fences)
6403{
6404 if (!context->getExtensions().fence)
6405 {
6406 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6407 return false;
6408 }
6409
6410 if (n < 0)
6411 {
6412 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
6413 return false;
6414 }
6415
6416 return true;
6417}
6418
6419bool ValidateGetFenceivNV(Context *context, GLuint fence, GLenum pname, GLint *params)
6420{
6421 if (!context->getExtensions().fence)
6422 {
6423 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6424 return false;
6425 }
6426
6427 FenceNV *fenceObject = context->getFenceNV(fence);
6428
6429 if (fenceObject == nullptr)
6430 {
6431 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6432 return false;
6433 }
6434
6435 if (!fenceObject->isSet())
6436 {
6437 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6438 return false;
6439 }
6440
6441 switch (pname)
6442 {
6443 case GL_FENCE_STATUS_NV:
6444 case GL_FENCE_CONDITION_NV:
6445 break;
6446
6447 default:
6448 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPname);
6449 return false;
6450 }
6451
6452 return true;
6453}
6454
6455bool ValidateGetGraphicsResetStatusEXT(Context *context)
6456{
6457 if (!context->getExtensions().robustness)
6458 {
6459 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6460 return false;
6461 }
6462
6463 return true;
6464}
6465
6466bool ValidateGetTranslatedShaderSourceANGLE(Context *context,
6467 GLuint shader,
6468 GLsizei bufsize,
6469 GLsizei *length,
6470 GLchar *source)
6471{
6472 if (!context->getExtensions().translatedShaderSource)
6473 {
6474 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6475 return false;
6476 }
6477
6478 if (bufsize < 0)
6479 {
6480 context->handleError(InvalidValue());
6481 return false;
6482 }
6483
6484 Shader *shaderObject = context->getShader(shader);
6485
6486 if (!shaderObject)
6487 {
6488 context->handleError(InvalidOperation());
6489 return false;
6490 }
6491
6492 return true;
6493}
6494
6495bool ValidateIsFenceNV(Context *context, GLuint fence)
6496{
6497 if (!context->getExtensions().fence)
6498 {
6499 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6500 return false;
6501 }
6502
6503 return true;
6504}
6505
Jamie Madill007530e2017-12-28 14:27:04 -05006506bool ValidateSetFenceNV(Context *context, GLuint fence, GLenum condition)
6507{
6508 if (!context->getExtensions().fence)
6509 {
6510 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6511 return false;
6512 }
6513
6514 if (condition != GL_ALL_COMPLETED_NV)
6515 {
6516 context->handleError(InvalidEnum());
6517 return false;
6518 }
6519
6520 FenceNV *fenceObject = context->getFenceNV(fence);
6521
6522 if (fenceObject == nullptr)
6523 {
6524 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6525 return false;
6526 }
6527
6528 return true;
6529}
6530
6531bool ValidateTestFenceNV(Context *context, GLuint fence)
6532{
6533 if (!context->getExtensions().fence)
6534 {
6535 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NVFenceNotSupported);
6536 return false;
6537 }
6538
6539 FenceNV *fenceObject = context->getFenceNV(fence);
6540
6541 if (fenceObject == nullptr)
6542 {
6543 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFence);
6544 return false;
6545 }
6546
6547 if (fenceObject->isSet() != GL_TRUE)
6548 {
6549 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFenceState);
6550 return false;
6551 }
6552
6553 return true;
6554}
6555
6556bool ValidateTexStorage2DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006557 TextureType type,
Jamie Madill007530e2017-12-28 14:27:04 -05006558 GLsizei levels,
6559 GLenum internalformat,
6560 GLsizei width,
6561 GLsizei height)
6562{
6563 if (!context->getExtensions().textureStorage)
6564 {
6565 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6566 return false;
6567 }
6568
6569 if (context->getClientMajorVersion() < 3)
6570 {
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006571 return ValidateES2TexStorageParameters(context, type, levels, internalformat, width,
Jamie Madill007530e2017-12-28 14:27:04 -05006572 height);
6573 }
6574
6575 ASSERT(context->getClientMajorVersion() >= 3);
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006576 return ValidateES3TexStorage2DParameters(context, type, levels, internalformat, width, height,
Jamie Madill007530e2017-12-28 14:27:04 -05006577 1);
6578}
6579
6580bool ValidateVertexAttribDivisorANGLE(Context *context, GLuint index, GLuint divisor)
6581{
6582 if (!context->getExtensions().instancedArrays)
6583 {
6584 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6585 return false;
6586 }
6587
6588 if (index >= MAX_VERTEX_ATTRIBS)
6589 {
6590 context->handleError(InvalidValue());
6591 return false;
6592 }
6593
6594 if (context->getLimitations().attributeZeroRequiresZeroDivisorInEXT)
6595 {
6596 if (index == 0 && divisor != 0)
6597 {
6598 const char *errorMessage =
6599 "The current context doesn't support setting a non-zero divisor on the "
6600 "attribute with index zero. "
6601 "Please reorder the attributes in your vertex shader so that attribute zero "
6602 "can have a zero divisor.";
6603 context->handleError(InvalidOperation() << errorMessage);
6604
6605 // We also output an error message to the debugger window if tracing is active, so
6606 // that developers can see the error message.
6607 ERR() << errorMessage;
6608 return false;
6609 }
6610 }
6611
6612 return true;
6613}
6614
6615bool ValidateTexImage3DOES(Context *context,
6616 GLenum target,
6617 GLint level,
6618 GLenum internalformat,
6619 GLsizei width,
6620 GLsizei height,
6621 GLsizei depth,
6622 GLint border,
6623 GLenum format,
6624 GLenum type,
6625 const void *pixels)
6626{
6627 UNIMPLEMENTED(); // FIXME
6628 return false;
6629}
6630
6631bool ValidatePopGroupMarkerEXT(Context *context)
6632{
6633 if (!context->getExtensions().debugMarker)
6634 {
6635 // The debug marker calls should not set error state
6636 // However, it seems reasonable to set an error state if the extension is not enabled
6637 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6638 return false;
6639 }
6640
6641 return true;
6642}
6643
Jamie Madillfa920eb2018-01-04 11:45:50 -05006644bool ValidateTexStorage1DEXT(Context *context,
6645 GLenum target,
6646 GLsizei levels,
6647 GLenum internalformat,
6648 GLsizei width)
6649{
6650 UNIMPLEMENTED();
6651 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6652 return false;
6653}
6654
6655bool ValidateTexStorage3DEXT(Context *context,
Corentin Wallezf0e89be2017-11-08 14:00:32 -08006656 TextureType target,
Jamie Madillfa920eb2018-01-04 11:45:50 -05006657 GLsizei levels,
6658 GLenum internalformat,
6659 GLsizei width,
6660 GLsizei height,
6661 GLsizei depth)
6662{
6663 if (!context->getExtensions().textureStorage)
6664 {
6665 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6666 return false;
6667 }
6668
6669 if (context->getClientMajorVersion() < 3)
6670 {
6671 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
6672 return false;
6673 }
6674
6675 return ValidateES3TexStorage3DParameters(context, target, levels, internalformat, width, height,
6676 depth);
6677}
6678
Jamie Madillc29968b2016-01-20 11:17:23 -05006679} // namespace gl