blob: 10209334c994f8f0cda9c32d0c308849c780ca30 [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 Madillef300b12016-10-07 15:12:09 -040018#include "libANGLE/Framebuffer.h"
19#include "libANGLE/FramebufferAttachment.h"
20#include "libANGLE/Renderbuffer.h"
21#include "libANGLE/Shader.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040022#include "libANGLE/Texture.h"
Jamie Madillef300b12016-10-07 15:12:09 -040023#include "libANGLE/Uniform.h"
Jamie Madill231c7f52017-04-26 13:45:37 -040024#include "libANGLE/VertexArray.h"
Jamie Madillef300b12016-10-07 15:12:09 -040025#include "libANGLE/formatutils.h"
26#include "libANGLE/validationES.h"
27#include "libANGLE/validationES3.h"
Geoff Lange8ebe7f2013-08-05 15:03:13 -040028
29namespace gl
30{
31
Jamie Madillc29968b2016-01-20 11:17:23 -050032namespace
33{
34
35bool IsPartialBlit(gl::Context *context,
36 const FramebufferAttachment *readBuffer,
37 const FramebufferAttachment *writeBuffer,
38 GLint srcX0,
39 GLint srcY0,
40 GLint srcX1,
41 GLint srcY1,
42 GLint dstX0,
43 GLint dstY0,
44 GLint dstX1,
45 GLint dstY1)
46{
47 const Extents &writeSize = writeBuffer->getSize();
48 const Extents &readSize = readBuffer->getSize();
49
50 if (srcX0 != 0 || srcY0 != 0 || dstX0 != 0 || dstY0 != 0 || dstX1 != writeSize.width ||
51 dstY1 != writeSize.height || srcX1 != readSize.width || srcY1 != readSize.height)
52 {
53 return true;
54 }
55
Jamie Madilldfde6ab2016-06-09 07:07:18 -070056 if (context->getGLState().isScissorTestEnabled())
Jamie Madillc29968b2016-01-20 11:17:23 -050057 {
Jamie Madilldfde6ab2016-06-09 07:07:18 -070058 const Rectangle &scissor = context->getGLState().getScissor();
Jamie Madillc29968b2016-01-20 11:17:23 -050059 return scissor.x > 0 || scissor.y > 0 || scissor.width < writeSize.width ||
60 scissor.height < writeSize.height;
61 }
62
63 return false;
64}
65
Sami Väisänend59ca052016-06-21 16:10:00 +030066template <typename T>
67bool ValidatePathInstances(gl::Context *context,
68 GLsizei numPaths,
69 const void *paths,
70 GLuint pathBase)
71{
72 const auto *array = static_cast<const T *>(paths);
73
74 for (GLsizei i = 0; i < numPaths; ++i)
75 {
76 const GLuint pathName = array[i] + pathBase;
77 if (context->hasPath(pathName) && !context->hasPathData(pathName))
78 {
Brandon Jonesafa75152017-07-21 13:11:29 -070079 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänend59ca052016-06-21 16:10:00 +030080 return false;
81 }
82 }
83 return true;
84}
85
86bool ValidateInstancedPathParameters(gl::Context *context,
87 GLsizei numPaths,
88 GLenum pathNameType,
89 const void *paths,
90 GLuint pathBase,
91 GLenum transformType,
92 const GLfloat *transformValues)
93{
94 if (!context->getExtensions().pathRendering)
95 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -050096 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänend59ca052016-06-21 16:10:00 +030097 return false;
98 }
99
100 if (paths == nullptr)
101 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500102 context->handleError(InvalidValue() << "No path name array.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300103 return false;
104 }
105
106 if (numPaths < 0)
107 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500108 context->handleError(InvalidValue() << "Invalid (negative) numPaths.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300109 return false;
110 }
111
112 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(numPaths))
113 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700114 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänend59ca052016-06-21 16:10:00 +0300115 return false;
116 }
117
118 std::uint32_t pathNameTypeSize = 0;
119 std::uint32_t componentCount = 0;
120
121 switch (pathNameType)
122 {
123 case GL_UNSIGNED_BYTE:
124 pathNameTypeSize = sizeof(GLubyte);
125 if (!ValidatePathInstances<GLubyte>(context, numPaths, paths, pathBase))
126 return false;
127 break;
128
129 case GL_BYTE:
130 pathNameTypeSize = sizeof(GLbyte);
131 if (!ValidatePathInstances<GLbyte>(context, numPaths, paths, pathBase))
132 return false;
133 break;
134
135 case GL_UNSIGNED_SHORT:
136 pathNameTypeSize = sizeof(GLushort);
137 if (!ValidatePathInstances<GLushort>(context, numPaths, paths, pathBase))
138 return false;
139 break;
140
141 case GL_SHORT:
142 pathNameTypeSize = sizeof(GLshort);
143 if (!ValidatePathInstances<GLshort>(context, numPaths, paths, pathBase))
144 return false;
145 break;
146
147 case GL_UNSIGNED_INT:
148 pathNameTypeSize = sizeof(GLuint);
149 if (!ValidatePathInstances<GLuint>(context, numPaths, paths, pathBase))
150 return false;
151 break;
152
153 case GL_INT:
154 pathNameTypeSize = sizeof(GLint);
155 if (!ValidatePathInstances<GLint>(context, numPaths, paths, pathBase))
156 return false;
157 break;
158
159 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500160 context->handleError(InvalidEnum() << "Invalid path name type.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300161 return false;
162 }
163
164 switch (transformType)
165 {
166 case GL_NONE:
167 componentCount = 0;
168 break;
169 case GL_TRANSLATE_X_CHROMIUM:
170 case GL_TRANSLATE_Y_CHROMIUM:
171 componentCount = 1;
172 break;
173 case GL_TRANSLATE_2D_CHROMIUM:
174 componentCount = 2;
175 break;
176 case GL_TRANSLATE_3D_CHROMIUM:
177 componentCount = 3;
178 break;
179 case GL_AFFINE_2D_CHROMIUM:
180 case GL_TRANSPOSE_AFFINE_2D_CHROMIUM:
181 componentCount = 6;
182 break;
183 case GL_AFFINE_3D_CHROMIUM:
184 case GL_TRANSPOSE_AFFINE_3D_CHROMIUM:
185 componentCount = 12;
186 break;
187 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500188 context->handleError(InvalidEnum() << "Invalid transformation.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300189 return false;
190 }
191 if (componentCount != 0 && transformValues == nullptr)
192 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500193 context->handleError(InvalidValue() << "No transform array given.");
Sami Väisänend59ca052016-06-21 16:10:00 +0300194 return false;
195 }
196
197 angle::CheckedNumeric<std::uint32_t> checkedSize(0);
198 checkedSize += (numPaths * pathNameTypeSize);
199 checkedSize += (numPaths * sizeof(GLfloat) * componentCount);
200 if (!checkedSize.IsValid())
201 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700202 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänend59ca052016-06-21 16:10:00 +0300203 return false;
204 }
205
206 return true;
207}
208
Geoff Lang4f0e0032017-05-01 16:04:35 -0400209bool IsValidCopyTextureSourceInternalFormatEnum(GLenum internalFormat)
Geoff Lang97073d12016-04-20 10:42:34 -0700210{
Geoff Lang4f0e0032017-05-01 16:04:35 -0400211 // Table 1.1 from the CHROMIUM_copy_texture spec
Geoff Langca271392017-04-05 12:30:00 -0400212 switch (GetUnsizedFormat(internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -0700213 {
Geoff Lang4f0e0032017-05-01 16:04:35 -0400214 case GL_RED:
Geoff Lang97073d12016-04-20 10:42:34 -0700215 case GL_ALPHA:
216 case GL_LUMINANCE:
217 case GL_LUMINANCE_ALPHA:
218 case GL_RGB:
219 case GL_RGBA:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400220 case GL_RGB8:
221 case GL_RGBA8:
222 case GL_BGRA_EXT:
223 case GL_BGRA8_EXT:
Geoff Lang97073d12016-04-20 10:42:34 -0700224 return true;
225
Geoff Lang4f0e0032017-05-01 16:04:35 -0400226 default:
227 return false;
228 }
229}
Geoff Lang97073d12016-04-20 10:42:34 -0700230
Geoff Lang4f0e0032017-05-01 16:04:35 -0400231bool IsValidCopySubTextureSourceInternalFormat(GLenum internalFormat)
232{
233 return IsValidCopyTextureSourceInternalFormatEnum(internalFormat);
234}
235
Geoff Lang4f0e0032017-05-01 16:04:35 -0400236bool IsValidCopyTextureDestinationInternalFormatEnum(GLint internalFormat)
237{
238 // Table 1.0 from the CHROMIUM_copy_texture spec
239 switch (internalFormat)
240 {
241 case GL_RGB:
242 case GL_RGBA:
243 case GL_RGB8:
244 case GL_RGBA8:
Geoff Lang97073d12016-04-20 10:42:34 -0700245 case GL_BGRA_EXT:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400246 case GL_BGRA8_EXT:
247 case GL_SRGB_EXT:
248 case GL_SRGB_ALPHA_EXT:
249 case GL_R8:
250 case GL_R8UI:
251 case GL_RG8:
252 case GL_RG8UI:
253 case GL_SRGB8:
254 case GL_RGB565:
255 case GL_RGB8UI:
Geoff Lang6be3d4c2017-06-16 15:54:15 -0400256 case GL_RGB10_A2:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400257 case GL_SRGB8_ALPHA8:
258 case GL_RGB5_A1:
259 case GL_RGBA4:
260 case GL_RGBA8UI:
261 case GL_RGB9_E5:
262 case GL_R16F:
263 case GL_R32F:
264 case GL_RG16F:
265 case GL_RG32F:
266 case GL_RGB16F:
267 case GL_RGB32F:
268 case GL_RGBA16F:
269 case GL_RGBA32F:
270 case GL_R11F_G11F_B10F:
Brandon Jones340b7b82017-06-26 13:02:31 -0700271 case GL_LUMINANCE:
272 case GL_LUMINANCE_ALPHA:
273 case GL_ALPHA:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400274 return true;
Geoff Lang97073d12016-04-20 10:42:34 -0700275
276 default:
277 return false;
278 }
279}
280
Geoff Lang6be3d4c2017-06-16 15:54:15 -0400281bool IsValidCopySubTextureDestionationInternalFormat(GLenum internalFormat)
282{
283 return IsValidCopyTextureDestinationInternalFormatEnum(internalFormat);
284}
285
Geoff Lang97073d12016-04-20 10:42:34 -0700286bool IsValidCopyTextureDestinationFormatType(Context *context, GLint internalFormat, GLenum type)
287{
Geoff Lang4f0e0032017-05-01 16:04:35 -0400288 if (!IsValidCopyTextureDestinationInternalFormatEnum(internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -0700289 {
Geoff Lang4f0e0032017-05-01 16:04:35 -0400290 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700291 }
292
Geoff Langc0094ec2017-08-16 14:16:24 -0400293 if (!ValidES3FormatCombination(GetUnsizedFormat(internalFormat), type, internalFormat))
294 {
295 context->handleError(InvalidOperation()
296 << "Invalid combination of type and internalFormat.");
297 return false;
298 }
299
Geoff Lang4f0e0032017-05-01 16:04:35 -0400300 const InternalFormat &internalFormatInfo = GetInternalFormatInfo(internalFormat, type);
301 if (!internalFormatInfo.textureSupport(context->getClientVersion(), context->getExtensions()))
Geoff Lang97073d12016-04-20 10:42:34 -0700302 {
Geoff Lang4f0e0032017-05-01 16:04:35 -0400303 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700304 }
305
306 return true;
307}
308
Geoff Lang4f0e0032017-05-01 16:04:35 -0400309bool IsValidCopyTextureDestinationTarget(Context *context, GLenum textureType, GLenum target)
Geoff Lang97073d12016-04-20 10:42:34 -0700310{
311 switch (target)
312 {
313 case GL_TEXTURE_2D:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400314 return textureType == GL_TEXTURE_2D;
315
316 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
317 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
318 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
319 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
320 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
321 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
322 return textureType == GL_TEXTURE_CUBE_MAP;
Geoff Lang97073d12016-04-20 10:42:34 -0700323
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400324 case GL_TEXTURE_RECTANGLE_ANGLE:
325 return textureType == GL_TEXTURE_RECTANGLE_ANGLE &&
326 context->getExtensions().textureRectangle;
Geoff Lang97073d12016-04-20 10:42:34 -0700327
328 default:
329 return false;
330 }
331}
332
333bool IsValidCopyTextureSourceTarget(Context *context, GLenum target)
334{
Geoff Lang4f0e0032017-05-01 16:04:35 -0400335 switch (target)
Geoff Lang97073d12016-04-20 10:42:34 -0700336 {
Geoff Lang4f0e0032017-05-01 16:04:35 -0400337 case GL_TEXTURE_2D:
338 return true;
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400339 case GL_TEXTURE_RECTANGLE_ANGLE:
340 return context->getExtensions().textureRectangle;
Geoff Lang4f0e0032017-05-01 16:04:35 -0400341
342 // TODO(geofflang): accept GL_TEXTURE_EXTERNAL_OES if the texture_external extension is
343 // supported
344
345 default:
346 return false;
347 }
348}
349
350bool IsValidCopyTextureSourceLevel(Context *context, GLenum target, GLint level)
351{
Geoff Lang3847f942017-07-12 11:17:28 -0400352 if (!ValidMipLevel(context, target, level))
Geoff Lang4f0e0032017-05-01 16:04:35 -0400353 {
354 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700355 }
356
Geoff Lang4f0e0032017-05-01 16:04:35 -0400357 if (level > 0 && context->getClientVersion() < ES_3_0)
358 {
359 return false;
360 }
Geoff Lang97073d12016-04-20 10:42:34 -0700361
Geoff Lang4f0e0032017-05-01 16:04:35 -0400362 return true;
363}
364
365bool IsValidCopyTextureDestinationLevel(Context *context,
366 GLenum target,
367 GLint level,
368 GLsizei width,
369 GLsizei height)
370{
Geoff Lang3847f942017-07-12 11:17:28 -0400371 if (!ValidMipLevel(context, target, level))
Geoff Lang4f0e0032017-05-01 16:04:35 -0400372 {
373 return false;
374 }
375
Geoff Lang4f0e0032017-05-01 16:04:35 -0400376 const Caps &caps = context->getCaps();
377 if (target == GL_TEXTURE_2D)
378 {
379 if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
380 static_cast<GLuint>(height) > (caps.max2DTextureSize >> level))
381 {
382 return false;
383 }
384 }
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400385 else if (target == GL_TEXTURE_RECTANGLE_ANGLE)
386 {
387 ASSERT(level == 0);
388 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
389 static_cast<GLuint>(height) > caps.maxRectangleTextureSize)
390 {
391 return false;
392 }
393 }
Geoff Lang4f0e0032017-05-01 16:04:35 -0400394 else if (IsCubeMapTextureTarget(target))
395 {
396 if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level) ||
397 static_cast<GLuint>(height) > (caps.maxCubeMapTextureSize >> level))
398 {
399 return false;
400 }
401 }
402
403 return true;
Geoff Lang97073d12016-04-20 10:42:34 -0700404}
405
Jamie Madillc1d770e2017-04-13 17:31:24 -0400406bool IsValidStencilFunc(GLenum func)
407{
408 switch (func)
409 {
410 case GL_NEVER:
411 case GL_ALWAYS:
412 case GL_LESS:
413 case GL_LEQUAL:
414 case GL_EQUAL:
415 case GL_GEQUAL:
416 case GL_GREATER:
417 case GL_NOTEQUAL:
418 return true;
419
420 default:
421 return false;
422 }
423}
424
425bool IsValidStencilFace(GLenum face)
426{
427 switch (face)
428 {
429 case GL_FRONT:
430 case GL_BACK:
431 case GL_FRONT_AND_BACK:
432 return true;
433
434 default:
435 return false;
436 }
437}
438
439bool IsValidStencilOp(GLenum op)
440{
441 switch (op)
442 {
443 case GL_ZERO:
444 case GL_KEEP:
445 case GL_REPLACE:
446 case GL_INCR:
447 case GL_DECR:
448 case GL_INVERT:
449 case GL_INCR_WRAP:
450 case GL_DECR_WRAP:
451 return true;
452
453 default:
454 return false;
455 }
456}
457
Jamie Madillbe849e42017-05-02 15:49:00 -0400458bool ValidateES2CopyTexImageParameters(ValidationContext *context,
459 GLenum target,
460 GLint level,
461 GLenum internalformat,
462 bool isSubImage,
463 GLint xoffset,
464 GLint yoffset,
465 GLint x,
466 GLint y,
467 GLsizei width,
468 GLsizei height,
469 GLint border)
470{
471 if (!ValidTexture2DDestinationTarget(context, target))
472 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700473 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -0400474 return false;
475 }
476
477 if (!ValidImageSizeParameters(context, target, level, width, height, 1, isSubImage))
478 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500479 context->handleError(InvalidValue() << "Invalid texture dimensions.");
Jamie Madillbe849e42017-05-02 15:49:00 -0400480 return false;
481 }
482
483 Format textureFormat = Format::Invalid();
484 if (!ValidateCopyTexImageParametersBase(context, target, level, internalformat, isSubImage,
485 xoffset, yoffset, 0, x, y, width, height, border,
486 &textureFormat))
487 {
488 return false;
489 }
490
491 const gl::Framebuffer *framebuffer = context->getGLState().getReadFramebuffer();
492 GLenum colorbufferFormat =
493 framebuffer->getReadColorbuffer()->getFormat().info->sizedInternalFormat;
494 const auto &formatInfo = *textureFormat.info;
495
496 // [OpenGL ES 2.0.24] table 3.9
497 if (isSubImage)
498 {
499 switch (formatInfo.format)
500 {
501 case GL_ALPHA:
502 if (colorbufferFormat != GL_ALPHA8_EXT && colorbufferFormat != GL_RGBA4 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400503 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGBA8_OES &&
504 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400505 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700506 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400507 return false;
508 }
509 break;
510 case GL_LUMINANCE:
511 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
512 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
513 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400514 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGRA8_EXT &&
515 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400516 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700517 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400518 return false;
519 }
520 break;
521 case GL_RED_EXT:
522 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
523 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
524 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
525 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_R32F &&
526 colorbufferFormat != GL_RG32F && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400527 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
528 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400529 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700530 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400531 return false;
532 }
533 break;
534 case GL_RG_EXT:
535 if (colorbufferFormat != GL_RG8_EXT && colorbufferFormat != GL_RGB565 &&
536 colorbufferFormat != GL_RGB8_OES && colorbufferFormat != GL_RGBA4 &&
537 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGBA8_OES &&
538 colorbufferFormat != GL_RG32F && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400539 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
540 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400541 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700542 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400543 return false;
544 }
545 break;
546 case GL_RGB:
547 if (colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
548 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
549 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400550 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
551 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400552 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700553 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400554 return false;
555 }
556 break;
557 case GL_LUMINANCE_ALPHA:
558 case GL_RGBA:
559 if (colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400560 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_RGBA32F &&
561 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400562 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700563 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400564 return false;
565 }
566 break;
567 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
568 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
569 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
570 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
571 case GL_ETC1_RGB8_OES:
572 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
573 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
574 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
575 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
576 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
Brandon Jones6cad5662017-06-14 13:25:13 -0700577 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400578 return false;
579 case GL_DEPTH_COMPONENT:
580 case GL_DEPTH_STENCIL_OES:
Brandon Jones6cad5662017-06-14 13:25:13 -0700581 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400582 return false;
583 default:
Brandon Jones6cad5662017-06-14 13:25:13 -0700584 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400585 return false;
586 }
587
588 if (formatInfo.type == GL_FLOAT && !context->getExtensions().textureFloat)
589 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700590 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400591 return false;
592 }
593 }
594 else
595 {
596 switch (internalformat)
597 {
598 case GL_ALPHA:
599 if (colorbufferFormat != GL_ALPHA8_EXT && colorbufferFormat != GL_RGBA4 &&
600 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_BGRA8_EXT &&
601 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGR5_A1_ANGLEX)
602 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700603 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400604 return false;
605 }
606 break;
607 case GL_LUMINANCE:
608 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
609 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
610 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
611 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
612 colorbufferFormat != GL_BGR5_A1_ANGLEX)
613 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700614 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400615 return false;
616 }
617 break;
618 case GL_RED_EXT:
619 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
620 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
621 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
622 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
623 colorbufferFormat != GL_BGR5_A1_ANGLEX)
624 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700625 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400626 return false;
627 }
628 break;
629 case GL_RG_EXT:
630 if (colorbufferFormat != GL_RG8_EXT && colorbufferFormat != GL_RGB565 &&
631 colorbufferFormat != GL_RGB8_OES && colorbufferFormat != GL_RGBA4 &&
632 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_BGRA8_EXT &&
633 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGR5_A1_ANGLEX)
634 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700635 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400636 return false;
637 }
638 break;
639 case GL_RGB:
640 if (colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
641 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
642 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
643 colorbufferFormat != GL_BGR5_A1_ANGLEX)
644 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700645 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400646 return false;
647 }
648 break;
649 case GL_LUMINANCE_ALPHA:
650 case GL_RGBA:
651 if (colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
652 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
653 colorbufferFormat != GL_BGR5_A1_ANGLEX)
654 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700655 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400656 return false;
657 }
658 break;
659 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
660 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
661 if (context->getExtensions().textureCompressionDXT1)
662 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700663 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400664 return false;
665 }
666 else
667 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700668 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400669 return false;
670 }
671 break;
672 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
673 if (context->getExtensions().textureCompressionDXT3)
674 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700675 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400676 return false;
677 }
678 else
679 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700680 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400681 return false;
682 }
683 break;
684 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
685 if (context->getExtensions().textureCompressionDXT5)
686 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700687 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400688 return false;
689 }
690 else
691 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700692 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400693 return false;
694 }
695 break;
696 case GL_ETC1_RGB8_OES:
697 if (context->getExtensions().compressedETC1RGB8Texture)
698 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500699 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -0400700 return false;
701 }
702 else
703 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500704 context->handleError(InvalidEnum());
Jamie Madillbe849e42017-05-02 15:49:00 -0400705 return false;
706 }
707 break;
708 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
709 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
710 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
711 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
712 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
713 if (context->getExtensions().lossyETCDecode)
714 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500715 context->handleError(InvalidOperation()
716 << "ETC lossy decode formats can't be copied to.");
Jamie Madillbe849e42017-05-02 15:49:00 -0400717 return false;
718 }
719 else
720 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500721 context->handleError(InvalidEnum()
722 << "ANGLE_lossy_etc_decode extension is not supported.");
Jamie Madillbe849e42017-05-02 15:49:00 -0400723 return false;
724 }
725 break;
726 case GL_DEPTH_COMPONENT:
727 case GL_DEPTH_COMPONENT16:
728 case GL_DEPTH_COMPONENT32_OES:
729 case GL_DEPTH_STENCIL_OES:
730 case GL_DEPTH24_STENCIL8_OES:
731 if (context->getExtensions().depthTextures)
732 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500733 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -0400734 return false;
735 }
736 else
737 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500738 context->handleError(InvalidEnum());
Jamie Madillbe849e42017-05-02 15:49:00 -0400739 return false;
740 }
741 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500742 context->handleError(InvalidEnum());
Jamie Madillbe849e42017-05-02 15:49:00 -0400743 return false;
744 }
745 }
746
747 // If width or height is zero, it is a no-op. Return false without setting an error.
748 return (width > 0 && height > 0);
749}
750
751bool ValidCap(const Context *context, GLenum cap, bool queryOnly)
752{
753 switch (cap)
754 {
755 // EXT_multisample_compatibility
756 case GL_MULTISAMPLE_EXT:
757 case GL_SAMPLE_ALPHA_TO_ONE_EXT:
758 return context->getExtensions().multisampleCompatibility;
759
760 case GL_CULL_FACE:
761 case GL_POLYGON_OFFSET_FILL:
762 case GL_SAMPLE_ALPHA_TO_COVERAGE:
763 case GL_SAMPLE_COVERAGE:
764 case GL_SCISSOR_TEST:
765 case GL_STENCIL_TEST:
766 case GL_DEPTH_TEST:
767 case GL_BLEND:
768 case GL_DITHER:
769 return true;
770
771 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
772 case GL_RASTERIZER_DISCARD:
773 return (context->getClientMajorVersion() >= 3);
774
775 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
776 case GL_DEBUG_OUTPUT:
777 return context->getExtensions().debug;
778
779 case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
780 return queryOnly && context->getExtensions().bindGeneratesResource;
781
782 case GL_CLIENT_ARRAYS_ANGLE:
783 return queryOnly && context->getExtensions().clientArrays;
784
785 case GL_FRAMEBUFFER_SRGB_EXT:
786 return context->getExtensions().sRGBWriteControl;
787
788 case GL_SAMPLE_MASK:
789 return context->getClientVersion() >= Version(3, 1);
790
791 case GL_CONTEXT_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
792 return queryOnly && context->getExtensions().robustResourceInitialization;
793
794 default:
795 return false;
796 }
797}
798
Geoff Langfc32e8b2017-05-31 14:16:59 -0400799// Return true if a character belongs to the ASCII subset as defined in GLSL ES 1.0 spec section
800// 3.1.
Geoff Langcab92ee2017-07-19 17:32:07 -0400801bool IsValidESSLCharacter(unsigned char c)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400802{
803 // Printing characters are valid except " $ ` @ \ ' DEL.
Geoff Langcab92ee2017-07-19 17:32:07 -0400804 if (c >= 32 && c <= 126 && c != '"' && c != '$' && c != '`' && c != '@' && c != '\\' &&
805 c != '\'')
Geoff Langfc32e8b2017-05-31 14:16:59 -0400806 {
807 return true;
808 }
809
810 // Horizontal tab, line feed, vertical tab, form feed, carriage return are also valid.
811 if (c >= 9 && c <= 13)
812 {
813 return true;
814 }
815
816 return false;
817}
818
Geoff Langcab92ee2017-07-19 17:32:07 -0400819bool IsValidESSLString(const char *str, size_t len)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400820{
Geoff Langa71a98e2017-06-19 15:15:00 -0400821 for (size_t i = 0; i < len; i++)
822 {
Geoff Langcab92ee2017-07-19 17:32:07 -0400823 if (!IsValidESSLCharacter(str[i]))
Geoff Langa71a98e2017-06-19 15:15:00 -0400824 {
825 return false;
826 }
827 }
828
829 return true;
Geoff Langfc32e8b2017-05-31 14:16:59 -0400830}
831
Geoff Langcab92ee2017-07-19 17:32:07 -0400832bool IsValidESSLShaderSourceString(const char *str, size_t len, bool lineContinuationAllowed)
833{
834 enum class ParseState
835 {
836 // Have not seen an ASCII non-whitespace character yet on
837 // this line. Possible that we might see a preprocessor
838 // directive.
839 BEGINING_OF_LINE,
840
841 // Have seen at least one ASCII non-whitespace character
842 // on this line.
843 MIDDLE_OF_LINE,
844
845 // Handling a preprocessor directive. Passes through all
846 // characters up to the end of the line. Disables comment
847 // processing.
848 IN_PREPROCESSOR_DIRECTIVE,
849
850 // Handling a single-line comment. The comment text is
851 // replaced with a single space.
852 IN_SINGLE_LINE_COMMENT,
853
854 // Handling a multi-line comment. Newlines are passed
855 // through to preserve line numbers.
856 IN_MULTI_LINE_COMMENT
857 };
858
859 ParseState state = ParseState::BEGINING_OF_LINE;
860 size_t pos = 0;
861
862 while (pos < len)
863 {
864 char c = str[pos];
865 char next = pos + 1 < len ? str[pos + 1] : 0;
866
867 // Check for newlines
868 if (c == '\n' || c == '\r')
869 {
870 if (state != ParseState::IN_MULTI_LINE_COMMENT)
871 {
872 state = ParseState::BEGINING_OF_LINE;
873 }
874
875 pos++;
876 continue;
877 }
878
879 switch (state)
880 {
881 case ParseState::BEGINING_OF_LINE:
882 if (c == ' ')
883 {
884 // Maintain the BEGINING_OF_LINE state until a non-space is seen
885 pos++;
886 }
887 else if (c == '#')
888 {
889 state = ParseState::IN_PREPROCESSOR_DIRECTIVE;
890 pos++;
891 }
892 else
893 {
894 // Don't advance, re-process this character with the MIDDLE_OF_LINE state
895 state = ParseState::MIDDLE_OF_LINE;
896 }
897 break;
898
899 case ParseState::MIDDLE_OF_LINE:
900 if (c == '/' && next == '/')
901 {
902 state = ParseState::IN_SINGLE_LINE_COMMENT;
903 pos++;
904 }
905 else if (c == '/' && next == '*')
906 {
907 state = ParseState::IN_MULTI_LINE_COMMENT;
908 pos++;
909 }
910 else if (lineContinuationAllowed && c == '\\' && (next == '\n' || next == '\r'))
911 {
912 // Skip line continuation characters
913 }
914 else if (!IsValidESSLCharacter(c))
915 {
916 return false;
917 }
918 pos++;
919 break;
920
921 case ParseState::IN_PREPROCESSOR_DIRECTIVE:
922 // No matter what the character is, just pass it
923 // through. Do not parse comments in this state.
924 pos++;
925 break;
926
927 case ParseState::IN_SINGLE_LINE_COMMENT:
928 // Line-continuation characters are processed before comment processing.
929 // Advance string if a new line character is immediately behind
930 // line-continuation character.
931 if (c == '\\' && (next == '\n' || next == '\r'))
932 {
933 pos++;
934 }
935 pos++;
936 break;
937
938 case ParseState::IN_MULTI_LINE_COMMENT:
939 if (c == '*' && next == '/')
940 {
941 state = ParseState::MIDDLE_OF_LINE;
942 pos++;
943 }
944 pos++;
945 break;
946 }
947 }
948
949 return true;
950}
951
Brandon Jonesed5b46f2017-07-21 08:39:17 -0700952bool ValidateWebGLNamePrefix(ValidationContext *context, const GLchar *name)
953{
954 ASSERT(context->isWebGL());
955
956 // WebGL 1.0 [Section 6.16] GLSL Constructs
957 // Identifiers starting with "webgl_" and "_webgl_" are reserved for use by WebGL.
958 if (strncmp(name, "webgl_", 6) == 0 || strncmp(name, "_webgl_", 7) == 0)
959 {
960 ANGLE_VALIDATION_ERR(context, InvalidOperation(), WebglBindAttribLocationReservedPrefix);
961 return false;
962 }
963
964 return true;
965}
966
967bool ValidateWebGLNameLength(ValidationContext *context, size_t length)
968{
969 ASSERT(context->isWebGL());
970
971 if (context->isWebGL1() && length > 256)
972 {
973 // WebGL 1.0 [Section 6.21] Maxmimum Uniform and Attribute Location Lengths
974 // WebGL imposes a limit of 256 characters on the lengths of uniform and attribute
975 // locations.
976 ANGLE_VALIDATION_ERR(context, InvalidValue(), WebglNameLengthLimitExceeded);
977
978 return false;
979 }
980 else if (length > 1024)
981 {
982 // WebGL 2.0 [Section 4.3.2] WebGL 2.0 imposes a limit of 1024 characters on the lengths of
983 // uniform and attribute locations.
984 ANGLE_VALIDATION_ERR(context, InvalidValue(), Webgl2NameLengthLimitExceeded);
985 return false;
986 }
987
988 return true;
989}
990
Jamie Madillc29968b2016-01-20 11:17:23 -0500991} // anonymous namespace
992
Geoff Langff5b2d52016-09-07 11:32:23 -0400993bool ValidateES2TexImageParameters(Context *context,
994 GLenum target,
995 GLint level,
996 GLenum internalformat,
997 bool isCompressed,
998 bool isSubImage,
999 GLint xoffset,
1000 GLint yoffset,
1001 GLsizei width,
1002 GLsizei height,
1003 GLint border,
1004 GLenum format,
1005 GLenum type,
1006 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04001007 const void *pixels)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001008{
Jamie Madill6f38f822014-06-06 17:12:20 -04001009 if (!ValidTexture2DDestinationTarget(context, target))
1010 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001011 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Geoff Langb1196682014-07-23 13:47:29 -04001012 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -04001013 }
1014
Austin Kinross08528e12015-10-07 16:24:40 -07001015 if (!ValidImageSizeParameters(context, target, level, width, height, 1, isSubImage))
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001016 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001017 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001018 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001019 }
1020
Brandon Jones6cad5662017-06-14 13:25:13 -07001021 if (!ValidMipLevel(context, target, level))
1022 {
1023 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
1024 return false;
1025 }
1026
1027 if (xoffset < 0 || std::numeric_limits<GLsizei>::max() - xoffset < width ||
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001028 std::numeric_limits<GLsizei>::max() - yoffset < height)
1029 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001030 ANGLE_VALIDATION_ERR(context, InvalidValue(), ResourceMaxTextureSize);
Geoff Langb1196682014-07-23 13:47:29 -04001031 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001032 }
1033
Geoff Lang6e898aa2017-06-02 11:17:26 -04001034 // From GL_CHROMIUM_color_buffer_float_rgb[a]:
1035 // GL_RGB[A] / GL_RGB[A]32F becomes an allowable format / internalformat parameter pair for
1036 // TexImage2D. The restriction in section 3.7.1 of the OpenGL ES 2.0 spec that the
1037 // internalformat parameter and format parameter of TexImage2D must match is lifted for this
1038 // case.
1039 bool nonEqualFormatsAllowed =
1040 (internalformat == GL_RGB32F && context->getExtensions().colorBufferFloatRGB) ||
1041 (internalformat == GL_RGBA32F && context->getExtensions().colorBufferFloatRGBA);
1042
1043 if (!isSubImage && !isCompressed && internalformat != format && !nonEqualFormatsAllowed)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001044 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001045 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001046 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001047 }
1048
Geoff Langaae65a42014-05-26 12:43:44 -04001049 const gl::Caps &caps = context->getCaps();
1050
Geoff Langa9be0dc2014-12-17 12:34:40 -05001051 if (target == GL_TEXTURE_2D)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001052 {
Geoff Langa9be0dc2014-12-17 12:34:40 -05001053 if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
1054 static_cast<GLuint>(height) > (caps.max2DTextureSize >> level))
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001055 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001056 context->handleError(InvalidValue());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001057 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001058 }
Geoff Langa9be0dc2014-12-17 12:34:40 -05001059 }
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001060 else if (target == GL_TEXTURE_RECTANGLE_ANGLE)
1061 {
1062 ASSERT(level == 0);
1063 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1064 static_cast<GLuint>(height) > caps.maxRectangleTextureSize)
1065 {
1066 context->handleError(InvalidValue());
1067 return false;
1068 }
1069 if (isCompressed)
1070 {
1071 context->handleError(InvalidEnum()
1072 << "Rectangle texture cannot have a compressed format.");
1073 return false;
1074 }
1075 }
Geoff Lang691e58c2014-12-19 17:03:25 -05001076 else if (IsCubeMapTextureTarget(target))
Geoff Langa9be0dc2014-12-17 12:34:40 -05001077 {
1078 if (!isSubImage && width != height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001079 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001080 ANGLE_VALIDATION_ERR(context, InvalidValue(), CubemapFacesEqualDimensions);
Geoff Langa9be0dc2014-12-17 12:34:40 -05001081 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001082 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001083
Geoff Langa9be0dc2014-12-17 12:34:40 -05001084 if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level) ||
1085 static_cast<GLuint>(height) > (caps.maxCubeMapTextureSize >> level))
1086 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001087 context->handleError(InvalidValue());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001088 return false;
1089 }
1090 }
1091 else
1092 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001093 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001094 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001095 }
1096
He Yunchaoced53ae2016-11-29 15:00:51 +08001097 gl::Texture *texture =
1098 context->getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001099 if (!texture)
1100 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001101 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Geoff Langb1196682014-07-23 13:47:29 -04001102 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001103 }
1104
Geoff Langa9be0dc2014-12-17 12:34:40 -05001105 if (isSubImage)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001106 {
Geoff Langca271392017-04-05 12:30:00 -04001107 const InternalFormat &textureInternalFormat = *texture->getFormat(target, level).info;
1108 if (textureInternalFormat.internalFormat == GL_NONE)
Geoff Langc51642b2016-11-14 16:18:26 -05001109 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001110 context->handleError(InvalidOperation() << "Texture level does not exist.");
Geoff Langc51642b2016-11-14 16:18:26 -05001111 return false;
1112 }
1113
Geoff Langa9be0dc2014-12-17 12:34:40 -05001114 if (format != GL_NONE)
1115 {
Geoff Langca271392017-04-05 12:30:00 -04001116 if (GetInternalFormatInfo(format, type).sizedInternalFormat !=
1117 textureInternalFormat.sizedInternalFormat)
Geoff Langa9be0dc2014-12-17 12:34:40 -05001118 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001119 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TypeMismatch);
Geoff Langa9be0dc2014-12-17 12:34:40 -05001120 return false;
1121 }
1122 }
1123
1124 if (static_cast<size_t>(xoffset + width) > texture->getWidth(target, level) ||
1125 static_cast<size_t>(yoffset + height) > texture->getHeight(target, level))
1126 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001127 context->handleError(InvalidValue());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001128 return false;
1129 }
1130 }
1131 else
1132 {
Geoff Lang69cce582015-09-17 13:20:36 -04001133 if (texture->getImmutableFormat())
Geoff Langa9be0dc2014-12-17 12:34:40 -05001134 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001135 context->handleError(InvalidOperation());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001136 return false;
1137 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001138 }
1139
1140 // Verify zero border
1141 if (border != 0)
1142 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001143 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidBorder);
Geoff Langb1196682014-07-23 13:47:29 -04001144 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001145 }
1146
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001147 if (isCompressed)
1148 {
tmartino0ccd5ae2015-10-01 14:33:14 -04001149 GLenum actualInternalFormat =
Geoff Langca271392017-04-05 12:30:00 -04001150 isSubImage ? texture->getFormat(target, level).info->sizedInternalFormat
1151 : internalformat;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001152 switch (actualInternalFormat)
1153 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001154 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1155 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1156 if (!context->getExtensions().textureCompressionDXT1)
1157 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001158 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001159 return false;
1160 }
1161 break;
1162 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1163 if (!context->getExtensions().textureCompressionDXT1)
1164 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001165 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001166 return false;
1167 }
1168 break;
1169 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1170 if (!context->getExtensions().textureCompressionDXT5)
1171 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001172 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001173 return false;
1174 }
1175 break;
Kai Ninomiya02f075c2016-12-22 14:55:46 -08001176 case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
1177 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
1178 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
1179 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
1180 if (!context->getExtensions().textureCompressionS3TCsRGB)
1181 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001182 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
Kai Ninomiya02f075c2016-12-22 14:55:46 -08001183 return false;
1184 }
1185 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001186 case GL_ETC1_RGB8_OES:
1187 if (!context->getExtensions().compressedETC1RGB8Texture)
1188 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001189 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001190 return false;
1191 }
1192 break;
1193 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001194 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1195 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1196 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1197 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001198 if (!context->getExtensions().lossyETCDecode)
1199 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001200 context->handleError(InvalidEnum()
1201 << "ANGLE_lossy_etc_decode extension is not supported");
He Yunchaoced53ae2016-11-29 15:00:51 +08001202 return false;
1203 }
1204 break;
1205 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001206 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
Geoff Langb1196682014-07-23 13:47:29 -04001207 return false;
tmartino0ccd5ae2015-10-01 14:33:14 -04001208 }
Geoff Lang966c9402017-04-18 12:38:27 -04001209
1210 if (isSubImage)
tmartino0ccd5ae2015-10-01 14:33:14 -04001211 {
Geoff Lang966c9402017-04-18 12:38:27 -04001212 if (!ValidCompressedSubImageSize(context, actualInternalFormat, xoffset, yoffset, width,
1213 height, texture->getWidth(target, level),
1214 texture->getHeight(target, level)))
1215 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001216 context->handleError(InvalidOperation() << "Invalid compressed format dimension.");
Geoff Lang966c9402017-04-18 12:38:27 -04001217 return false;
1218 }
1219
1220 if (format != actualInternalFormat)
1221 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001222 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Geoff Lang966c9402017-04-18 12:38:27 -04001223 return false;
1224 }
1225 }
1226 else
1227 {
1228 if (!ValidCompressedImageSize(context, actualInternalFormat, level, width, height))
1229 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001230 context->handleError(InvalidOperation() << "Invalid compressed format dimension.");
Geoff Lang966c9402017-04-18 12:38:27 -04001231 return false;
1232 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001233 }
1234 }
1235 else
1236 {
1237 // validate <type> by itself (used as secondary key below)
1238 switch (type)
1239 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001240 case GL_UNSIGNED_BYTE:
1241 case GL_UNSIGNED_SHORT_5_6_5:
1242 case GL_UNSIGNED_SHORT_4_4_4_4:
1243 case GL_UNSIGNED_SHORT_5_5_5_1:
1244 case GL_UNSIGNED_SHORT:
1245 case GL_UNSIGNED_INT:
1246 case GL_UNSIGNED_INT_24_8_OES:
1247 case GL_HALF_FLOAT_OES:
1248 case GL_FLOAT:
1249 break;
1250 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001251 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidType);
He Yunchaoced53ae2016-11-29 15:00:51 +08001252 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001253 }
1254
1255 // validate <format> + <type> combinations
1256 // - invalid <format> -> sets INVALID_ENUM
1257 // - invalid <format>+<type> combination -> sets INVALID_OPERATION
1258 switch (format)
1259 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001260 case GL_ALPHA:
1261 case GL_LUMINANCE:
1262 case GL_LUMINANCE_ALPHA:
1263 switch (type)
1264 {
1265 case GL_UNSIGNED_BYTE:
1266 case GL_FLOAT:
1267 case GL_HALF_FLOAT_OES:
1268 break;
1269 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001270 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001271 return false;
1272 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001273 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001274 case GL_RED:
1275 case GL_RG:
1276 if (!context->getExtensions().textureRG)
1277 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001278 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001279 return false;
1280 }
1281 switch (type)
1282 {
1283 case GL_UNSIGNED_BYTE:
1284 case GL_FLOAT:
1285 case GL_HALF_FLOAT_OES:
1286 break;
1287 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001288 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001289 return false;
1290 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001291 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001292 case GL_RGB:
1293 switch (type)
1294 {
1295 case GL_UNSIGNED_BYTE:
1296 case GL_UNSIGNED_SHORT_5_6_5:
1297 case GL_FLOAT:
1298 case GL_HALF_FLOAT_OES:
1299 break;
1300 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001301 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001302 return false;
1303 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001304 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001305 case GL_RGBA:
1306 switch (type)
1307 {
1308 case GL_UNSIGNED_BYTE:
1309 case GL_UNSIGNED_SHORT_4_4_4_4:
1310 case GL_UNSIGNED_SHORT_5_5_5_1:
1311 case GL_FLOAT:
1312 case GL_HALF_FLOAT_OES:
1313 break;
1314 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001315 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001316 return false;
1317 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001318 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001319 case GL_BGRA_EXT:
1320 switch (type)
1321 {
1322 case GL_UNSIGNED_BYTE:
1323 break;
1324 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001325 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001326 return false;
1327 }
1328 break;
1329 case GL_SRGB_EXT:
1330 case GL_SRGB_ALPHA_EXT:
1331 if (!context->getExtensions().sRGB)
1332 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001333 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001334 return false;
1335 }
1336 switch (type)
1337 {
1338 case GL_UNSIGNED_BYTE:
1339 break;
1340 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001341 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001342 return false;
1343 }
1344 break;
1345 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are
1346 // handled below
1347 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1348 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1349 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1350 break;
1351 case GL_DEPTH_COMPONENT:
1352 switch (type)
1353 {
1354 case GL_UNSIGNED_SHORT:
1355 case GL_UNSIGNED_INT:
1356 break;
1357 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001358 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001359 return false;
1360 }
1361 break;
1362 case GL_DEPTH_STENCIL_OES:
1363 switch (type)
1364 {
1365 case GL_UNSIGNED_INT_24_8_OES:
1366 break;
1367 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001368 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001369 return false;
1370 }
1371 break;
1372 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001373 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001374 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001375 }
1376
1377 switch (format)
1378 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001379 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1380 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1381 if (context->getExtensions().textureCompressionDXT1)
1382 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001383 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001384 return false;
1385 }
1386 else
1387 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001388 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001389 return false;
1390 }
1391 break;
1392 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1393 if (context->getExtensions().textureCompressionDXT3)
1394 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001395 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001396 return false;
1397 }
1398 else
1399 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001400 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001401 return false;
1402 }
1403 break;
1404 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1405 if (context->getExtensions().textureCompressionDXT5)
1406 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001407 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001408 return false;
1409 }
1410 else
1411 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001412 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001413 return false;
1414 }
1415 break;
1416 case GL_ETC1_RGB8_OES:
1417 if (context->getExtensions().compressedETC1RGB8Texture)
1418 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001419 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001420 return false;
1421 }
1422 else
1423 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001424 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001425 return false;
1426 }
1427 break;
1428 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001429 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1430 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1431 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1432 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001433 if (context->getExtensions().lossyETCDecode)
1434 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001435 context->handleError(InvalidOperation()
1436 << "ETC lossy decode formats can't work with this type.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001437 return false;
1438 }
1439 else
1440 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001441 context->handleError(InvalidEnum()
1442 << "ANGLE_lossy_etc_decode extension is not supported.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001443 return false;
1444 }
1445 break;
1446 case GL_DEPTH_COMPONENT:
1447 case GL_DEPTH_STENCIL_OES:
1448 if (!context->getExtensions().depthTextures)
1449 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001450 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001451 return false;
1452 }
1453 if (target != GL_TEXTURE_2D)
1454 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001455 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTargetAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001456 return false;
1457 }
1458 // OES_depth_texture supports loading depth data and multiple levels,
1459 // but ANGLE_depth_texture does not
Brandon Jonesafa75152017-07-21 13:11:29 -07001460 if (pixels != nullptr)
He Yunchaoced53ae2016-11-29 15:00:51 +08001461 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001462 ANGLE_VALIDATION_ERR(context, InvalidOperation(), PixelDataNotNull);
1463 return false;
1464 }
1465 if (level != 0)
1466 {
1467 ANGLE_VALIDATION_ERR(context, InvalidOperation(), LevelNotZero);
He Yunchaoced53ae2016-11-29 15:00:51 +08001468 return false;
1469 }
1470 break;
1471 default:
1472 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001473 }
1474
Geoff Lang6e898aa2017-06-02 11:17:26 -04001475 if (!isSubImage)
1476 {
1477 switch (internalformat)
1478 {
1479 case GL_RGBA32F:
1480 if (!context->getExtensions().colorBufferFloatRGBA)
1481 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001482 context->handleError(InvalidValue()
1483 << "Sized GL_RGBA32F internal format requires "
1484 "GL_CHROMIUM_color_buffer_float_rgba");
Geoff Lang6e898aa2017-06-02 11:17:26 -04001485 return false;
1486 }
1487 if (type != GL_FLOAT)
1488 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001489 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001490 return false;
1491 }
1492 if (format != GL_RGBA)
1493 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001494 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001495 return false;
1496 }
1497 break;
1498
1499 case GL_RGB32F:
1500 if (!context->getExtensions().colorBufferFloatRGB)
1501 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001502 context->handleError(InvalidValue()
1503 << "Sized GL_RGB32F internal format requires "
1504 "GL_CHROMIUM_color_buffer_float_rgb");
Geoff Lang6e898aa2017-06-02 11:17:26 -04001505 return false;
1506 }
1507 if (type != GL_FLOAT)
1508 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001509 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001510 return false;
1511 }
1512 if (format != GL_RGB)
1513 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001514 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001515 return false;
1516 }
1517 break;
1518
1519 default:
1520 break;
1521 }
1522 }
1523
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001524 if (type == GL_FLOAT)
1525 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001526 if (!context->getExtensions().textureFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001527 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001528 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001529 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001530 }
1531 }
1532 else if (type == GL_HALF_FLOAT_OES)
1533 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001534 if (!context->getExtensions().textureHalfFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001535 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001536 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001537 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001538 }
1539 }
1540 }
1541
Geoff Langdbcced82017-06-06 15:55:54 -04001542 GLenum sizeCheckFormat = isSubImage ? format : internalformat;
1543 if (!ValidImageDataSize(context, target, width, height, 1, sizeCheckFormat, type, pixels,
Geoff Langff5b2d52016-09-07 11:32:23 -04001544 imageSize))
1545 {
1546 return false;
1547 }
1548
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001549 return true;
1550}
1551
He Yunchaoced53ae2016-11-29 15:00:51 +08001552bool ValidateES2TexStorageParameters(Context *context,
1553 GLenum target,
1554 GLsizei levels,
1555 GLenum internalformat,
1556 GLsizei width,
1557 GLsizei height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001558{
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001559 if (target != GL_TEXTURE_2D && target != GL_TEXTURE_CUBE_MAP &&
1560 target != GL_TEXTURE_RECTANGLE_ANGLE)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001561 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001562 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001563 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001564 }
1565
1566 if (width < 1 || height < 1 || levels < 1)
1567 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001568 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001569 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001570 }
1571
1572 if (target == GL_TEXTURE_CUBE_MAP && width != height)
1573 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001574 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001575 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001576 }
1577
1578 if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1)
1579 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001580 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001581 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001582 }
1583
Geoff Langca271392017-04-05 12:30:00 -04001584 const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalformat);
Geoff Lang5d601382014-07-22 15:14:06 -04001585 if (formatInfo.format == GL_NONE || formatInfo.type == GL_NONE)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001586 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001587 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001588 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001589 }
1590
Geoff Langaae65a42014-05-26 12:43:44 -04001591 const gl::Caps &caps = context->getCaps();
1592
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001593 switch (target)
1594 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001595 case GL_TEXTURE_2D:
1596 if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
1597 static_cast<GLuint>(height) > caps.max2DTextureSize)
1598 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001599 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001600 return false;
1601 }
1602 break;
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001603 case GL_TEXTURE_RECTANGLE_ANGLE:
1604 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1605 static_cast<GLuint>(height) > caps.maxRectangleTextureSize || levels != 1)
1606 {
1607 context->handleError(InvalidValue());
1608 return false;
1609 }
1610 if (formatInfo.compressed)
1611 {
1612 context->handleError(InvalidEnum()
1613 << "Rectangle texture cannot have a compressed format.");
1614 return false;
1615 }
1616 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001617 case GL_TEXTURE_CUBE_MAP:
1618 if (static_cast<GLuint>(width) > caps.maxCubeMapTextureSize ||
1619 static_cast<GLuint>(height) > caps.maxCubeMapTextureSize)
1620 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001621 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001622 return false;
1623 }
1624 break;
1625 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001626 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001627 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001628 }
1629
Geoff Langc0b9ef42014-07-02 10:02:37 -04001630 if (levels != 1 && !context->getExtensions().textureNPOT)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001631 {
1632 if (!gl::isPow2(width) || !gl::isPow2(height))
1633 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001634 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001635 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001636 }
1637 }
1638
1639 switch (internalformat)
1640 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001641 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1642 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1643 if (!context->getExtensions().textureCompressionDXT1)
1644 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001645 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001646 return false;
1647 }
1648 break;
1649 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1650 if (!context->getExtensions().textureCompressionDXT3)
1651 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001652 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001653 return false;
1654 }
1655 break;
1656 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1657 if (!context->getExtensions().textureCompressionDXT5)
1658 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001659 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001660 return false;
1661 }
1662 break;
1663 case GL_ETC1_RGB8_OES:
1664 if (!context->getExtensions().compressedETC1RGB8Texture)
1665 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001666 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001667 return false;
1668 }
1669 break;
1670 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001671 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1672 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1673 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1674 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001675 if (!context->getExtensions().lossyETCDecode)
1676 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001677 context->handleError(InvalidEnum()
1678 << "ANGLE_lossy_etc_decode extension is not supported.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001679 return false;
1680 }
1681 break;
1682 case GL_RGBA32F_EXT:
1683 case GL_RGB32F_EXT:
1684 case GL_ALPHA32F_EXT:
1685 case GL_LUMINANCE32F_EXT:
1686 case GL_LUMINANCE_ALPHA32F_EXT:
1687 if (!context->getExtensions().textureFloat)
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_RGBA16F_EXT:
1694 case GL_RGB16F_EXT:
1695 case GL_ALPHA16F_EXT:
1696 case GL_LUMINANCE16F_EXT:
1697 case GL_LUMINANCE_ALPHA16F_EXT:
1698 if (!context->getExtensions().textureHalfFloat)
1699 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001700 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001701 return false;
1702 }
1703 break;
1704 case GL_R8_EXT:
1705 case GL_RG8_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001706 if (!context->getExtensions().textureRG)
1707 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001708 context->handleError(InvalidEnum());
Geoff Lang677bb6f2017-04-05 12:40:40 -04001709 return false;
1710 }
1711 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001712 case GL_R16F_EXT:
1713 case GL_RG16F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001714 if (!context->getExtensions().textureRG || !context->getExtensions().textureHalfFloat)
1715 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001716 context->handleError(InvalidEnum());
Geoff Lang677bb6f2017-04-05 12:40:40 -04001717 return false;
1718 }
1719 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001720 case GL_R32F_EXT:
1721 case GL_RG32F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001722 if (!context->getExtensions().textureRG || !context->getExtensions().textureFloat)
He Yunchaoced53ae2016-11-29 15:00:51 +08001723 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001724 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001725 return false;
1726 }
1727 break;
1728 case GL_DEPTH_COMPONENT16:
1729 case GL_DEPTH_COMPONENT32_OES:
1730 case GL_DEPTH24_STENCIL8_OES:
1731 if (!context->getExtensions().depthTextures)
1732 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001733 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001734 return false;
1735 }
1736 if (target != GL_TEXTURE_2D)
1737 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001738 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001739 return false;
1740 }
1741 // ANGLE_depth_texture only supports 1-level textures
1742 if (levels != 1)
1743 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001744 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001745 return false;
1746 }
1747 break;
1748 default:
1749 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001750 }
1751
Geoff Lang691e58c2014-12-19 17:03:25 -05001752 gl::Texture *texture = context->getTargetTexture(target);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001753 if (!texture || texture->id() == 0)
1754 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001755 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001756 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001757 }
1758
Geoff Lang69cce582015-09-17 13:20:36 -04001759 if (texture->getImmutableFormat())
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001760 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001761 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001762 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001763 }
1764
1765 return true;
1766}
1767
He Yunchaoced53ae2016-11-29 15:00:51 +08001768bool ValidateDiscardFramebufferEXT(Context *context,
1769 GLenum target,
1770 GLsizei numAttachments,
Austin Kinross08332632015-05-05 13:35:47 -07001771 const GLenum *attachments)
1772{
Jamie Madillc29968b2016-01-20 11:17:23 -05001773 if (!context->getExtensions().discardFramebuffer)
1774 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001775 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Jamie Madillc29968b2016-01-20 11:17:23 -05001776 return false;
1777 }
1778
Austin Kinross08332632015-05-05 13:35:47 -07001779 bool defaultFramebuffer = false;
1780
1781 switch (target)
1782 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001783 case GL_FRAMEBUFFER:
1784 defaultFramebuffer =
1785 (context->getGLState().getTargetFramebuffer(GL_FRAMEBUFFER)->id() == 0);
1786 break;
1787 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001788 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
He Yunchaoced53ae2016-11-29 15:00:51 +08001789 return false;
Austin Kinross08332632015-05-05 13:35:47 -07001790 }
1791
He Yunchaoced53ae2016-11-29 15:00:51 +08001792 return ValidateDiscardFramebufferBase(context, target, numAttachments, attachments,
1793 defaultFramebuffer);
Austin Kinross08332632015-05-05 13:35:47 -07001794}
1795
Austin Kinrossbc781f32015-10-26 09:27:38 -07001796bool ValidateBindVertexArrayOES(Context *context, GLuint array)
1797{
1798 if (!context->getExtensions().vertexArrayObject)
1799 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001800 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001801 return false;
1802 }
1803
1804 return ValidateBindVertexArrayBase(context, array);
1805}
1806
Jamie Madilld7576732017-08-26 18:49:50 -04001807bool ValidateDeleteVertexArraysOES(Context *context, GLsizei n, const GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001808{
1809 if (!context->getExtensions().vertexArrayObject)
1810 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001811 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001812 return false;
1813 }
1814
Olli Etuaho41997e72016-03-10 13:38:39 +02001815 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001816}
1817
Jamie Madilld7576732017-08-26 18:49:50 -04001818bool ValidateGenVertexArraysOES(Context *context, GLsizei n, GLuint *arrays)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001819{
1820 if (!context->getExtensions().vertexArrayObject)
1821 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001822 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001823 return false;
1824 }
1825
Olli Etuaho41997e72016-03-10 13:38:39 +02001826 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001827}
1828
Jamie Madilld7576732017-08-26 18:49:50 -04001829bool ValidateIsVertexArrayOES(Context *context, GLuint array)
Austin Kinrossbc781f32015-10-26 09:27:38 -07001830{
1831 if (!context->getExtensions().vertexArrayObject)
1832 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001833 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001834 return false;
1835 }
1836
1837 return true;
1838}
Geoff Langc5629752015-12-07 16:29:04 -05001839
1840bool ValidateProgramBinaryOES(Context *context,
1841 GLuint program,
1842 GLenum binaryFormat,
1843 const void *binary,
1844 GLint length)
1845{
1846 if (!context->getExtensions().getProgramBinary)
1847 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001848 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05001849 return false;
1850 }
1851
1852 return ValidateProgramBinaryBase(context, program, binaryFormat, binary, length);
1853}
1854
1855bool ValidateGetProgramBinaryOES(Context *context,
1856 GLuint program,
1857 GLsizei bufSize,
1858 GLsizei *length,
1859 GLenum *binaryFormat,
1860 void *binary)
1861{
1862 if (!context->getExtensions().getProgramBinary)
1863 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001864 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05001865 return false;
1866 }
1867
1868 return ValidateGetProgramBinaryBase(context, program, bufSize, length, binaryFormat, binary);
1869}
Geoff Lange102fee2015-12-10 11:23:30 -05001870
Geoff Lang70d0f492015-12-10 17:45:46 -05001871static bool ValidDebugSource(GLenum source, bool mustBeThirdPartyOrApplication)
1872{
1873 switch (source)
1874 {
1875 case GL_DEBUG_SOURCE_API:
1876 case GL_DEBUG_SOURCE_SHADER_COMPILER:
1877 case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
1878 case GL_DEBUG_SOURCE_OTHER:
1879 // Only THIRD_PARTY and APPLICATION sources are allowed to be manually inserted
1880 return !mustBeThirdPartyOrApplication;
1881
1882 case GL_DEBUG_SOURCE_THIRD_PARTY:
1883 case GL_DEBUG_SOURCE_APPLICATION:
1884 return true;
1885
1886 default:
1887 return false;
1888 }
1889}
1890
1891static bool ValidDebugType(GLenum type)
1892{
1893 switch (type)
1894 {
1895 case GL_DEBUG_TYPE_ERROR:
1896 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
1897 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
1898 case GL_DEBUG_TYPE_PERFORMANCE:
1899 case GL_DEBUG_TYPE_PORTABILITY:
1900 case GL_DEBUG_TYPE_OTHER:
1901 case GL_DEBUG_TYPE_MARKER:
1902 case GL_DEBUG_TYPE_PUSH_GROUP:
1903 case GL_DEBUG_TYPE_POP_GROUP:
1904 return true;
1905
1906 default:
1907 return false;
1908 }
1909}
1910
1911static bool ValidDebugSeverity(GLenum severity)
1912{
1913 switch (severity)
1914 {
1915 case GL_DEBUG_SEVERITY_HIGH:
1916 case GL_DEBUG_SEVERITY_MEDIUM:
1917 case GL_DEBUG_SEVERITY_LOW:
1918 case GL_DEBUG_SEVERITY_NOTIFICATION:
1919 return true;
1920
1921 default:
1922 return false;
1923 }
1924}
1925
Geoff Lange102fee2015-12-10 11:23:30 -05001926bool ValidateDebugMessageControlKHR(Context *context,
1927 GLenum source,
1928 GLenum type,
1929 GLenum severity,
1930 GLsizei count,
1931 const GLuint *ids,
1932 GLboolean enabled)
1933{
1934 if (!context->getExtensions().debug)
1935 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001936 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05001937 return false;
1938 }
1939
Geoff Lang70d0f492015-12-10 17:45:46 -05001940 if (!ValidDebugSource(source, false) && source != GL_DONT_CARE)
1941 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001942 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05001943 return false;
1944 }
1945
1946 if (!ValidDebugType(type) && type != GL_DONT_CARE)
1947 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001948 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05001949 return false;
1950 }
1951
1952 if (!ValidDebugSeverity(severity) && severity != GL_DONT_CARE)
1953 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001954 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSeverity);
Geoff Lang70d0f492015-12-10 17:45:46 -05001955 return false;
1956 }
1957
1958 if (count > 0)
1959 {
1960 if (source == GL_DONT_CARE || type == GL_DONT_CARE)
1961 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001962 context->handleError(
1963 InvalidOperation()
1964 << "If count is greater than zero, source and severity cannot be GL_DONT_CARE.");
Geoff Lang70d0f492015-12-10 17:45:46 -05001965 return false;
1966 }
1967
1968 if (severity != GL_DONT_CARE)
1969 {
Jamie Madill437fa652016-05-03 15:13:24 -04001970 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001971 InvalidOperation()
1972 << "If count is greater than zero, severity must be GL_DONT_CARE.");
Geoff Lang70d0f492015-12-10 17:45:46 -05001973 return false;
1974 }
1975 }
1976
Geoff Lange102fee2015-12-10 11:23:30 -05001977 return true;
1978}
1979
1980bool ValidateDebugMessageInsertKHR(Context *context,
1981 GLenum source,
1982 GLenum type,
1983 GLuint id,
1984 GLenum severity,
1985 GLsizei length,
1986 const GLchar *buf)
1987{
1988 if (!context->getExtensions().debug)
1989 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001990 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05001991 return false;
1992 }
1993
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001994 if (!context->getGLState().getDebug().isOutputEnabled())
Geoff Lang70d0f492015-12-10 17:45:46 -05001995 {
1996 // If the DEBUG_OUTPUT state is disabled calls to DebugMessageInsert are discarded and do
1997 // not generate an error.
1998 return false;
1999 }
2000
2001 if (!ValidDebugSeverity(severity))
2002 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002003 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002004 return false;
2005 }
2006
2007 if (!ValidDebugType(type))
2008 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002009 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05002010 return false;
2011 }
2012
2013 if (!ValidDebugSource(source, true))
2014 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002015 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002016 return false;
2017 }
2018
2019 size_t messageLength = (length < 0) ? strlen(buf) : length;
2020 if (messageLength > context->getExtensions().maxDebugMessageLength)
2021 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002022 context->handleError(InvalidValue()
2023 << "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002024 return false;
2025 }
2026
Geoff Lange102fee2015-12-10 11:23:30 -05002027 return true;
2028}
2029
2030bool ValidateDebugMessageCallbackKHR(Context *context,
2031 GLDEBUGPROCKHR callback,
2032 const void *userParam)
2033{
2034 if (!context->getExtensions().debug)
2035 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002036 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002037 return false;
2038 }
2039
Geoff Lange102fee2015-12-10 11:23:30 -05002040 return true;
2041}
2042
2043bool ValidateGetDebugMessageLogKHR(Context *context,
2044 GLuint count,
2045 GLsizei bufSize,
2046 GLenum *sources,
2047 GLenum *types,
2048 GLuint *ids,
2049 GLenum *severities,
2050 GLsizei *lengths,
2051 GLchar *messageLog)
2052{
2053 if (!context->getExtensions().debug)
2054 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002055 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002056 return false;
2057 }
2058
Geoff Lang70d0f492015-12-10 17:45:46 -05002059 if (bufSize < 0 && messageLog != nullptr)
2060 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002061 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002062 return false;
2063 }
2064
Geoff Lange102fee2015-12-10 11:23:30 -05002065 return true;
2066}
2067
2068bool ValidatePushDebugGroupKHR(Context *context,
2069 GLenum source,
2070 GLuint id,
2071 GLsizei length,
2072 const GLchar *message)
2073{
2074 if (!context->getExtensions().debug)
2075 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002076 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002077 return false;
2078 }
2079
Geoff Lang70d0f492015-12-10 17:45:46 -05002080 if (!ValidDebugSource(source, true))
2081 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002082 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002083 return false;
2084 }
2085
2086 size_t messageLength = (length < 0) ? strlen(message) : length;
2087 if (messageLength > context->getExtensions().maxDebugMessageLength)
2088 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002089 context->handleError(InvalidValue()
2090 << "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002091 return false;
2092 }
2093
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002094 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002095 if (currentStackSize >= context->getExtensions().maxDebugGroupStackDepth)
2096 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002097 context
2098 ->handleError(StackOverflow()
2099 << "Cannot push more than GL_MAX_DEBUG_GROUP_STACK_DEPTH debug groups.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002100 return false;
2101 }
2102
Geoff Lange102fee2015-12-10 11:23:30 -05002103 return true;
2104}
2105
2106bool ValidatePopDebugGroupKHR(Context *context)
2107{
2108 if (!context->getExtensions().debug)
2109 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002110 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002111 return false;
2112 }
2113
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002114 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002115 if (currentStackSize <= 1)
2116 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002117 context->handleError(StackUnderflow() << "Cannot pop the default debug group.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002118 return false;
2119 }
2120
2121 return true;
2122}
2123
2124static bool ValidateObjectIdentifierAndName(Context *context, GLenum identifier, GLuint name)
2125{
2126 switch (identifier)
2127 {
2128 case GL_BUFFER:
2129 if (context->getBuffer(name) == nullptr)
2130 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002131 context->handleError(InvalidValue() << "name is not a valid buffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002132 return false;
2133 }
2134 return true;
2135
2136 case GL_SHADER:
2137 if (context->getShader(name) == nullptr)
2138 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002139 context->handleError(InvalidValue() << "name is not a valid shader.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002140 return false;
2141 }
2142 return true;
2143
2144 case GL_PROGRAM:
2145 if (context->getProgram(name) == nullptr)
2146 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002147 context->handleError(InvalidValue() << "name is not a valid program.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002148 return false;
2149 }
2150 return true;
2151
2152 case GL_VERTEX_ARRAY:
2153 if (context->getVertexArray(name) == nullptr)
2154 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002155 context->handleError(InvalidValue() << "name is not a valid vertex array.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002156 return false;
2157 }
2158 return true;
2159
2160 case GL_QUERY:
2161 if (context->getQuery(name) == nullptr)
2162 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002163 context->handleError(InvalidValue() << "name is not a valid query.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002164 return false;
2165 }
2166 return true;
2167
2168 case GL_TRANSFORM_FEEDBACK:
2169 if (context->getTransformFeedback(name) == nullptr)
2170 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002171 context->handleError(InvalidValue() << "name is not a valid transform feedback.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002172 return false;
2173 }
2174 return true;
2175
2176 case GL_SAMPLER:
2177 if (context->getSampler(name) == nullptr)
2178 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002179 context->handleError(InvalidValue() << "name is not a valid sampler.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002180 return false;
2181 }
2182 return true;
2183
2184 case GL_TEXTURE:
2185 if (context->getTexture(name) == nullptr)
2186 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002187 context->handleError(InvalidValue() << "name is not a valid texture.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002188 return false;
2189 }
2190 return true;
2191
2192 case GL_RENDERBUFFER:
2193 if (context->getRenderbuffer(name) == nullptr)
2194 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002195 context->handleError(InvalidValue() << "name is not a valid renderbuffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002196 return false;
2197 }
2198 return true;
2199
2200 case GL_FRAMEBUFFER:
2201 if (context->getFramebuffer(name) == nullptr)
2202 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002203 context->handleError(InvalidValue() << "name is not a valid framebuffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002204 return false;
2205 }
2206 return true;
2207
2208 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002209 context->handleError(InvalidEnum() << "Invalid identifier.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002210 return false;
2211 }
Geoff Lange102fee2015-12-10 11:23:30 -05002212}
2213
Martin Radev9d901792016-07-15 15:58:58 +03002214static bool ValidateLabelLength(Context *context, GLsizei length, const GLchar *label)
2215{
2216 size_t labelLength = 0;
2217
2218 if (length < 0)
2219 {
2220 if (label != nullptr)
2221 {
2222 labelLength = strlen(label);
2223 }
2224 }
2225 else
2226 {
2227 labelLength = static_cast<size_t>(length);
2228 }
2229
2230 if (labelLength > context->getExtensions().maxLabelLength)
2231 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002232 context->handleError(InvalidValue() << "Label length is larger than GL_MAX_LABEL_LENGTH.");
Martin Radev9d901792016-07-15 15:58:58 +03002233 return false;
2234 }
2235
2236 return true;
2237}
2238
Geoff Lange102fee2015-12-10 11:23:30 -05002239bool ValidateObjectLabelKHR(Context *context,
2240 GLenum identifier,
2241 GLuint name,
2242 GLsizei length,
2243 const GLchar *label)
2244{
2245 if (!context->getExtensions().debug)
2246 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002247 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002248 return false;
2249 }
2250
Geoff Lang70d0f492015-12-10 17:45:46 -05002251 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2252 {
2253 return false;
2254 }
2255
Martin Radev9d901792016-07-15 15:58:58 +03002256 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002257 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002258 return false;
2259 }
2260
Geoff Lange102fee2015-12-10 11:23:30 -05002261 return true;
2262}
2263
2264bool ValidateGetObjectLabelKHR(Context *context,
2265 GLenum identifier,
2266 GLuint name,
2267 GLsizei bufSize,
2268 GLsizei *length,
2269 GLchar *label)
2270{
2271 if (!context->getExtensions().debug)
2272 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002273 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002274 return false;
2275 }
2276
Geoff Lang70d0f492015-12-10 17:45:46 -05002277 if (bufSize < 0)
2278 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002279 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002280 return false;
2281 }
2282
2283 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2284 {
2285 return false;
2286 }
2287
Martin Radev9d901792016-07-15 15:58:58 +03002288 return true;
Geoff Lang70d0f492015-12-10 17:45:46 -05002289}
2290
2291static bool ValidateObjectPtrName(Context *context, const void *ptr)
2292{
Jamie Madill70b5bb02017-08-28 13:32:37 -04002293 if (context->getSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr))) == nullptr)
Geoff Lang70d0f492015-12-10 17:45:46 -05002294 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002295 context->handleError(InvalidValue() << "name is not a valid sync.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002296 return false;
2297 }
2298
Geoff Lange102fee2015-12-10 11:23:30 -05002299 return true;
2300}
2301
2302bool ValidateObjectPtrLabelKHR(Context *context,
2303 const void *ptr,
2304 GLsizei length,
2305 const GLchar *label)
2306{
2307 if (!context->getExtensions().debug)
2308 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002309 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002310 return false;
2311 }
2312
Geoff Lang70d0f492015-12-10 17:45:46 -05002313 if (!ValidateObjectPtrName(context, ptr))
2314 {
2315 return false;
2316 }
2317
Martin Radev9d901792016-07-15 15:58:58 +03002318 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002319 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002320 return false;
2321 }
2322
Geoff Lange102fee2015-12-10 11:23:30 -05002323 return true;
2324}
2325
2326bool ValidateGetObjectPtrLabelKHR(Context *context,
2327 const void *ptr,
2328 GLsizei bufSize,
2329 GLsizei *length,
2330 GLchar *label)
2331{
2332 if (!context->getExtensions().debug)
2333 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002334 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002335 return false;
2336 }
2337
Geoff Lang70d0f492015-12-10 17:45:46 -05002338 if (bufSize < 0)
2339 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002340 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002341 return false;
2342 }
2343
2344 if (!ValidateObjectPtrName(context, ptr))
2345 {
2346 return false;
2347 }
2348
Martin Radev9d901792016-07-15 15:58:58 +03002349 return true;
Geoff Lange102fee2015-12-10 11:23:30 -05002350}
2351
2352bool ValidateGetPointervKHR(Context *context, GLenum pname, void **params)
2353{
2354 if (!context->getExtensions().debug)
2355 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002356 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002357 return false;
2358 }
2359
Geoff Lang70d0f492015-12-10 17:45:46 -05002360 // TODO: represent this in Context::getQueryParameterInfo.
2361 switch (pname)
2362 {
2363 case GL_DEBUG_CALLBACK_FUNCTION:
2364 case GL_DEBUG_CALLBACK_USER_PARAM:
2365 break;
2366
2367 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07002368 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Geoff Lang70d0f492015-12-10 17:45:46 -05002369 return false;
2370 }
2371
Geoff Lange102fee2015-12-10 11:23:30 -05002372 return true;
2373}
Jamie Madillc29968b2016-01-20 11:17:23 -05002374
2375bool ValidateBlitFramebufferANGLE(Context *context,
2376 GLint srcX0,
2377 GLint srcY0,
2378 GLint srcX1,
2379 GLint srcY1,
2380 GLint dstX0,
2381 GLint dstY0,
2382 GLint dstX1,
2383 GLint dstY1,
2384 GLbitfield mask,
2385 GLenum filter)
2386{
2387 if (!context->getExtensions().framebufferBlit)
2388 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002389 context->handleError(InvalidOperation() << "Blit extension not available.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002390 return false;
2391 }
2392
2393 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
2394 {
2395 // TODO(jmadill): Determine if this should be available on other implementations.
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002396 context->handleError(InvalidOperation() << "Scaling and flipping in "
2397 "BlitFramebufferANGLE not supported by this "
2398 "implementation.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002399 return false;
2400 }
2401
2402 if (filter == GL_LINEAR)
2403 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002404 context->handleError(InvalidEnum() << "Linear blit not supported in this extension");
Jamie Madillc29968b2016-01-20 11:17:23 -05002405 return false;
2406 }
2407
Jamie Madill51f40ec2016-06-15 14:06:00 -04002408 Framebuffer *readFramebuffer = context->getGLState().getReadFramebuffer();
2409 Framebuffer *drawFramebuffer = context->getGLState().getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002410
2411 if (mask & GL_COLOR_BUFFER_BIT)
2412 {
2413 const FramebufferAttachment *readColorAttachment = readFramebuffer->getReadColorbuffer();
2414 const FramebufferAttachment *drawColorAttachment = drawFramebuffer->getFirstColorbuffer();
2415
2416 if (readColorAttachment && drawColorAttachment)
2417 {
2418 if (!(readColorAttachment->type() == GL_TEXTURE &&
2419 readColorAttachment->getTextureImageIndex().type == GL_TEXTURE_2D) &&
2420 readColorAttachment->type() != GL_RENDERBUFFER &&
2421 readColorAttachment->type() != GL_FRAMEBUFFER_DEFAULT)
2422 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002423 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002424 return false;
2425 }
2426
Geoff Langa15472a2015-08-11 11:48:03 -04002427 for (size_t drawbufferIdx = 0;
2428 drawbufferIdx < drawFramebuffer->getDrawbufferStateCount(); ++drawbufferIdx)
Jamie Madillc29968b2016-01-20 11:17:23 -05002429 {
Geoff Langa15472a2015-08-11 11:48:03 -04002430 const FramebufferAttachment *attachment =
2431 drawFramebuffer->getDrawBuffer(drawbufferIdx);
2432 if (attachment)
Jamie Madillc29968b2016-01-20 11:17:23 -05002433 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002434 if (!(attachment->type() == GL_TEXTURE &&
2435 attachment->getTextureImageIndex().type == GL_TEXTURE_2D) &&
2436 attachment->type() != GL_RENDERBUFFER &&
2437 attachment->type() != GL_FRAMEBUFFER_DEFAULT)
2438 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002439 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002440 return false;
2441 }
2442
2443 // Return an error if the destination formats do not match
Kenneth Russell69382852017-07-21 16:38:44 -04002444 if (!Format::EquivalentForBlit(attachment->getFormat(),
2445 readColorAttachment->getFormat()))
Jamie Madillc29968b2016-01-20 11:17:23 -05002446 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002447 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002448 return false;
2449 }
2450 }
2451 }
2452
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002453 if (readFramebuffer->getSamples(context) != 0 &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002454 IsPartialBlit(context, readColorAttachment, drawColorAttachment, srcX0, srcY0,
2455 srcX1, srcY1, dstX0, dstY0, dstX1, dstY1))
2456 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002457 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002458 return false;
2459 }
2460 }
2461 }
2462
2463 GLenum masks[] = {GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT};
2464 GLenum attachments[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
2465 for (size_t i = 0; i < 2; i++)
2466 {
2467 if (mask & masks[i])
2468 {
2469 const FramebufferAttachment *readBuffer =
2470 readFramebuffer->getAttachment(attachments[i]);
2471 const FramebufferAttachment *drawBuffer =
2472 drawFramebuffer->getAttachment(attachments[i]);
2473
2474 if (readBuffer && drawBuffer)
2475 {
2476 if (IsPartialBlit(context, readBuffer, drawBuffer, srcX0, srcY0, srcX1, srcY1,
2477 dstX0, dstY0, dstX1, dstY1))
2478 {
2479 // only whole-buffer copies are permitted
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002480 context->handleError(InvalidOperation() << "Only whole-buffer depth and "
2481 "stencil blits are supported by "
2482 "this extension.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002483 return false;
2484 }
2485
2486 if (readBuffer->getSamples() != 0 || drawBuffer->getSamples() != 0)
2487 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002488 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002489 return false;
2490 }
2491 }
2492 }
2493 }
2494
2495 return ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0,
2496 dstX1, dstY1, mask, filter);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04002497}
Jamie Madillc29968b2016-01-20 11:17:23 -05002498
2499bool ValidateClear(ValidationContext *context, GLbitfield mask)
2500{
Jamie Madill51f40ec2016-06-15 14:06:00 -04002501 auto fbo = context->getGLState().getDrawFramebuffer();
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002502 if (fbo->checkStatus(context) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002503 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002504 context->handleError(InvalidFramebufferOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002505 return false;
2506 }
2507
2508 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
2509 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002510 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidClearMask);
Jamie Madillc29968b2016-01-20 11:17:23 -05002511 return false;
2512 }
2513
Geoff Lang76e65652017-03-27 14:58:02 -04002514 if (context->getExtensions().webglCompatibility && (mask & GL_COLOR_BUFFER_BIT) != 0)
2515 {
2516 constexpr GLenum validComponentTypes[] = {GL_FLOAT, GL_UNSIGNED_NORMALIZED,
2517 GL_SIGNED_NORMALIZED};
2518
Corentin Wallez59c41592017-07-11 13:19:54 -04002519 for (GLuint drawBufferIdx = 0; drawBufferIdx < fbo->getDrawbufferStateCount();
Geoff Lang76e65652017-03-27 14:58:02 -04002520 drawBufferIdx++)
2521 {
2522 if (!ValidateWebGLFramebufferAttachmentClearType(
2523 context, drawBufferIdx, validComponentTypes, ArraySize(validComponentTypes)))
2524 {
2525 return false;
2526 }
2527 }
2528 }
2529
Jamie Madillc29968b2016-01-20 11:17:23 -05002530 return true;
2531}
2532
2533bool ValidateDrawBuffersEXT(ValidationContext *context, GLsizei n, const GLenum *bufs)
2534{
2535 if (!context->getExtensions().drawBuffers)
2536 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002537 context->handleError(InvalidOperation() << "Extension not supported.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002538 return false;
2539 }
2540
2541 return ValidateDrawBuffersBase(context, n, bufs);
2542}
2543
Jamie Madill73a84962016-02-12 09:27:23 -05002544bool ValidateTexImage2D(Context *context,
2545 GLenum target,
2546 GLint level,
2547 GLint internalformat,
2548 GLsizei width,
2549 GLsizei height,
2550 GLint border,
2551 GLenum format,
2552 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002553 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002554{
Martin Radev1be913c2016-07-11 17:59:16 +03002555 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002556 {
2557 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
Geoff Langff5b2d52016-09-07 11:32:23 -04002558 0, 0, width, height, border, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002559 }
2560
Martin Radev1be913c2016-07-11 17:59:16 +03002561 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002562 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002563 0, 0, width, height, 1, border, format, type, -1,
2564 pixels);
2565}
2566
2567bool ValidateTexImage2DRobust(Context *context,
2568 GLenum target,
2569 GLint level,
2570 GLint internalformat,
2571 GLsizei width,
2572 GLsizei height,
2573 GLint border,
2574 GLenum format,
2575 GLenum type,
2576 GLsizei bufSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002577 const void *pixels)
Geoff Langff5b2d52016-09-07 11:32:23 -04002578{
2579 if (!ValidateRobustEntryPoint(context, bufSize))
2580 {
2581 return false;
2582 }
2583
2584 if (context->getClientMajorVersion() < 3)
2585 {
2586 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
2587 0, 0, width, height, border, format, type, bufSize,
2588 pixels);
2589 }
2590
2591 ASSERT(context->getClientMajorVersion() >= 3);
2592 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
2593 0, 0, width, height, 1, border, format, type, bufSize,
2594 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002595}
2596
2597bool ValidateTexSubImage2D(Context *context,
2598 GLenum target,
2599 GLint level,
2600 GLint xoffset,
2601 GLint yoffset,
2602 GLsizei width,
2603 GLsizei height,
2604 GLenum format,
2605 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002606 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002607{
2608
Martin Radev1be913c2016-07-11 17:59:16 +03002609 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002610 {
2611 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002612 yoffset, width, height, 0, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002613 }
2614
Martin Radev1be913c2016-07-11 17:59:16 +03002615 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002616 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002617 yoffset, 0, width, height, 1, 0, format, type, -1,
2618 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002619}
2620
Geoff Langc52f6f12016-10-14 10:18:00 -04002621bool ValidateTexSubImage2DRobustANGLE(Context *context,
2622 GLenum target,
2623 GLint level,
2624 GLint xoffset,
2625 GLint yoffset,
2626 GLsizei width,
2627 GLsizei height,
2628 GLenum format,
2629 GLenum type,
2630 GLsizei bufSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002631 const void *pixels)
Geoff Langc52f6f12016-10-14 10:18:00 -04002632{
2633 if (!ValidateRobustEntryPoint(context, bufSize))
2634 {
2635 return false;
2636 }
2637
2638 if (context->getClientMajorVersion() < 3)
2639 {
2640 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
2641 yoffset, width, height, 0, format, type, bufSize,
2642 pixels);
2643 }
2644
2645 ASSERT(context->getClientMajorVersion() >= 3);
2646 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
2647 yoffset, 0, width, height, 1, 0, format, type, bufSize,
2648 pixels);
2649}
2650
Jamie Madill73a84962016-02-12 09:27:23 -05002651bool ValidateCompressedTexImage2D(Context *context,
2652 GLenum target,
2653 GLint level,
2654 GLenum internalformat,
2655 GLsizei width,
2656 GLsizei height,
2657 GLint border,
2658 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002659 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002660{
Martin Radev1be913c2016-07-11 17:59:16 +03002661 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002662 {
2663 if (!ValidateES2TexImageParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002664 0, width, height, border, GL_NONE, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002665 {
2666 return false;
2667 }
2668 }
2669 else
2670 {
Martin Radev1be913c2016-07-11 17:59:16 +03002671 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002672 if (!ValidateES3TexImage2DParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002673 0, 0, width, height, 1, border, GL_NONE, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002674 data))
2675 {
2676 return false;
2677 }
2678 }
2679
Geoff Langca271392017-04-05 12:30:00 -04002680 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalformat);
Jamie Madill513558d2016-06-02 13:04:11 -04002681 auto blockSizeOrErr =
Jamie Madill4b4cdff2016-06-06 13:53:38 -07002682 formatInfo.computeCompressedImageSize(GL_UNSIGNED_BYTE, gl::Extents(width, height, 1));
Jamie Madille2e406c2016-06-02 13:04:10 -04002683 if (blockSizeOrErr.isError())
2684 {
2685 context->handleError(blockSizeOrErr.getError());
2686 return false;
2687 }
2688
2689 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSizeOrErr.getResult())
Jamie Madill73a84962016-02-12 09:27:23 -05002690 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002691 ANGLE_VALIDATION_ERR(context, InvalidValue(), CompressedTextureDimensionsMustMatchData);
Jamie Madill73a84962016-02-12 09:27:23 -05002692 return false;
2693 }
2694
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002695 if (target == GL_TEXTURE_RECTANGLE_ANGLE)
2696 {
2697 context->handleError(InvalidEnum() << "Rectangle texture cannot have a compressed format.");
2698 return false;
2699 }
2700
Jamie Madill73a84962016-02-12 09:27:23 -05002701 return true;
2702}
2703
Corentin Wallezb2931602017-04-11 15:58:57 -04002704bool ValidateCompressedTexImage2DRobustANGLE(Context *context,
2705 GLenum target,
2706 GLint level,
2707 GLenum internalformat,
2708 GLsizei width,
2709 GLsizei height,
2710 GLint border,
2711 GLsizei imageSize,
2712 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002713 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002714{
2715 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2716 {
2717 return false;
2718 }
2719
2720 return ValidateCompressedTexImage2D(context, target, level, internalformat, width, height,
2721 border, imageSize, data);
2722}
2723bool ValidateCompressedTexSubImage2DRobustANGLE(Context *context,
2724 GLenum target,
2725 GLint level,
2726 GLint xoffset,
2727 GLint yoffset,
2728 GLsizei width,
2729 GLsizei height,
2730 GLenum format,
2731 GLsizei imageSize,
2732 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002733 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002734{
2735 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2736 {
2737 return false;
2738 }
2739
2740 return ValidateCompressedTexSubImage2D(context, target, level, xoffset, yoffset, width, height,
2741 format, imageSize, data);
2742}
2743
Jamie Madill73a84962016-02-12 09:27:23 -05002744bool ValidateCompressedTexSubImage2D(Context *context,
2745 GLenum target,
2746 GLint level,
2747 GLint xoffset,
2748 GLint yoffset,
2749 GLsizei width,
2750 GLsizei height,
2751 GLenum format,
2752 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002753 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002754{
Martin Radev1be913c2016-07-11 17:59:16 +03002755 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002756 {
2757 if (!ValidateES2TexImageParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002758 yoffset, width, height, 0, format, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002759 {
2760 return false;
2761 }
2762 }
2763 else
2764 {
Martin Radev1be913c2016-07-11 17:59:16 +03002765 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002766 if (!ValidateES3TexImage2DParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002767 yoffset, 0, width, height, 1, 0, format, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002768 data))
2769 {
2770 return false;
2771 }
2772 }
2773
Geoff Langca271392017-04-05 12:30:00 -04002774 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(format);
Jamie Madill513558d2016-06-02 13:04:11 -04002775 auto blockSizeOrErr =
Jamie Madill4b4cdff2016-06-06 13:53:38 -07002776 formatInfo.computeCompressedImageSize(GL_UNSIGNED_BYTE, gl::Extents(width, height, 1));
Jamie Madille2e406c2016-06-02 13:04:10 -04002777 if (blockSizeOrErr.isError())
2778 {
2779 context->handleError(blockSizeOrErr.getError());
2780 return false;
2781 }
2782
2783 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSizeOrErr.getResult())
Jamie Madill73a84962016-02-12 09:27:23 -05002784 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002785 context->handleError(InvalidValue());
Jamie Madill73a84962016-02-12 09:27:23 -05002786 return false;
2787 }
2788
2789 return true;
2790}
2791
Olli Etuaho4f667482016-03-30 15:56:35 +03002792bool ValidateGetBufferPointervOES(Context *context, GLenum target, GLenum pname, void **params)
2793{
Geoff Lang496c02d2016-10-20 11:38:11 -07002794 return ValidateGetBufferPointervBase(context, target, pname, nullptr, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03002795}
2796
2797bool ValidateMapBufferOES(Context *context, GLenum target, GLenum access)
2798{
2799 if (!context->getExtensions().mapBuffer)
2800 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002801 context->handleError(InvalidOperation() << "Map buffer extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002802 return false;
2803 }
2804
2805 if (!ValidBufferTarget(context, target))
2806 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002807 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03002808 return false;
2809 }
2810
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002811 Buffer *buffer = context->getGLState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002812
2813 if (buffer == nullptr)
2814 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002815 context->handleError(InvalidOperation() << "Attempted to map buffer object zero.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002816 return false;
2817 }
2818
2819 if (access != GL_WRITE_ONLY_OES)
2820 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002821 context->handleError(InvalidEnum() << "Non-write buffer mapping not supported.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002822 return false;
2823 }
2824
2825 if (buffer->isMapped())
2826 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002827 context->handleError(InvalidOperation() << "Buffer is already mapped.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002828 return false;
2829 }
2830
Geoff Lang79f71042017-08-14 16:43:43 -04002831 return ValidateMapBufferBase(context, target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002832}
2833
2834bool ValidateUnmapBufferOES(Context *context, GLenum target)
2835{
2836 if (!context->getExtensions().mapBuffer)
2837 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002838 context->handleError(InvalidOperation() << "Map buffer extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002839 return false;
2840 }
2841
2842 return ValidateUnmapBufferBase(context, target);
2843}
2844
2845bool ValidateMapBufferRangeEXT(Context *context,
2846 GLenum target,
2847 GLintptr offset,
2848 GLsizeiptr length,
2849 GLbitfield access)
2850{
2851 if (!context->getExtensions().mapBufferRange)
2852 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002853 context->handleError(InvalidOperation() << "Map buffer range extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002854 return false;
2855 }
2856
2857 return ValidateMapBufferRangeBase(context, target, offset, length, access);
2858}
2859
Geoff Lang79f71042017-08-14 16:43:43 -04002860bool ValidateMapBufferBase(Context *context, GLenum target)
2861{
2862 Buffer *buffer = context->getGLState().getTargetBuffer(target);
2863 ASSERT(buffer != nullptr);
2864
2865 // Check if this buffer is currently being used as a transform feedback output buffer
2866 TransformFeedback *transformFeedback = context->getGLState().getCurrentTransformFeedback();
2867 if (transformFeedback != nullptr && transformFeedback->isActive())
2868 {
2869 for (size_t i = 0; i < transformFeedback->getIndexedBufferCount(); i++)
2870 {
2871 const auto &transformFeedbackBuffer = transformFeedback->getIndexedBuffer(i);
2872 if (transformFeedbackBuffer.get() == buffer)
2873 {
2874 context->handleError(InvalidOperation()
2875 << "Buffer is currently bound for transform feedback.");
2876 return false;
2877 }
2878 }
2879 }
2880
2881 return true;
2882}
2883
Olli Etuaho4f667482016-03-30 15:56:35 +03002884bool ValidateFlushMappedBufferRangeEXT(Context *context,
2885 GLenum target,
2886 GLintptr offset,
2887 GLsizeiptr length)
2888{
2889 if (!context->getExtensions().mapBufferRange)
2890 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002891 context->handleError(InvalidOperation() << "Map buffer range extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002892 return false;
2893 }
2894
2895 return ValidateFlushMappedBufferRangeBase(context, target, offset, length);
2896}
2897
Ian Ewell54f87462016-03-10 13:47:21 -05002898bool ValidateBindTexture(Context *context, GLenum target, GLuint texture)
2899{
2900 Texture *textureObject = context->getTexture(texture);
2901 if (textureObject && textureObject->getTarget() != target && texture != 0)
2902 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002903 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TypeMismatch);
Ian Ewell54f87462016-03-10 13:47:21 -05002904 return false;
2905 }
2906
Geoff Langf41a7152016-09-19 15:11:17 -04002907 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
2908 !context->isTextureGenerated(texture))
2909 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002910 context->handleError(InvalidOperation() << "Texture was not generated");
Geoff Langf41a7152016-09-19 15:11:17 -04002911 return false;
2912 }
2913
Ian Ewell54f87462016-03-10 13:47:21 -05002914 switch (target)
2915 {
2916 case GL_TEXTURE_2D:
2917 case GL_TEXTURE_CUBE_MAP:
2918 break;
2919
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002920 case GL_TEXTURE_RECTANGLE_ANGLE:
2921 if (!context->getExtensions().textureRectangle)
2922 {
2923 context->handleError(InvalidEnum()
2924 << "Context does not support GL_ANGLE_texture_rectangle");
2925 return false;
2926 }
2927 break;
2928
Ian Ewell54f87462016-03-10 13:47:21 -05002929 case GL_TEXTURE_3D:
2930 case GL_TEXTURE_2D_ARRAY:
Martin Radev1be913c2016-07-11 17:59:16 +03002931 if (context->getClientMajorVersion() < 3)
Ian Ewell54f87462016-03-10 13:47:21 -05002932 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002933 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES3Required);
Ian Ewell54f87462016-03-10 13:47:21 -05002934 return false;
2935 }
2936 break;
Geoff Lang3b573612016-10-31 14:08:10 -04002937
2938 case GL_TEXTURE_2D_MULTISAMPLE:
2939 if (context->getClientVersion() < Version(3, 1))
2940 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002941 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
Geoff Lang3b573612016-10-31 14:08:10 -04002942 return false;
2943 }
Geoff Lang3b573612016-10-31 14:08:10 -04002944 break;
2945
Ian Ewell54f87462016-03-10 13:47:21 -05002946 case GL_TEXTURE_EXTERNAL_OES:
Geoff Langb66a9092016-05-16 15:59:14 -04002947 if (!context->getExtensions().eglImageExternal &&
2948 !context->getExtensions().eglStreamConsumerExternal)
Ian Ewell54f87462016-03-10 13:47:21 -05002949 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002950 context->handleError(InvalidEnum() << "External texture extension not enabled");
Ian Ewell54f87462016-03-10 13:47:21 -05002951 return false;
2952 }
2953 break;
2954 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07002955 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Ian Ewell54f87462016-03-10 13:47:21 -05002956 return false;
2957 }
2958
2959 return true;
2960}
2961
Geoff Langd8605522016-04-13 10:19:12 -04002962bool ValidateBindUniformLocationCHROMIUM(Context *context,
2963 GLuint program,
2964 GLint location,
2965 const GLchar *name)
2966{
2967 if (!context->getExtensions().bindUniformLocation)
2968 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002969 context->handleError(InvalidOperation()
2970 << "GL_CHROMIUM_bind_uniform_location is not available.");
Geoff Langd8605522016-04-13 10:19:12 -04002971 return false;
2972 }
2973
2974 Program *programObject = GetValidProgram(context, program);
2975 if (!programObject)
2976 {
2977 return false;
2978 }
2979
2980 if (location < 0)
2981 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002982 context->handleError(InvalidValue() << "Location cannot be less than 0.");
Geoff Langd8605522016-04-13 10:19:12 -04002983 return false;
2984 }
2985
2986 const Caps &caps = context->getCaps();
2987 if (static_cast<size_t>(location) >=
2988 (caps.maxVertexUniformVectors + caps.maxFragmentUniformVectors) * 4)
2989 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002990 context->handleError(InvalidValue() << "Location must be less than "
2991 "(MAX_VERTEX_UNIFORM_VECTORS + "
2992 "MAX_FRAGMENT_UNIFORM_VECTORS) * 4");
Geoff Langd8605522016-04-13 10:19:12 -04002993 return false;
2994 }
2995
Geoff Langfc32e8b2017-05-31 14:16:59 -04002996 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
2997 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04002998 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04002999 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003000 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04003001 return false;
3002 }
3003
Geoff Langd8605522016-04-13 10:19:12 -04003004 if (strncmp(name, "gl_", 3) == 0)
3005 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003006 ANGLE_VALIDATION_ERR(context, InvalidValue(), NameBeginsWithGL);
Geoff Langd8605522016-04-13 10:19:12 -04003007 return false;
3008 }
3009
3010 return true;
3011}
3012
Jamie Madille2e406c2016-06-02 13:04:10 -04003013bool ValidateCoverageModulationCHROMIUM(Context *context, GLenum components)
Sami Väisänena797e062016-05-12 15:23:40 +03003014{
3015 if (!context->getExtensions().framebufferMixedSamples)
3016 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003017 context->handleError(InvalidOperation()
3018 << "GL_CHROMIUM_framebuffer_mixed_samples is not available.");
Sami Väisänena797e062016-05-12 15:23:40 +03003019 return false;
3020 }
3021 switch (components)
3022 {
3023 case GL_RGB:
3024 case GL_RGBA:
3025 case GL_ALPHA:
3026 case GL_NONE:
3027 break;
3028 default:
3029 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003030 InvalidEnum()
3031 << "GLenum components is not one of GL_RGB, GL_RGBA, GL_ALPHA or GL_NONE.");
Sami Väisänena797e062016-05-12 15:23:40 +03003032 return false;
3033 }
3034
3035 return true;
3036}
3037
Sami Väisänene45e53b2016-05-25 10:36:04 +03003038// CHROMIUM_path_rendering
3039
3040bool ValidateMatrix(Context *context, GLenum matrixMode, const GLfloat *matrix)
3041{
3042 if (!context->getExtensions().pathRendering)
3043 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003044 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003045 return false;
3046 }
3047 if (matrixMode != GL_PATH_MODELVIEW_CHROMIUM && matrixMode != GL_PATH_PROJECTION_CHROMIUM)
3048 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003049 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidMatrixMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003050 return false;
3051 }
3052 if (matrix == nullptr)
3053 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003054 context->handleError(InvalidOperation() << "Invalid matrix.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003055 return false;
3056 }
3057 return true;
3058}
3059
3060bool ValidateMatrixMode(Context *context, GLenum matrixMode)
3061{
3062 if (!context->getExtensions().pathRendering)
3063 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003064 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003065 return false;
3066 }
3067 if (matrixMode != GL_PATH_MODELVIEW_CHROMIUM && matrixMode != GL_PATH_PROJECTION_CHROMIUM)
3068 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003069 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidMatrixMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003070 return false;
3071 }
3072 return true;
3073}
3074
3075bool ValidateGenPaths(Context *context, GLsizei range)
3076{
3077 if (!context->getExtensions().pathRendering)
3078 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003079 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003080 return false;
3081 }
3082
3083 // range = 0 is undefined in NV_path_rendering.
3084 // we add stricter semantic check here and require a non zero positive range.
3085 if (range <= 0)
3086 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003087 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003088 return false;
3089 }
3090
3091 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range))
3092 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003093 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003094 return false;
3095 }
3096
3097 return true;
3098}
3099
3100bool ValidateDeletePaths(Context *context, GLuint path, GLsizei range)
3101{
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 angle::CheckedNumeric<std::uint32_t> checkedRange(path);
3117 checkedRange += range;
3118
3119 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range) || !checkedRange.IsValid())
3120 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003121 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003122 return false;
3123 }
3124 return true;
3125}
3126
3127bool ValidatePathCommands(Context *context,
3128 GLuint path,
3129 GLsizei numCommands,
3130 const GLubyte *commands,
3131 GLsizei numCoords,
3132 GLenum coordType,
3133 const void *coords)
3134{
3135 if (!context->getExtensions().pathRendering)
3136 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003137 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003138 return false;
3139 }
3140 if (!context->hasPath(path))
3141 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003142 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003143 return false;
3144 }
3145
3146 if (numCommands < 0)
3147 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003148 context->handleError(InvalidValue() << "Invalid number of commands.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003149 return false;
3150 }
3151 else if (numCommands > 0)
3152 {
3153 if (!commands)
3154 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003155 context->handleError(InvalidValue() << "No commands array given.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003156 return false;
3157 }
3158 }
3159
3160 if (numCoords < 0)
3161 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003162 context->handleError(InvalidValue() << "Invalid number of coordinates.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003163 return false;
3164 }
3165 else if (numCoords > 0)
3166 {
3167 if (!coords)
3168 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003169 context->handleError(InvalidValue() << "No coordinate array given.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003170 return false;
3171 }
3172 }
3173
3174 std::uint32_t coordTypeSize = 0;
3175 switch (coordType)
3176 {
3177 case GL_BYTE:
3178 coordTypeSize = sizeof(GLbyte);
3179 break;
3180
3181 case GL_UNSIGNED_BYTE:
3182 coordTypeSize = sizeof(GLubyte);
3183 break;
3184
3185 case GL_SHORT:
3186 coordTypeSize = sizeof(GLshort);
3187 break;
3188
3189 case GL_UNSIGNED_SHORT:
3190 coordTypeSize = sizeof(GLushort);
3191 break;
3192
3193 case GL_FLOAT:
3194 coordTypeSize = sizeof(GLfloat);
3195 break;
3196
3197 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003198 context->handleError(InvalidEnum() << "Invalid coordinate type.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003199 return false;
3200 }
3201
3202 angle::CheckedNumeric<std::uint32_t> checkedSize(numCommands);
3203 checkedSize += (coordTypeSize * numCoords);
3204 if (!checkedSize.IsValid())
3205 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003206 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003207 return false;
3208 }
3209
3210 // early return skips command data validation when it doesn't exist.
3211 if (!commands)
3212 return true;
3213
3214 GLsizei expectedNumCoords = 0;
3215 for (GLsizei i = 0; i < numCommands; ++i)
3216 {
3217 switch (commands[i])
3218 {
3219 case GL_CLOSE_PATH_CHROMIUM: // no coordinates.
3220 break;
3221 case GL_MOVE_TO_CHROMIUM:
3222 case GL_LINE_TO_CHROMIUM:
3223 expectedNumCoords += 2;
3224 break;
3225 case GL_QUADRATIC_CURVE_TO_CHROMIUM:
3226 expectedNumCoords += 4;
3227 break;
3228 case GL_CUBIC_CURVE_TO_CHROMIUM:
3229 expectedNumCoords += 6;
3230 break;
3231 case GL_CONIC_CURVE_TO_CHROMIUM:
3232 expectedNumCoords += 5;
3233 break;
3234 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003235 context->handleError(InvalidEnum() << "Invalid command.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003236 return false;
3237 }
3238 }
3239 if (expectedNumCoords != numCoords)
3240 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003241 context->handleError(InvalidValue() << "Invalid number of coordinates.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003242 return false;
3243 }
3244
3245 return true;
3246}
3247
3248bool ValidateSetPathParameter(Context *context, GLuint path, GLenum pname, GLfloat value)
3249{
3250 if (!context->getExtensions().pathRendering)
3251 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003252 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003253 return false;
3254 }
3255 if (!context->hasPath(path))
3256 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003257 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003258 return false;
3259 }
3260
3261 switch (pname)
3262 {
3263 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3264 if (value < 0.0f)
3265 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003266 context->handleError(InvalidValue() << "Invalid stroke width.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003267 return false;
3268 }
3269 break;
3270 case GL_PATH_END_CAPS_CHROMIUM:
3271 switch (static_cast<GLenum>(value))
3272 {
3273 case GL_FLAT_CHROMIUM:
3274 case GL_SQUARE_CHROMIUM:
3275 case GL_ROUND_CHROMIUM:
3276 break;
3277 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003278 context->handleError(InvalidEnum() << "Invalid end caps.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003279 return false;
3280 }
3281 break;
3282 case GL_PATH_JOIN_STYLE_CHROMIUM:
3283 switch (static_cast<GLenum>(value))
3284 {
3285 case GL_MITER_REVERT_CHROMIUM:
3286 case GL_BEVEL_CHROMIUM:
3287 case GL_ROUND_CHROMIUM:
3288 break;
3289 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003290 context->handleError(InvalidEnum() << "Invalid join style.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003291 return false;
3292 }
3293 case GL_PATH_MITER_LIMIT_CHROMIUM:
3294 if (value < 0.0f)
3295 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003296 context->handleError(InvalidValue() << "Invalid miter limit.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003297 return false;
3298 }
3299 break;
3300
3301 case GL_PATH_STROKE_BOUND_CHROMIUM:
3302 // no errors, only clamping.
3303 break;
3304
3305 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003306 context->handleError(InvalidEnum() << "Invalid path parameter.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003307 return false;
3308 }
3309 return true;
3310}
3311
3312bool ValidateGetPathParameter(Context *context, GLuint path, GLenum pname, GLfloat *value)
3313{
3314 if (!context->getExtensions().pathRendering)
3315 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003316 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003317 return false;
3318 }
3319
3320 if (!context->hasPath(path))
3321 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003322 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003323 return false;
3324 }
3325 if (!value)
3326 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003327 context->handleError(InvalidValue() << "No value array.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003328 return false;
3329 }
3330
3331 switch (pname)
3332 {
3333 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3334 case GL_PATH_END_CAPS_CHROMIUM:
3335 case GL_PATH_JOIN_STYLE_CHROMIUM:
3336 case GL_PATH_MITER_LIMIT_CHROMIUM:
3337 case GL_PATH_STROKE_BOUND_CHROMIUM:
3338 break;
3339
3340 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003341 context->handleError(InvalidEnum() << "Invalid path parameter.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003342 return false;
3343 }
3344
3345 return true;
3346}
3347
3348bool ValidatePathStencilFunc(Context *context, GLenum func, GLint ref, GLuint mask)
3349{
3350 if (!context->getExtensions().pathRendering)
3351 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003352 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003353 return false;
3354 }
3355
3356 switch (func)
3357 {
3358 case GL_NEVER:
3359 case GL_ALWAYS:
3360 case GL_LESS:
3361 case GL_LEQUAL:
3362 case GL_EQUAL:
3363 case GL_GEQUAL:
3364 case GL_GREATER:
3365 case GL_NOTEQUAL:
3366 break;
3367 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07003368 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003369 return false;
3370 }
3371
3372 return true;
3373}
3374
3375// Note that the spec specifies that for the path drawing commands
3376// if the path object is not an existing path object the command
3377// does nothing and no error is generated.
3378// However if the path object exists but has not been specified any
3379// commands then an error is generated.
3380
3381bool ValidateStencilFillPath(Context *context, GLuint path, GLenum fillMode, GLuint mask)
3382{
3383 if (!context->getExtensions().pathRendering)
3384 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003385 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003386 return false;
3387 }
3388 if (context->hasPath(path) && !context->hasPathData(path))
3389 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003390 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003391 return false;
3392 }
3393
3394 switch (fillMode)
3395 {
3396 case GL_COUNT_UP_CHROMIUM:
3397 case GL_COUNT_DOWN_CHROMIUM:
3398 break;
3399 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003400 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003401 return false;
3402 }
3403
3404 if (!isPow2(mask + 1))
3405 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003406 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003407 return false;
3408 }
3409
3410 return true;
3411}
3412
3413bool ValidateStencilStrokePath(Context *context, GLuint path, GLint reference, GLuint mask)
3414{
3415 if (!context->getExtensions().pathRendering)
3416 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003417 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003418 return false;
3419 }
3420 if (context->hasPath(path) && !context->hasPathData(path))
3421 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003422 context->handleError(InvalidOperation() << "No such path or path has no data.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003423 return false;
3424 }
3425
3426 return true;
3427}
3428
3429bool ValidateCoverPath(Context *context, GLuint path, GLenum coverMode)
3430{
3431 if (!context->getExtensions().pathRendering)
3432 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003433 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003434 return false;
3435 }
3436 if (context->hasPath(path) && !context->hasPathData(path))
3437 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003438 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003439 return false;
3440 }
3441
3442 switch (coverMode)
3443 {
3444 case GL_CONVEX_HULL_CHROMIUM:
3445 case GL_BOUNDING_BOX_CHROMIUM:
3446 break;
3447 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003448 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003449 return false;
3450 }
3451 return true;
3452}
3453
3454bool ValidateStencilThenCoverFillPath(Context *context,
3455 GLuint path,
3456 GLenum fillMode,
3457 GLuint mask,
3458 GLenum coverMode)
3459{
3460 return ValidateStencilFillPath(context, path, fillMode, mask) &&
3461 ValidateCoverPath(context, path, coverMode);
3462}
3463
3464bool ValidateStencilThenCoverStrokePath(Context *context,
3465 GLuint path,
3466 GLint reference,
3467 GLuint mask,
3468 GLenum coverMode)
3469{
3470 return ValidateStencilStrokePath(context, path, reference, mask) &&
3471 ValidateCoverPath(context, path, coverMode);
3472}
3473
3474bool ValidateIsPath(Context *context)
3475{
3476 if (!context->getExtensions().pathRendering)
3477 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003478 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003479 return false;
3480 }
3481 return true;
3482}
3483
Sami Väisänend59ca052016-06-21 16:10:00 +03003484bool ValidateCoverFillPathInstanced(Context *context,
3485 GLsizei numPaths,
3486 GLenum pathNameType,
3487 const void *paths,
3488 GLuint pathBase,
3489 GLenum coverMode,
3490 GLenum transformType,
3491 const GLfloat *transformValues)
3492{
3493 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3494 transformType, transformValues))
3495 return false;
3496
3497 switch (coverMode)
3498 {
3499 case GL_CONVEX_HULL_CHROMIUM:
3500 case GL_BOUNDING_BOX_CHROMIUM:
3501 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3502 break;
3503 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003504 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003505 return false;
3506 }
3507
3508 return true;
3509}
3510
3511bool ValidateCoverStrokePathInstanced(Context *context,
3512 GLsizei numPaths,
3513 GLenum pathNameType,
3514 const void *paths,
3515 GLuint pathBase,
3516 GLenum coverMode,
3517 GLenum transformType,
3518 const GLfloat *transformValues)
3519{
3520 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3521 transformType, transformValues))
3522 return false;
3523
3524 switch (coverMode)
3525 {
3526 case GL_CONVEX_HULL_CHROMIUM:
3527 case GL_BOUNDING_BOX_CHROMIUM:
3528 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3529 break;
3530 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003531 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003532 return false;
3533 }
3534
3535 return true;
3536}
3537
3538bool ValidateStencilFillPathInstanced(Context *context,
3539 GLsizei numPaths,
3540 GLenum pathNameType,
3541 const void *paths,
3542 GLuint pathBase,
3543 GLenum fillMode,
3544 GLuint mask,
3545 GLenum transformType,
3546 const GLfloat *transformValues)
3547{
3548
3549 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3550 transformType, transformValues))
3551 return false;
3552
3553 switch (fillMode)
3554 {
3555 case GL_COUNT_UP_CHROMIUM:
3556 case GL_COUNT_DOWN_CHROMIUM:
3557 break;
3558 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003559 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003560 return false;
3561 }
3562 if (!isPow2(mask + 1))
3563 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003564 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003565 return false;
3566 }
3567 return true;
3568}
3569
3570bool ValidateStencilStrokePathInstanced(Context *context,
3571 GLsizei numPaths,
3572 GLenum pathNameType,
3573 const void *paths,
3574 GLuint pathBase,
3575 GLint reference,
3576 GLuint mask,
3577 GLenum transformType,
3578 const GLfloat *transformValues)
3579{
3580 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3581 transformType, transformValues))
3582 return false;
3583
3584 // no more validation here.
3585
3586 return true;
3587}
3588
3589bool ValidateStencilThenCoverFillPathInstanced(Context *context,
3590 GLsizei numPaths,
3591 GLenum pathNameType,
3592 const void *paths,
3593 GLuint pathBase,
3594 GLenum fillMode,
3595 GLuint mask,
3596 GLenum coverMode,
3597 GLenum transformType,
3598 const GLfloat *transformValues)
3599{
3600 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3601 transformType, transformValues))
3602 return false;
3603
3604 switch (coverMode)
3605 {
3606 case GL_CONVEX_HULL_CHROMIUM:
3607 case GL_BOUNDING_BOX_CHROMIUM:
3608 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3609 break;
3610 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003611 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003612 return false;
3613 }
3614
3615 switch (fillMode)
3616 {
3617 case GL_COUNT_UP_CHROMIUM:
3618 case GL_COUNT_DOWN_CHROMIUM:
3619 break;
3620 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003621 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003622 return false;
3623 }
3624 if (!isPow2(mask + 1))
3625 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003626 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003627 return false;
3628 }
3629
3630 return true;
3631}
3632
3633bool ValidateStencilThenCoverStrokePathInstanced(Context *context,
3634 GLsizei numPaths,
3635 GLenum pathNameType,
3636 const void *paths,
3637 GLuint pathBase,
3638 GLint reference,
3639 GLuint mask,
3640 GLenum coverMode,
3641 GLenum transformType,
3642 const GLfloat *transformValues)
3643{
3644 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3645 transformType, transformValues))
3646 return false;
3647
3648 switch (coverMode)
3649 {
3650 case GL_CONVEX_HULL_CHROMIUM:
3651 case GL_BOUNDING_BOX_CHROMIUM:
3652 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3653 break;
3654 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003655 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003656 return false;
3657 }
3658
3659 return true;
3660}
3661
Sami Väisänen46eaa942016-06-29 10:26:37 +03003662bool ValidateBindFragmentInputLocation(Context *context,
3663 GLuint program,
3664 GLint location,
3665 const GLchar *name)
3666{
3667 if (!context->getExtensions().pathRendering)
3668 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003669 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003670 return false;
3671 }
3672
3673 const GLint MaxLocation = context->getCaps().maxVaryingVectors * 4;
3674 if (location >= MaxLocation)
3675 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003676 context->handleError(InvalidValue() << "Location exceeds max varying.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003677 return false;
3678 }
3679
3680 const auto *programObject = context->getProgram(program);
3681 if (!programObject)
3682 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003683 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003684 return false;
3685 }
3686
3687 if (!name)
3688 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003689 context->handleError(InvalidValue() << "No name given.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003690 return false;
3691 }
3692
3693 if (angle::BeginsWith(name, "gl_"))
3694 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003695 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003696 return false;
3697 }
3698
3699 return true;
3700}
3701
3702bool ValidateProgramPathFragmentInputGen(Context *context,
3703 GLuint program,
3704 GLint location,
3705 GLenum genMode,
3706 GLint components,
3707 const GLfloat *coeffs)
3708{
3709 if (!context->getExtensions().pathRendering)
3710 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003711 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003712 return false;
3713 }
3714
3715 const auto *programObject = context->getProgram(program);
3716 if (!programObject || programObject->isFlaggedForDeletion())
3717 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003718 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramDoesNotExist);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003719 return false;
3720 }
3721
3722 if (!programObject->isLinked())
3723 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003724 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003725 return false;
3726 }
3727
3728 switch (genMode)
3729 {
3730 case GL_NONE:
3731 if (components != 0)
3732 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003733 context->handleError(InvalidValue() << "Invalid components.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003734 return false;
3735 }
3736 break;
3737
3738 case GL_OBJECT_LINEAR_CHROMIUM:
3739 case GL_EYE_LINEAR_CHROMIUM:
3740 case GL_CONSTANT_CHROMIUM:
3741 if (components < 1 || components > 4)
3742 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003743 context->handleError(InvalidValue() << "Invalid components.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003744 return false;
3745 }
3746 if (!coeffs)
3747 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003748 context->handleError(InvalidValue() << "No coefficients array given.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003749 return false;
3750 }
3751 break;
3752
3753 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003754 context->handleError(InvalidEnum() << "Invalid gen mode.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003755 return false;
3756 }
3757
3758 // If the location is -1 then the command is silently ignored
3759 // and no further validation is needed.
3760 if (location == -1)
3761 return true;
3762
Jamie Madillbd044ed2017-06-05 12:59:21 -04003763 const auto &binding = programObject->getFragmentInputBindingInfo(context, location);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003764
3765 if (!binding.valid)
3766 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003767 context->handleError(InvalidOperation() << "No such binding.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003768 return false;
3769 }
3770
3771 if (binding.type != GL_NONE)
3772 {
3773 GLint expectedComponents = 0;
3774 switch (binding.type)
3775 {
3776 case GL_FLOAT:
3777 expectedComponents = 1;
3778 break;
3779 case GL_FLOAT_VEC2:
3780 expectedComponents = 2;
3781 break;
3782 case GL_FLOAT_VEC3:
3783 expectedComponents = 3;
3784 break;
3785 case GL_FLOAT_VEC4:
3786 expectedComponents = 4;
3787 break;
3788 default:
He Yunchaoced53ae2016-11-29 15:00:51 +08003789 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003790 InvalidOperation()
3791 << "Fragment input type is not a floating point scalar or vector.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003792 return false;
3793 }
3794 if (expectedComponents != components && genMode != GL_NONE)
3795 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003796 context->handleError(InvalidOperation() << "Unexpected number of components");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003797 return false;
3798 }
3799 }
3800 return true;
3801}
3802
Geoff Lang97073d12016-04-20 10:42:34 -07003803bool ValidateCopyTextureCHROMIUM(Context *context,
3804 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003805 GLint sourceLevel,
3806 GLenum destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003807 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003808 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003809 GLint internalFormat,
3810 GLenum destType,
3811 GLboolean unpackFlipY,
3812 GLboolean unpackPremultiplyAlpha,
3813 GLboolean unpackUnmultiplyAlpha)
3814{
3815 if (!context->getExtensions().copyTexture)
3816 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003817 context->handleError(InvalidOperation()
3818 << "GL_CHROMIUM_copy_texture extension not available.");
Geoff Lang97073d12016-04-20 10:42:34 -07003819 return false;
3820 }
3821
Geoff Lang4f0e0032017-05-01 16:04:35 -04003822 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07003823 if (source == nullptr)
3824 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003825 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003826 return false;
3827 }
3828
3829 if (!IsValidCopyTextureSourceTarget(context, source->getTarget()))
3830 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003831 context->handleError(InvalidValue() << "Source texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07003832 return false;
3833 }
3834
3835 GLenum sourceTarget = source->getTarget();
3836 ASSERT(sourceTarget != GL_TEXTURE_CUBE_MAP);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003837
3838 if (!IsValidCopyTextureSourceLevel(context, source->getTarget(), sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07003839 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003840 context->handleError(InvalidValue() << "Source texture level is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07003841 return false;
3842 }
3843
Geoff Lang4f0e0032017-05-01 16:04:35 -04003844 GLsizei sourceWidth = static_cast<GLsizei>(source->getWidth(sourceTarget, sourceLevel));
3845 GLsizei sourceHeight = static_cast<GLsizei>(source->getHeight(sourceTarget, sourceLevel));
3846 if (sourceWidth == 0 || sourceHeight == 0)
3847 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003848 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003849 return false;
3850 }
3851
3852 const InternalFormat &sourceFormat = *source->getFormat(sourceTarget, sourceLevel).info;
3853 if (!IsValidCopyTextureSourceInternalFormatEnum(sourceFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07003854 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003855 context->handleError(InvalidOperation() << "Source texture internal format is invalid.");
Geoff Lang97073d12016-04-20 10:42:34 -07003856 return false;
3857 }
3858
Geoff Lang4f0e0032017-05-01 16:04:35 -04003859 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07003860 if (dest == nullptr)
3861 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003862 context->handleError(InvalidValue()
3863 << "Destination texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003864 return false;
3865 }
3866
Geoff Lang4f0e0032017-05-01 16:04:35 -04003867 if (!IsValidCopyTextureDestinationTarget(context, dest->getTarget(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07003868 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003869 context->handleError(InvalidValue() << "Destination texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07003870 return false;
3871 }
3872
Geoff Lang4f0e0032017-05-01 16:04:35 -04003873 if (!IsValidCopyTextureDestinationLevel(context, destTarget, destLevel, sourceWidth,
3874 sourceHeight))
3875 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003876 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003877 return false;
3878 }
3879
Geoff Lang97073d12016-04-20 10:42:34 -07003880 if (!IsValidCopyTextureDestinationFormatType(context, internalFormat, destType))
3881 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003882 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07003883 return false;
3884 }
3885
Geoff Lang4f0e0032017-05-01 16:04:35 -04003886 if (IsCubeMapTextureTarget(destTarget) && sourceWidth != sourceHeight)
3887 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003888 context->handleError(
3889 InvalidValue() << "Destination width and height must be equal for cube map textures.");
Geoff Lang4f0e0032017-05-01 16:04:35 -04003890 return false;
3891 }
3892
Geoff Lang97073d12016-04-20 10:42:34 -07003893 if (dest->getImmutableFormat())
3894 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003895 context->handleError(InvalidOperation() << "Destination texture is immutable.");
Geoff Lang97073d12016-04-20 10:42:34 -07003896 return false;
3897 }
3898
3899 return true;
3900}
3901
3902bool ValidateCopySubTextureCHROMIUM(Context *context,
3903 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003904 GLint sourceLevel,
3905 GLenum destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003906 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003907 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003908 GLint xoffset,
3909 GLint yoffset,
3910 GLint x,
3911 GLint y,
3912 GLsizei width,
3913 GLsizei height,
3914 GLboolean unpackFlipY,
3915 GLboolean unpackPremultiplyAlpha,
3916 GLboolean unpackUnmultiplyAlpha)
3917{
3918 if (!context->getExtensions().copyTexture)
3919 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003920 context->handleError(InvalidOperation()
3921 << "GL_CHROMIUM_copy_texture extension not available.");
Geoff Lang97073d12016-04-20 10:42:34 -07003922 return false;
3923 }
3924
Geoff Lang4f0e0032017-05-01 16:04:35 -04003925 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07003926 if (source == nullptr)
3927 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003928 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003929 return false;
3930 }
3931
3932 if (!IsValidCopyTextureSourceTarget(context, source->getTarget()))
3933 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003934 context->handleError(InvalidValue() << "Source texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07003935 return false;
3936 }
3937
3938 GLenum sourceTarget = source->getTarget();
3939 ASSERT(sourceTarget != GL_TEXTURE_CUBE_MAP);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003940
3941 if (!IsValidCopyTextureSourceLevel(context, source->getTarget(), sourceLevel))
3942 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003943 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003944 return false;
3945 }
3946
3947 if (source->getWidth(sourceTarget, sourceLevel) == 0 ||
3948 source->getHeight(sourceTarget, sourceLevel) == 0)
Geoff Lang97073d12016-04-20 10:42:34 -07003949 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003950 context->handleError(InvalidValue()
3951 << "The source level of the source texture must be defined.");
Geoff Lang97073d12016-04-20 10:42:34 -07003952 return false;
3953 }
3954
3955 if (x < 0 || y < 0)
3956 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003957 context->handleError(InvalidValue() << "x and y cannot be negative.");
Geoff Lang97073d12016-04-20 10:42:34 -07003958 return false;
3959 }
3960
3961 if (width < 0 || height < 0)
3962 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003963 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Geoff Lang97073d12016-04-20 10:42:34 -07003964 return false;
3965 }
3966
Geoff Lang4f0e0032017-05-01 16:04:35 -04003967 if (static_cast<size_t>(x + width) > source->getWidth(sourceTarget, sourceLevel) ||
3968 static_cast<size_t>(y + height) > source->getHeight(sourceTarget, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07003969 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003970 ANGLE_VALIDATION_ERR(context, InvalidValue(), SourceTextureTooSmall);
Geoff Lang97073d12016-04-20 10:42:34 -07003971 return false;
3972 }
3973
Geoff Lang4f0e0032017-05-01 16:04:35 -04003974 const Format &sourceFormat = source->getFormat(sourceTarget, sourceLevel);
3975 if (!IsValidCopySubTextureSourceInternalFormat(sourceFormat.info->internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07003976 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003977 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07003978 return false;
3979 }
3980
Geoff Lang4f0e0032017-05-01 16:04:35 -04003981 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07003982 if (dest == nullptr)
3983 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003984 context->handleError(InvalidValue()
3985 << "Destination texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003986 return false;
3987 }
3988
Geoff Lang4f0e0032017-05-01 16:04:35 -04003989 if (!IsValidCopyTextureDestinationTarget(context, dest->getTarget(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07003990 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003991 context->handleError(InvalidValue() << "Destination texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07003992 return false;
3993 }
3994
Geoff Lang4f0e0032017-05-01 16:04:35 -04003995 if (!IsValidCopyTextureDestinationLevel(context, destTarget, destLevel, width, height))
Geoff Lang97073d12016-04-20 10:42:34 -07003996 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003997 context->handleError(InvalidValue() << "Destination texture level is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07003998 return false;
3999 }
4000
Geoff Lang4f0e0032017-05-01 16:04:35 -04004001 if (dest->getWidth(destTarget, destLevel) == 0 || dest->getHeight(destTarget, destLevel) == 0)
4002 {
Geoff Langbb1b19b2017-06-16 16:59:00 -04004003 context
4004 ->handleError(InvalidOperation()
4005 << "The destination level of the destination texture must be defined.");
Geoff Lang4f0e0032017-05-01 16:04:35 -04004006 return false;
4007 }
4008
4009 const InternalFormat &destFormat = *dest->getFormat(destTarget, destLevel).info;
4010 if (!IsValidCopySubTextureDestionationInternalFormat(destFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07004011 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004012 context->handleError(InvalidOperation()
4013 << "Destination internal format and type combination is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07004014 return false;
4015 }
4016
4017 if (xoffset < 0 || yoffset < 0)
4018 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004019 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Geoff Lang97073d12016-04-20 10:42:34 -07004020 return false;
4021 }
4022
Geoff Lang4f0e0032017-05-01 16:04:35 -04004023 if (static_cast<size_t>(xoffset + width) > dest->getWidth(destTarget, destLevel) ||
4024 static_cast<size_t>(yoffset + height) > dest->getHeight(destTarget, destLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07004025 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004026 context->handleError(InvalidValue() << "Destination texture not large enough to copy to.");
Geoff Lang97073d12016-04-20 10:42:34 -07004027 return false;
4028 }
4029
4030 return true;
4031}
4032
Geoff Lang47110bf2016-04-20 11:13:22 -07004033bool ValidateCompressedCopyTextureCHROMIUM(Context *context, GLuint sourceId, GLuint destId)
4034{
4035 if (!context->getExtensions().copyCompressedTexture)
4036 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004037 context->handleError(InvalidOperation()
4038 << "GL_CHROMIUM_copy_compressed_texture extension not available.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004039 return false;
4040 }
4041
4042 const gl::Texture *source = context->getTexture(sourceId);
4043 if (source == nullptr)
4044 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004045 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004046 return false;
4047 }
4048
4049 if (source->getTarget() != GL_TEXTURE_2D)
4050 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004051 context->handleError(InvalidValue() << "Source texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004052 return false;
4053 }
4054
4055 if (source->getWidth(GL_TEXTURE_2D, 0) == 0 || source->getHeight(GL_TEXTURE_2D, 0) == 0)
4056 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004057 context->handleError(InvalidValue() << "Source texture must level 0 defined.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004058 return false;
4059 }
4060
4061 const gl::Format &sourceFormat = source->getFormat(GL_TEXTURE_2D, 0);
4062 if (!sourceFormat.info->compressed)
4063 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004064 context->handleError(InvalidOperation()
4065 << "Source texture must have a compressed internal format.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004066 return false;
4067 }
4068
4069 const gl::Texture *dest = context->getTexture(destId);
4070 if (dest == nullptr)
4071 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004072 context->handleError(InvalidValue()
4073 << "Destination texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004074 return false;
4075 }
4076
4077 if (dest->getTarget() != GL_TEXTURE_2D)
4078 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004079 context->handleError(InvalidValue()
4080 << "Destination texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004081 return false;
4082 }
4083
4084 if (dest->getImmutableFormat())
4085 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004086 context->handleError(InvalidOperation() << "Destination cannot be immutable.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004087 return false;
4088 }
4089
4090 return true;
4091}
4092
Martin Radev4c4c8e72016-08-04 12:25:34 +03004093bool ValidateCreateShader(Context *context, GLenum type)
4094{
4095 switch (type)
4096 {
4097 case GL_VERTEX_SHADER:
4098 case GL_FRAGMENT_SHADER:
4099 break;
Geoff Langeb66a6e2016-10-31 13:06:12 -04004100
Martin Radev4c4c8e72016-08-04 12:25:34 +03004101 case GL_COMPUTE_SHADER:
Geoff Langeb66a6e2016-10-31 13:06:12 -04004102 if (context->getClientVersion() < Version(3, 1))
Martin Radev4c4c8e72016-08-04 12:25:34 +03004103 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004104 context->handleError(InvalidEnum() << "GL_COMPUTE_SHADER requires OpenGL ES 3.1.");
Geoff Langeb66a6e2016-10-31 13:06:12 -04004105 return false;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004106 }
Geoff Langeb66a6e2016-10-31 13:06:12 -04004107 break;
4108
Martin Radev4c4c8e72016-08-04 12:25:34 +03004109 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004110 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Martin Radev4c4c8e72016-08-04 12:25:34 +03004111 return false;
4112 }
Jamie Madill29639852016-09-02 15:00:09 -04004113
4114 return true;
4115}
4116
4117bool ValidateBufferData(ValidationContext *context,
4118 GLenum target,
4119 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004120 const void *data,
Jamie Madill29639852016-09-02 15:00:09 -04004121 GLenum usage)
4122{
4123 if (size < 0)
4124 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004125 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madill29639852016-09-02 15:00:09 -04004126 return false;
4127 }
4128
4129 switch (usage)
4130 {
4131 case GL_STREAM_DRAW:
4132 case GL_STATIC_DRAW:
4133 case GL_DYNAMIC_DRAW:
4134 break;
4135
4136 case GL_STREAM_READ:
4137 case GL_STREAM_COPY:
4138 case GL_STATIC_READ:
4139 case GL_STATIC_COPY:
4140 case GL_DYNAMIC_READ:
4141 case GL_DYNAMIC_COPY:
4142 if (context->getClientMajorVersion() < 3)
4143 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004144 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004145 return false;
4146 }
4147 break;
4148
4149 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004150 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004151 return false;
4152 }
4153
4154 if (!ValidBufferTarget(context, target))
4155 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004156 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004157 return false;
4158 }
4159
4160 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4161
4162 if (!buffer)
4163 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004164 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004165 return false;
4166 }
4167
4168 return true;
4169}
4170
4171bool ValidateBufferSubData(ValidationContext *context,
4172 GLenum target,
4173 GLintptr offset,
4174 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004175 const void *data)
Jamie Madill29639852016-09-02 15:00:09 -04004176{
Brandon Jones6cad5662017-06-14 13:25:13 -07004177 if (size < 0)
Jamie Madill29639852016-09-02 15:00:09 -04004178 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004179 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
4180 return false;
4181 }
4182
4183 if (offset < 0)
4184 {
4185 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Jamie Madill29639852016-09-02 15:00:09 -04004186 return false;
4187 }
4188
4189 if (!ValidBufferTarget(context, target))
4190 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004191 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004192 return false;
4193 }
4194
4195 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4196
4197 if (!buffer)
4198 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004199 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004200 return false;
4201 }
4202
4203 if (buffer->isMapped())
4204 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004205 context->handleError(InvalidOperation());
Jamie Madill29639852016-09-02 15:00:09 -04004206 return false;
4207 }
4208
4209 // Check for possible overflow of size + offset
4210 angle::CheckedNumeric<size_t> checkedSize(size);
4211 checkedSize += offset;
4212 if (!checkedSize.IsValid())
4213 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004214 context->handleError(OutOfMemory());
Jamie Madill29639852016-09-02 15:00:09 -04004215 return false;
4216 }
4217
4218 if (size + offset > buffer->getSize())
4219 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004220 ANGLE_VALIDATION_ERR(context, InvalidValue(), InsufficientBufferSize);
Jamie Madill29639852016-09-02 15:00:09 -04004221 return false;
4222 }
4223
Martin Radev4c4c8e72016-08-04 12:25:34 +03004224 return true;
4225}
4226
Geoff Langc339c4e2016-11-29 10:37:36 -05004227bool ValidateRequestExtensionANGLE(ValidationContext *context, const GLchar *name)
Geoff Langc287ea62016-09-16 14:46:51 -04004228{
Geoff Langc339c4e2016-11-29 10:37:36 -05004229 if (!context->getExtensions().requestExtension)
Geoff Langc287ea62016-09-16 14:46:51 -04004230 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004231 context->handleError(InvalidOperation() << "GL_ANGLE_request_extension is not available.");
Geoff Langc287ea62016-09-16 14:46:51 -04004232 return false;
4233 }
4234
4235 const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
4236 auto extension = extensionInfos.find(name);
Geoff Langc339c4e2016-11-29 10:37:36 -05004237 if (extension == extensionInfos.end() || !extension->second.Requestable)
Geoff Langc287ea62016-09-16 14:46:51 -04004238 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004239 context->handleError(InvalidOperation() << "Extension " << name << " is not requestable.");
Geoff Langc287ea62016-09-16 14:46:51 -04004240 return false;
4241 }
4242
4243 return true;
4244}
4245
Jamie Madillef300b12016-10-07 15:12:09 -04004246bool ValidateActiveTexture(ValidationContext *context, GLenum texture)
4247{
4248 if (texture < GL_TEXTURE0 ||
4249 texture > GL_TEXTURE0 + context->getCaps().maxCombinedTextureImageUnits - 1)
4250 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004251 context->handleError(InvalidEnum());
Jamie Madillef300b12016-10-07 15:12:09 -04004252 return false;
4253 }
4254
4255 return true;
4256}
4257
4258bool ValidateAttachShader(ValidationContext *context, GLuint program, GLuint shader)
4259{
4260 Program *programObject = GetValidProgram(context, program);
4261 if (!programObject)
4262 {
4263 return false;
4264 }
4265
4266 Shader *shaderObject = GetValidShader(context, shader);
4267 if (!shaderObject)
4268 {
4269 return false;
4270 }
4271
4272 switch (shaderObject->getType())
4273 {
4274 case GL_VERTEX_SHADER:
4275 {
4276 if (programObject->getAttachedVertexShader())
4277 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004278 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
Jamie Madillef300b12016-10-07 15:12:09 -04004279 return false;
4280 }
4281 break;
4282 }
4283 case GL_FRAGMENT_SHADER:
4284 {
4285 if (programObject->getAttachedFragmentShader())
4286 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004287 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
Jamie Madillef300b12016-10-07 15:12:09 -04004288 return false;
4289 }
4290 break;
4291 }
4292 case GL_COMPUTE_SHADER:
4293 {
4294 if (programObject->getAttachedComputeShader())
4295 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004296 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
Jamie Madillef300b12016-10-07 15:12:09 -04004297 return false;
4298 }
4299 break;
4300 }
4301 default:
4302 UNREACHABLE();
4303 break;
4304 }
4305
4306 return true;
4307}
4308
Jamie Madill01a80ee2016-11-07 12:06:18 -05004309bool ValidateBindAttribLocation(ValidationContext *context,
4310 GLuint program,
4311 GLuint index,
4312 const GLchar *name)
4313{
4314 if (index >= MAX_VERTEX_ATTRIBS)
4315 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004316 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004317 return false;
4318 }
4319
4320 if (strncmp(name, "gl_", 3) == 0)
4321 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004322 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004323 return false;
4324 }
4325
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004326 if (context->isWebGL())
Geoff Langfc32e8b2017-05-31 14:16:59 -04004327 {
Brandon Jonesed5b46f2017-07-21 08:39:17 -07004328 const size_t length = strlen(name);
4329
4330 if (!IsValidESSLString(name, length))
4331 {
4332 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters
4333 // for shader-related entry points
4334 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
4335 return false;
4336 }
4337
4338 if (!ValidateWebGLNameLength(context, length) || !ValidateWebGLNamePrefix(context, name))
4339 {
4340 return false;
4341 }
Geoff Langfc32e8b2017-05-31 14:16:59 -04004342 }
4343
Jamie Madill01a80ee2016-11-07 12:06:18 -05004344 return GetValidProgram(context, program) != nullptr;
4345}
4346
4347bool ValidateBindBuffer(ValidationContext *context, GLenum target, GLuint buffer)
4348{
4349 if (!ValidBufferTarget(context, target))
4350 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004351 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004352 return false;
4353 }
4354
4355 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4356 !context->isBufferGenerated(buffer))
4357 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004358 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004359 return false;
4360 }
4361
4362 return true;
4363}
4364
4365bool ValidateBindFramebuffer(ValidationContext *context, GLenum target, GLuint framebuffer)
4366{
4367 if (!ValidFramebufferTarget(target))
4368 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004369 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004370 return false;
4371 }
4372
4373 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4374 !context->isFramebufferGenerated(framebuffer))
4375 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004376 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004377 return false;
4378 }
4379
4380 return true;
4381}
4382
4383bool ValidateBindRenderbuffer(ValidationContext *context, GLenum target, GLuint renderbuffer)
4384{
4385 if (target != GL_RENDERBUFFER)
4386 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004387 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004388 return false;
4389 }
4390
4391 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4392 !context->isRenderbufferGenerated(renderbuffer))
4393 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004394 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004395 return false;
4396 }
4397
4398 return true;
4399}
4400
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004401static bool ValidBlendEquationMode(GLenum mode)
4402{
4403 switch (mode)
4404 {
4405 case GL_FUNC_ADD:
4406 case GL_FUNC_SUBTRACT:
4407 case GL_FUNC_REVERSE_SUBTRACT:
4408 case GL_MIN:
4409 case GL_MAX:
4410 return true;
4411
4412 default:
4413 return false;
4414 }
4415}
4416
Jamie Madillc1d770e2017-04-13 17:31:24 -04004417bool ValidateBlendColor(ValidationContext *context,
Jamie Madill876429b2017-04-20 15:46:24 -04004418 GLfloat red,
4419 GLfloat green,
4420 GLfloat blue,
4421 GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004422{
4423 return true;
4424}
4425
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004426bool ValidateBlendEquation(ValidationContext *context, GLenum mode)
4427{
4428 if (!ValidBlendEquationMode(mode))
4429 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004430 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004431 return false;
4432 }
4433
4434 return true;
4435}
4436
4437bool ValidateBlendEquationSeparate(ValidationContext *context, GLenum modeRGB, GLenum modeAlpha)
4438{
4439 if (!ValidBlendEquationMode(modeRGB))
4440 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004441 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004442 return false;
4443 }
4444
4445 if (!ValidBlendEquationMode(modeAlpha))
4446 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004447 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004448 return false;
4449 }
4450
4451 return true;
4452}
4453
4454bool ValidateBlendFunc(ValidationContext *context, GLenum sfactor, GLenum dfactor)
4455{
4456 return ValidateBlendFuncSeparate(context, sfactor, dfactor, sfactor, dfactor);
4457}
4458
4459static bool ValidSrcBlendFunc(GLenum srcBlend)
4460{
4461 switch (srcBlend)
4462 {
4463 case GL_ZERO:
4464 case GL_ONE:
4465 case GL_SRC_COLOR:
4466 case GL_ONE_MINUS_SRC_COLOR:
4467 case GL_DST_COLOR:
4468 case GL_ONE_MINUS_DST_COLOR:
4469 case GL_SRC_ALPHA:
4470 case GL_ONE_MINUS_SRC_ALPHA:
4471 case GL_DST_ALPHA:
4472 case GL_ONE_MINUS_DST_ALPHA:
4473 case GL_CONSTANT_COLOR:
4474 case GL_ONE_MINUS_CONSTANT_COLOR:
4475 case GL_CONSTANT_ALPHA:
4476 case GL_ONE_MINUS_CONSTANT_ALPHA:
4477 case GL_SRC_ALPHA_SATURATE:
4478 return true;
4479
4480 default:
4481 return false;
4482 }
4483}
4484
4485static bool ValidDstBlendFunc(GLenum dstBlend, GLint contextMajorVersion)
4486{
4487 switch (dstBlend)
4488 {
4489 case GL_ZERO:
4490 case GL_ONE:
4491 case GL_SRC_COLOR:
4492 case GL_ONE_MINUS_SRC_COLOR:
4493 case GL_DST_COLOR:
4494 case GL_ONE_MINUS_DST_COLOR:
4495 case GL_SRC_ALPHA:
4496 case GL_ONE_MINUS_SRC_ALPHA:
4497 case GL_DST_ALPHA:
4498 case GL_ONE_MINUS_DST_ALPHA:
4499 case GL_CONSTANT_COLOR:
4500 case GL_ONE_MINUS_CONSTANT_COLOR:
4501 case GL_CONSTANT_ALPHA:
4502 case GL_ONE_MINUS_CONSTANT_ALPHA:
4503 return true;
4504
4505 case GL_SRC_ALPHA_SATURATE:
4506 return (contextMajorVersion >= 3);
4507
4508 default:
4509 return false;
4510 }
4511}
4512
4513bool ValidateBlendFuncSeparate(ValidationContext *context,
4514 GLenum srcRGB,
4515 GLenum dstRGB,
4516 GLenum srcAlpha,
4517 GLenum dstAlpha)
4518{
4519 if (!ValidSrcBlendFunc(srcRGB))
4520 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004521 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004522 return false;
4523 }
4524
4525 if (!ValidDstBlendFunc(dstRGB, context->getClientMajorVersion()))
4526 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004527 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004528 return false;
4529 }
4530
4531 if (!ValidSrcBlendFunc(srcAlpha))
4532 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004533 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004534 return false;
4535 }
4536
4537 if (!ValidDstBlendFunc(dstAlpha, context->getClientMajorVersion()))
4538 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004539 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004540 return false;
4541 }
4542
Frank Henigman146e8a12017-03-02 23:22:37 -05004543 if (context->getLimitations().noSimultaneousConstantColorAndAlphaBlendFunc ||
4544 context->getExtensions().webglCompatibility)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004545 {
4546 bool constantColorUsed =
4547 (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
4548 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
4549
4550 bool constantAlphaUsed =
4551 (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
4552 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
4553
4554 if (constantColorUsed && constantAlphaUsed)
4555 {
Frank Henigman146e8a12017-03-02 23:22:37 -05004556 const char *msg;
4557 if (context->getExtensions().webglCompatibility)
4558 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004559 msg = kErrorInvalidConstantColor;
Frank Henigman146e8a12017-03-02 23:22:37 -05004560 }
4561 else
4562 {
4563 msg =
4564 "Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and "
4565 "GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR not supported by this "
4566 "implementation.";
4567 ERR() << msg;
4568 }
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004569 context->handleError(InvalidOperation() << msg);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004570 return false;
4571 }
4572 }
4573
4574 return true;
4575}
4576
Geoff Langc339c4e2016-11-29 10:37:36 -05004577bool ValidateGetString(Context *context, GLenum name)
4578{
4579 switch (name)
4580 {
4581 case GL_VENDOR:
4582 case GL_RENDERER:
4583 case GL_VERSION:
4584 case GL_SHADING_LANGUAGE_VERSION:
4585 case GL_EXTENSIONS:
4586 break;
4587
4588 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
4589 if (!context->getExtensions().requestExtension)
4590 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004591 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004592 return false;
4593 }
4594 break;
4595
4596 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07004597 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004598 return false;
4599 }
4600
4601 return true;
4602}
4603
Geoff Lang47c48082016-12-07 15:38:13 -05004604bool ValidateLineWidth(ValidationContext *context, GLfloat width)
4605{
4606 if (width <= 0.0f || isNaN(width))
4607 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004608 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidWidth);
Geoff Lang47c48082016-12-07 15:38:13 -05004609 return false;
4610 }
4611
4612 return true;
4613}
4614
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004615bool ValidateVertexAttribPointer(ValidationContext *context,
4616 GLuint index,
4617 GLint size,
4618 GLenum type,
4619 GLboolean normalized,
4620 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04004621 const void *ptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004622{
Shao80957d92017-02-20 21:25:59 +08004623 if (!ValidateVertexFormatBase(context, index, size, type, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004624 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004625 return false;
4626 }
4627
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004628 if (stride < 0)
4629 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004630 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeStride);
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004631 return false;
4632 }
4633
Shao80957d92017-02-20 21:25:59 +08004634 const Caps &caps = context->getCaps();
4635 if (context->getClientVersion() >= ES_3_1)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004636 {
Shao80957d92017-02-20 21:25:59 +08004637 if (stride > caps.maxVertexAttribStride)
4638 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004639 context->handleError(InvalidValue()
4640 << "stride cannot be greater than MAX_VERTEX_ATTRIB_STRIDE.");
Shao80957d92017-02-20 21:25:59 +08004641 return false;
4642 }
4643
4644 if (index >= caps.maxVertexAttribBindings)
4645 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004646 context->handleError(InvalidValue()
4647 << "index must be smaller than MAX_VERTEX_ATTRIB_BINDINGS.");
Shao80957d92017-02-20 21:25:59 +08004648 return false;
4649 }
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004650 }
4651
4652 // [OpenGL ES 3.0.2] Section 2.8 page 24:
4653 // An INVALID_OPERATION error is generated when a non-zero vertex array object
4654 // is bound, zero is bound to the ARRAY_BUFFER buffer object binding point,
4655 // and the pointer argument is not NULL.
Geoff Langfeb8c682017-02-13 16:07:35 -05004656 bool nullBufferAllowed = context->getGLState().areClientArraysEnabled() &&
4657 context->getGLState().getVertexArray()->id() == 0;
Shao80957d92017-02-20 21:25:59 +08004658 if (!nullBufferAllowed && context->getGLState().getArrayBufferId() == 0 && ptr != nullptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004659 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004660 context
4661 ->handleError(InvalidOperation()
4662 << "Client data cannot be used with a non-default vertex array object.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004663 return false;
4664 }
4665
4666 if (context->getExtensions().webglCompatibility)
4667 {
4668 // WebGL 1.0 [Section 6.14] Fixed point support
4669 // The WebGL API does not support the GL_FIXED data type.
4670 if (type == GL_FIXED)
4671 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004672 context->handleError(InvalidEnum() << "GL_FIXED is not supported in WebGL.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004673 return false;
4674 }
4675
Geoff Lang2d62ab72017-03-23 16:54:40 -04004676 if (!ValidateWebGLVertexAttribPointer(context, type, normalized, stride, ptr, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004677 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004678 return false;
4679 }
4680 }
4681
4682 return true;
4683}
4684
Jamie Madill876429b2017-04-20 15:46:24 -04004685bool ValidateDepthRangef(ValidationContext *context, GLfloat zNear, GLfloat zFar)
Frank Henigman6137ddc2017-02-10 18:55:07 -05004686{
4687 if (context->getExtensions().webglCompatibility && zNear > zFar)
4688 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004689 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidDepthRange);
Frank Henigman6137ddc2017-02-10 18:55:07 -05004690 return false;
4691 }
4692
4693 return true;
4694}
4695
Jamie Madille8fb6402017-02-14 17:56:40 -05004696bool ValidateRenderbufferStorage(ValidationContext *context,
4697 GLenum target,
4698 GLenum internalformat,
4699 GLsizei width,
4700 GLsizei height)
4701{
4702 return ValidateRenderbufferStorageParametersBase(context, target, 0, internalformat, width,
4703 height);
4704}
4705
4706bool ValidateRenderbufferStorageMultisampleANGLE(ValidationContext *context,
4707 GLenum target,
4708 GLsizei samples,
4709 GLenum internalformat,
4710 GLsizei width,
4711 GLsizei height)
4712{
4713 if (!context->getExtensions().framebufferMultisample)
4714 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004715 context->handleError(InvalidOperation()
4716 << "GL_ANGLE_framebuffer_multisample not available");
Jamie Madille8fb6402017-02-14 17:56:40 -05004717 return false;
4718 }
4719
4720 // ANGLE_framebuffer_multisample states that the value of samples must be less than or equal
4721 // to MAX_SAMPLES_ANGLE (Context::getCaps().maxSamples) otherwise GL_INVALID_OPERATION is
4722 // generated.
4723 if (static_cast<GLuint>(samples) > context->getCaps().maxSamples)
4724 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004725 context->handleError(InvalidValue());
Jamie Madille8fb6402017-02-14 17:56:40 -05004726 return false;
4727 }
4728
4729 // ANGLE_framebuffer_multisample states GL_OUT_OF_MEMORY is generated on a failure to create
4730 // the specified storage. This is different than ES 3.0 in which a sample number higher
4731 // than the maximum sample number supported by this format generates a GL_INVALID_VALUE.
4732 // The TextureCaps::getMaxSamples method is only guarenteed to be valid when the context is ES3.
4733 if (context->getClientMajorVersion() >= 3)
4734 {
4735 const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
4736 if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
4737 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004738 context->handleError(OutOfMemory());
Jamie Madille8fb6402017-02-14 17:56:40 -05004739 return false;
4740 }
4741 }
4742
4743 return ValidateRenderbufferStorageParametersBase(context, target, samples, internalformat,
4744 width, height);
4745}
4746
Jamie Madillc1d770e2017-04-13 17:31:24 -04004747bool ValidateCheckFramebufferStatus(ValidationContext *context, GLenum target)
4748{
4749 if (!ValidFramebufferTarget(target))
4750 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004751 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004752 return false;
4753 }
4754
4755 return true;
4756}
4757
4758bool ValidateClearColor(ValidationContext *context,
Jamie Madill876429b2017-04-20 15:46:24 -04004759 GLfloat red,
4760 GLfloat green,
4761 GLfloat blue,
4762 GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004763{
4764 return true;
4765}
4766
Jamie Madill876429b2017-04-20 15:46:24 -04004767bool ValidateClearDepthf(ValidationContext *context, GLfloat depth)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004768{
4769 return true;
4770}
4771
4772bool ValidateClearStencil(ValidationContext *context, GLint s)
4773{
4774 return true;
4775}
4776
4777bool ValidateColorMask(ValidationContext *context,
4778 GLboolean red,
4779 GLboolean green,
4780 GLboolean blue,
4781 GLboolean alpha)
4782{
4783 return true;
4784}
4785
4786bool ValidateCompileShader(ValidationContext *context, GLuint shader)
4787{
4788 return true;
4789}
4790
4791bool ValidateCreateProgram(ValidationContext *context)
4792{
4793 return true;
4794}
4795
4796bool ValidateCullFace(ValidationContext *context, GLenum mode)
4797{
4798 switch (mode)
4799 {
4800 case GL_FRONT:
4801 case GL_BACK:
4802 case GL_FRONT_AND_BACK:
4803 break;
4804
4805 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004806 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCullMode);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004807 return false;
4808 }
4809
4810 return true;
4811}
4812
4813bool ValidateDeleteProgram(ValidationContext *context, GLuint program)
4814{
4815 if (program == 0)
4816 {
4817 return false;
4818 }
4819
4820 if (!context->getProgram(program))
4821 {
4822 if (context->getShader(program))
4823 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004824 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004825 return false;
4826 }
4827 else
4828 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004829 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004830 return false;
4831 }
4832 }
4833
4834 return true;
4835}
4836
4837bool ValidateDeleteShader(ValidationContext *context, GLuint shader)
4838{
4839 if (shader == 0)
4840 {
4841 return false;
4842 }
4843
4844 if (!context->getShader(shader))
4845 {
4846 if (context->getProgram(shader))
4847 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004848 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004849 return false;
4850 }
4851 else
4852 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004853 ANGLE_VALIDATION_ERR(context, InvalidValue(), ExpectedShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004854 return false;
4855 }
4856 }
4857
4858 return true;
4859}
4860
4861bool ValidateDepthFunc(ValidationContext *context, GLenum func)
4862{
4863 switch (func)
4864 {
4865 case GL_NEVER:
4866 case GL_ALWAYS:
4867 case GL_LESS:
4868 case GL_LEQUAL:
4869 case GL_EQUAL:
4870 case GL_GREATER:
4871 case GL_GEQUAL:
4872 case GL_NOTEQUAL:
4873 break;
4874
4875 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004876 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004877 return false;
4878 }
4879
4880 return true;
4881}
4882
4883bool ValidateDepthMask(ValidationContext *context, GLboolean flag)
4884{
4885 return true;
4886}
4887
4888bool ValidateDetachShader(ValidationContext *context, GLuint program, GLuint shader)
4889{
4890 Program *programObject = GetValidProgram(context, program);
4891 if (!programObject)
4892 {
4893 return false;
4894 }
4895
4896 Shader *shaderObject = GetValidShader(context, shader);
4897 if (!shaderObject)
4898 {
4899 return false;
4900 }
4901
4902 const Shader *attachedShader = nullptr;
4903
4904 switch (shaderObject->getType())
4905 {
4906 case GL_VERTEX_SHADER:
4907 {
4908 attachedShader = programObject->getAttachedVertexShader();
4909 break;
4910 }
4911 case GL_FRAGMENT_SHADER:
4912 {
4913 attachedShader = programObject->getAttachedFragmentShader();
4914 break;
4915 }
4916 case GL_COMPUTE_SHADER:
4917 {
4918 attachedShader = programObject->getAttachedComputeShader();
4919 break;
4920 }
4921 default:
4922 UNREACHABLE();
4923 return false;
4924 }
4925
4926 if (attachedShader != shaderObject)
4927 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004928 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderToDetachMustBeAttached);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004929 return false;
4930 }
4931
4932 return true;
4933}
4934
4935bool ValidateDisableVertexAttribArray(ValidationContext *context, GLuint index)
4936{
4937 if (index >= MAX_VERTEX_ATTRIBS)
4938 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004939 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004940 return false;
4941 }
4942
4943 return true;
4944}
4945
4946bool ValidateEnableVertexAttribArray(ValidationContext *context, GLuint index)
4947{
4948 if (index >= MAX_VERTEX_ATTRIBS)
4949 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004950 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004951 return false;
4952 }
4953
4954 return true;
4955}
4956
4957bool ValidateFinish(ValidationContext *context)
4958{
4959 return true;
4960}
4961
4962bool ValidateFlush(ValidationContext *context)
4963{
4964 return true;
4965}
4966
4967bool ValidateFrontFace(ValidationContext *context, GLenum mode)
4968{
4969 switch (mode)
4970 {
4971 case GL_CW:
4972 case GL_CCW:
4973 break;
4974 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004975 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004976 return false;
4977 }
4978
4979 return true;
4980}
4981
4982bool ValidateGetActiveAttrib(ValidationContext *context,
4983 GLuint program,
4984 GLuint index,
4985 GLsizei bufsize,
4986 GLsizei *length,
4987 GLint *size,
4988 GLenum *type,
4989 GLchar *name)
4990{
4991 if (bufsize < 0)
4992 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004993 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004994 return false;
4995 }
4996
4997 Program *programObject = GetValidProgram(context, program);
4998
4999 if (!programObject)
5000 {
5001 return false;
5002 }
5003
5004 if (index >= static_cast<GLuint>(programObject->getActiveAttributeCount()))
5005 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005006 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005007 return false;
5008 }
5009
5010 return true;
5011}
5012
5013bool ValidateGetActiveUniform(ValidationContext *context,
5014 GLuint program,
5015 GLuint index,
5016 GLsizei bufsize,
5017 GLsizei *length,
5018 GLint *size,
5019 GLenum *type,
5020 GLchar *name)
5021{
5022 if (bufsize < 0)
5023 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005024 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005025 return false;
5026 }
5027
5028 Program *programObject = GetValidProgram(context, program);
5029
5030 if (!programObject)
5031 {
5032 return false;
5033 }
5034
5035 if (index >= static_cast<GLuint>(programObject->getActiveUniformCount()))
5036 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005037 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005038 return false;
5039 }
5040
5041 return true;
5042}
5043
5044bool ValidateGetAttachedShaders(ValidationContext *context,
5045 GLuint program,
5046 GLsizei maxcount,
5047 GLsizei *count,
5048 GLuint *shaders)
5049{
5050 if (maxcount < 0)
5051 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005052 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeMaxCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005053 return false;
5054 }
5055
5056 Program *programObject = GetValidProgram(context, program);
5057
5058 if (!programObject)
5059 {
5060 return false;
5061 }
5062
5063 return true;
5064}
5065
5066bool ValidateGetAttribLocation(ValidationContext *context, GLuint program, const GLchar *name)
5067{
Geoff Langfc32e8b2017-05-31 14:16:59 -04005068 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5069 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005070 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005071 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005072 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005073 return false;
5074 }
5075
Jamie Madillc1d770e2017-04-13 17:31:24 -04005076 Program *programObject = GetValidProgram(context, program);
5077
5078 if (!programObject)
5079 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005080 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005081 return false;
5082 }
5083
5084 if (!programObject->isLinked())
5085 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005086 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005087 return false;
5088 }
5089
5090 return true;
5091}
5092
5093bool ValidateGetBooleanv(ValidationContext *context, GLenum pname, GLboolean *params)
5094{
5095 GLenum nativeType;
5096 unsigned int numParams = 0;
5097 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5098}
5099
5100bool ValidateGetError(ValidationContext *context)
5101{
5102 return true;
5103}
5104
5105bool ValidateGetFloatv(ValidationContext *context, GLenum pname, GLfloat *params)
5106{
5107 GLenum nativeType;
5108 unsigned int numParams = 0;
5109 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5110}
5111
5112bool ValidateGetIntegerv(ValidationContext *context, GLenum pname, GLint *params)
5113{
5114 GLenum nativeType;
5115 unsigned int numParams = 0;
5116 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5117}
5118
5119bool ValidateGetProgramInfoLog(ValidationContext *context,
5120 GLuint program,
5121 GLsizei bufsize,
5122 GLsizei *length,
5123 GLchar *infolog)
5124{
5125 if (bufsize < 0)
5126 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005127 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005128 return false;
5129 }
5130
5131 Program *programObject = GetValidProgram(context, program);
5132 if (!programObject)
5133 {
5134 return false;
5135 }
5136
5137 return true;
5138}
5139
5140bool ValidateGetShaderInfoLog(ValidationContext *context,
5141 GLuint shader,
5142 GLsizei bufsize,
5143 GLsizei *length,
5144 GLchar *infolog)
5145{
5146 if (bufsize < 0)
5147 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005148 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005149 return false;
5150 }
5151
5152 Shader *shaderObject = GetValidShader(context, shader);
5153 if (!shaderObject)
5154 {
5155 return false;
5156 }
5157
5158 return true;
5159}
5160
5161bool ValidateGetShaderPrecisionFormat(ValidationContext *context,
5162 GLenum shadertype,
5163 GLenum precisiontype,
5164 GLint *range,
5165 GLint *precision)
5166{
5167 switch (shadertype)
5168 {
5169 case GL_VERTEX_SHADER:
5170 case GL_FRAGMENT_SHADER:
5171 break;
5172 case GL_COMPUTE_SHADER:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005173 context->handleError(InvalidOperation()
5174 << "compute shader precision not yet implemented.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005175 return false;
5176 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005177 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005178 return false;
5179 }
5180
5181 switch (precisiontype)
5182 {
5183 case GL_LOW_FLOAT:
5184 case GL_MEDIUM_FLOAT:
5185 case GL_HIGH_FLOAT:
5186 case GL_LOW_INT:
5187 case GL_MEDIUM_INT:
5188 case GL_HIGH_INT:
5189 break;
5190
5191 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005192 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPrecision);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005193 return false;
5194 }
5195
5196 return true;
5197}
5198
5199bool ValidateGetShaderSource(ValidationContext *context,
5200 GLuint shader,
5201 GLsizei bufsize,
5202 GLsizei *length,
5203 GLchar *source)
5204{
5205 if (bufsize < 0)
5206 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005207 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005208 return false;
5209 }
5210
5211 Shader *shaderObject = GetValidShader(context, shader);
5212 if (!shaderObject)
5213 {
5214 return false;
5215 }
5216
5217 return true;
5218}
5219
5220bool ValidateGetUniformLocation(ValidationContext *context, GLuint program, const GLchar *name)
5221{
5222 if (strstr(name, "gl_") == name)
5223 {
5224 return false;
5225 }
5226
Geoff Langfc32e8b2017-05-31 14:16:59 -04005227 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5228 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005229 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005230 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005231 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005232 return false;
5233 }
5234
Jamie Madillc1d770e2017-04-13 17:31:24 -04005235 Program *programObject = GetValidProgram(context, program);
5236
5237 if (!programObject)
5238 {
5239 return false;
5240 }
5241
5242 if (!programObject->isLinked())
5243 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005244 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005245 return false;
5246 }
5247
5248 return true;
5249}
5250
5251bool ValidateHint(ValidationContext *context, GLenum target, GLenum mode)
5252{
5253 switch (mode)
5254 {
5255 case GL_FASTEST:
5256 case GL_NICEST:
5257 case GL_DONT_CARE:
5258 break;
5259
5260 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005261 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005262 return false;
5263 }
5264
5265 switch (target)
5266 {
5267 case GL_GENERATE_MIPMAP_HINT:
5268 break;
5269
Geoff Lange7bd2182017-06-16 16:13:13 -04005270 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
5271 if (context->getClientVersion() < ES_3_0 &&
5272 !context->getExtensions().standardDerivatives)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005273 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005274 context->handleError(InvalidOperation()
5275 << "hint requires OES_standard_derivatives.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005276 return false;
5277 }
5278 break;
5279
5280 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005281 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005282 return false;
5283 }
5284
5285 return true;
5286}
5287
5288bool ValidateIsBuffer(ValidationContext *context, GLuint buffer)
5289{
5290 return true;
5291}
5292
5293bool ValidateIsFramebuffer(ValidationContext *context, GLuint framebuffer)
5294{
5295 return true;
5296}
5297
5298bool ValidateIsProgram(ValidationContext *context, GLuint program)
5299{
5300 return true;
5301}
5302
5303bool ValidateIsRenderbuffer(ValidationContext *context, GLuint renderbuffer)
5304{
5305 return true;
5306}
5307
5308bool ValidateIsShader(ValidationContext *context, GLuint shader)
5309{
5310 return true;
5311}
5312
5313bool ValidateIsTexture(ValidationContext *context, GLuint texture)
5314{
5315 return true;
5316}
5317
5318bool ValidatePixelStorei(ValidationContext *context, GLenum pname, GLint param)
5319{
5320 if (context->getClientMajorVersion() < 3)
5321 {
5322 switch (pname)
5323 {
5324 case GL_UNPACK_IMAGE_HEIGHT:
5325 case GL_UNPACK_SKIP_IMAGES:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005326 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005327 return false;
5328
5329 case GL_UNPACK_ROW_LENGTH:
5330 case GL_UNPACK_SKIP_ROWS:
5331 case GL_UNPACK_SKIP_PIXELS:
5332 if (!context->getExtensions().unpackSubimage)
5333 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005334 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005335 return false;
5336 }
5337 break;
5338
5339 case GL_PACK_ROW_LENGTH:
5340 case GL_PACK_SKIP_ROWS:
5341 case GL_PACK_SKIP_PIXELS:
5342 if (!context->getExtensions().packSubimage)
5343 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005344 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005345 return false;
5346 }
5347 break;
5348 }
5349 }
5350
5351 if (param < 0)
5352 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005353 context->handleError(InvalidValue() << "Cannot use negative values in PixelStorei");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005354 return false;
5355 }
5356
5357 switch (pname)
5358 {
5359 case GL_UNPACK_ALIGNMENT:
5360 if (param != 1 && param != 2 && param != 4 && param != 8)
5361 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005362 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005363 return false;
5364 }
5365 break;
5366
5367 case GL_PACK_ALIGNMENT:
5368 if (param != 1 && param != 2 && param != 4 && param != 8)
5369 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005370 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005371 return false;
5372 }
5373 break;
5374
5375 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
5376 case GL_UNPACK_ROW_LENGTH:
5377 case GL_UNPACK_IMAGE_HEIGHT:
5378 case GL_UNPACK_SKIP_IMAGES:
5379 case GL_UNPACK_SKIP_ROWS:
5380 case GL_UNPACK_SKIP_PIXELS:
5381 case GL_PACK_ROW_LENGTH:
5382 case GL_PACK_SKIP_ROWS:
5383 case GL_PACK_SKIP_PIXELS:
5384 break;
5385
5386 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005387 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005388 return false;
5389 }
5390
5391 return true;
5392}
5393
5394bool ValidatePolygonOffset(ValidationContext *context, GLfloat factor, GLfloat units)
5395{
5396 return true;
5397}
5398
5399bool ValidateReleaseShaderCompiler(ValidationContext *context)
5400{
5401 return true;
5402}
5403
Jamie Madill876429b2017-04-20 15:46:24 -04005404bool ValidateSampleCoverage(ValidationContext *context, GLfloat value, GLboolean invert)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005405{
5406 return true;
5407}
5408
5409bool ValidateScissor(ValidationContext *context, GLint x, GLint y, GLsizei width, GLsizei height)
5410{
5411 if (width < 0 || height < 0)
5412 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005413 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005414 return false;
5415 }
5416
5417 return true;
5418}
5419
5420bool ValidateShaderBinary(ValidationContext *context,
5421 GLsizei n,
5422 const GLuint *shaders,
5423 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04005424 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005425 GLsizei length)
5426{
5427 const std::vector<GLenum> &shaderBinaryFormats = context->getCaps().shaderBinaryFormats;
5428 if (std::find(shaderBinaryFormats.begin(), shaderBinaryFormats.end(), binaryformat) ==
5429 shaderBinaryFormats.end())
5430 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005431 context->handleError(InvalidEnum() << "Invalid shader binary format.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005432 return false;
5433 }
5434
5435 return true;
5436}
5437
5438bool ValidateShaderSource(ValidationContext *context,
5439 GLuint shader,
5440 GLsizei count,
5441 const GLchar *const *string,
5442 const GLint *length)
5443{
5444 if (count < 0)
5445 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005446 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005447 return false;
5448 }
5449
Geoff Langfc32e8b2017-05-31 14:16:59 -04005450 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5451 // shader-related entry points
5452 if (context->getExtensions().webglCompatibility)
5453 {
5454 for (GLsizei i = 0; i < count; i++)
5455 {
Geoff Langcab92ee2017-07-19 17:32:07 -04005456 size_t len =
5457 (length && length[i] >= 0) ? static_cast<size_t>(length[i]) : strlen(string[i]);
Geoff Langa71a98e2017-06-19 15:15:00 -04005458
5459 // Backslash as line-continuation is allowed in WebGL 2.0.
Geoff Langcab92ee2017-07-19 17:32:07 -04005460 if (!IsValidESSLShaderSourceString(string[i], len,
5461 context->getClientVersion() >= ES_3_0))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005462 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005463 ANGLE_VALIDATION_ERR(context, InvalidValue(), ShaderSourceInvalidCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005464 return false;
5465 }
5466 }
5467 }
5468
Jamie Madillc1d770e2017-04-13 17:31:24 -04005469 Shader *shaderObject = GetValidShader(context, shader);
5470 if (!shaderObject)
5471 {
5472 return false;
5473 }
5474
5475 return true;
5476}
5477
5478bool ValidateStencilFunc(ValidationContext *context, GLenum func, GLint ref, GLuint mask)
5479{
5480 if (!IsValidStencilFunc(func))
5481 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005482 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005483 return false;
5484 }
5485
5486 return true;
5487}
5488
5489bool ValidateStencilFuncSeparate(ValidationContext *context,
5490 GLenum face,
5491 GLenum func,
5492 GLint ref,
5493 GLuint mask)
5494{
5495 if (!IsValidStencilFace(face))
5496 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005497 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005498 return false;
5499 }
5500
5501 if (!IsValidStencilFunc(func))
5502 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005503 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005504 return false;
5505 }
5506
5507 return true;
5508}
5509
5510bool ValidateStencilMask(ValidationContext *context, GLuint mask)
5511{
5512 return true;
5513}
5514
5515bool ValidateStencilMaskSeparate(ValidationContext *context, GLenum face, GLuint mask)
5516{
5517 if (!IsValidStencilFace(face))
5518 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005519 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005520 return false;
5521 }
5522
5523 return true;
5524}
5525
5526bool ValidateStencilOp(ValidationContext *context, GLenum fail, GLenum zfail, GLenum zpass)
5527{
5528 if (!IsValidStencilOp(fail))
5529 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005530 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005531 return false;
5532 }
5533
5534 if (!IsValidStencilOp(zfail))
5535 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005536 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005537 return false;
5538 }
5539
5540 if (!IsValidStencilOp(zpass))
5541 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005542 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005543 return false;
5544 }
5545
5546 return true;
5547}
5548
5549bool ValidateStencilOpSeparate(ValidationContext *context,
5550 GLenum face,
5551 GLenum fail,
5552 GLenum zfail,
5553 GLenum zpass)
5554{
5555 if (!IsValidStencilFace(face))
5556 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005557 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005558 return false;
5559 }
5560
5561 return ValidateStencilOp(context, fail, zfail, zpass);
5562}
5563
5564bool ValidateUniform1f(ValidationContext *context, GLint location, GLfloat x)
5565{
5566 return ValidateUniform(context, GL_FLOAT, location, 1);
5567}
5568
5569bool ValidateUniform1fv(ValidationContext *context, GLint location, GLsizei count, const GLfloat *v)
5570{
5571 return ValidateUniform(context, GL_FLOAT, location, count);
5572}
5573
Jamie Madillbe849e42017-05-02 15:49:00 -04005574bool ValidateUniform1i(ValidationContext *context, GLint location, GLint x)
5575{
5576 return ValidateUniform1iv(context, location, 1, &x);
5577}
5578
Jamie Madillc1d770e2017-04-13 17:31:24 -04005579bool ValidateUniform2f(ValidationContext *context, GLint location, GLfloat x, GLfloat y)
5580{
5581 return ValidateUniform(context, GL_FLOAT_VEC2, location, 1);
5582}
5583
5584bool ValidateUniform2fv(ValidationContext *context, GLint location, GLsizei count, const GLfloat *v)
5585{
5586 return ValidateUniform(context, GL_FLOAT_VEC2, location, count);
5587}
5588
5589bool ValidateUniform2i(ValidationContext *context, GLint location, GLint x, GLint y)
5590{
5591 return ValidateUniform(context, GL_INT_VEC2, location, 1);
5592}
5593
5594bool ValidateUniform2iv(ValidationContext *context, GLint location, GLsizei count, const GLint *v)
5595{
5596 return ValidateUniform(context, GL_INT_VEC2, location, count);
5597}
5598
5599bool ValidateUniform3f(ValidationContext *context, GLint location, GLfloat x, GLfloat y, GLfloat z)
5600{
5601 return ValidateUniform(context, GL_FLOAT_VEC3, location, 1);
5602}
5603
5604bool ValidateUniform3fv(ValidationContext *context, GLint location, GLsizei count, const GLfloat *v)
5605{
5606 return ValidateUniform(context, GL_FLOAT_VEC3, location, count);
5607}
5608
5609bool ValidateUniform3i(ValidationContext *context, GLint location, GLint x, GLint y, GLint z)
5610{
5611 return ValidateUniform(context, GL_INT_VEC3, location, 1);
5612}
5613
5614bool ValidateUniform3iv(ValidationContext *context, GLint location, GLsizei count, const GLint *v)
5615{
5616 return ValidateUniform(context, GL_INT_VEC3, location, count);
5617}
5618
5619bool ValidateUniform4f(ValidationContext *context,
5620 GLint location,
5621 GLfloat x,
5622 GLfloat y,
5623 GLfloat z,
5624 GLfloat w)
5625{
5626 return ValidateUniform(context, GL_FLOAT_VEC4, location, 1);
5627}
5628
5629bool ValidateUniform4fv(ValidationContext *context, GLint location, GLsizei count, const GLfloat *v)
5630{
5631 return ValidateUniform(context, GL_FLOAT_VEC4, location, count);
5632}
5633
5634bool ValidateUniform4i(ValidationContext *context,
5635 GLint location,
5636 GLint x,
5637 GLint y,
5638 GLint z,
5639 GLint w)
5640{
5641 return ValidateUniform(context, GL_INT_VEC4, location, 1);
5642}
5643
5644bool ValidateUniform4iv(ValidationContext *context, GLint location, GLsizei count, const GLint *v)
5645{
5646 return ValidateUniform(context, GL_INT_VEC4, location, count);
5647}
5648
5649bool ValidateUniformMatrix2fv(ValidationContext *context,
5650 GLint location,
5651 GLsizei count,
5652 GLboolean transpose,
5653 const GLfloat *value)
5654{
5655 return ValidateUniformMatrix(context, GL_FLOAT_MAT2, location, count, transpose);
5656}
5657
5658bool ValidateUniformMatrix3fv(ValidationContext *context,
5659 GLint location,
5660 GLsizei count,
5661 GLboolean transpose,
5662 const GLfloat *value)
5663{
5664 return ValidateUniformMatrix(context, GL_FLOAT_MAT3, location, count, transpose);
5665}
5666
5667bool ValidateUniformMatrix4fv(ValidationContext *context,
5668 GLint location,
5669 GLsizei count,
5670 GLboolean transpose,
5671 const GLfloat *value)
5672{
5673 return ValidateUniformMatrix(context, GL_FLOAT_MAT4, location, count, transpose);
5674}
5675
5676bool ValidateValidateProgram(ValidationContext *context, GLuint program)
5677{
5678 Program *programObject = GetValidProgram(context, program);
5679
5680 if (!programObject)
5681 {
5682 return false;
5683 }
5684
5685 return true;
5686}
5687
Jamie Madillc1d770e2017-04-13 17:31:24 -04005688bool ValidateVertexAttrib1f(ValidationContext *context, GLuint index, GLfloat x)
5689{
5690 return ValidateVertexAttribIndex(context, index);
5691}
5692
5693bool ValidateVertexAttrib1fv(ValidationContext *context, GLuint index, const GLfloat *values)
5694{
5695 return ValidateVertexAttribIndex(context, index);
5696}
5697
5698bool ValidateVertexAttrib2f(ValidationContext *context, GLuint index, GLfloat x, GLfloat y)
5699{
5700 return ValidateVertexAttribIndex(context, index);
5701}
5702
5703bool ValidateVertexAttrib2fv(ValidationContext *context, GLuint index, const GLfloat *values)
5704{
5705 return ValidateVertexAttribIndex(context, index);
5706}
5707
5708bool ValidateVertexAttrib3f(ValidationContext *context,
5709 GLuint index,
5710 GLfloat x,
5711 GLfloat y,
5712 GLfloat z)
5713{
5714 return ValidateVertexAttribIndex(context, index);
5715}
5716
5717bool ValidateVertexAttrib3fv(ValidationContext *context, GLuint index, const GLfloat *values)
5718{
5719 return ValidateVertexAttribIndex(context, index);
5720}
5721
5722bool ValidateVertexAttrib4f(ValidationContext *context,
5723 GLuint index,
5724 GLfloat x,
5725 GLfloat y,
5726 GLfloat z,
5727 GLfloat w)
5728{
5729 return ValidateVertexAttribIndex(context, index);
5730}
5731
5732bool ValidateVertexAttrib4fv(ValidationContext *context, GLuint index, const GLfloat *values)
5733{
5734 return ValidateVertexAttribIndex(context, index);
5735}
5736
5737bool ValidateViewport(ValidationContext *context, GLint x, GLint y, GLsizei width, GLsizei height)
5738{
5739 if (width < 0 || height < 0)
5740 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005741 ANGLE_VALIDATION_ERR(context, InvalidValue(), ViewportNegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005742 return false;
5743 }
5744
5745 return true;
5746}
5747
5748bool ValidateDrawArrays(ValidationContext *context, GLenum mode, GLint first, GLsizei count)
5749{
5750 return ValidateDrawArraysCommon(context, mode, first, count, 1);
5751}
5752
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005753bool ValidateDrawElements(ValidationContext *context,
5754 GLenum mode,
5755 GLsizei count,
5756 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04005757 const void *indices)
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005758{
5759 return ValidateDrawElementsCommon(context, mode, count, type, indices, 1);
5760}
5761
Jamie Madillbe849e42017-05-02 15:49:00 -04005762bool ValidateGetFramebufferAttachmentParameteriv(ValidationContext *context,
5763 GLenum target,
5764 GLenum attachment,
5765 GLenum pname,
5766 GLint *params)
5767{
5768 return ValidateGetFramebufferAttachmentParameterivBase(context, target, attachment, pname,
5769 nullptr);
5770}
5771
5772bool ValidateGetProgramiv(ValidationContext *context, GLuint program, GLenum pname, GLint *params)
5773{
5774 return ValidateGetProgramivBase(context, program, pname, nullptr);
5775}
5776
5777bool ValidateCopyTexImage2D(ValidationContext *context,
5778 GLenum target,
5779 GLint level,
5780 GLenum internalformat,
5781 GLint x,
5782 GLint y,
5783 GLsizei width,
5784 GLsizei height,
5785 GLint border)
5786{
5787 if (context->getClientMajorVersion() < 3)
5788 {
5789 return ValidateES2CopyTexImageParameters(context, target, level, internalformat, false, 0,
5790 0, x, y, width, height, border);
5791 }
5792
5793 ASSERT(context->getClientMajorVersion() == 3);
5794 return ValidateES3CopyTexImage2DParameters(context, target, level, internalformat, false, 0, 0,
5795 0, x, y, width, height, border);
5796}
5797
5798bool ValidateCopyTexSubImage2D(Context *context,
5799 GLenum target,
5800 GLint level,
5801 GLint xoffset,
5802 GLint yoffset,
5803 GLint x,
5804 GLint y,
5805 GLsizei width,
5806 GLsizei height)
5807{
5808 if (context->getClientMajorVersion() < 3)
5809 {
5810 return ValidateES2CopyTexImageParameters(context, target, level, GL_NONE, true, xoffset,
5811 yoffset, x, y, width, height, 0);
5812 }
5813
5814 return ValidateES3CopyTexImage2DParameters(context, target, level, GL_NONE, true, xoffset,
5815 yoffset, 0, x, y, width, height, 0);
5816}
5817
5818bool ValidateDeleteBuffers(Context *context, GLint n, const GLuint *)
5819{
5820 return ValidateGenOrDelete(context, n);
5821}
5822
5823bool ValidateDeleteFramebuffers(Context *context, GLint n, const GLuint *)
5824{
5825 return ValidateGenOrDelete(context, n);
5826}
5827
5828bool ValidateDeleteRenderbuffers(Context *context, GLint n, const GLuint *)
5829{
5830 return ValidateGenOrDelete(context, n);
5831}
5832
5833bool ValidateDeleteTextures(Context *context, GLint n, const GLuint *)
5834{
5835 return ValidateGenOrDelete(context, n);
5836}
5837
5838bool ValidateDisable(Context *context, GLenum cap)
5839{
5840 if (!ValidCap(context, cap, false))
5841 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005842 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005843 return false;
5844 }
5845
5846 return true;
5847}
5848
5849bool ValidateEnable(Context *context, GLenum cap)
5850{
5851 if (!ValidCap(context, cap, false))
5852 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005853 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005854 return false;
5855 }
5856
5857 if (context->getLimitations().noSampleAlphaToCoverageSupport &&
5858 cap == GL_SAMPLE_ALPHA_TO_COVERAGE)
5859 {
5860 const char *errorMessage = "Current renderer doesn't support alpha-to-coverage";
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005861 context->handleError(InvalidOperation() << errorMessage);
Jamie Madillbe849e42017-05-02 15:49:00 -04005862
5863 // We also output an error message to the debugger window if tracing is active, so that
5864 // developers can see the error message.
5865 ERR() << errorMessage;
5866 return false;
5867 }
5868
5869 return true;
5870}
5871
5872bool ValidateFramebufferRenderbuffer(Context *context,
5873 GLenum target,
5874 GLenum attachment,
5875 GLenum renderbuffertarget,
5876 GLuint renderbuffer)
5877{
Brandon Jones6cad5662017-06-14 13:25:13 -07005878 if (!ValidFramebufferTarget(target))
Jamie Madillbe849e42017-05-02 15:49:00 -04005879 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005880 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
5881 return false;
5882 }
5883
5884 if (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0)
5885 {
5886 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005887 return false;
5888 }
5889
5890 return ValidateFramebufferRenderbufferParameters(context, target, attachment,
5891 renderbuffertarget, renderbuffer);
5892}
5893
5894bool ValidateFramebufferTexture2D(Context *context,
5895 GLenum target,
5896 GLenum attachment,
5897 GLenum textarget,
5898 GLuint texture,
5899 GLint level)
5900{
5901 // Attachments are required to be bound to level 0 without ES3 or the GL_OES_fbo_render_mipmap
5902 // extension
5903 if (context->getClientMajorVersion() < 3 && !context->getExtensions().fboRenderMipmap &&
5904 level != 0)
5905 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005906 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidFramebufferTextureLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04005907 return false;
5908 }
5909
5910 if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
5911 {
5912 return false;
5913 }
5914
5915 if (texture != 0)
5916 {
5917 gl::Texture *tex = context->getTexture(texture);
5918 ASSERT(tex);
5919
5920 const gl::Caps &caps = context->getCaps();
5921
5922 switch (textarget)
5923 {
5924 case GL_TEXTURE_2D:
5925 {
5926 if (level > gl::log2(caps.max2DTextureSize))
5927 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005928 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04005929 return false;
5930 }
5931 if (tex->getTarget() != GL_TEXTURE_2D)
5932 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005933 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005934 return false;
5935 }
5936 }
5937 break;
5938
Corentin Wallez13c0dd42017-07-04 18:27:01 -04005939 case GL_TEXTURE_RECTANGLE_ANGLE:
5940 {
5941 if (level != 0)
5942 {
5943 context->handleError(InvalidValue());
5944 return false;
5945 }
5946 if (tex->getTarget() != GL_TEXTURE_RECTANGLE_ANGLE)
5947 {
5948 context->handleError(InvalidOperation()
5949 << "Textarget must match the texture target type.");
5950 return false;
5951 }
5952 }
5953 break;
5954
Jamie Madillbe849e42017-05-02 15:49:00 -04005955 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
5956 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
5957 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
5958 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
5959 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
5960 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
5961 {
5962 if (level > gl::log2(caps.maxCubeMapTextureSize))
5963 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005964 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04005965 return false;
5966 }
5967 if (tex->getTarget() != GL_TEXTURE_CUBE_MAP)
5968 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005969 context->handleError(InvalidOperation()
5970 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005971 return false;
5972 }
5973 }
5974 break;
5975
5976 case GL_TEXTURE_2D_MULTISAMPLE:
5977 {
5978 if (context->getClientVersion() < ES_3_1)
5979 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005980 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
Jamie Madillbe849e42017-05-02 15:49:00 -04005981 return false;
5982 }
5983
5984 if (level != 0)
5985 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005986 ANGLE_VALIDATION_ERR(context, InvalidValue(), LevelNotZero);
Jamie Madillbe849e42017-05-02 15:49:00 -04005987 return false;
5988 }
5989 if (tex->getTarget() != GL_TEXTURE_2D_MULTISAMPLE)
5990 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005991 context->handleError(InvalidOperation()
5992 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005993 return false;
5994 }
5995 }
5996 break;
5997
5998 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005999 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006000 return false;
6001 }
6002
6003 const Format &format = tex->getFormat(textarget, level);
6004 if (format.info->compressed)
6005 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006006 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -04006007 return false;
6008 }
6009 }
6010
6011 return true;
6012}
6013
6014bool ValidateGenBuffers(Context *context, GLint n, GLuint *)
6015{
6016 return ValidateGenOrDelete(context, n);
6017}
6018
6019bool ValidateGenFramebuffers(Context *context, GLint n, GLuint *)
6020{
6021 return ValidateGenOrDelete(context, n);
6022}
6023
6024bool ValidateGenRenderbuffers(Context *context, GLint n, GLuint *)
6025{
6026 return ValidateGenOrDelete(context, n);
6027}
6028
6029bool ValidateGenTextures(Context *context, GLint n, GLuint *)
6030{
6031 return ValidateGenOrDelete(context, n);
6032}
6033
6034bool ValidateGenerateMipmap(Context *context, GLenum target)
6035{
6036 if (!ValidTextureTarget(context, target))
6037 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006038 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04006039 return false;
6040 }
6041
6042 Texture *texture = context->getTargetTexture(target);
6043
6044 if (texture == nullptr)
6045 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006046 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04006047 return false;
6048 }
6049
6050 const GLuint effectiveBaseLevel = texture->getTextureState().getEffectiveBaseLevel();
6051
6052 // This error isn't spelled out in the spec in a very explicit way, but we interpret the spec so
6053 // that out-of-range base level has a non-color-renderable / non-texture-filterable format.
6054 if (effectiveBaseLevel >= gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
6055 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006056 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -04006057 return false;
6058 }
6059
6060 GLenum baseTarget = (target == GL_TEXTURE_CUBE_MAP) ? GL_TEXTURE_CUBE_MAP_POSITIVE_X : target;
6061 const auto &format = texture->getFormat(baseTarget, effectiveBaseLevel);
6062 const TextureCaps &formatCaps = context->getTextureCaps().get(format.info->sizedInternalFormat);
6063
Brandon Jones6cad5662017-06-14 13:25:13 -07006064 if (format.info->compressed)
6065 {
6066 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
6067 return false;
6068 }
6069
Jamie Madillbe849e42017-05-02 15:49:00 -04006070 // GenerateMipmap should not generate an INVALID_OPERATION for textures created with
Brandon Jones6cad5662017-06-14 13:25:13 -07006071 // unsized formats or that are color renderable and filterable. Since we do not track if
Jamie Madillbe849e42017-05-02 15:49:00 -04006072 // the texture was created with sized or unsized format (only sized formats are stored),
6073 // it is not possible to make sure the the LUMA formats can generate mipmaps (they should
6074 // be able to) because they aren't color renderable. Simply do a special case for LUMA
6075 // textures since they're the only texture format that can be created with unsized formats
6076 // that is not color renderable. New unsized formats are unlikely to be added, since ES2
6077 // was the last version to use add them.
6078 if (format.info->depthBits > 0 || format.info->stencilBits > 0 || !formatCaps.filterable ||
Brandon Jones6cad5662017-06-14 13:25:13 -07006079 (!formatCaps.renderable && !format.info->isLUMA()))
Jamie Madillbe849e42017-05-02 15:49:00 -04006080 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006081 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -04006082 return false;
6083 }
6084
Geoff Lang65ac5b92017-05-01 13:16:30 -04006085 // ES3 and WebGL grant mipmap generation for sRGB textures but GL_EXT_sRGB does not.
6086 bool supportsSRGBMipmapGeneration =
6087 context->getClientVersion() >= ES_3_0 || context->getExtensions().webglCompatibility;
6088 if (!supportsSRGBMipmapGeneration && format.info->colorEncoding == GL_SRGB)
Jamie Madillbe849e42017-05-02 15:49:00 -04006089 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006090 context->handleError(InvalidOperation()
6091 << "Mipmap generation of sRGB textures is not allowed.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006092 return false;
6093 }
6094
6095 // Non-power of 2 ES2 check
6096 if (context->getClientVersion() < Version(3, 0) && !context->getExtensions().textureNPOT &&
6097 (!isPow2(static_cast<int>(texture->getWidth(baseTarget, 0))) ||
6098 !isPow2(static_cast<int>(texture->getHeight(baseTarget, 0)))))
6099 {
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006100 ASSERT(target == GL_TEXTURE_2D || target == GL_TEXTURE_RECTANGLE_ANGLE ||
6101 target == GL_TEXTURE_CUBE_MAP);
Brandon Jones6cad5662017-06-14 13:25:13 -07006102 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotPow2);
Jamie Madillbe849e42017-05-02 15:49:00 -04006103 return false;
6104 }
6105
6106 // Cube completeness check
6107 if (target == GL_TEXTURE_CUBE_MAP && !texture->getTextureState().isCubeComplete())
6108 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006109 ANGLE_VALIDATION_ERR(context, InvalidOperation(), CubemapIncomplete);
Jamie Madillbe849e42017-05-02 15:49:00 -04006110 return false;
6111 }
6112
6113 return true;
6114}
6115
6116bool ValidateGetBufferParameteriv(ValidationContext *context,
6117 GLenum target,
6118 GLenum pname,
6119 GLint *params)
6120{
6121 return ValidateGetBufferParameterBase(context, target, pname, false, nullptr);
6122}
6123
6124bool ValidateGetRenderbufferParameteriv(Context *context,
6125 GLenum target,
6126 GLenum pname,
6127 GLint *params)
6128{
6129 return ValidateGetRenderbufferParameterivBase(context, target, pname, nullptr);
6130}
6131
6132bool ValidateGetShaderiv(Context *context, GLuint shader, GLenum pname, GLint *params)
6133{
6134 return ValidateGetShaderivBase(context, shader, pname, nullptr);
6135}
6136
6137bool ValidateGetTexParameterfv(Context *context, GLenum target, GLenum pname, GLfloat *params)
6138{
6139 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6140}
6141
6142bool ValidateGetTexParameteriv(Context *context, GLenum target, GLenum pname, GLint *params)
6143{
6144 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6145}
6146
6147bool ValidateGetUniformfv(Context *context, GLuint program, GLint location, GLfloat *params)
6148{
6149 return ValidateGetUniformBase(context, program, location);
6150}
6151
6152bool ValidateGetUniformiv(Context *context, GLuint program, GLint location, GLint *params)
6153{
6154 return ValidateGetUniformBase(context, program, location);
6155}
6156
6157bool ValidateGetVertexAttribfv(Context *context, GLuint index, GLenum pname, GLfloat *params)
6158{
6159 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6160}
6161
6162bool ValidateGetVertexAttribiv(Context *context, GLuint index, GLenum pname, GLint *params)
6163{
6164 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6165}
6166
6167bool ValidateGetVertexAttribPointerv(Context *context, GLuint index, GLenum pname, void **pointer)
6168{
6169 return ValidateGetVertexAttribBase(context, index, pname, nullptr, true, false);
6170}
6171
6172bool ValidateIsEnabled(Context *context, GLenum cap)
6173{
6174 if (!ValidCap(context, cap, true))
6175 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006176 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006177 return false;
6178 }
6179
6180 return true;
6181}
6182
6183bool ValidateLinkProgram(Context *context, GLuint program)
6184{
6185 if (context->hasActiveTransformFeedback(program))
6186 {
6187 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006188 context->handleError(InvalidOperation() << "Cannot link program while program is "
6189 "associated with an active transform "
6190 "feedback object.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006191 return false;
6192 }
6193
6194 Program *programObject = GetValidProgram(context, program);
6195 if (!programObject)
6196 {
6197 return false;
6198 }
6199
6200 return true;
6201}
6202
Jamie Madill4928b7c2017-06-20 12:57:39 -04006203bool ValidateReadPixels(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04006204 GLint x,
6205 GLint y,
6206 GLsizei width,
6207 GLsizei height,
6208 GLenum format,
6209 GLenum type,
6210 void *pixels)
6211{
6212 return ValidateReadPixelsBase(context, x, y, width, height, format, type, -1, nullptr, nullptr,
6213 nullptr, pixels);
6214}
6215
6216bool ValidateTexParameterf(Context *context, GLenum target, GLenum pname, GLfloat param)
6217{
6218 return ValidateTexParameterBase(context, target, pname, -1, &param);
6219}
6220
6221bool ValidateTexParameterfv(Context *context, GLenum target, GLenum pname, const GLfloat *params)
6222{
6223 return ValidateTexParameterBase(context, target, pname, -1, params);
6224}
6225
6226bool ValidateTexParameteri(Context *context, GLenum target, GLenum pname, GLint param)
6227{
6228 return ValidateTexParameterBase(context, target, pname, -1, &param);
6229}
6230
6231bool ValidateTexParameteriv(Context *context, GLenum target, GLenum pname, const GLint *params)
6232{
6233 return ValidateTexParameterBase(context, target, pname, -1, params);
6234}
6235
6236bool ValidateUseProgram(Context *context, GLuint program)
6237{
6238 if (program != 0)
6239 {
6240 Program *programObject = context->getProgram(program);
6241 if (!programObject)
6242 {
6243 // ES 3.1.0 section 7.3 page 72
6244 if (context->getShader(program))
6245 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006246 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006247 return false;
6248 }
6249 else
6250 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006251 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006252 return false;
6253 }
6254 }
6255 if (!programObject->isLinked())
6256 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006257 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillbe849e42017-05-02 15:49:00 -04006258 return false;
6259 }
6260 }
6261 if (context->getGLState().isTransformFeedbackActiveUnpaused())
6262 {
6263 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006264 context
6265 ->handleError(InvalidOperation()
6266 << "Cannot change active program while transform feedback is unpaused.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006267 return false;
6268 }
6269
6270 return true;
6271}
6272
Jamie Madillc29968b2016-01-20 11:17:23 -05006273} // namespace gl