blob: 5dfa4ef8e34b941cd9f631fde8d315c0cb141b17 [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 Lang4f0e0032017-05-01 16:04:35 -0400293 const InternalFormat &internalFormatInfo = GetInternalFormatInfo(internalFormat, type);
294 if (!internalFormatInfo.textureSupport(context->getClientVersion(), context->getExtensions()))
Geoff Lang97073d12016-04-20 10:42:34 -0700295 {
Geoff Lang4f0e0032017-05-01 16:04:35 -0400296 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700297 }
298
299 return true;
300}
301
Geoff Lang4f0e0032017-05-01 16:04:35 -0400302bool IsValidCopyTextureDestinationTarget(Context *context, GLenum textureType, GLenum target)
Geoff Lang97073d12016-04-20 10:42:34 -0700303{
304 switch (target)
305 {
306 case GL_TEXTURE_2D:
Geoff Lang4f0e0032017-05-01 16:04:35 -0400307 return textureType == GL_TEXTURE_2D;
308
309 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
310 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
311 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
312 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
313 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
314 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
315 return textureType == GL_TEXTURE_CUBE_MAP;
Geoff Lang97073d12016-04-20 10:42:34 -0700316
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400317 case GL_TEXTURE_RECTANGLE_ANGLE:
318 return textureType == GL_TEXTURE_RECTANGLE_ANGLE &&
319 context->getExtensions().textureRectangle;
Geoff Lang97073d12016-04-20 10:42:34 -0700320
321 default:
322 return false;
323 }
324}
325
326bool IsValidCopyTextureSourceTarget(Context *context, GLenum target)
327{
Geoff Lang4f0e0032017-05-01 16:04:35 -0400328 switch (target)
Geoff Lang97073d12016-04-20 10:42:34 -0700329 {
Geoff Lang4f0e0032017-05-01 16:04:35 -0400330 case GL_TEXTURE_2D:
331 return true;
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400332 case GL_TEXTURE_RECTANGLE_ANGLE:
333 return context->getExtensions().textureRectangle;
Geoff Lang4f0e0032017-05-01 16:04:35 -0400334
335 // TODO(geofflang): accept GL_TEXTURE_EXTERNAL_OES if the texture_external extension is
336 // supported
337
338 default:
339 return false;
340 }
341}
342
343bool IsValidCopyTextureSourceLevel(Context *context, GLenum target, GLint level)
344{
Geoff Lang3847f942017-07-12 11:17:28 -0400345 if (!ValidMipLevel(context, target, level))
Geoff Lang4f0e0032017-05-01 16:04:35 -0400346 {
347 return false;
Geoff Lang97073d12016-04-20 10:42:34 -0700348 }
349
Geoff Lang4f0e0032017-05-01 16:04:35 -0400350 if (level > 0 && context->getClientVersion() < ES_3_0)
351 {
352 return false;
353 }
Geoff Lang97073d12016-04-20 10:42:34 -0700354
Geoff Lang4f0e0032017-05-01 16:04:35 -0400355 return true;
356}
357
358bool IsValidCopyTextureDestinationLevel(Context *context,
359 GLenum target,
360 GLint level,
361 GLsizei width,
362 GLsizei height)
363{
Geoff Lang3847f942017-07-12 11:17:28 -0400364 if (!ValidMipLevel(context, target, level))
Geoff Lang4f0e0032017-05-01 16:04:35 -0400365 {
366 return false;
367 }
368
Geoff Lang4f0e0032017-05-01 16:04:35 -0400369 const Caps &caps = context->getCaps();
370 if (target == GL_TEXTURE_2D)
371 {
372 if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
373 static_cast<GLuint>(height) > (caps.max2DTextureSize >> level))
374 {
375 return false;
376 }
377 }
Corentin Wallez13c0dd42017-07-04 18:27:01 -0400378 else if (target == GL_TEXTURE_RECTANGLE_ANGLE)
379 {
380 ASSERT(level == 0);
381 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
382 static_cast<GLuint>(height) > caps.maxRectangleTextureSize)
383 {
384 return false;
385 }
386 }
Geoff Lang4f0e0032017-05-01 16:04:35 -0400387 else if (IsCubeMapTextureTarget(target))
388 {
389 if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level) ||
390 static_cast<GLuint>(height) > (caps.maxCubeMapTextureSize >> level))
391 {
392 return false;
393 }
394 }
395
396 return true;
Geoff Lang97073d12016-04-20 10:42:34 -0700397}
398
Jamie Madillc1d770e2017-04-13 17:31:24 -0400399bool IsValidStencilFunc(GLenum func)
400{
401 switch (func)
402 {
403 case GL_NEVER:
404 case GL_ALWAYS:
405 case GL_LESS:
406 case GL_LEQUAL:
407 case GL_EQUAL:
408 case GL_GEQUAL:
409 case GL_GREATER:
410 case GL_NOTEQUAL:
411 return true;
412
413 default:
414 return false;
415 }
416}
417
418bool IsValidStencilFace(GLenum face)
419{
420 switch (face)
421 {
422 case GL_FRONT:
423 case GL_BACK:
424 case GL_FRONT_AND_BACK:
425 return true;
426
427 default:
428 return false;
429 }
430}
431
432bool IsValidStencilOp(GLenum op)
433{
434 switch (op)
435 {
436 case GL_ZERO:
437 case GL_KEEP:
438 case GL_REPLACE:
439 case GL_INCR:
440 case GL_DECR:
441 case GL_INVERT:
442 case GL_INCR_WRAP:
443 case GL_DECR_WRAP:
444 return true;
445
446 default:
447 return false;
448 }
449}
450
Jamie Madillbe849e42017-05-02 15:49:00 -0400451bool ValidateES2CopyTexImageParameters(ValidationContext *context,
452 GLenum target,
453 GLint level,
454 GLenum internalformat,
455 bool isSubImage,
456 GLint xoffset,
457 GLint yoffset,
458 GLint x,
459 GLint y,
460 GLsizei width,
461 GLsizei height,
462 GLint border)
463{
464 if (!ValidTexture2DDestinationTarget(context, target))
465 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700466 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -0400467 return false;
468 }
469
470 if (!ValidImageSizeParameters(context, target, level, width, height, 1, isSubImage))
471 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500472 context->handleError(InvalidValue() << "Invalid texture dimensions.");
Jamie Madillbe849e42017-05-02 15:49:00 -0400473 return false;
474 }
475
476 Format textureFormat = Format::Invalid();
477 if (!ValidateCopyTexImageParametersBase(context, target, level, internalformat, isSubImage,
478 xoffset, yoffset, 0, x, y, width, height, border,
479 &textureFormat))
480 {
481 return false;
482 }
483
484 const gl::Framebuffer *framebuffer = context->getGLState().getReadFramebuffer();
485 GLenum colorbufferFormat =
486 framebuffer->getReadColorbuffer()->getFormat().info->sizedInternalFormat;
487 const auto &formatInfo = *textureFormat.info;
488
489 // [OpenGL ES 2.0.24] table 3.9
490 if (isSubImage)
491 {
492 switch (formatInfo.format)
493 {
494 case GL_ALPHA:
495 if (colorbufferFormat != GL_ALPHA8_EXT && colorbufferFormat != GL_RGBA4 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400496 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGBA8_OES &&
497 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400498 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700499 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400500 return false;
501 }
502 break;
503 case GL_LUMINANCE:
504 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
505 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
506 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400507 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGRA8_EXT &&
508 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400509 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700510 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400511 return false;
512 }
513 break;
514 case GL_RED_EXT:
515 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
516 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
517 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
518 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_R32F &&
519 colorbufferFormat != GL_RG32F && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400520 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
521 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400522 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700523 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400524 return false;
525 }
526 break;
527 case GL_RG_EXT:
528 if (colorbufferFormat != GL_RG8_EXT && colorbufferFormat != GL_RGB565 &&
529 colorbufferFormat != GL_RGB8_OES && colorbufferFormat != GL_RGBA4 &&
530 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGBA8_OES &&
531 colorbufferFormat != GL_RG32F && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400532 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
533 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400534 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700535 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400536 return false;
537 }
538 break;
539 case GL_RGB:
540 if (colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
541 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
542 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_RGB32F &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400543 colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
544 colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400545 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700546 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400547 return false;
548 }
549 break;
550 case GL_LUMINANCE_ALPHA:
551 case GL_RGBA:
552 if (colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
Geoff Lang0c09e262017-05-03 09:43:13 -0400553 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_RGBA32F &&
554 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_BGR5_A1_ANGLEX)
Jamie Madillbe849e42017-05-02 15:49:00 -0400555 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700556 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400557 return false;
558 }
559 break;
560 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
561 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
562 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
563 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
564 case GL_ETC1_RGB8_OES:
565 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
566 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
567 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
568 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
569 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
Brandon Jones6cad5662017-06-14 13:25:13 -0700570 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400571 return false;
572 case GL_DEPTH_COMPONENT:
573 case GL_DEPTH_STENCIL_OES:
Brandon Jones6cad5662017-06-14 13:25:13 -0700574 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400575 return false;
576 default:
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 }
580
581 if (formatInfo.type == GL_FLOAT && !context->getExtensions().textureFloat)
582 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700583 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400584 return false;
585 }
586 }
587 else
588 {
589 switch (internalformat)
590 {
591 case GL_ALPHA:
592 if (colorbufferFormat != GL_ALPHA8_EXT && colorbufferFormat != GL_RGBA4 &&
593 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_BGRA8_EXT &&
594 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGR5_A1_ANGLEX)
595 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700596 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400597 return false;
598 }
599 break;
600 case GL_LUMINANCE:
601 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
602 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
603 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
604 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
605 colorbufferFormat != GL_BGR5_A1_ANGLEX)
606 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700607 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400608 return false;
609 }
610 break;
611 case GL_RED_EXT:
612 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
613 colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
614 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
615 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
616 colorbufferFormat != GL_BGR5_A1_ANGLEX)
617 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700618 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400619 return false;
620 }
621 break;
622 case GL_RG_EXT:
623 if (colorbufferFormat != GL_RG8_EXT && colorbufferFormat != GL_RGB565 &&
624 colorbufferFormat != GL_RGB8_OES && colorbufferFormat != GL_RGBA4 &&
625 colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_BGRA8_EXT &&
626 colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGR5_A1_ANGLEX)
627 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700628 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400629 return false;
630 }
631 break;
632 case GL_RGB:
633 if (colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
634 colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
635 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
636 colorbufferFormat != GL_BGR5_A1_ANGLEX)
637 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700638 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400639 return false;
640 }
641 break;
642 case GL_LUMINANCE_ALPHA:
643 case GL_RGBA:
644 if (colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
645 colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
646 colorbufferFormat != GL_BGR5_A1_ANGLEX)
647 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700648 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400649 return false;
650 }
651 break;
652 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
653 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
654 if (context->getExtensions().textureCompressionDXT1)
655 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700656 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400657 return false;
658 }
659 else
660 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700661 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400662 return false;
663 }
664 break;
665 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
666 if (context->getExtensions().textureCompressionDXT3)
667 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700668 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400669 return false;
670 }
671 else
672 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700673 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400674 return false;
675 }
676 break;
677 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
678 if (context->getExtensions().textureCompressionDXT5)
679 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700680 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Jamie Madillbe849e42017-05-02 15:49:00 -0400681 return false;
682 }
683 else
684 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700685 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -0400686 return false;
687 }
688 break;
689 case GL_ETC1_RGB8_OES:
690 if (context->getExtensions().compressedETC1RGB8Texture)
691 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500692 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -0400693 return false;
694 }
695 else
696 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500697 context->handleError(InvalidEnum());
Jamie Madillbe849e42017-05-02 15:49:00 -0400698 return false;
699 }
700 break;
701 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
702 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
703 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
704 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
705 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
706 if (context->getExtensions().lossyETCDecode)
707 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500708 context->handleError(InvalidOperation()
709 << "ETC lossy decode formats can't be copied to.");
Jamie Madillbe849e42017-05-02 15:49:00 -0400710 return false;
711 }
712 else
713 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500714 context->handleError(InvalidEnum()
715 << "ANGLE_lossy_etc_decode extension is not supported.");
Jamie Madillbe849e42017-05-02 15:49:00 -0400716 return false;
717 }
718 break;
719 case GL_DEPTH_COMPONENT:
720 case GL_DEPTH_COMPONENT16:
721 case GL_DEPTH_COMPONENT32_OES:
722 case GL_DEPTH_STENCIL_OES:
723 case GL_DEPTH24_STENCIL8_OES:
724 if (context->getExtensions().depthTextures)
725 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500726 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -0400727 return false;
728 }
729 else
730 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500731 context->handleError(InvalidEnum());
Jamie Madillbe849e42017-05-02 15:49:00 -0400732 return false;
733 }
734 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500735 context->handleError(InvalidEnum());
Jamie Madillbe849e42017-05-02 15:49:00 -0400736 return false;
737 }
738 }
739
740 // If width or height is zero, it is a no-op. Return false without setting an error.
741 return (width > 0 && height > 0);
742}
743
744bool ValidCap(const Context *context, GLenum cap, bool queryOnly)
745{
746 switch (cap)
747 {
748 // EXT_multisample_compatibility
749 case GL_MULTISAMPLE_EXT:
750 case GL_SAMPLE_ALPHA_TO_ONE_EXT:
751 return context->getExtensions().multisampleCompatibility;
752
753 case GL_CULL_FACE:
754 case GL_POLYGON_OFFSET_FILL:
755 case GL_SAMPLE_ALPHA_TO_COVERAGE:
756 case GL_SAMPLE_COVERAGE:
757 case GL_SCISSOR_TEST:
758 case GL_STENCIL_TEST:
759 case GL_DEPTH_TEST:
760 case GL_BLEND:
761 case GL_DITHER:
762 return true;
763
764 case GL_PRIMITIVE_RESTART_FIXED_INDEX:
765 case GL_RASTERIZER_DISCARD:
766 return (context->getClientMajorVersion() >= 3);
767
768 case GL_DEBUG_OUTPUT_SYNCHRONOUS:
769 case GL_DEBUG_OUTPUT:
770 return context->getExtensions().debug;
771
772 case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
773 return queryOnly && context->getExtensions().bindGeneratesResource;
774
775 case GL_CLIENT_ARRAYS_ANGLE:
776 return queryOnly && context->getExtensions().clientArrays;
777
778 case GL_FRAMEBUFFER_SRGB_EXT:
779 return context->getExtensions().sRGBWriteControl;
780
781 case GL_SAMPLE_MASK:
782 return context->getClientVersion() >= Version(3, 1);
783
784 case GL_CONTEXT_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
785 return queryOnly && context->getExtensions().robustResourceInitialization;
786
787 default:
788 return false;
789 }
790}
791
Geoff Langfc32e8b2017-05-31 14:16:59 -0400792// Return true if a character belongs to the ASCII subset as defined in GLSL ES 1.0 spec section
793// 3.1.
Geoff Langcab92ee2017-07-19 17:32:07 -0400794bool IsValidESSLCharacter(unsigned char c)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400795{
796 // Printing characters are valid except " $ ` @ \ ' DEL.
Geoff Langcab92ee2017-07-19 17:32:07 -0400797 if (c >= 32 && c <= 126 && c != '"' && c != '$' && c != '`' && c != '@' && c != '\\' &&
798 c != '\'')
Geoff Langfc32e8b2017-05-31 14:16:59 -0400799 {
800 return true;
801 }
802
803 // Horizontal tab, line feed, vertical tab, form feed, carriage return are also valid.
804 if (c >= 9 && c <= 13)
805 {
806 return true;
807 }
808
809 return false;
810}
811
Geoff Langcab92ee2017-07-19 17:32:07 -0400812bool IsValidESSLString(const char *str, size_t len)
Geoff Langfc32e8b2017-05-31 14:16:59 -0400813{
Geoff Langa71a98e2017-06-19 15:15:00 -0400814 for (size_t i = 0; i < len; i++)
815 {
Geoff Langcab92ee2017-07-19 17:32:07 -0400816 if (!IsValidESSLCharacter(str[i]))
Geoff Langa71a98e2017-06-19 15:15:00 -0400817 {
818 return false;
819 }
820 }
821
822 return true;
Geoff Langfc32e8b2017-05-31 14:16:59 -0400823}
824
Geoff Langcab92ee2017-07-19 17:32:07 -0400825bool IsValidESSLShaderSourceString(const char *str, size_t len, bool lineContinuationAllowed)
826{
827 enum class ParseState
828 {
829 // Have not seen an ASCII non-whitespace character yet on
830 // this line. Possible that we might see a preprocessor
831 // directive.
832 BEGINING_OF_LINE,
833
834 // Have seen at least one ASCII non-whitespace character
835 // on this line.
836 MIDDLE_OF_LINE,
837
838 // Handling a preprocessor directive. Passes through all
839 // characters up to the end of the line. Disables comment
840 // processing.
841 IN_PREPROCESSOR_DIRECTIVE,
842
843 // Handling a single-line comment. The comment text is
844 // replaced with a single space.
845 IN_SINGLE_LINE_COMMENT,
846
847 // Handling a multi-line comment. Newlines are passed
848 // through to preserve line numbers.
849 IN_MULTI_LINE_COMMENT
850 };
851
852 ParseState state = ParseState::BEGINING_OF_LINE;
853 size_t pos = 0;
854
855 while (pos < len)
856 {
857 char c = str[pos];
858 char next = pos + 1 < len ? str[pos + 1] : 0;
859
860 // Check for newlines
861 if (c == '\n' || c == '\r')
862 {
863 if (state != ParseState::IN_MULTI_LINE_COMMENT)
864 {
865 state = ParseState::BEGINING_OF_LINE;
866 }
867
868 pos++;
869 continue;
870 }
871
872 switch (state)
873 {
874 case ParseState::BEGINING_OF_LINE:
875 if (c == ' ')
876 {
877 // Maintain the BEGINING_OF_LINE state until a non-space is seen
878 pos++;
879 }
880 else if (c == '#')
881 {
882 state = ParseState::IN_PREPROCESSOR_DIRECTIVE;
883 pos++;
884 }
885 else
886 {
887 // Don't advance, re-process this character with the MIDDLE_OF_LINE state
888 state = ParseState::MIDDLE_OF_LINE;
889 }
890 break;
891
892 case ParseState::MIDDLE_OF_LINE:
893 if (c == '/' && next == '/')
894 {
895 state = ParseState::IN_SINGLE_LINE_COMMENT;
896 pos++;
897 }
898 else if (c == '/' && next == '*')
899 {
900 state = ParseState::IN_MULTI_LINE_COMMENT;
901 pos++;
902 }
903 else if (lineContinuationAllowed && c == '\\' && (next == '\n' || next == '\r'))
904 {
905 // Skip line continuation characters
906 }
907 else if (!IsValidESSLCharacter(c))
908 {
909 return false;
910 }
911 pos++;
912 break;
913
914 case ParseState::IN_PREPROCESSOR_DIRECTIVE:
915 // No matter what the character is, just pass it
916 // through. Do not parse comments in this state.
917 pos++;
918 break;
919
920 case ParseState::IN_SINGLE_LINE_COMMENT:
921 // Line-continuation characters are processed before comment processing.
922 // Advance string if a new line character is immediately behind
923 // line-continuation character.
924 if (c == '\\' && (next == '\n' || next == '\r'))
925 {
926 pos++;
927 }
928 pos++;
929 break;
930
931 case ParseState::IN_MULTI_LINE_COMMENT:
932 if (c == '*' && next == '/')
933 {
934 state = ParseState::MIDDLE_OF_LINE;
935 pos++;
936 }
937 pos++;
938 break;
939 }
940 }
941
942 return true;
943}
944
Jamie Madillc29968b2016-01-20 11:17:23 -0500945} // anonymous namespace
946
Geoff Langff5b2d52016-09-07 11:32:23 -0400947bool ValidateES2TexImageParameters(Context *context,
948 GLenum target,
949 GLint level,
950 GLenum internalformat,
951 bool isCompressed,
952 bool isSubImage,
953 GLint xoffset,
954 GLint yoffset,
955 GLsizei width,
956 GLsizei height,
957 GLint border,
958 GLenum format,
959 GLenum type,
960 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -0400961 const void *pixels)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400962{
Jamie Madill6f38f822014-06-06 17:12:20 -0400963 if (!ValidTexture2DDestinationTarget(context, target))
964 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700965 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Geoff Langb1196682014-07-23 13:47:29 -0400966 return false;
Jamie Madill6f38f822014-06-06 17:12:20 -0400967 }
968
Austin Kinross08528e12015-10-07 16:24:40 -0700969 if (!ValidImageSizeParameters(context, target, level, width, height, 1, isSubImage))
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400970 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500971 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -0400972 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400973 }
974
Brandon Jones6cad5662017-06-14 13:25:13 -0700975 if (!ValidMipLevel(context, target, level))
976 {
977 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
978 return false;
979 }
980
981 if (xoffset < 0 || std::numeric_limits<GLsizei>::max() - xoffset < width ||
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400982 std::numeric_limits<GLsizei>::max() - yoffset < height)
983 {
Brandon Jones6cad5662017-06-14 13:25:13 -0700984 ANGLE_VALIDATION_ERR(context, InvalidValue(), ResourceMaxTextureSize);
Geoff Langb1196682014-07-23 13:47:29 -0400985 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400986 }
987
Geoff Lang6e898aa2017-06-02 11:17:26 -0400988 // From GL_CHROMIUM_color_buffer_float_rgb[a]:
989 // GL_RGB[A] / GL_RGB[A]32F becomes an allowable format / internalformat parameter pair for
990 // TexImage2D. The restriction in section 3.7.1 of the OpenGL ES 2.0 spec that the
991 // internalformat parameter and format parameter of TexImage2D must match is lifted for this
992 // case.
993 bool nonEqualFormatsAllowed =
994 (internalformat == GL_RGB32F && context->getExtensions().colorBufferFloatRGB) ||
995 (internalformat == GL_RGBA32F && context->getExtensions().colorBufferFloatRGBA);
996
997 if (!isSubImage && !isCompressed && internalformat != format && !nonEqualFormatsAllowed)
Geoff Lange8ebe7f2013-08-05 15:03:13 -0400998 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -0500999 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001000 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001001 }
1002
Geoff Langaae65a42014-05-26 12:43:44 -04001003 const gl::Caps &caps = context->getCaps();
1004
Geoff Langa9be0dc2014-12-17 12:34:40 -05001005 if (target == GL_TEXTURE_2D)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001006 {
Geoff Langa9be0dc2014-12-17 12:34:40 -05001007 if (static_cast<GLuint>(width) > (caps.max2DTextureSize >> level) ||
1008 static_cast<GLuint>(height) > (caps.max2DTextureSize >> level))
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001009 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001010 context->handleError(InvalidValue());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001011 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001012 }
Geoff Langa9be0dc2014-12-17 12:34:40 -05001013 }
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001014 else if (target == GL_TEXTURE_RECTANGLE_ANGLE)
1015 {
1016 ASSERT(level == 0);
1017 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1018 static_cast<GLuint>(height) > caps.maxRectangleTextureSize)
1019 {
1020 context->handleError(InvalidValue());
1021 return false;
1022 }
1023 if (isCompressed)
1024 {
1025 context->handleError(InvalidEnum()
1026 << "Rectangle texture cannot have a compressed format.");
1027 return false;
1028 }
1029 }
Geoff Lang691e58c2014-12-19 17:03:25 -05001030 else if (IsCubeMapTextureTarget(target))
Geoff Langa9be0dc2014-12-17 12:34:40 -05001031 {
1032 if (!isSubImage && width != height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001033 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001034 ANGLE_VALIDATION_ERR(context, InvalidValue(), CubemapFacesEqualDimensions);
Geoff Langa9be0dc2014-12-17 12:34:40 -05001035 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001036 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001037
Geoff Langa9be0dc2014-12-17 12:34:40 -05001038 if (static_cast<GLuint>(width) > (caps.maxCubeMapTextureSize >> level) ||
1039 static_cast<GLuint>(height) > (caps.maxCubeMapTextureSize >> level))
1040 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001041 context->handleError(InvalidValue());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001042 return false;
1043 }
1044 }
1045 else
1046 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001047 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001048 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001049 }
1050
He Yunchaoced53ae2016-11-29 15:00:51 +08001051 gl::Texture *texture =
1052 context->getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001053 if (!texture)
1054 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001055 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Geoff Langb1196682014-07-23 13:47:29 -04001056 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001057 }
1058
Geoff Langa9be0dc2014-12-17 12:34:40 -05001059 if (isSubImage)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001060 {
Geoff Langca271392017-04-05 12:30:00 -04001061 const InternalFormat &textureInternalFormat = *texture->getFormat(target, level).info;
1062 if (textureInternalFormat.internalFormat == GL_NONE)
Geoff Langc51642b2016-11-14 16:18:26 -05001063 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001064 context->handleError(InvalidOperation() << "Texture level does not exist.");
Geoff Langc51642b2016-11-14 16:18:26 -05001065 return false;
1066 }
1067
Geoff Langa9be0dc2014-12-17 12:34:40 -05001068 if (format != GL_NONE)
1069 {
Geoff Langca271392017-04-05 12:30:00 -04001070 if (GetInternalFormatInfo(format, type).sizedInternalFormat !=
1071 textureInternalFormat.sizedInternalFormat)
Geoff Langa9be0dc2014-12-17 12:34:40 -05001072 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001073 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TypeMismatch);
Geoff Langa9be0dc2014-12-17 12:34:40 -05001074 return false;
1075 }
1076 }
1077
1078 if (static_cast<size_t>(xoffset + width) > texture->getWidth(target, level) ||
1079 static_cast<size_t>(yoffset + height) > texture->getHeight(target, level))
1080 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001081 context->handleError(InvalidValue());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001082 return false;
1083 }
1084 }
1085 else
1086 {
Geoff Lang69cce582015-09-17 13:20:36 -04001087 if (texture->getImmutableFormat())
Geoff Langa9be0dc2014-12-17 12:34:40 -05001088 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001089 context->handleError(InvalidOperation());
Geoff Langa9be0dc2014-12-17 12:34:40 -05001090 return false;
1091 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001092 }
1093
1094 // Verify zero border
1095 if (border != 0)
1096 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001097 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidBorder);
Geoff Langb1196682014-07-23 13:47:29 -04001098 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001099 }
1100
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001101 if (isCompressed)
1102 {
tmartino0ccd5ae2015-10-01 14:33:14 -04001103 GLenum actualInternalFormat =
Geoff Langca271392017-04-05 12:30:00 -04001104 isSubImage ? texture->getFormat(target, level).info->sizedInternalFormat
1105 : internalformat;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001106 switch (actualInternalFormat)
1107 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001108 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1109 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1110 if (!context->getExtensions().textureCompressionDXT1)
1111 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001112 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001113 return false;
1114 }
1115 break;
1116 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1117 if (!context->getExtensions().textureCompressionDXT1)
1118 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001119 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001120 return false;
1121 }
1122 break;
1123 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1124 if (!context->getExtensions().textureCompressionDXT5)
1125 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001126 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001127 return false;
1128 }
1129 break;
Kai Ninomiya02f075c2016-12-22 14:55:46 -08001130 case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
1131 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
1132 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
1133 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
1134 if (!context->getExtensions().textureCompressionS3TCsRGB)
1135 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001136 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
Kai Ninomiya02f075c2016-12-22 14:55:46 -08001137 return false;
1138 }
1139 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001140 case GL_ETC1_RGB8_OES:
1141 if (!context->getExtensions().compressedETC1RGB8Texture)
1142 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001143 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001144 return false;
1145 }
1146 break;
1147 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001148 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1149 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1150 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1151 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001152 if (!context->getExtensions().lossyETCDecode)
1153 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001154 context->handleError(InvalidEnum()
1155 << "ANGLE_lossy_etc_decode extension is not supported");
He Yunchaoced53ae2016-11-29 15:00:51 +08001156 return false;
1157 }
1158 break;
1159 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001160 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidInternalFormat);
Geoff Langb1196682014-07-23 13:47:29 -04001161 return false;
tmartino0ccd5ae2015-10-01 14:33:14 -04001162 }
Geoff Lang966c9402017-04-18 12:38:27 -04001163
1164 if (isSubImage)
tmartino0ccd5ae2015-10-01 14:33:14 -04001165 {
Geoff Lang966c9402017-04-18 12:38:27 -04001166 if (!ValidCompressedSubImageSize(context, actualInternalFormat, xoffset, yoffset, width,
1167 height, texture->getWidth(target, level),
1168 texture->getHeight(target, level)))
1169 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001170 context->handleError(InvalidOperation() << "Invalid compressed format dimension.");
Geoff Lang966c9402017-04-18 12:38:27 -04001171 return false;
1172 }
1173
1174 if (format != actualInternalFormat)
1175 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001176 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidFormat);
Geoff Lang966c9402017-04-18 12:38:27 -04001177 return false;
1178 }
1179 }
1180 else
1181 {
1182 if (!ValidCompressedImageSize(context, actualInternalFormat, level, width, height))
1183 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001184 context->handleError(InvalidOperation() << "Invalid compressed format dimension.");
Geoff Lang966c9402017-04-18 12:38:27 -04001185 return false;
1186 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001187 }
1188 }
1189 else
1190 {
1191 // validate <type> by itself (used as secondary key below)
1192 switch (type)
1193 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001194 case GL_UNSIGNED_BYTE:
1195 case GL_UNSIGNED_SHORT_5_6_5:
1196 case GL_UNSIGNED_SHORT_4_4_4_4:
1197 case GL_UNSIGNED_SHORT_5_5_5_1:
1198 case GL_UNSIGNED_SHORT:
1199 case GL_UNSIGNED_INT:
1200 case GL_UNSIGNED_INT_24_8_OES:
1201 case GL_HALF_FLOAT_OES:
1202 case GL_FLOAT:
1203 break;
1204 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001205 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidType);
He Yunchaoced53ae2016-11-29 15:00:51 +08001206 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001207 }
1208
1209 // validate <format> + <type> combinations
1210 // - invalid <format> -> sets INVALID_ENUM
1211 // - invalid <format>+<type> combination -> sets INVALID_OPERATION
1212 switch (format)
1213 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001214 case GL_ALPHA:
1215 case GL_LUMINANCE:
1216 case GL_LUMINANCE_ALPHA:
1217 switch (type)
1218 {
1219 case GL_UNSIGNED_BYTE:
1220 case GL_FLOAT:
1221 case GL_HALF_FLOAT_OES:
1222 break;
1223 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001224 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001225 return false;
1226 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001227 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001228 case GL_RED:
1229 case GL_RG:
1230 if (!context->getExtensions().textureRG)
1231 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001232 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001233 return false;
1234 }
1235 switch (type)
1236 {
1237 case GL_UNSIGNED_BYTE:
1238 case GL_FLOAT:
1239 case GL_HALF_FLOAT_OES:
1240 break;
1241 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001242 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001243 return false;
1244 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001245 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001246 case GL_RGB:
1247 switch (type)
1248 {
1249 case GL_UNSIGNED_BYTE:
1250 case GL_UNSIGNED_SHORT_5_6_5:
1251 case GL_FLOAT:
1252 case GL_HALF_FLOAT_OES:
1253 break;
1254 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001255 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001256 return false;
1257 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001258 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001259 case GL_RGBA:
1260 switch (type)
1261 {
1262 case GL_UNSIGNED_BYTE:
1263 case GL_UNSIGNED_SHORT_4_4_4_4:
1264 case GL_UNSIGNED_SHORT_5_5_5_1:
1265 case GL_FLOAT:
1266 case GL_HALF_FLOAT_OES:
1267 break;
1268 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001269 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001270 return false;
1271 }
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001272 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001273 case GL_BGRA_EXT:
1274 switch (type)
1275 {
1276 case GL_UNSIGNED_BYTE:
1277 break;
1278 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001279 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001280 return false;
1281 }
1282 break;
1283 case GL_SRGB_EXT:
1284 case GL_SRGB_ALPHA_EXT:
1285 if (!context->getExtensions().sRGB)
1286 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001287 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001288 return false;
1289 }
1290 switch (type)
1291 {
1292 case GL_UNSIGNED_BYTE:
1293 break;
1294 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001295 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001296 return false;
1297 }
1298 break;
1299 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are
1300 // handled below
1301 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1302 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1303 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1304 break;
1305 case GL_DEPTH_COMPONENT:
1306 switch (type)
1307 {
1308 case GL_UNSIGNED_SHORT:
1309 case GL_UNSIGNED_INT:
1310 break;
1311 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001312 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001313 return false;
1314 }
1315 break;
1316 case GL_DEPTH_STENCIL_OES:
1317 switch (type)
1318 {
1319 case GL_UNSIGNED_INT_24_8_OES:
1320 break;
1321 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001322 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001323 return false;
1324 }
1325 break;
1326 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001327 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001328 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001329 }
1330
1331 switch (format)
1332 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001333 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1334 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1335 if (context->getExtensions().textureCompressionDXT1)
1336 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001337 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001338 return false;
1339 }
1340 else
1341 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001342 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001343 return false;
1344 }
1345 break;
1346 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1347 if (context->getExtensions().textureCompressionDXT3)
1348 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001349 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001350 return false;
1351 }
1352 else
1353 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001354 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001355 return false;
1356 }
1357 break;
1358 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1359 if (context->getExtensions().textureCompressionDXT5)
1360 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001361 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001362 return false;
1363 }
1364 else
1365 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001366 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001367 return false;
1368 }
1369 break;
1370 case GL_ETC1_RGB8_OES:
1371 if (context->getExtensions().compressedETC1RGB8Texture)
1372 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001373 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001374 return false;
1375 }
1376 else
1377 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001378 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001379 return false;
1380 }
1381 break;
1382 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001383 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1384 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1385 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1386 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001387 if (context->getExtensions().lossyETCDecode)
1388 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001389 context->handleError(InvalidOperation()
1390 << "ETC lossy decode formats can't work with this type.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001391 return false;
1392 }
1393 else
1394 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001395 context->handleError(InvalidEnum()
1396 << "ANGLE_lossy_etc_decode extension is not supported.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001397 return false;
1398 }
1399 break;
1400 case GL_DEPTH_COMPONENT:
1401 case GL_DEPTH_STENCIL_OES:
1402 if (!context->getExtensions().depthTextures)
1403 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001404 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001405 return false;
1406 }
1407 if (target != GL_TEXTURE_2D)
1408 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001409 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTargetAndFormat);
He Yunchaoced53ae2016-11-29 15:00:51 +08001410 return false;
1411 }
1412 // OES_depth_texture supports loading depth data and multiple levels,
1413 // but ANGLE_depth_texture does not
Brandon Jonesafa75152017-07-21 13:11:29 -07001414 if (pixels != nullptr)
He Yunchaoced53ae2016-11-29 15:00:51 +08001415 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001416 ANGLE_VALIDATION_ERR(context, InvalidOperation(), PixelDataNotNull);
1417 return false;
1418 }
1419 if (level != 0)
1420 {
1421 ANGLE_VALIDATION_ERR(context, InvalidOperation(), LevelNotZero);
He Yunchaoced53ae2016-11-29 15:00:51 +08001422 return false;
1423 }
1424 break;
1425 default:
1426 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001427 }
1428
Geoff Lang6e898aa2017-06-02 11:17:26 -04001429 if (!isSubImage)
1430 {
1431 switch (internalformat)
1432 {
1433 case GL_RGBA32F:
1434 if (!context->getExtensions().colorBufferFloatRGBA)
1435 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001436 context->handleError(InvalidValue()
1437 << "Sized GL_RGBA32F internal format requires "
1438 "GL_CHROMIUM_color_buffer_float_rgba");
Geoff Lang6e898aa2017-06-02 11:17:26 -04001439 return false;
1440 }
1441 if (type != GL_FLOAT)
1442 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001443 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001444 return false;
1445 }
1446 if (format != GL_RGBA)
1447 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001448 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001449 return false;
1450 }
1451 break;
1452
1453 case GL_RGB32F:
1454 if (!context->getExtensions().colorBufferFloatRGB)
1455 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001456 context->handleError(InvalidValue()
1457 << "Sized GL_RGB32F internal format requires "
1458 "GL_CHROMIUM_color_buffer_float_rgb");
Geoff Lang6e898aa2017-06-02 11:17:26 -04001459 return false;
1460 }
1461 if (type != GL_FLOAT)
1462 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001463 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001464 return false;
1465 }
1466 if (format != GL_RGB)
1467 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001468 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang6e898aa2017-06-02 11:17:26 -04001469 return false;
1470 }
1471 break;
1472
1473 default:
1474 break;
1475 }
1476 }
1477
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001478 if (type == GL_FLOAT)
1479 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001480 if (!context->getExtensions().textureFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001481 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001482 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001483 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001484 }
1485 }
1486 else if (type == GL_HALF_FLOAT_OES)
1487 {
Geoff Langc0b9ef42014-07-02 10:02:37 -04001488 if (!context->getExtensions().textureHalfFloat)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001489 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001490 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001491 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001492 }
1493 }
1494 }
1495
Geoff Langdbcced82017-06-06 15:55:54 -04001496 GLenum sizeCheckFormat = isSubImage ? format : internalformat;
1497 if (!ValidImageDataSize(context, target, width, height, 1, sizeCheckFormat, type, pixels,
Geoff Langff5b2d52016-09-07 11:32:23 -04001498 imageSize))
1499 {
1500 return false;
1501 }
1502
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001503 return true;
1504}
1505
He Yunchaoced53ae2016-11-29 15:00:51 +08001506bool ValidateES2TexStorageParameters(Context *context,
1507 GLenum target,
1508 GLsizei levels,
1509 GLenum internalformat,
1510 GLsizei width,
1511 GLsizei height)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001512{
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001513 if (target != GL_TEXTURE_2D && target != GL_TEXTURE_CUBE_MAP &&
1514 target != GL_TEXTURE_RECTANGLE_ANGLE)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001515 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001516 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001517 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001518 }
1519
1520 if (width < 1 || height < 1 || levels < 1)
1521 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001522 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001523 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001524 }
1525
1526 if (target == GL_TEXTURE_CUBE_MAP && width != height)
1527 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001528 context->handleError(InvalidValue());
Geoff Langb1196682014-07-23 13:47:29 -04001529 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001530 }
1531
1532 if (levels != 1 && levels != gl::log2(std::max(width, height)) + 1)
1533 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001534 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001535 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001536 }
1537
Geoff Langca271392017-04-05 12:30:00 -04001538 const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalformat);
Geoff Lang5d601382014-07-22 15:14:06 -04001539 if (formatInfo.format == GL_NONE || formatInfo.type == GL_NONE)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001540 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001541 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001542 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001543 }
1544
Geoff Langaae65a42014-05-26 12:43:44 -04001545 const gl::Caps &caps = context->getCaps();
1546
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001547 switch (target)
1548 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001549 case GL_TEXTURE_2D:
1550 if (static_cast<GLuint>(width) > caps.max2DTextureSize ||
1551 static_cast<GLuint>(height) > caps.max2DTextureSize)
1552 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001553 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001554 return false;
1555 }
1556 break;
Corentin Wallez13c0dd42017-07-04 18:27:01 -04001557 case GL_TEXTURE_RECTANGLE_ANGLE:
1558 if (static_cast<GLuint>(width) > caps.maxRectangleTextureSize ||
1559 static_cast<GLuint>(height) > caps.maxRectangleTextureSize || levels != 1)
1560 {
1561 context->handleError(InvalidValue());
1562 return false;
1563 }
1564 if (formatInfo.compressed)
1565 {
1566 context->handleError(InvalidEnum()
1567 << "Rectangle texture cannot have a compressed format.");
1568 return false;
1569 }
1570 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001571 case GL_TEXTURE_CUBE_MAP:
1572 if (static_cast<GLuint>(width) > caps.maxCubeMapTextureSize ||
1573 static_cast<GLuint>(height) > caps.maxCubeMapTextureSize)
1574 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001575 context->handleError(InvalidValue());
He Yunchaoced53ae2016-11-29 15:00:51 +08001576 return false;
1577 }
1578 break;
1579 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001580 context->handleError(InvalidEnum());
Geoff Langb1196682014-07-23 13:47:29 -04001581 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001582 }
1583
Geoff Langc0b9ef42014-07-02 10:02:37 -04001584 if (levels != 1 && !context->getExtensions().textureNPOT)
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001585 {
1586 if (!gl::isPow2(width) || !gl::isPow2(height))
1587 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001588 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001589 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001590 }
1591 }
1592
1593 switch (internalformat)
1594 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001595 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1596 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1597 if (!context->getExtensions().textureCompressionDXT1)
1598 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001599 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001600 return false;
1601 }
1602 break;
1603 case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE:
1604 if (!context->getExtensions().textureCompressionDXT3)
1605 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001606 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001607 return false;
1608 }
1609 break;
1610 case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE:
1611 if (!context->getExtensions().textureCompressionDXT5)
1612 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001613 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001614 return false;
1615 }
1616 break;
1617 case GL_ETC1_RGB8_OES:
1618 if (!context->getExtensions().compressedETC1RGB8Texture)
1619 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001620 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001621 return false;
1622 }
1623 break;
1624 case GL_ETC1_RGB8_LOSSY_DECODE_ANGLE:
Minmin Gong390208b2017-02-28 18:03:06 -08001625 case GL_COMPRESSED_RGB8_LOSSY_DECODE_ETC2_ANGLE:
1626 case GL_COMPRESSED_SRGB8_LOSSY_DECODE_ETC2_ANGLE:
1627 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
1628 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_LOSSY_DECODE_ETC2_ANGLE:
He Yunchaoced53ae2016-11-29 15:00:51 +08001629 if (!context->getExtensions().lossyETCDecode)
1630 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001631 context->handleError(InvalidEnum()
1632 << "ANGLE_lossy_etc_decode extension is not supported.");
He Yunchaoced53ae2016-11-29 15:00:51 +08001633 return false;
1634 }
1635 break;
1636 case GL_RGBA32F_EXT:
1637 case GL_RGB32F_EXT:
1638 case GL_ALPHA32F_EXT:
1639 case GL_LUMINANCE32F_EXT:
1640 case GL_LUMINANCE_ALPHA32F_EXT:
1641 if (!context->getExtensions().textureFloat)
1642 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001643 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001644 return false;
1645 }
1646 break;
1647 case GL_RGBA16F_EXT:
1648 case GL_RGB16F_EXT:
1649 case GL_ALPHA16F_EXT:
1650 case GL_LUMINANCE16F_EXT:
1651 case GL_LUMINANCE_ALPHA16F_EXT:
1652 if (!context->getExtensions().textureHalfFloat)
1653 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001654 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001655 return false;
1656 }
1657 break;
1658 case GL_R8_EXT:
1659 case GL_RG8_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001660 if (!context->getExtensions().textureRG)
1661 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001662 context->handleError(InvalidEnum());
Geoff Lang677bb6f2017-04-05 12:40:40 -04001663 return false;
1664 }
1665 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001666 case GL_R16F_EXT:
1667 case GL_RG16F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001668 if (!context->getExtensions().textureRG || !context->getExtensions().textureHalfFloat)
1669 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001670 context->handleError(InvalidEnum());
Geoff Lang677bb6f2017-04-05 12:40:40 -04001671 return false;
1672 }
1673 break;
He Yunchaoced53ae2016-11-29 15:00:51 +08001674 case GL_R32F_EXT:
1675 case GL_RG32F_EXT:
Geoff Lang677bb6f2017-04-05 12:40:40 -04001676 if (!context->getExtensions().textureRG || !context->getExtensions().textureFloat)
He Yunchaoced53ae2016-11-29 15:00:51 +08001677 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001678 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001679 return false;
1680 }
1681 break;
1682 case GL_DEPTH_COMPONENT16:
1683 case GL_DEPTH_COMPONENT32_OES:
1684 case GL_DEPTH24_STENCIL8_OES:
1685 if (!context->getExtensions().depthTextures)
1686 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001687 context->handleError(InvalidEnum());
He Yunchaoced53ae2016-11-29 15:00:51 +08001688 return false;
1689 }
1690 if (target != GL_TEXTURE_2D)
1691 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001692 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001693 return false;
1694 }
1695 // ANGLE_depth_texture only supports 1-level textures
1696 if (levels != 1)
1697 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001698 context->handleError(InvalidOperation());
He Yunchaoced53ae2016-11-29 15:00:51 +08001699 return false;
1700 }
1701 break;
1702 default:
1703 break;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001704 }
1705
Geoff Lang691e58c2014-12-19 17:03:25 -05001706 gl::Texture *texture = context->getTargetTexture(target);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001707 if (!texture || texture->id() == 0)
1708 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001709 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001710 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001711 }
1712
Geoff Lang69cce582015-09-17 13:20:36 -04001713 if (texture->getImmutableFormat())
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001714 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001715 context->handleError(InvalidOperation());
Geoff Langb1196682014-07-23 13:47:29 -04001716 return false;
Geoff Lange8ebe7f2013-08-05 15:03:13 -04001717 }
1718
1719 return true;
1720}
1721
He Yunchaoced53ae2016-11-29 15:00:51 +08001722bool ValidateDiscardFramebufferEXT(Context *context,
1723 GLenum target,
1724 GLsizei numAttachments,
Austin Kinross08332632015-05-05 13:35:47 -07001725 const GLenum *attachments)
1726{
Jamie Madillc29968b2016-01-20 11:17:23 -05001727 if (!context->getExtensions().discardFramebuffer)
1728 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001729 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Jamie Madillc29968b2016-01-20 11:17:23 -05001730 return false;
1731 }
1732
Austin Kinross08332632015-05-05 13:35:47 -07001733 bool defaultFramebuffer = false;
1734
1735 switch (target)
1736 {
He Yunchaoced53ae2016-11-29 15:00:51 +08001737 case GL_FRAMEBUFFER:
1738 defaultFramebuffer =
1739 (context->getGLState().getTargetFramebuffer(GL_FRAMEBUFFER)->id() == 0);
1740 break;
1741 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07001742 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
He Yunchaoced53ae2016-11-29 15:00:51 +08001743 return false;
Austin Kinross08332632015-05-05 13:35:47 -07001744 }
1745
He Yunchaoced53ae2016-11-29 15:00:51 +08001746 return ValidateDiscardFramebufferBase(context, target, numAttachments, attachments,
1747 defaultFramebuffer);
Austin Kinross08332632015-05-05 13:35:47 -07001748}
1749
Austin Kinrossbc781f32015-10-26 09:27:38 -07001750bool ValidateBindVertexArrayOES(Context *context, GLuint array)
1751{
1752 if (!context->getExtensions().vertexArrayObject)
1753 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001754 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001755 return false;
1756 }
1757
1758 return ValidateBindVertexArrayBase(context, array);
1759}
1760
1761bool ValidateDeleteVertexArraysOES(Context *context, GLsizei n)
1762{
1763 if (!context->getExtensions().vertexArrayObject)
1764 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001765 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001766 return false;
1767 }
1768
Olli Etuaho41997e72016-03-10 13:38:39 +02001769 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001770}
1771
1772bool ValidateGenVertexArraysOES(Context *context, GLsizei n)
1773{
1774 if (!context->getExtensions().vertexArrayObject)
1775 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001776 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001777 return false;
1778 }
1779
Olli Etuaho41997e72016-03-10 13:38:39 +02001780 return ValidateGenOrDelete(context, n);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001781}
1782
1783bool ValidateIsVertexArrayOES(Context *context)
1784{
1785 if (!context->getExtensions().vertexArrayObject)
1786 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001787 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Austin Kinrossbc781f32015-10-26 09:27:38 -07001788 return false;
1789 }
1790
1791 return true;
1792}
Geoff Langc5629752015-12-07 16:29:04 -05001793
1794bool ValidateProgramBinaryOES(Context *context,
1795 GLuint program,
1796 GLenum binaryFormat,
1797 const void *binary,
1798 GLint length)
1799{
1800 if (!context->getExtensions().getProgramBinary)
1801 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001802 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05001803 return false;
1804 }
1805
1806 return ValidateProgramBinaryBase(context, program, binaryFormat, binary, length);
1807}
1808
1809bool ValidateGetProgramBinaryOES(Context *context,
1810 GLuint program,
1811 GLsizei bufSize,
1812 GLsizei *length,
1813 GLenum *binaryFormat,
1814 void *binary)
1815{
1816 if (!context->getExtensions().getProgramBinary)
1817 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001818 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Langc5629752015-12-07 16:29:04 -05001819 return false;
1820 }
1821
1822 return ValidateGetProgramBinaryBase(context, program, bufSize, length, binaryFormat, binary);
1823}
Geoff Lange102fee2015-12-10 11:23:30 -05001824
Geoff Lang70d0f492015-12-10 17:45:46 -05001825static bool ValidDebugSource(GLenum source, bool mustBeThirdPartyOrApplication)
1826{
1827 switch (source)
1828 {
1829 case GL_DEBUG_SOURCE_API:
1830 case GL_DEBUG_SOURCE_SHADER_COMPILER:
1831 case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
1832 case GL_DEBUG_SOURCE_OTHER:
1833 // Only THIRD_PARTY and APPLICATION sources are allowed to be manually inserted
1834 return !mustBeThirdPartyOrApplication;
1835
1836 case GL_DEBUG_SOURCE_THIRD_PARTY:
1837 case GL_DEBUG_SOURCE_APPLICATION:
1838 return true;
1839
1840 default:
1841 return false;
1842 }
1843}
1844
1845static bool ValidDebugType(GLenum type)
1846{
1847 switch (type)
1848 {
1849 case GL_DEBUG_TYPE_ERROR:
1850 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
1851 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
1852 case GL_DEBUG_TYPE_PERFORMANCE:
1853 case GL_DEBUG_TYPE_PORTABILITY:
1854 case GL_DEBUG_TYPE_OTHER:
1855 case GL_DEBUG_TYPE_MARKER:
1856 case GL_DEBUG_TYPE_PUSH_GROUP:
1857 case GL_DEBUG_TYPE_POP_GROUP:
1858 return true;
1859
1860 default:
1861 return false;
1862 }
1863}
1864
1865static bool ValidDebugSeverity(GLenum severity)
1866{
1867 switch (severity)
1868 {
1869 case GL_DEBUG_SEVERITY_HIGH:
1870 case GL_DEBUG_SEVERITY_MEDIUM:
1871 case GL_DEBUG_SEVERITY_LOW:
1872 case GL_DEBUG_SEVERITY_NOTIFICATION:
1873 return true;
1874
1875 default:
1876 return false;
1877 }
1878}
1879
Geoff Lange102fee2015-12-10 11:23:30 -05001880bool ValidateDebugMessageControlKHR(Context *context,
1881 GLenum source,
1882 GLenum type,
1883 GLenum severity,
1884 GLsizei count,
1885 const GLuint *ids,
1886 GLboolean enabled)
1887{
1888 if (!context->getExtensions().debug)
1889 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001890 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05001891 return false;
1892 }
1893
Geoff Lang70d0f492015-12-10 17:45:46 -05001894 if (!ValidDebugSource(source, false) && source != GL_DONT_CARE)
1895 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001896 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05001897 return false;
1898 }
1899
1900 if (!ValidDebugType(type) && type != GL_DONT_CARE)
1901 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001902 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05001903 return false;
1904 }
1905
1906 if (!ValidDebugSeverity(severity) && severity != GL_DONT_CARE)
1907 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001908 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSeverity);
Geoff Lang70d0f492015-12-10 17:45:46 -05001909 return false;
1910 }
1911
1912 if (count > 0)
1913 {
1914 if (source == GL_DONT_CARE || type == GL_DONT_CARE)
1915 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001916 context->handleError(
1917 InvalidOperation()
1918 << "If count is greater than zero, source and severity cannot be GL_DONT_CARE.");
Geoff Lang70d0f492015-12-10 17:45:46 -05001919 return false;
1920 }
1921
1922 if (severity != GL_DONT_CARE)
1923 {
Jamie Madill437fa652016-05-03 15:13:24 -04001924 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001925 InvalidOperation()
1926 << "If count is greater than zero, severity must be GL_DONT_CARE.");
Geoff Lang70d0f492015-12-10 17:45:46 -05001927 return false;
1928 }
1929 }
1930
Geoff Lange102fee2015-12-10 11:23:30 -05001931 return true;
1932}
1933
1934bool ValidateDebugMessageInsertKHR(Context *context,
1935 GLenum source,
1936 GLenum type,
1937 GLuint id,
1938 GLenum severity,
1939 GLsizei length,
1940 const GLchar *buf)
1941{
1942 if (!context->getExtensions().debug)
1943 {
Brandon Jones6cad5662017-06-14 13:25:13 -07001944 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05001945 return false;
1946 }
1947
Jamie Madilldfde6ab2016-06-09 07:07:18 -07001948 if (!context->getGLState().getDebug().isOutputEnabled())
Geoff Lang70d0f492015-12-10 17:45:46 -05001949 {
1950 // If the DEBUG_OUTPUT state is disabled calls to DebugMessageInsert are discarded and do
1951 // not generate an error.
1952 return false;
1953 }
1954
1955 if (!ValidDebugSeverity(severity))
1956 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001957 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05001958 return false;
1959 }
1960
1961 if (!ValidDebugType(type))
1962 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001963 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugType);
Geoff Lang70d0f492015-12-10 17:45:46 -05001964 return false;
1965 }
1966
1967 if (!ValidDebugSource(source, true))
1968 {
Brandon Jonesafa75152017-07-21 13:11:29 -07001969 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05001970 return false;
1971 }
1972
1973 size_t messageLength = (length < 0) ? strlen(buf) : length;
1974 if (messageLength > context->getExtensions().maxDebugMessageLength)
1975 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05001976 context->handleError(InvalidValue()
1977 << "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH.");
Geoff Lang70d0f492015-12-10 17:45:46 -05001978 return false;
1979 }
1980
Geoff Lange102fee2015-12-10 11:23:30 -05001981 return true;
1982}
1983
1984bool ValidateDebugMessageCallbackKHR(Context *context,
1985 GLDEBUGPROCKHR callback,
1986 const void *userParam)
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
Geoff Lange102fee2015-12-10 11:23:30 -05001994 return true;
1995}
1996
1997bool ValidateGetDebugMessageLogKHR(Context *context,
1998 GLuint count,
1999 GLsizei bufSize,
2000 GLenum *sources,
2001 GLenum *types,
2002 GLuint *ids,
2003 GLenum *severities,
2004 GLsizei *lengths,
2005 GLchar *messageLog)
2006{
2007 if (!context->getExtensions().debug)
2008 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002009 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002010 return false;
2011 }
2012
Geoff Lang70d0f492015-12-10 17:45:46 -05002013 if (bufSize < 0 && messageLog != nullptr)
2014 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002015 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002016 return false;
2017 }
2018
Geoff Lange102fee2015-12-10 11:23:30 -05002019 return true;
2020}
2021
2022bool ValidatePushDebugGroupKHR(Context *context,
2023 GLenum source,
2024 GLuint id,
2025 GLsizei length,
2026 const GLchar *message)
2027{
2028 if (!context->getExtensions().debug)
2029 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002030 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002031 return false;
2032 }
2033
Geoff Lang70d0f492015-12-10 17:45:46 -05002034 if (!ValidDebugSource(source, true))
2035 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002036 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidDebugSource);
Geoff Lang70d0f492015-12-10 17:45:46 -05002037 return false;
2038 }
2039
2040 size_t messageLength = (length < 0) ? strlen(message) : length;
2041 if (messageLength > context->getExtensions().maxDebugMessageLength)
2042 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002043 context->handleError(InvalidValue()
2044 << "Message length is larger than GL_MAX_DEBUG_MESSAGE_LENGTH.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002045 return false;
2046 }
2047
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002048 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002049 if (currentStackSize >= context->getExtensions().maxDebugGroupStackDepth)
2050 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002051 context
2052 ->handleError(StackOverflow()
2053 << "Cannot push more than GL_MAX_DEBUG_GROUP_STACK_DEPTH debug groups.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002054 return false;
2055 }
2056
Geoff Lange102fee2015-12-10 11:23:30 -05002057 return true;
2058}
2059
2060bool ValidatePopDebugGroupKHR(Context *context)
2061{
2062 if (!context->getExtensions().debug)
2063 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002064 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002065 return false;
2066 }
2067
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002068 size_t currentStackSize = context->getGLState().getDebug().getGroupStackDepth();
Geoff Lang70d0f492015-12-10 17:45:46 -05002069 if (currentStackSize <= 1)
2070 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002071 context->handleError(StackUnderflow() << "Cannot pop the default debug group.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002072 return false;
2073 }
2074
2075 return true;
2076}
2077
2078static bool ValidateObjectIdentifierAndName(Context *context, GLenum identifier, GLuint name)
2079{
2080 switch (identifier)
2081 {
2082 case GL_BUFFER:
2083 if (context->getBuffer(name) == nullptr)
2084 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002085 context->handleError(InvalidValue() << "name is not a valid buffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002086 return false;
2087 }
2088 return true;
2089
2090 case GL_SHADER:
2091 if (context->getShader(name) == nullptr)
2092 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002093 context->handleError(InvalidValue() << "name is not a valid shader.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002094 return false;
2095 }
2096 return true;
2097
2098 case GL_PROGRAM:
2099 if (context->getProgram(name) == nullptr)
2100 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002101 context->handleError(InvalidValue() << "name is not a valid program.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002102 return false;
2103 }
2104 return true;
2105
2106 case GL_VERTEX_ARRAY:
2107 if (context->getVertexArray(name) == nullptr)
2108 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002109 context->handleError(InvalidValue() << "name is not a valid vertex array.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002110 return false;
2111 }
2112 return true;
2113
2114 case GL_QUERY:
2115 if (context->getQuery(name) == nullptr)
2116 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002117 context->handleError(InvalidValue() << "name is not a valid query.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002118 return false;
2119 }
2120 return true;
2121
2122 case GL_TRANSFORM_FEEDBACK:
2123 if (context->getTransformFeedback(name) == nullptr)
2124 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002125 context->handleError(InvalidValue() << "name is not a valid transform feedback.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002126 return false;
2127 }
2128 return true;
2129
2130 case GL_SAMPLER:
2131 if (context->getSampler(name) == nullptr)
2132 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002133 context->handleError(InvalidValue() << "name is not a valid sampler.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002134 return false;
2135 }
2136 return true;
2137
2138 case GL_TEXTURE:
2139 if (context->getTexture(name) == nullptr)
2140 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002141 context->handleError(InvalidValue() << "name is not a valid texture.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002142 return false;
2143 }
2144 return true;
2145
2146 case GL_RENDERBUFFER:
2147 if (context->getRenderbuffer(name) == nullptr)
2148 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002149 context->handleError(InvalidValue() << "name is not a valid renderbuffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002150 return false;
2151 }
2152 return true;
2153
2154 case GL_FRAMEBUFFER:
2155 if (context->getFramebuffer(name) == nullptr)
2156 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002157 context->handleError(InvalidValue() << "name is not a valid framebuffer.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002158 return false;
2159 }
2160 return true;
2161
2162 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002163 context->handleError(InvalidEnum() << "Invalid identifier.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002164 return false;
2165 }
Geoff Lange102fee2015-12-10 11:23:30 -05002166}
2167
Martin Radev9d901792016-07-15 15:58:58 +03002168static bool ValidateLabelLength(Context *context, GLsizei length, const GLchar *label)
2169{
2170 size_t labelLength = 0;
2171
2172 if (length < 0)
2173 {
2174 if (label != nullptr)
2175 {
2176 labelLength = strlen(label);
2177 }
2178 }
2179 else
2180 {
2181 labelLength = static_cast<size_t>(length);
2182 }
2183
2184 if (labelLength > context->getExtensions().maxLabelLength)
2185 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002186 context->handleError(InvalidValue() << "Label length is larger than GL_MAX_LABEL_LENGTH.");
Martin Radev9d901792016-07-15 15:58:58 +03002187 return false;
2188 }
2189
2190 return true;
2191}
2192
Geoff Lange102fee2015-12-10 11:23:30 -05002193bool ValidateObjectLabelKHR(Context *context,
2194 GLenum identifier,
2195 GLuint name,
2196 GLsizei length,
2197 const GLchar *label)
2198{
2199 if (!context->getExtensions().debug)
2200 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002201 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002202 return false;
2203 }
2204
Geoff Lang70d0f492015-12-10 17:45:46 -05002205 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2206 {
2207 return false;
2208 }
2209
Martin Radev9d901792016-07-15 15:58:58 +03002210 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002211 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002212 return false;
2213 }
2214
Geoff Lange102fee2015-12-10 11:23:30 -05002215 return true;
2216}
2217
2218bool ValidateGetObjectLabelKHR(Context *context,
2219 GLenum identifier,
2220 GLuint name,
2221 GLsizei bufSize,
2222 GLsizei *length,
2223 GLchar *label)
2224{
2225 if (!context->getExtensions().debug)
2226 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002227 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002228 return false;
2229 }
2230
Geoff Lang70d0f492015-12-10 17:45:46 -05002231 if (bufSize < 0)
2232 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002233 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002234 return false;
2235 }
2236
2237 if (!ValidateObjectIdentifierAndName(context, identifier, name))
2238 {
2239 return false;
2240 }
2241
Martin Radev9d901792016-07-15 15:58:58 +03002242 return true;
Geoff Lang70d0f492015-12-10 17:45:46 -05002243}
2244
2245static bool ValidateObjectPtrName(Context *context, const void *ptr)
2246{
2247 if (context->getFenceSync(reinterpret_cast<GLsync>(const_cast<void *>(ptr))) == nullptr)
2248 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002249 context->handleError(InvalidValue() << "name is not a valid sync.");
Geoff Lang70d0f492015-12-10 17:45:46 -05002250 return false;
2251 }
2252
Geoff Lange102fee2015-12-10 11:23:30 -05002253 return true;
2254}
2255
2256bool ValidateObjectPtrLabelKHR(Context *context,
2257 const void *ptr,
2258 GLsizei length,
2259 const GLchar *label)
2260{
2261 if (!context->getExtensions().debug)
2262 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002263 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002264 return false;
2265 }
2266
Geoff Lang70d0f492015-12-10 17:45:46 -05002267 if (!ValidateObjectPtrName(context, ptr))
2268 {
2269 return false;
2270 }
2271
Martin Radev9d901792016-07-15 15:58:58 +03002272 if (!ValidateLabelLength(context, length, label))
Geoff Lang70d0f492015-12-10 17:45:46 -05002273 {
Geoff Lang70d0f492015-12-10 17:45:46 -05002274 return false;
2275 }
2276
Geoff Lange102fee2015-12-10 11:23:30 -05002277 return true;
2278}
2279
2280bool ValidateGetObjectPtrLabelKHR(Context *context,
2281 const void *ptr,
2282 GLsizei bufSize,
2283 GLsizei *length,
2284 GLchar *label)
2285{
2286 if (!context->getExtensions().debug)
2287 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002288 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002289 return false;
2290 }
2291
Geoff Lang70d0f492015-12-10 17:45:46 -05002292 if (bufSize < 0)
2293 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002294 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Geoff Lang70d0f492015-12-10 17:45:46 -05002295 return false;
2296 }
2297
2298 if (!ValidateObjectPtrName(context, ptr))
2299 {
2300 return false;
2301 }
2302
Martin Radev9d901792016-07-15 15:58:58 +03002303 return true;
Geoff Lange102fee2015-12-10 11:23:30 -05002304}
2305
2306bool ValidateGetPointervKHR(Context *context, GLenum pname, void **params)
2307{
2308 if (!context->getExtensions().debug)
2309 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002310 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExtensionNotEnabled);
Geoff Lange102fee2015-12-10 11:23:30 -05002311 return false;
2312 }
2313
Geoff Lang70d0f492015-12-10 17:45:46 -05002314 // TODO: represent this in Context::getQueryParameterInfo.
2315 switch (pname)
2316 {
2317 case GL_DEBUG_CALLBACK_FUNCTION:
2318 case GL_DEBUG_CALLBACK_USER_PARAM:
2319 break;
2320
2321 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07002322 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Geoff Lang70d0f492015-12-10 17:45:46 -05002323 return false;
2324 }
2325
Geoff Lange102fee2015-12-10 11:23:30 -05002326 return true;
2327}
Jamie Madillc29968b2016-01-20 11:17:23 -05002328
2329bool ValidateBlitFramebufferANGLE(Context *context,
2330 GLint srcX0,
2331 GLint srcY0,
2332 GLint srcX1,
2333 GLint srcY1,
2334 GLint dstX0,
2335 GLint dstY0,
2336 GLint dstX1,
2337 GLint dstY1,
2338 GLbitfield mask,
2339 GLenum filter)
2340{
2341 if (!context->getExtensions().framebufferBlit)
2342 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002343 context->handleError(InvalidOperation() << "Blit extension not available.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002344 return false;
2345 }
2346
2347 if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
2348 {
2349 // TODO(jmadill): Determine if this should be available on other implementations.
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002350 context->handleError(InvalidOperation() << "Scaling and flipping in "
2351 "BlitFramebufferANGLE not supported by this "
2352 "implementation.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002353 return false;
2354 }
2355
2356 if (filter == GL_LINEAR)
2357 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002358 context->handleError(InvalidEnum() << "Linear blit not supported in this extension");
Jamie Madillc29968b2016-01-20 11:17:23 -05002359 return false;
2360 }
2361
Jamie Madill51f40ec2016-06-15 14:06:00 -04002362 Framebuffer *readFramebuffer = context->getGLState().getReadFramebuffer();
2363 Framebuffer *drawFramebuffer = context->getGLState().getDrawFramebuffer();
Jamie Madillc29968b2016-01-20 11:17:23 -05002364
2365 if (mask & GL_COLOR_BUFFER_BIT)
2366 {
2367 const FramebufferAttachment *readColorAttachment = readFramebuffer->getReadColorbuffer();
2368 const FramebufferAttachment *drawColorAttachment = drawFramebuffer->getFirstColorbuffer();
2369
2370 if (readColorAttachment && drawColorAttachment)
2371 {
2372 if (!(readColorAttachment->type() == GL_TEXTURE &&
2373 readColorAttachment->getTextureImageIndex().type == GL_TEXTURE_2D) &&
2374 readColorAttachment->type() != GL_RENDERBUFFER &&
2375 readColorAttachment->type() != GL_FRAMEBUFFER_DEFAULT)
2376 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002377 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002378 return false;
2379 }
2380
Geoff Langa15472a2015-08-11 11:48:03 -04002381 for (size_t drawbufferIdx = 0;
2382 drawbufferIdx < drawFramebuffer->getDrawbufferStateCount(); ++drawbufferIdx)
Jamie Madillc29968b2016-01-20 11:17:23 -05002383 {
Geoff Langa15472a2015-08-11 11:48:03 -04002384 const FramebufferAttachment *attachment =
2385 drawFramebuffer->getDrawBuffer(drawbufferIdx);
2386 if (attachment)
Jamie Madillc29968b2016-01-20 11:17:23 -05002387 {
Jamie Madillc29968b2016-01-20 11:17:23 -05002388 if (!(attachment->type() == GL_TEXTURE &&
2389 attachment->getTextureImageIndex().type == GL_TEXTURE_2D) &&
2390 attachment->type() != GL_RENDERBUFFER &&
2391 attachment->type() != GL_FRAMEBUFFER_DEFAULT)
2392 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002393 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002394 return false;
2395 }
2396
2397 // Return an error if the destination formats do not match
Kenneth Russell69382852017-07-21 16:38:44 -04002398 if (!Format::EquivalentForBlit(attachment->getFormat(),
2399 readColorAttachment->getFormat()))
Jamie Madillc29968b2016-01-20 11:17:23 -05002400 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002401 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002402 return false;
2403 }
2404 }
2405 }
2406
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002407 if (readFramebuffer->getSamples(context) != 0 &&
Jamie Madillc29968b2016-01-20 11:17:23 -05002408 IsPartialBlit(context, readColorAttachment, drawColorAttachment, srcX0, srcY0,
2409 srcX1, srcY1, dstX0, dstY0, dstX1, dstY1))
2410 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002411 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002412 return false;
2413 }
2414 }
2415 }
2416
2417 GLenum masks[] = {GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT};
2418 GLenum attachments[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
2419 for (size_t i = 0; i < 2; i++)
2420 {
2421 if (mask & masks[i])
2422 {
2423 const FramebufferAttachment *readBuffer =
2424 readFramebuffer->getAttachment(attachments[i]);
2425 const FramebufferAttachment *drawBuffer =
2426 drawFramebuffer->getAttachment(attachments[i]);
2427
2428 if (readBuffer && drawBuffer)
2429 {
2430 if (IsPartialBlit(context, readBuffer, drawBuffer, srcX0, srcY0, srcX1, srcY1,
2431 dstX0, dstY0, dstX1, dstY1))
2432 {
2433 // only whole-buffer copies are permitted
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002434 context->handleError(InvalidOperation() << "Only whole-buffer depth and "
2435 "stencil blits are supported by "
2436 "this extension.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002437 return false;
2438 }
2439
2440 if (readBuffer->getSamples() != 0 || drawBuffer->getSamples() != 0)
2441 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002442 context->handleError(InvalidOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002443 return false;
2444 }
2445 }
2446 }
2447 }
2448
2449 return ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0,
2450 dstX1, dstY1, mask, filter);
Geoff Lange8ebe7f2013-08-05 15:03:13 -04002451}
Jamie Madillc29968b2016-01-20 11:17:23 -05002452
2453bool ValidateClear(ValidationContext *context, GLbitfield mask)
2454{
Jamie Madill51f40ec2016-06-15 14:06:00 -04002455 auto fbo = context->getGLState().getDrawFramebuffer();
Jamie Madilldd43e6c2017-03-24 14:18:49 -04002456 if (fbo->checkStatus(context) != GL_FRAMEBUFFER_COMPLETE)
Jamie Madillc29968b2016-01-20 11:17:23 -05002457 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002458 context->handleError(InvalidFramebufferOperation());
Jamie Madillc29968b2016-01-20 11:17:23 -05002459 return false;
2460 }
2461
2462 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
2463 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002464 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidClearMask);
Jamie Madillc29968b2016-01-20 11:17:23 -05002465 return false;
2466 }
2467
Geoff Lang76e65652017-03-27 14:58:02 -04002468 if (context->getExtensions().webglCompatibility && (mask & GL_COLOR_BUFFER_BIT) != 0)
2469 {
2470 constexpr GLenum validComponentTypes[] = {GL_FLOAT, GL_UNSIGNED_NORMALIZED,
2471 GL_SIGNED_NORMALIZED};
2472
Corentin Wallez59c41592017-07-11 13:19:54 -04002473 for (GLuint drawBufferIdx = 0; drawBufferIdx < fbo->getDrawbufferStateCount();
Geoff Lang76e65652017-03-27 14:58:02 -04002474 drawBufferIdx++)
2475 {
2476 if (!ValidateWebGLFramebufferAttachmentClearType(
2477 context, drawBufferIdx, validComponentTypes, ArraySize(validComponentTypes)))
2478 {
2479 return false;
2480 }
2481 }
2482 }
2483
Jamie Madillc29968b2016-01-20 11:17:23 -05002484 return true;
2485}
2486
2487bool ValidateDrawBuffersEXT(ValidationContext *context, GLsizei n, const GLenum *bufs)
2488{
2489 if (!context->getExtensions().drawBuffers)
2490 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002491 context->handleError(InvalidOperation() << "Extension not supported.");
Jamie Madillc29968b2016-01-20 11:17:23 -05002492 return false;
2493 }
2494
2495 return ValidateDrawBuffersBase(context, n, bufs);
2496}
2497
Jamie Madill73a84962016-02-12 09:27:23 -05002498bool ValidateTexImage2D(Context *context,
2499 GLenum target,
2500 GLint level,
2501 GLint internalformat,
2502 GLsizei width,
2503 GLsizei height,
2504 GLint border,
2505 GLenum format,
2506 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002507 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002508{
Martin Radev1be913c2016-07-11 17:59:16 +03002509 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002510 {
2511 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
Geoff Langff5b2d52016-09-07 11:32:23 -04002512 0, 0, width, height, border, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002513 }
2514
Martin Radev1be913c2016-07-11 17:59:16 +03002515 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002516 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002517 0, 0, width, height, 1, border, format, type, -1,
2518 pixels);
2519}
2520
2521bool ValidateTexImage2DRobust(Context *context,
2522 GLenum target,
2523 GLint level,
2524 GLint internalformat,
2525 GLsizei width,
2526 GLsizei height,
2527 GLint border,
2528 GLenum format,
2529 GLenum type,
2530 GLsizei bufSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002531 const void *pixels)
Geoff Langff5b2d52016-09-07 11:32:23 -04002532{
2533 if (!ValidateRobustEntryPoint(context, bufSize))
2534 {
2535 return false;
2536 }
2537
2538 if (context->getClientMajorVersion() < 3)
2539 {
2540 return ValidateES2TexImageParameters(context, target, level, internalformat, false, false,
2541 0, 0, width, height, border, format, type, bufSize,
2542 pixels);
2543 }
2544
2545 ASSERT(context->getClientMajorVersion() >= 3);
2546 return ValidateES3TexImage2DParameters(context, target, level, internalformat, false, false, 0,
2547 0, 0, width, height, 1, border, format, type, bufSize,
2548 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002549}
2550
2551bool ValidateTexSubImage2D(Context *context,
2552 GLenum target,
2553 GLint level,
2554 GLint xoffset,
2555 GLint yoffset,
2556 GLsizei width,
2557 GLsizei height,
2558 GLenum format,
2559 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04002560 const void *pixels)
Jamie Madill73a84962016-02-12 09:27:23 -05002561{
2562
Martin Radev1be913c2016-07-11 17:59:16 +03002563 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002564 {
2565 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002566 yoffset, width, height, 0, format, type, -1, pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002567 }
2568
Martin Radev1be913c2016-07-11 17:59:16 +03002569 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002570 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
Geoff Langff5b2d52016-09-07 11:32:23 -04002571 yoffset, 0, width, height, 1, 0, format, type, -1,
2572 pixels);
Jamie Madill73a84962016-02-12 09:27:23 -05002573}
2574
Geoff Langc52f6f12016-10-14 10:18:00 -04002575bool ValidateTexSubImage2DRobustANGLE(Context *context,
2576 GLenum target,
2577 GLint level,
2578 GLint xoffset,
2579 GLint yoffset,
2580 GLsizei width,
2581 GLsizei height,
2582 GLenum format,
2583 GLenum type,
2584 GLsizei bufSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002585 const void *pixels)
Geoff Langc52f6f12016-10-14 10:18:00 -04002586{
2587 if (!ValidateRobustEntryPoint(context, bufSize))
2588 {
2589 return false;
2590 }
2591
2592 if (context->getClientMajorVersion() < 3)
2593 {
2594 return ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, xoffset,
2595 yoffset, width, height, 0, format, type, bufSize,
2596 pixels);
2597 }
2598
2599 ASSERT(context->getClientMajorVersion() >= 3);
2600 return ValidateES3TexImage2DParameters(context, target, level, GL_NONE, false, true, xoffset,
2601 yoffset, 0, width, height, 1, 0, format, type, bufSize,
2602 pixels);
2603}
2604
Jamie Madill73a84962016-02-12 09:27:23 -05002605bool ValidateCompressedTexImage2D(Context *context,
2606 GLenum target,
2607 GLint level,
2608 GLenum internalformat,
2609 GLsizei width,
2610 GLsizei height,
2611 GLint border,
2612 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002613 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002614{
Martin Radev1be913c2016-07-11 17:59:16 +03002615 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002616 {
2617 if (!ValidateES2TexImageParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002618 0, width, height, border, GL_NONE, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002619 {
2620 return false;
2621 }
2622 }
2623 else
2624 {
Martin Radev1be913c2016-07-11 17:59:16 +03002625 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002626 if (!ValidateES3TexImage2DParameters(context, target, level, internalformat, true, false, 0,
Geoff Langff5b2d52016-09-07 11:32:23 -04002627 0, 0, width, height, 1, border, GL_NONE, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002628 data))
2629 {
2630 return false;
2631 }
2632 }
2633
Geoff Langca271392017-04-05 12:30:00 -04002634 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalformat);
Jamie Madill513558d2016-06-02 13:04:11 -04002635 auto blockSizeOrErr =
Jamie Madill4b4cdff2016-06-06 13:53:38 -07002636 formatInfo.computeCompressedImageSize(GL_UNSIGNED_BYTE, gl::Extents(width, height, 1));
Jamie Madille2e406c2016-06-02 13:04:10 -04002637 if (blockSizeOrErr.isError())
2638 {
2639 context->handleError(blockSizeOrErr.getError());
2640 return false;
2641 }
2642
2643 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSizeOrErr.getResult())
Jamie Madill73a84962016-02-12 09:27:23 -05002644 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002645 ANGLE_VALIDATION_ERR(context, InvalidValue(), CompressedTextureDimensionsMustMatchData);
Jamie Madill73a84962016-02-12 09:27:23 -05002646 return false;
2647 }
2648
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002649 if (target == GL_TEXTURE_RECTANGLE_ANGLE)
2650 {
2651 context->handleError(InvalidEnum() << "Rectangle texture cannot have a compressed format.");
2652 return false;
2653 }
2654
Jamie Madill73a84962016-02-12 09:27:23 -05002655 return true;
2656}
2657
Corentin Wallezb2931602017-04-11 15:58:57 -04002658bool ValidateCompressedTexImage2DRobustANGLE(Context *context,
2659 GLenum target,
2660 GLint level,
2661 GLenum internalformat,
2662 GLsizei width,
2663 GLsizei height,
2664 GLint border,
2665 GLsizei imageSize,
2666 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002667 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002668{
2669 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2670 {
2671 return false;
2672 }
2673
2674 return ValidateCompressedTexImage2D(context, target, level, internalformat, width, height,
2675 border, imageSize, data);
2676}
2677bool ValidateCompressedTexSubImage2DRobustANGLE(Context *context,
2678 GLenum target,
2679 GLint level,
2680 GLint xoffset,
2681 GLint yoffset,
2682 GLsizei width,
2683 GLsizei height,
2684 GLenum format,
2685 GLsizei imageSize,
2686 GLsizei dataSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002687 const void *data)
Corentin Wallezb2931602017-04-11 15:58:57 -04002688{
2689 if (!ValidateRobustCompressedTexImageBase(context, imageSize, dataSize))
2690 {
2691 return false;
2692 }
2693
2694 return ValidateCompressedTexSubImage2D(context, target, level, xoffset, yoffset, width, height,
2695 format, imageSize, data);
2696}
2697
Jamie Madill73a84962016-02-12 09:27:23 -05002698bool ValidateCompressedTexSubImage2D(Context *context,
2699 GLenum target,
2700 GLint level,
2701 GLint xoffset,
2702 GLint yoffset,
2703 GLsizei width,
2704 GLsizei height,
2705 GLenum format,
2706 GLsizei imageSize,
Jamie Madill876429b2017-04-20 15:46:24 -04002707 const void *data)
Jamie Madill73a84962016-02-12 09:27:23 -05002708{
Martin Radev1be913c2016-07-11 17:59:16 +03002709 if (context->getClientMajorVersion() < 3)
Jamie Madill73a84962016-02-12 09:27:23 -05002710 {
2711 if (!ValidateES2TexImageParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002712 yoffset, width, height, 0, format, GL_NONE, -1, data))
Jamie Madill73a84962016-02-12 09:27:23 -05002713 {
2714 return false;
2715 }
2716 }
2717 else
2718 {
Martin Radev1be913c2016-07-11 17:59:16 +03002719 ASSERT(context->getClientMajorVersion() >= 3);
Jamie Madill73a84962016-02-12 09:27:23 -05002720 if (!ValidateES3TexImage2DParameters(context, target, level, GL_NONE, true, true, xoffset,
Geoff Lang966c9402017-04-18 12:38:27 -04002721 yoffset, 0, width, height, 1, 0, format, GL_NONE, -1,
Jamie Madill73a84962016-02-12 09:27:23 -05002722 data))
2723 {
2724 return false;
2725 }
2726 }
2727
Geoff Langca271392017-04-05 12:30:00 -04002728 const InternalFormat &formatInfo = GetSizedInternalFormatInfo(format);
Jamie Madill513558d2016-06-02 13:04:11 -04002729 auto blockSizeOrErr =
Jamie Madill4b4cdff2016-06-06 13:53:38 -07002730 formatInfo.computeCompressedImageSize(GL_UNSIGNED_BYTE, gl::Extents(width, height, 1));
Jamie Madille2e406c2016-06-02 13:04:10 -04002731 if (blockSizeOrErr.isError())
2732 {
2733 context->handleError(blockSizeOrErr.getError());
2734 return false;
2735 }
2736
2737 if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSizeOrErr.getResult())
Jamie Madill73a84962016-02-12 09:27:23 -05002738 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002739 context->handleError(InvalidValue());
Jamie Madill73a84962016-02-12 09:27:23 -05002740 return false;
2741 }
2742
2743 return true;
2744}
2745
Olli Etuaho4f667482016-03-30 15:56:35 +03002746bool ValidateGetBufferPointervOES(Context *context, GLenum target, GLenum pname, void **params)
2747{
Geoff Lang496c02d2016-10-20 11:38:11 -07002748 return ValidateGetBufferPointervBase(context, target, pname, nullptr, params);
Olli Etuaho4f667482016-03-30 15:56:35 +03002749}
2750
2751bool ValidateMapBufferOES(Context *context, GLenum target, GLenum access)
2752{
2753 if (!context->getExtensions().mapBuffer)
2754 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002755 context->handleError(InvalidOperation() << "Map buffer extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002756 return false;
2757 }
2758
2759 if (!ValidBufferTarget(context, target))
2760 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002761 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Olli Etuaho4f667482016-03-30 15:56:35 +03002762 return false;
2763 }
2764
Jamie Madilldfde6ab2016-06-09 07:07:18 -07002765 Buffer *buffer = context->getGLState().getTargetBuffer(target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002766
2767 if (buffer == nullptr)
2768 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002769 context->handleError(InvalidOperation() << "Attempted to map buffer object zero.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002770 return false;
2771 }
2772
2773 if (access != GL_WRITE_ONLY_OES)
2774 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002775 context->handleError(InvalidEnum() << "Non-write buffer mapping not supported.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002776 return false;
2777 }
2778
2779 if (buffer->isMapped())
2780 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002781 context->handleError(InvalidOperation() << "Buffer is already mapped.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002782 return false;
2783 }
2784
Geoff Lang79f71042017-08-14 16:43:43 -04002785 return ValidateMapBufferBase(context, target);
Olli Etuaho4f667482016-03-30 15:56:35 +03002786}
2787
2788bool ValidateUnmapBufferOES(Context *context, GLenum target)
2789{
2790 if (!context->getExtensions().mapBuffer)
2791 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002792 context->handleError(InvalidOperation() << "Map buffer extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002793 return false;
2794 }
2795
2796 return ValidateUnmapBufferBase(context, target);
2797}
2798
2799bool ValidateMapBufferRangeEXT(Context *context,
2800 GLenum target,
2801 GLintptr offset,
2802 GLsizeiptr length,
2803 GLbitfield access)
2804{
2805 if (!context->getExtensions().mapBufferRange)
2806 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002807 context->handleError(InvalidOperation() << "Map buffer range extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002808 return false;
2809 }
2810
2811 return ValidateMapBufferRangeBase(context, target, offset, length, access);
2812}
2813
Geoff Lang79f71042017-08-14 16:43:43 -04002814bool ValidateMapBufferBase(Context *context, GLenum target)
2815{
2816 Buffer *buffer = context->getGLState().getTargetBuffer(target);
2817 ASSERT(buffer != nullptr);
2818
2819 // Check if this buffer is currently being used as a transform feedback output buffer
2820 TransformFeedback *transformFeedback = context->getGLState().getCurrentTransformFeedback();
2821 if (transformFeedback != nullptr && transformFeedback->isActive())
2822 {
2823 for (size_t i = 0; i < transformFeedback->getIndexedBufferCount(); i++)
2824 {
2825 const auto &transformFeedbackBuffer = transformFeedback->getIndexedBuffer(i);
2826 if (transformFeedbackBuffer.get() == buffer)
2827 {
2828 context->handleError(InvalidOperation()
2829 << "Buffer is currently bound for transform feedback.");
2830 return false;
2831 }
2832 }
2833 }
2834
2835 return true;
2836}
2837
Olli Etuaho4f667482016-03-30 15:56:35 +03002838bool ValidateFlushMappedBufferRangeEXT(Context *context,
2839 GLenum target,
2840 GLintptr offset,
2841 GLsizeiptr length)
2842{
2843 if (!context->getExtensions().mapBufferRange)
2844 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002845 context->handleError(InvalidOperation() << "Map buffer range extension not available.");
Olli Etuaho4f667482016-03-30 15:56:35 +03002846 return false;
2847 }
2848
2849 return ValidateFlushMappedBufferRangeBase(context, target, offset, length);
2850}
2851
Ian Ewell54f87462016-03-10 13:47:21 -05002852bool ValidateBindTexture(Context *context, GLenum target, GLuint texture)
2853{
2854 Texture *textureObject = context->getTexture(texture);
2855 if (textureObject && textureObject->getTarget() != target && texture != 0)
2856 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002857 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TypeMismatch);
Ian Ewell54f87462016-03-10 13:47:21 -05002858 return false;
2859 }
2860
Geoff Langf41a7152016-09-19 15:11:17 -04002861 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
2862 !context->isTextureGenerated(texture))
2863 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002864 context->handleError(InvalidOperation() << "Texture was not generated");
Geoff Langf41a7152016-09-19 15:11:17 -04002865 return false;
2866 }
2867
Ian Ewell54f87462016-03-10 13:47:21 -05002868 switch (target)
2869 {
2870 case GL_TEXTURE_2D:
2871 case GL_TEXTURE_CUBE_MAP:
2872 break;
2873
Corentin Wallez13c0dd42017-07-04 18:27:01 -04002874 case GL_TEXTURE_RECTANGLE_ANGLE:
2875 if (!context->getExtensions().textureRectangle)
2876 {
2877 context->handleError(InvalidEnum()
2878 << "Context does not support GL_ANGLE_texture_rectangle");
2879 return false;
2880 }
2881 break;
2882
Ian Ewell54f87462016-03-10 13:47:21 -05002883 case GL_TEXTURE_3D:
2884 case GL_TEXTURE_2D_ARRAY:
Martin Radev1be913c2016-07-11 17:59:16 +03002885 if (context->getClientMajorVersion() < 3)
Ian Ewell54f87462016-03-10 13:47:21 -05002886 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002887 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES3Required);
Ian Ewell54f87462016-03-10 13:47:21 -05002888 return false;
2889 }
2890 break;
Geoff Lang3b573612016-10-31 14:08:10 -04002891
2892 case GL_TEXTURE_2D_MULTISAMPLE:
2893 if (context->getClientVersion() < Version(3, 1))
2894 {
Brandon Jonesafa75152017-07-21 13:11:29 -07002895 ANGLE_VALIDATION_ERR(context, InvalidEnum(), ES31Required);
Geoff Lang3b573612016-10-31 14:08:10 -04002896 return false;
2897 }
Geoff Lang3b573612016-10-31 14:08:10 -04002898 break;
2899
Ian Ewell54f87462016-03-10 13:47:21 -05002900 case GL_TEXTURE_EXTERNAL_OES:
Geoff Langb66a9092016-05-16 15:59:14 -04002901 if (!context->getExtensions().eglImageExternal &&
2902 !context->getExtensions().eglStreamConsumerExternal)
Ian Ewell54f87462016-03-10 13:47:21 -05002903 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002904 context->handleError(InvalidEnum() << "External texture extension not enabled");
Ian Ewell54f87462016-03-10 13:47:21 -05002905 return false;
2906 }
2907 break;
2908 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07002909 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Ian Ewell54f87462016-03-10 13:47:21 -05002910 return false;
2911 }
2912
2913 return true;
2914}
2915
Geoff Langd8605522016-04-13 10:19:12 -04002916bool ValidateBindUniformLocationCHROMIUM(Context *context,
2917 GLuint program,
2918 GLint location,
2919 const GLchar *name)
2920{
2921 if (!context->getExtensions().bindUniformLocation)
2922 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002923 context->handleError(InvalidOperation()
2924 << "GL_CHROMIUM_bind_uniform_location is not available.");
Geoff Langd8605522016-04-13 10:19:12 -04002925 return false;
2926 }
2927
2928 Program *programObject = GetValidProgram(context, program);
2929 if (!programObject)
2930 {
2931 return false;
2932 }
2933
2934 if (location < 0)
2935 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002936 context->handleError(InvalidValue() << "Location cannot be less than 0.");
Geoff Langd8605522016-04-13 10:19:12 -04002937 return false;
2938 }
2939
2940 const Caps &caps = context->getCaps();
2941 if (static_cast<size_t>(location) >=
2942 (caps.maxVertexUniformVectors + caps.maxFragmentUniformVectors) * 4)
2943 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002944 context->handleError(InvalidValue() << "Location must be less than "
2945 "(MAX_VERTEX_UNIFORM_VECTORS + "
2946 "MAX_FRAGMENT_UNIFORM_VECTORS) * 4");
Geoff Langd8605522016-04-13 10:19:12 -04002947 return false;
2948 }
2949
Geoff Langfc32e8b2017-05-31 14:16:59 -04002950 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
2951 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04002952 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04002953 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002954 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04002955 return false;
2956 }
2957
Geoff Langd8605522016-04-13 10:19:12 -04002958 if (strncmp(name, "gl_", 3) == 0)
2959 {
Brandon Jones6cad5662017-06-14 13:25:13 -07002960 ANGLE_VALIDATION_ERR(context, InvalidValue(), NameBeginsWithGL);
Geoff Langd8605522016-04-13 10:19:12 -04002961 return false;
2962 }
2963
2964 return true;
2965}
2966
Jamie Madille2e406c2016-06-02 13:04:10 -04002967bool ValidateCoverageModulationCHROMIUM(Context *context, GLenum components)
Sami Väisänena797e062016-05-12 15:23:40 +03002968{
2969 if (!context->getExtensions().framebufferMixedSamples)
2970 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002971 context->handleError(InvalidOperation()
2972 << "GL_CHROMIUM_framebuffer_mixed_samples is not available.");
Sami Väisänena797e062016-05-12 15:23:40 +03002973 return false;
2974 }
2975 switch (components)
2976 {
2977 case GL_RGB:
2978 case GL_RGBA:
2979 case GL_ALPHA:
2980 case GL_NONE:
2981 break;
2982 default:
2983 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002984 InvalidEnum()
2985 << "GLenum components is not one of GL_RGB, GL_RGBA, GL_ALPHA or GL_NONE.");
Sami Väisänena797e062016-05-12 15:23:40 +03002986 return false;
2987 }
2988
2989 return true;
2990}
2991
Sami Väisänene45e53b2016-05-25 10:36:04 +03002992// CHROMIUM_path_rendering
2993
2994bool ValidateMatrix(Context *context, GLenum matrixMode, const GLfloat *matrix)
2995{
2996 if (!context->getExtensions().pathRendering)
2997 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05002998 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03002999 return false;
3000 }
3001 if (matrixMode != GL_PATH_MODELVIEW_CHROMIUM && matrixMode != GL_PATH_PROJECTION_CHROMIUM)
3002 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003003 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidMatrixMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003004 return false;
3005 }
3006 if (matrix == nullptr)
3007 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003008 context->handleError(InvalidOperation() << "Invalid matrix.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003009 return false;
3010 }
3011 return true;
3012}
3013
3014bool ValidateMatrixMode(Context *context, GLenum matrixMode)
3015{
3016 if (!context->getExtensions().pathRendering)
3017 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003018 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003019 return false;
3020 }
3021 if (matrixMode != GL_PATH_MODELVIEW_CHROMIUM && matrixMode != GL_PATH_PROJECTION_CHROMIUM)
3022 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003023 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidMatrixMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003024 return false;
3025 }
3026 return true;
3027}
3028
3029bool ValidateGenPaths(Context *context, GLsizei range)
3030{
3031 if (!context->getExtensions().pathRendering)
3032 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003033 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003034 return false;
3035 }
3036
3037 // range = 0 is undefined in NV_path_rendering.
3038 // we add stricter semantic check here and require a non zero positive range.
3039 if (range <= 0)
3040 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003041 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003042 return false;
3043 }
3044
3045 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range))
3046 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003047 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003048 return false;
3049 }
3050
3051 return true;
3052}
3053
3054bool ValidateDeletePaths(Context *context, GLuint path, GLsizei range)
3055{
3056 if (!context->getExtensions().pathRendering)
3057 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003058 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003059 return false;
3060 }
3061
3062 // range = 0 is undefined in NV_path_rendering.
3063 // we add stricter semantic check here and require a non zero positive range.
3064 if (range <= 0)
3065 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003066 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidRange);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003067 return false;
3068 }
3069
3070 angle::CheckedNumeric<std::uint32_t> checkedRange(path);
3071 checkedRange += range;
3072
3073 if (!angle::IsValueInRangeForNumericType<std::uint32_t>(range) || !checkedRange.IsValid())
3074 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003075 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003076 return false;
3077 }
3078 return true;
3079}
3080
3081bool ValidatePathCommands(Context *context,
3082 GLuint path,
3083 GLsizei numCommands,
3084 const GLubyte *commands,
3085 GLsizei numCoords,
3086 GLenum coordType,
3087 const void *coords)
3088{
3089 if (!context->getExtensions().pathRendering)
3090 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003091 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003092 return false;
3093 }
3094 if (!context->hasPath(path))
3095 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003096 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003097 return false;
3098 }
3099
3100 if (numCommands < 0)
3101 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003102 context->handleError(InvalidValue() << "Invalid number of commands.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003103 return false;
3104 }
3105 else if (numCommands > 0)
3106 {
3107 if (!commands)
3108 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003109 context->handleError(InvalidValue() << "No commands array given.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003110 return false;
3111 }
3112 }
3113
3114 if (numCoords < 0)
3115 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003116 context->handleError(InvalidValue() << "Invalid number of coordinates.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003117 return false;
3118 }
3119 else if (numCoords > 0)
3120 {
3121 if (!coords)
3122 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003123 context->handleError(InvalidValue() << "No coordinate array given.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003124 return false;
3125 }
3126 }
3127
3128 std::uint32_t coordTypeSize = 0;
3129 switch (coordType)
3130 {
3131 case GL_BYTE:
3132 coordTypeSize = sizeof(GLbyte);
3133 break;
3134
3135 case GL_UNSIGNED_BYTE:
3136 coordTypeSize = sizeof(GLubyte);
3137 break;
3138
3139 case GL_SHORT:
3140 coordTypeSize = sizeof(GLshort);
3141 break;
3142
3143 case GL_UNSIGNED_SHORT:
3144 coordTypeSize = sizeof(GLushort);
3145 break;
3146
3147 case GL_FLOAT:
3148 coordTypeSize = sizeof(GLfloat);
3149 break;
3150
3151 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003152 context->handleError(InvalidEnum() << "Invalid coordinate type.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003153 return false;
3154 }
3155
3156 angle::CheckedNumeric<std::uint32_t> checkedSize(numCommands);
3157 checkedSize += (coordTypeSize * numCoords);
3158 if (!checkedSize.IsValid())
3159 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003160 ANGLE_VALIDATION_ERR(context, InvalidOperation(), IntegerOverflow);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003161 return false;
3162 }
3163
3164 // early return skips command data validation when it doesn't exist.
3165 if (!commands)
3166 return true;
3167
3168 GLsizei expectedNumCoords = 0;
3169 for (GLsizei i = 0; i < numCommands; ++i)
3170 {
3171 switch (commands[i])
3172 {
3173 case GL_CLOSE_PATH_CHROMIUM: // no coordinates.
3174 break;
3175 case GL_MOVE_TO_CHROMIUM:
3176 case GL_LINE_TO_CHROMIUM:
3177 expectedNumCoords += 2;
3178 break;
3179 case GL_QUADRATIC_CURVE_TO_CHROMIUM:
3180 expectedNumCoords += 4;
3181 break;
3182 case GL_CUBIC_CURVE_TO_CHROMIUM:
3183 expectedNumCoords += 6;
3184 break;
3185 case GL_CONIC_CURVE_TO_CHROMIUM:
3186 expectedNumCoords += 5;
3187 break;
3188 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003189 context->handleError(InvalidEnum() << "Invalid command.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003190 return false;
3191 }
3192 }
3193 if (expectedNumCoords != numCoords)
3194 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003195 context->handleError(InvalidValue() << "Invalid number of coordinates.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003196 return false;
3197 }
3198
3199 return true;
3200}
3201
3202bool ValidateSetPathParameter(Context *context, GLuint path, GLenum pname, GLfloat value)
3203{
3204 if (!context->getExtensions().pathRendering)
3205 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003206 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003207 return false;
3208 }
3209 if (!context->hasPath(path))
3210 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003211 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003212 return false;
3213 }
3214
3215 switch (pname)
3216 {
3217 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3218 if (value < 0.0f)
3219 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003220 context->handleError(InvalidValue() << "Invalid stroke width.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003221 return false;
3222 }
3223 break;
3224 case GL_PATH_END_CAPS_CHROMIUM:
3225 switch (static_cast<GLenum>(value))
3226 {
3227 case GL_FLAT_CHROMIUM:
3228 case GL_SQUARE_CHROMIUM:
3229 case GL_ROUND_CHROMIUM:
3230 break;
3231 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003232 context->handleError(InvalidEnum() << "Invalid end caps.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003233 return false;
3234 }
3235 break;
3236 case GL_PATH_JOIN_STYLE_CHROMIUM:
3237 switch (static_cast<GLenum>(value))
3238 {
3239 case GL_MITER_REVERT_CHROMIUM:
3240 case GL_BEVEL_CHROMIUM:
3241 case GL_ROUND_CHROMIUM:
3242 break;
3243 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003244 context->handleError(InvalidEnum() << "Invalid join style.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003245 return false;
3246 }
3247 case GL_PATH_MITER_LIMIT_CHROMIUM:
3248 if (value < 0.0f)
3249 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003250 context->handleError(InvalidValue() << "Invalid miter limit.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003251 return false;
3252 }
3253 break;
3254
3255 case GL_PATH_STROKE_BOUND_CHROMIUM:
3256 // no errors, only clamping.
3257 break;
3258
3259 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003260 context->handleError(InvalidEnum() << "Invalid path parameter.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003261 return false;
3262 }
3263 return true;
3264}
3265
3266bool ValidateGetPathParameter(Context *context, GLuint path, GLenum pname, GLfloat *value)
3267{
3268 if (!context->getExtensions().pathRendering)
3269 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003270 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003271 return false;
3272 }
3273
3274 if (!context->hasPath(path))
3275 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003276 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003277 return false;
3278 }
3279 if (!value)
3280 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003281 context->handleError(InvalidValue() << "No value array.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003282 return false;
3283 }
3284
3285 switch (pname)
3286 {
3287 case GL_PATH_STROKE_WIDTH_CHROMIUM:
3288 case GL_PATH_END_CAPS_CHROMIUM:
3289 case GL_PATH_JOIN_STYLE_CHROMIUM:
3290 case GL_PATH_MITER_LIMIT_CHROMIUM:
3291 case GL_PATH_STROKE_BOUND_CHROMIUM:
3292 break;
3293
3294 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003295 context->handleError(InvalidEnum() << "Invalid path parameter.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003296 return false;
3297 }
3298
3299 return true;
3300}
3301
3302bool ValidatePathStencilFunc(Context *context, GLenum func, GLint ref, GLuint mask)
3303{
3304 if (!context->getExtensions().pathRendering)
3305 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003306 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003307 return false;
3308 }
3309
3310 switch (func)
3311 {
3312 case GL_NEVER:
3313 case GL_ALWAYS:
3314 case GL_LESS:
3315 case GL_LEQUAL:
3316 case GL_EQUAL:
3317 case GL_GEQUAL:
3318 case GL_GREATER:
3319 case GL_NOTEQUAL:
3320 break;
3321 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07003322 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003323 return false;
3324 }
3325
3326 return true;
3327}
3328
3329// Note that the spec specifies that for the path drawing commands
3330// if the path object is not an existing path object the command
3331// does nothing and no error is generated.
3332// However if the path object exists but has not been specified any
3333// commands then an error is generated.
3334
3335bool ValidateStencilFillPath(Context *context, GLuint path, GLenum fillMode, GLuint mask)
3336{
3337 if (!context->getExtensions().pathRendering)
3338 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003339 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003340 return false;
3341 }
3342 if (context->hasPath(path) && !context->hasPathData(path))
3343 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003344 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003345 return false;
3346 }
3347
3348 switch (fillMode)
3349 {
3350 case GL_COUNT_UP_CHROMIUM:
3351 case GL_COUNT_DOWN_CHROMIUM:
3352 break;
3353 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003354 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003355 return false;
3356 }
3357
3358 if (!isPow2(mask + 1))
3359 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003360 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003361 return false;
3362 }
3363
3364 return true;
3365}
3366
3367bool ValidateStencilStrokePath(Context *context, GLuint path, GLint reference, GLuint mask)
3368{
3369 if (!context->getExtensions().pathRendering)
3370 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003371 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003372 return false;
3373 }
3374 if (context->hasPath(path) && !context->hasPathData(path))
3375 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003376 context->handleError(InvalidOperation() << "No such path or path has no data.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003377 return false;
3378 }
3379
3380 return true;
3381}
3382
3383bool ValidateCoverPath(Context *context, GLuint path, GLenum coverMode)
3384{
3385 if (!context->getExtensions().pathRendering)
3386 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003387 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003388 return false;
3389 }
3390 if (context->hasPath(path) && !context->hasPathData(path))
3391 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003392 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NoSuchPath);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003393 return false;
3394 }
3395
3396 switch (coverMode)
3397 {
3398 case GL_CONVEX_HULL_CHROMIUM:
3399 case GL_BOUNDING_BOX_CHROMIUM:
3400 break;
3401 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003402 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänene45e53b2016-05-25 10:36:04 +03003403 return false;
3404 }
3405 return true;
3406}
3407
3408bool ValidateStencilThenCoverFillPath(Context *context,
3409 GLuint path,
3410 GLenum fillMode,
3411 GLuint mask,
3412 GLenum coverMode)
3413{
3414 return ValidateStencilFillPath(context, path, fillMode, mask) &&
3415 ValidateCoverPath(context, path, coverMode);
3416}
3417
3418bool ValidateStencilThenCoverStrokePath(Context *context,
3419 GLuint path,
3420 GLint reference,
3421 GLuint mask,
3422 GLenum coverMode)
3423{
3424 return ValidateStencilStrokePath(context, path, reference, mask) &&
3425 ValidateCoverPath(context, path, coverMode);
3426}
3427
3428bool ValidateIsPath(Context *context)
3429{
3430 if (!context->getExtensions().pathRendering)
3431 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003432 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänene45e53b2016-05-25 10:36:04 +03003433 return false;
3434 }
3435 return true;
3436}
3437
Sami Väisänend59ca052016-06-21 16:10:00 +03003438bool ValidateCoverFillPathInstanced(Context *context,
3439 GLsizei numPaths,
3440 GLenum pathNameType,
3441 const void *paths,
3442 GLuint pathBase,
3443 GLenum coverMode,
3444 GLenum transformType,
3445 const GLfloat *transformValues)
3446{
3447 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3448 transformType, transformValues))
3449 return false;
3450
3451 switch (coverMode)
3452 {
3453 case GL_CONVEX_HULL_CHROMIUM:
3454 case GL_BOUNDING_BOX_CHROMIUM:
3455 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3456 break;
3457 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003458 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003459 return false;
3460 }
3461
3462 return true;
3463}
3464
3465bool ValidateCoverStrokePathInstanced(Context *context,
3466 GLsizei numPaths,
3467 GLenum pathNameType,
3468 const void *paths,
3469 GLuint pathBase,
3470 GLenum coverMode,
3471 GLenum transformType,
3472 const GLfloat *transformValues)
3473{
3474 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3475 transformType, transformValues))
3476 return false;
3477
3478 switch (coverMode)
3479 {
3480 case GL_CONVEX_HULL_CHROMIUM:
3481 case GL_BOUNDING_BOX_CHROMIUM:
3482 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3483 break;
3484 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003485 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003486 return false;
3487 }
3488
3489 return true;
3490}
3491
3492bool ValidateStencilFillPathInstanced(Context *context,
3493 GLsizei numPaths,
3494 GLenum pathNameType,
3495 const void *paths,
3496 GLuint pathBase,
3497 GLenum fillMode,
3498 GLuint mask,
3499 GLenum transformType,
3500 const GLfloat *transformValues)
3501{
3502
3503 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3504 transformType, transformValues))
3505 return false;
3506
3507 switch (fillMode)
3508 {
3509 case GL_COUNT_UP_CHROMIUM:
3510 case GL_COUNT_DOWN_CHROMIUM:
3511 break;
3512 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003513 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003514 return false;
3515 }
3516 if (!isPow2(mask + 1))
3517 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003518 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003519 return false;
3520 }
3521 return true;
3522}
3523
3524bool ValidateStencilStrokePathInstanced(Context *context,
3525 GLsizei numPaths,
3526 GLenum pathNameType,
3527 const void *paths,
3528 GLuint pathBase,
3529 GLint reference,
3530 GLuint mask,
3531 GLenum transformType,
3532 const GLfloat *transformValues)
3533{
3534 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3535 transformType, transformValues))
3536 return false;
3537
3538 // no more validation here.
3539
3540 return true;
3541}
3542
3543bool ValidateStencilThenCoverFillPathInstanced(Context *context,
3544 GLsizei numPaths,
3545 GLenum pathNameType,
3546 const void *paths,
3547 GLuint pathBase,
3548 GLenum fillMode,
3549 GLuint mask,
3550 GLenum coverMode,
3551 GLenum transformType,
3552 const GLfloat *transformValues)
3553{
3554 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3555 transformType, transformValues))
3556 return false;
3557
3558 switch (coverMode)
3559 {
3560 case GL_CONVEX_HULL_CHROMIUM:
3561 case GL_BOUNDING_BOX_CHROMIUM:
3562 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3563 break;
3564 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003565 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003566 return false;
3567 }
3568
3569 switch (fillMode)
3570 {
3571 case GL_COUNT_UP_CHROMIUM:
3572 case GL_COUNT_DOWN_CHROMIUM:
3573 break;
3574 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003575 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFillMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003576 return false;
3577 }
3578 if (!isPow2(mask + 1))
3579 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003580 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidStencilBitMask);
Sami Väisänend59ca052016-06-21 16:10:00 +03003581 return false;
3582 }
3583
3584 return true;
3585}
3586
3587bool ValidateStencilThenCoverStrokePathInstanced(Context *context,
3588 GLsizei numPaths,
3589 GLenum pathNameType,
3590 const void *paths,
3591 GLuint pathBase,
3592 GLint reference,
3593 GLuint mask,
3594 GLenum coverMode,
3595 GLenum transformType,
3596 const GLfloat *transformValues)
3597{
3598 if (!ValidateInstancedPathParameters(context, numPaths, pathNameType, paths, pathBase,
3599 transformType, transformValues))
3600 return false;
3601
3602 switch (coverMode)
3603 {
3604 case GL_CONVEX_HULL_CHROMIUM:
3605 case GL_BOUNDING_BOX_CHROMIUM:
3606 case GL_BOUNDING_BOX_OF_BOUNDING_BOXES_CHROMIUM:
3607 break;
3608 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07003609 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCoverMode);
Sami Väisänend59ca052016-06-21 16:10:00 +03003610 return false;
3611 }
3612
3613 return true;
3614}
3615
Sami Väisänen46eaa942016-06-29 10:26:37 +03003616bool ValidateBindFragmentInputLocation(Context *context,
3617 GLuint program,
3618 GLint location,
3619 const GLchar *name)
3620{
3621 if (!context->getExtensions().pathRendering)
3622 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003623 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003624 return false;
3625 }
3626
3627 const GLint MaxLocation = context->getCaps().maxVaryingVectors * 4;
3628 if (location >= MaxLocation)
3629 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003630 context->handleError(InvalidValue() << "Location exceeds max varying.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003631 return false;
3632 }
3633
3634 const auto *programObject = context->getProgram(program);
3635 if (!programObject)
3636 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003637 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003638 return false;
3639 }
3640
3641 if (!name)
3642 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003643 context->handleError(InvalidValue() << "No name given.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003644 return false;
3645 }
3646
3647 if (angle::BeginsWith(name, "gl_"))
3648 {
Brandon Jonesafa75152017-07-21 13:11:29 -07003649 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003650 return false;
3651 }
3652
3653 return true;
3654}
3655
3656bool ValidateProgramPathFragmentInputGen(Context *context,
3657 GLuint program,
3658 GLint location,
3659 GLenum genMode,
3660 GLint components,
3661 const GLfloat *coeffs)
3662{
3663 if (!context->getExtensions().pathRendering)
3664 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003665 context->handleError(InvalidOperation() << "GL_CHROMIUM_path_rendering is not available.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003666 return false;
3667 }
3668
3669 const auto *programObject = context->getProgram(program);
3670 if (!programObject || programObject->isFlaggedForDeletion())
3671 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003672 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramDoesNotExist);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003673 return false;
3674 }
3675
3676 if (!programObject->isLinked())
3677 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003678 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003679 return false;
3680 }
3681
3682 switch (genMode)
3683 {
3684 case GL_NONE:
3685 if (components != 0)
3686 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003687 context->handleError(InvalidValue() << "Invalid components.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003688 return false;
3689 }
3690 break;
3691
3692 case GL_OBJECT_LINEAR_CHROMIUM:
3693 case GL_EYE_LINEAR_CHROMIUM:
3694 case GL_CONSTANT_CHROMIUM:
3695 if (components < 1 || components > 4)
3696 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003697 context->handleError(InvalidValue() << "Invalid components.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003698 return false;
3699 }
3700 if (!coeffs)
3701 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003702 context->handleError(InvalidValue() << "No coefficients array given.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003703 return false;
3704 }
3705 break;
3706
3707 default:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003708 context->handleError(InvalidEnum() << "Invalid gen mode.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003709 return false;
3710 }
3711
3712 // If the location is -1 then the command is silently ignored
3713 // and no further validation is needed.
3714 if (location == -1)
3715 return true;
3716
Jamie Madillbd044ed2017-06-05 12:59:21 -04003717 const auto &binding = programObject->getFragmentInputBindingInfo(context, location);
Sami Väisänen46eaa942016-06-29 10:26:37 +03003718
3719 if (!binding.valid)
3720 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003721 context->handleError(InvalidOperation() << "No such binding.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003722 return false;
3723 }
3724
3725 if (binding.type != GL_NONE)
3726 {
3727 GLint expectedComponents = 0;
3728 switch (binding.type)
3729 {
3730 case GL_FLOAT:
3731 expectedComponents = 1;
3732 break;
3733 case GL_FLOAT_VEC2:
3734 expectedComponents = 2;
3735 break;
3736 case GL_FLOAT_VEC3:
3737 expectedComponents = 3;
3738 break;
3739 case GL_FLOAT_VEC4:
3740 expectedComponents = 4;
3741 break;
3742 default:
He Yunchaoced53ae2016-11-29 15:00:51 +08003743 context->handleError(
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003744 InvalidOperation()
3745 << "Fragment input type is not a floating point scalar or vector.");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003746 return false;
3747 }
3748 if (expectedComponents != components && genMode != GL_NONE)
3749 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003750 context->handleError(InvalidOperation() << "Unexpected number of components");
Sami Väisänen46eaa942016-06-29 10:26:37 +03003751 return false;
3752 }
3753 }
3754 return true;
3755}
3756
Geoff Lang97073d12016-04-20 10:42:34 -07003757bool ValidateCopyTextureCHROMIUM(Context *context,
3758 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003759 GLint sourceLevel,
3760 GLenum destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003761 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003762 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003763 GLint internalFormat,
3764 GLenum destType,
3765 GLboolean unpackFlipY,
3766 GLboolean unpackPremultiplyAlpha,
3767 GLboolean unpackUnmultiplyAlpha)
3768{
3769 if (!context->getExtensions().copyTexture)
3770 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003771 context->handleError(InvalidOperation()
3772 << "GL_CHROMIUM_copy_texture extension not available.");
Geoff Lang97073d12016-04-20 10:42:34 -07003773 return false;
3774 }
3775
Geoff Lang4f0e0032017-05-01 16:04:35 -04003776 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07003777 if (source == nullptr)
3778 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003779 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003780 return false;
3781 }
3782
3783 if (!IsValidCopyTextureSourceTarget(context, source->getTarget()))
3784 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003785 context->handleError(InvalidValue() << "Source texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07003786 return false;
3787 }
3788
3789 GLenum sourceTarget = source->getTarget();
3790 ASSERT(sourceTarget != GL_TEXTURE_CUBE_MAP);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003791
3792 if (!IsValidCopyTextureSourceLevel(context, source->getTarget(), sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07003793 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003794 context->handleError(InvalidValue() << "Source texture level is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07003795 return false;
3796 }
3797
Geoff Lang4f0e0032017-05-01 16:04:35 -04003798 GLsizei sourceWidth = static_cast<GLsizei>(source->getWidth(sourceTarget, sourceLevel));
3799 GLsizei sourceHeight = static_cast<GLsizei>(source->getHeight(sourceTarget, sourceLevel));
3800 if (sourceWidth == 0 || sourceHeight == 0)
3801 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003802 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003803 return false;
3804 }
3805
3806 const InternalFormat &sourceFormat = *source->getFormat(sourceTarget, sourceLevel).info;
3807 if (!IsValidCopyTextureSourceInternalFormatEnum(sourceFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07003808 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003809 context->handleError(InvalidOperation() << "Source texture internal format is invalid.");
Geoff Lang97073d12016-04-20 10:42:34 -07003810 return false;
3811 }
3812
Geoff Lang4f0e0032017-05-01 16:04:35 -04003813 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07003814 if (dest == nullptr)
3815 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003816 context->handleError(InvalidValue()
3817 << "Destination texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003818 return false;
3819 }
3820
Geoff Lang4f0e0032017-05-01 16:04:35 -04003821 if (!IsValidCopyTextureDestinationTarget(context, dest->getTarget(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07003822 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003823 context->handleError(InvalidValue() << "Destination texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07003824 return false;
3825 }
3826
Geoff Lang4f0e0032017-05-01 16:04:35 -04003827 if (!IsValidCopyTextureDestinationLevel(context, destTarget, destLevel, sourceWidth,
3828 sourceHeight))
3829 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003830 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003831 return false;
3832 }
3833
Geoff Lang97073d12016-04-20 10:42:34 -07003834 if (!IsValidCopyTextureDestinationFormatType(context, internalFormat, destType))
3835 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003836 ANGLE_VALIDATION_ERR(context, InvalidOperation(), MismatchedTypeAndFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07003837 return false;
3838 }
3839
Geoff Lang4f0e0032017-05-01 16:04:35 -04003840 if (IsCubeMapTextureTarget(destTarget) && sourceWidth != sourceHeight)
3841 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003842 context->handleError(
3843 InvalidValue() << "Destination width and height must be equal for cube map textures.");
Geoff Lang4f0e0032017-05-01 16:04:35 -04003844 return false;
3845 }
3846
Geoff Lang97073d12016-04-20 10:42:34 -07003847 if (dest->getImmutableFormat())
3848 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003849 context->handleError(InvalidOperation() << "Destination texture is immutable.");
Geoff Lang97073d12016-04-20 10:42:34 -07003850 return false;
3851 }
3852
3853 return true;
3854}
3855
3856bool ValidateCopySubTextureCHROMIUM(Context *context,
3857 GLuint sourceId,
Geoff Langfc72a072017-03-24 14:52:39 -04003858 GLint sourceLevel,
3859 GLenum destTarget,
Geoff Lang97073d12016-04-20 10:42:34 -07003860 GLuint destId,
Geoff Langfc72a072017-03-24 14:52:39 -04003861 GLint destLevel,
Geoff Lang97073d12016-04-20 10:42:34 -07003862 GLint xoffset,
3863 GLint yoffset,
3864 GLint x,
3865 GLint y,
3866 GLsizei width,
3867 GLsizei height,
3868 GLboolean unpackFlipY,
3869 GLboolean unpackPremultiplyAlpha,
3870 GLboolean unpackUnmultiplyAlpha)
3871{
3872 if (!context->getExtensions().copyTexture)
3873 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003874 context->handleError(InvalidOperation()
3875 << "GL_CHROMIUM_copy_texture extension not available.");
Geoff Lang97073d12016-04-20 10:42:34 -07003876 return false;
3877 }
3878
Geoff Lang4f0e0032017-05-01 16:04:35 -04003879 const Texture *source = context->getTexture(sourceId);
Geoff Lang97073d12016-04-20 10:42:34 -07003880 if (source == nullptr)
3881 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003882 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003883 return false;
3884 }
3885
3886 if (!IsValidCopyTextureSourceTarget(context, source->getTarget()))
3887 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003888 context->handleError(InvalidValue() << "Source texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07003889 return false;
3890 }
3891
3892 GLenum sourceTarget = source->getTarget();
3893 ASSERT(sourceTarget != GL_TEXTURE_CUBE_MAP);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003894
3895 if (!IsValidCopyTextureSourceLevel(context, source->getTarget(), sourceLevel))
3896 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003897 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidMipLevel);
Geoff Lang4f0e0032017-05-01 16:04:35 -04003898 return false;
3899 }
3900
3901 if (source->getWidth(sourceTarget, sourceLevel) == 0 ||
3902 source->getHeight(sourceTarget, sourceLevel) == 0)
Geoff Lang97073d12016-04-20 10:42:34 -07003903 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003904 context->handleError(InvalidValue()
3905 << "The source level of the source texture must be defined.");
Geoff Lang97073d12016-04-20 10:42:34 -07003906 return false;
3907 }
3908
3909 if (x < 0 || y < 0)
3910 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003911 context->handleError(InvalidValue() << "x and y cannot be negative.");
Geoff Lang97073d12016-04-20 10:42:34 -07003912 return false;
3913 }
3914
3915 if (width < 0 || height < 0)
3916 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003917 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Geoff Lang97073d12016-04-20 10:42:34 -07003918 return false;
3919 }
3920
Geoff Lang4f0e0032017-05-01 16:04:35 -04003921 if (static_cast<size_t>(x + width) > source->getWidth(sourceTarget, sourceLevel) ||
3922 static_cast<size_t>(y + height) > source->getHeight(sourceTarget, sourceLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07003923 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003924 ANGLE_VALIDATION_ERR(context, InvalidValue(), SourceTextureTooSmall);
Geoff Lang97073d12016-04-20 10:42:34 -07003925 return false;
3926 }
3927
Geoff Lang4f0e0032017-05-01 16:04:35 -04003928 const Format &sourceFormat = source->getFormat(sourceTarget, sourceLevel);
3929 if (!IsValidCopySubTextureSourceInternalFormat(sourceFormat.info->internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07003930 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003931 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidInternalFormat);
Geoff Lang97073d12016-04-20 10:42:34 -07003932 return false;
3933 }
3934
Geoff Lang4f0e0032017-05-01 16:04:35 -04003935 const Texture *dest = context->getTexture(destId);
Geoff Lang97073d12016-04-20 10:42:34 -07003936 if (dest == nullptr)
3937 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003938 context->handleError(InvalidValue()
3939 << "Destination texture is not a valid texture object.");
Geoff Lang97073d12016-04-20 10:42:34 -07003940 return false;
3941 }
3942
Geoff Lang4f0e0032017-05-01 16:04:35 -04003943 if (!IsValidCopyTextureDestinationTarget(context, dest->getTarget(), destTarget))
Geoff Lang97073d12016-04-20 10:42:34 -07003944 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003945 context->handleError(InvalidValue() << "Destination texture a valid texture type.");
Geoff Lang97073d12016-04-20 10:42:34 -07003946 return false;
3947 }
3948
Geoff Lang4f0e0032017-05-01 16:04:35 -04003949 if (!IsValidCopyTextureDestinationLevel(context, destTarget, destLevel, width, height))
Geoff Lang97073d12016-04-20 10:42:34 -07003950 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003951 context->handleError(InvalidValue() << "Destination texture level is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07003952 return false;
3953 }
3954
Geoff Lang4f0e0032017-05-01 16:04:35 -04003955 if (dest->getWidth(destTarget, destLevel) == 0 || dest->getHeight(destTarget, destLevel) == 0)
3956 {
Geoff Langbb1b19b2017-06-16 16:59:00 -04003957 context
3958 ->handleError(InvalidOperation()
3959 << "The destination level of the destination texture must be defined.");
Geoff Lang4f0e0032017-05-01 16:04:35 -04003960 return false;
3961 }
3962
3963 const InternalFormat &destFormat = *dest->getFormat(destTarget, destLevel).info;
3964 if (!IsValidCopySubTextureDestionationInternalFormat(destFormat.internalFormat))
Geoff Lang97073d12016-04-20 10:42:34 -07003965 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003966 context->handleError(InvalidOperation()
3967 << "Destination internal format and type combination is not valid.");
Geoff Lang97073d12016-04-20 10:42:34 -07003968 return false;
3969 }
3970
3971 if (xoffset < 0 || yoffset < 0)
3972 {
Brandon Jones6cad5662017-06-14 13:25:13 -07003973 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Geoff Lang97073d12016-04-20 10:42:34 -07003974 return false;
3975 }
3976
Geoff Lang4f0e0032017-05-01 16:04:35 -04003977 if (static_cast<size_t>(xoffset + width) > dest->getWidth(destTarget, destLevel) ||
3978 static_cast<size_t>(yoffset + height) > dest->getHeight(destTarget, destLevel))
Geoff Lang97073d12016-04-20 10:42:34 -07003979 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003980 context->handleError(InvalidValue() << "Destination texture not large enough to copy to.");
Geoff Lang97073d12016-04-20 10:42:34 -07003981 return false;
3982 }
3983
3984 return true;
3985}
3986
Geoff Lang47110bf2016-04-20 11:13:22 -07003987bool ValidateCompressedCopyTextureCHROMIUM(Context *context, GLuint sourceId, GLuint destId)
3988{
3989 if (!context->getExtensions().copyCompressedTexture)
3990 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003991 context->handleError(InvalidOperation()
3992 << "GL_CHROMIUM_copy_compressed_texture extension not available.");
Geoff Lang47110bf2016-04-20 11:13:22 -07003993 return false;
3994 }
3995
3996 const gl::Texture *source = context->getTexture(sourceId);
3997 if (source == nullptr)
3998 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05003999 context->handleError(InvalidValue() << "Source texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004000 return false;
4001 }
4002
4003 if (source->getTarget() != GL_TEXTURE_2D)
4004 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004005 context->handleError(InvalidValue() << "Source texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004006 return false;
4007 }
4008
4009 if (source->getWidth(GL_TEXTURE_2D, 0) == 0 || source->getHeight(GL_TEXTURE_2D, 0) == 0)
4010 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004011 context->handleError(InvalidValue() << "Source texture must level 0 defined.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004012 return false;
4013 }
4014
4015 const gl::Format &sourceFormat = source->getFormat(GL_TEXTURE_2D, 0);
4016 if (!sourceFormat.info->compressed)
4017 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004018 context->handleError(InvalidOperation()
4019 << "Source texture must have a compressed internal format.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004020 return false;
4021 }
4022
4023 const gl::Texture *dest = context->getTexture(destId);
4024 if (dest == nullptr)
4025 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004026 context->handleError(InvalidValue()
4027 << "Destination texture is not a valid texture object.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004028 return false;
4029 }
4030
4031 if (dest->getTarget() != GL_TEXTURE_2D)
4032 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004033 context->handleError(InvalidValue()
4034 << "Destination texture must be of type GL_TEXTURE_2D.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004035 return false;
4036 }
4037
4038 if (dest->getImmutableFormat())
4039 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004040 context->handleError(InvalidOperation() << "Destination cannot be immutable.");
Geoff Lang47110bf2016-04-20 11:13:22 -07004041 return false;
4042 }
4043
4044 return true;
4045}
4046
Martin Radev4c4c8e72016-08-04 12:25:34 +03004047bool ValidateCreateShader(Context *context, GLenum type)
4048{
4049 switch (type)
4050 {
4051 case GL_VERTEX_SHADER:
4052 case GL_FRAGMENT_SHADER:
4053 break;
Geoff Langeb66a6e2016-10-31 13:06:12 -04004054
Martin Radev4c4c8e72016-08-04 12:25:34 +03004055 case GL_COMPUTE_SHADER:
Geoff Langeb66a6e2016-10-31 13:06:12 -04004056 if (context->getClientVersion() < Version(3, 1))
Martin Radev4c4c8e72016-08-04 12:25:34 +03004057 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004058 context->handleError(InvalidEnum() << "GL_COMPUTE_SHADER requires OpenGL ES 3.1.");
Geoff Langeb66a6e2016-10-31 13:06:12 -04004059 return false;
Martin Radev4c4c8e72016-08-04 12:25:34 +03004060 }
Geoff Langeb66a6e2016-10-31 13:06:12 -04004061 break;
4062
Martin Radev4c4c8e72016-08-04 12:25:34 +03004063 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004064 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Martin Radev4c4c8e72016-08-04 12:25:34 +03004065 return false;
4066 }
Jamie Madill29639852016-09-02 15:00:09 -04004067
4068 return true;
4069}
4070
4071bool ValidateBufferData(ValidationContext *context,
4072 GLenum target,
4073 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004074 const void *data,
Jamie Madill29639852016-09-02 15:00:09 -04004075 GLenum usage)
4076{
4077 if (size < 0)
4078 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004079 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madill29639852016-09-02 15:00:09 -04004080 return false;
4081 }
4082
4083 switch (usage)
4084 {
4085 case GL_STREAM_DRAW:
4086 case GL_STATIC_DRAW:
4087 case GL_DYNAMIC_DRAW:
4088 break;
4089
4090 case GL_STREAM_READ:
4091 case GL_STREAM_COPY:
4092 case GL_STATIC_READ:
4093 case GL_STATIC_COPY:
4094 case GL_DYNAMIC_READ:
4095 case GL_DYNAMIC_COPY:
4096 if (context->getClientMajorVersion() < 3)
4097 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004098 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004099 return false;
4100 }
4101 break;
4102
4103 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004104 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferUsage);
Jamie Madill29639852016-09-02 15:00:09 -04004105 return false;
4106 }
4107
4108 if (!ValidBufferTarget(context, target))
4109 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004110 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004111 return false;
4112 }
4113
4114 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4115
4116 if (!buffer)
4117 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004118 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004119 return false;
4120 }
4121
4122 return true;
4123}
4124
4125bool ValidateBufferSubData(ValidationContext *context,
4126 GLenum target,
4127 GLintptr offset,
4128 GLsizeiptr size,
Jamie Madill876429b2017-04-20 15:46:24 -04004129 const void *data)
Jamie Madill29639852016-09-02 15:00:09 -04004130{
Brandon Jones6cad5662017-06-14 13:25:13 -07004131 if (size < 0)
Jamie Madill29639852016-09-02 15:00:09 -04004132 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004133 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
4134 return false;
4135 }
4136
4137 if (offset < 0)
4138 {
4139 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeOffset);
Jamie Madill29639852016-09-02 15:00:09 -04004140 return false;
4141 }
4142
4143 if (!ValidBufferTarget(context, target))
4144 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004145 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill29639852016-09-02 15:00:09 -04004146 return false;
4147 }
4148
4149 Buffer *buffer = context->getGLState().getTargetBuffer(target);
4150
4151 if (!buffer)
4152 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004153 ANGLE_VALIDATION_ERR(context, InvalidOperation(), BufferNotBound);
Jamie Madill29639852016-09-02 15:00:09 -04004154 return false;
4155 }
4156
4157 if (buffer->isMapped())
4158 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004159 context->handleError(InvalidOperation());
Jamie Madill29639852016-09-02 15:00:09 -04004160 return false;
4161 }
4162
4163 // Check for possible overflow of size + offset
4164 angle::CheckedNumeric<size_t> checkedSize(size);
4165 checkedSize += offset;
4166 if (!checkedSize.IsValid())
4167 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004168 context->handleError(OutOfMemory());
Jamie Madill29639852016-09-02 15:00:09 -04004169 return false;
4170 }
4171
4172 if (size + offset > buffer->getSize())
4173 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004174 ANGLE_VALIDATION_ERR(context, InvalidValue(), InsufficientBufferSize);
Jamie Madill29639852016-09-02 15:00:09 -04004175 return false;
4176 }
4177
Martin Radev4c4c8e72016-08-04 12:25:34 +03004178 return true;
4179}
4180
Geoff Langc339c4e2016-11-29 10:37:36 -05004181bool ValidateRequestExtensionANGLE(ValidationContext *context, const GLchar *name)
Geoff Langc287ea62016-09-16 14:46:51 -04004182{
Geoff Langc339c4e2016-11-29 10:37:36 -05004183 if (!context->getExtensions().requestExtension)
Geoff Langc287ea62016-09-16 14:46:51 -04004184 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004185 context->handleError(InvalidOperation() << "GL_ANGLE_request_extension is not available.");
Geoff Langc287ea62016-09-16 14:46:51 -04004186 return false;
4187 }
4188
4189 const ExtensionInfoMap &extensionInfos = GetExtensionInfoMap();
4190 auto extension = extensionInfos.find(name);
Geoff Langc339c4e2016-11-29 10:37:36 -05004191 if (extension == extensionInfos.end() || !extension->second.Requestable)
Geoff Langc287ea62016-09-16 14:46:51 -04004192 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004193 context->handleError(InvalidOperation() << "Extension " << name << " is not requestable.");
Geoff Langc287ea62016-09-16 14:46:51 -04004194 return false;
4195 }
4196
4197 return true;
4198}
4199
Jamie Madillef300b12016-10-07 15:12:09 -04004200bool ValidateActiveTexture(ValidationContext *context, GLenum texture)
4201{
4202 if (texture < GL_TEXTURE0 ||
4203 texture > GL_TEXTURE0 + context->getCaps().maxCombinedTextureImageUnits - 1)
4204 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004205 context->handleError(InvalidEnum());
Jamie Madillef300b12016-10-07 15:12:09 -04004206 return false;
4207 }
4208
4209 return true;
4210}
4211
4212bool ValidateAttachShader(ValidationContext *context, GLuint program, GLuint shader)
4213{
4214 Program *programObject = GetValidProgram(context, program);
4215 if (!programObject)
4216 {
4217 return false;
4218 }
4219
4220 Shader *shaderObject = GetValidShader(context, shader);
4221 if (!shaderObject)
4222 {
4223 return false;
4224 }
4225
4226 switch (shaderObject->getType())
4227 {
4228 case GL_VERTEX_SHADER:
4229 {
4230 if (programObject->getAttachedVertexShader())
4231 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004232 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
Jamie Madillef300b12016-10-07 15:12:09 -04004233 return false;
4234 }
4235 break;
4236 }
4237 case GL_FRAGMENT_SHADER:
4238 {
4239 if (programObject->getAttachedFragmentShader())
4240 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004241 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
Jamie Madillef300b12016-10-07 15:12:09 -04004242 return false;
4243 }
4244 break;
4245 }
4246 case GL_COMPUTE_SHADER:
4247 {
4248 if (programObject->getAttachedComputeShader())
4249 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004250 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderAttachmentHasShader);
Jamie Madillef300b12016-10-07 15:12:09 -04004251 return false;
4252 }
4253 break;
4254 }
4255 default:
4256 UNREACHABLE();
4257 break;
4258 }
4259
4260 return true;
4261}
4262
Jamie Madill01a80ee2016-11-07 12:06:18 -05004263bool ValidateBindAttribLocation(ValidationContext *context,
4264 GLuint program,
4265 GLuint index,
4266 const GLchar *name)
4267{
4268 if (index >= MAX_VERTEX_ATTRIBS)
4269 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004270 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004271 return false;
4272 }
4273
4274 if (strncmp(name, "gl_", 3) == 0)
4275 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004276 ANGLE_VALIDATION_ERR(context, InvalidOperation(), NameBeginsWithGL);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004277 return false;
4278 }
4279
Geoff Langfc32e8b2017-05-31 14:16:59 -04004280 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
4281 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04004282 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04004283 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004284 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04004285 return false;
4286 }
4287
Jamie Madill01a80ee2016-11-07 12:06:18 -05004288 return GetValidProgram(context, program) != nullptr;
4289}
4290
4291bool ValidateBindBuffer(ValidationContext *context, GLenum target, GLuint buffer)
4292{
4293 if (!ValidBufferTarget(context, target))
4294 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004295 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBufferTypes);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004296 return false;
4297 }
4298
4299 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4300 !context->isBufferGenerated(buffer))
4301 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004302 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004303 return false;
4304 }
4305
4306 return true;
4307}
4308
4309bool ValidateBindFramebuffer(ValidationContext *context, GLenum target, GLuint framebuffer)
4310{
4311 if (!ValidFramebufferTarget(target))
4312 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004313 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004314 return false;
4315 }
4316
4317 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4318 !context->isFramebufferGenerated(framebuffer))
4319 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004320 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004321 return false;
4322 }
4323
4324 return true;
4325}
4326
4327bool ValidateBindRenderbuffer(ValidationContext *context, GLenum target, GLuint renderbuffer)
4328{
4329 if (target != GL_RENDERBUFFER)
4330 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004331 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004332 return false;
4333 }
4334
4335 if (!context->getGLState().isBindGeneratesResourceEnabled() &&
4336 !context->isRenderbufferGenerated(renderbuffer))
4337 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004338 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ObjectNotGenerated);
Jamie Madill01a80ee2016-11-07 12:06:18 -05004339 return false;
4340 }
4341
4342 return true;
4343}
4344
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004345static bool ValidBlendEquationMode(GLenum mode)
4346{
4347 switch (mode)
4348 {
4349 case GL_FUNC_ADD:
4350 case GL_FUNC_SUBTRACT:
4351 case GL_FUNC_REVERSE_SUBTRACT:
4352 case GL_MIN:
4353 case GL_MAX:
4354 return true;
4355
4356 default:
4357 return false;
4358 }
4359}
4360
Jamie Madillc1d770e2017-04-13 17:31:24 -04004361bool ValidateBlendColor(ValidationContext *context,
Jamie Madill876429b2017-04-20 15:46:24 -04004362 GLfloat red,
4363 GLfloat green,
4364 GLfloat blue,
4365 GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004366{
4367 return true;
4368}
4369
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004370bool ValidateBlendEquation(ValidationContext *context, GLenum mode)
4371{
4372 if (!ValidBlendEquationMode(mode))
4373 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004374 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004375 return false;
4376 }
4377
4378 return true;
4379}
4380
4381bool ValidateBlendEquationSeparate(ValidationContext *context, GLenum modeRGB, GLenum modeAlpha)
4382{
4383 if (!ValidBlendEquationMode(modeRGB))
4384 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004385 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004386 return false;
4387 }
4388
4389 if (!ValidBlendEquationMode(modeAlpha))
4390 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004391 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendEquation);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004392 return false;
4393 }
4394
4395 return true;
4396}
4397
4398bool ValidateBlendFunc(ValidationContext *context, GLenum sfactor, GLenum dfactor)
4399{
4400 return ValidateBlendFuncSeparate(context, sfactor, dfactor, sfactor, dfactor);
4401}
4402
4403static bool ValidSrcBlendFunc(GLenum srcBlend)
4404{
4405 switch (srcBlend)
4406 {
4407 case GL_ZERO:
4408 case GL_ONE:
4409 case GL_SRC_COLOR:
4410 case GL_ONE_MINUS_SRC_COLOR:
4411 case GL_DST_COLOR:
4412 case GL_ONE_MINUS_DST_COLOR:
4413 case GL_SRC_ALPHA:
4414 case GL_ONE_MINUS_SRC_ALPHA:
4415 case GL_DST_ALPHA:
4416 case GL_ONE_MINUS_DST_ALPHA:
4417 case GL_CONSTANT_COLOR:
4418 case GL_ONE_MINUS_CONSTANT_COLOR:
4419 case GL_CONSTANT_ALPHA:
4420 case GL_ONE_MINUS_CONSTANT_ALPHA:
4421 case GL_SRC_ALPHA_SATURATE:
4422 return true;
4423
4424 default:
4425 return false;
4426 }
4427}
4428
4429static bool ValidDstBlendFunc(GLenum dstBlend, GLint contextMajorVersion)
4430{
4431 switch (dstBlend)
4432 {
4433 case GL_ZERO:
4434 case GL_ONE:
4435 case GL_SRC_COLOR:
4436 case GL_ONE_MINUS_SRC_COLOR:
4437 case GL_DST_COLOR:
4438 case GL_ONE_MINUS_DST_COLOR:
4439 case GL_SRC_ALPHA:
4440 case GL_ONE_MINUS_SRC_ALPHA:
4441 case GL_DST_ALPHA:
4442 case GL_ONE_MINUS_DST_ALPHA:
4443 case GL_CONSTANT_COLOR:
4444 case GL_ONE_MINUS_CONSTANT_COLOR:
4445 case GL_CONSTANT_ALPHA:
4446 case GL_ONE_MINUS_CONSTANT_ALPHA:
4447 return true;
4448
4449 case GL_SRC_ALPHA_SATURATE:
4450 return (contextMajorVersion >= 3);
4451
4452 default:
4453 return false;
4454 }
4455}
4456
4457bool ValidateBlendFuncSeparate(ValidationContext *context,
4458 GLenum srcRGB,
4459 GLenum dstRGB,
4460 GLenum srcAlpha,
4461 GLenum dstAlpha)
4462{
4463 if (!ValidSrcBlendFunc(srcRGB))
4464 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004465 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004466 return false;
4467 }
4468
4469 if (!ValidDstBlendFunc(dstRGB, context->getClientMajorVersion()))
4470 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004471 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004472 return false;
4473 }
4474
4475 if (!ValidSrcBlendFunc(srcAlpha))
4476 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004477 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004478 return false;
4479 }
4480
4481 if (!ValidDstBlendFunc(dstAlpha, context->getClientMajorVersion()))
4482 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004483 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidBlendFunction);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004484 return false;
4485 }
4486
Frank Henigman146e8a12017-03-02 23:22:37 -05004487 if (context->getLimitations().noSimultaneousConstantColorAndAlphaBlendFunc ||
4488 context->getExtensions().webglCompatibility)
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004489 {
4490 bool constantColorUsed =
4491 (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
4492 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
4493
4494 bool constantAlphaUsed =
4495 (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
4496 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
4497
4498 if (constantColorUsed && constantAlphaUsed)
4499 {
Frank Henigman146e8a12017-03-02 23:22:37 -05004500 const char *msg;
4501 if (context->getExtensions().webglCompatibility)
4502 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004503 msg = kErrorInvalidConstantColor;
Frank Henigman146e8a12017-03-02 23:22:37 -05004504 }
4505 else
4506 {
4507 msg =
4508 "Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and "
4509 "GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR not supported by this "
4510 "implementation.";
4511 ERR() << msg;
4512 }
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004513 context->handleError(InvalidOperation() << msg);
Jamie Madill8a9e4bc2016-11-13 20:02:12 -05004514 return false;
4515 }
4516 }
4517
4518 return true;
4519}
4520
Geoff Langc339c4e2016-11-29 10:37:36 -05004521bool ValidateGetString(Context *context, GLenum name)
4522{
4523 switch (name)
4524 {
4525 case GL_VENDOR:
4526 case GL_RENDERER:
4527 case GL_VERSION:
4528 case GL_SHADING_LANGUAGE_VERSION:
4529 case GL_EXTENSIONS:
4530 break;
4531
4532 case GL_REQUESTABLE_EXTENSIONS_ANGLE:
4533 if (!context->getExtensions().requestExtension)
4534 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004535 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004536 return false;
4537 }
4538 break;
4539
4540 default:
Brandon Jonesafa75152017-07-21 13:11:29 -07004541 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidName);
Geoff Langc339c4e2016-11-29 10:37:36 -05004542 return false;
4543 }
4544
4545 return true;
4546}
4547
Geoff Lang47c48082016-12-07 15:38:13 -05004548bool ValidateLineWidth(ValidationContext *context, GLfloat width)
4549{
4550 if (width <= 0.0f || isNaN(width))
4551 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004552 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidWidth);
Geoff Lang47c48082016-12-07 15:38:13 -05004553 return false;
4554 }
4555
4556 return true;
4557}
4558
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004559bool ValidateVertexAttribPointer(ValidationContext *context,
4560 GLuint index,
4561 GLint size,
4562 GLenum type,
4563 GLboolean normalized,
4564 GLsizei stride,
Jamie Madill876429b2017-04-20 15:46:24 -04004565 const void *ptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004566{
Shao80957d92017-02-20 21:25:59 +08004567 if (!ValidateVertexFormatBase(context, index, size, type, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004568 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004569 return false;
4570 }
4571
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004572 if (stride < 0)
4573 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004574 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeStride);
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004575 return false;
4576 }
4577
Shao80957d92017-02-20 21:25:59 +08004578 const Caps &caps = context->getCaps();
4579 if (context->getClientVersion() >= ES_3_1)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004580 {
Shao80957d92017-02-20 21:25:59 +08004581 if (stride > caps.maxVertexAttribStride)
4582 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004583 context->handleError(InvalidValue()
4584 << "stride cannot be greater than MAX_VERTEX_ATTRIB_STRIDE.");
Shao80957d92017-02-20 21:25:59 +08004585 return false;
4586 }
4587
4588 if (index >= caps.maxVertexAttribBindings)
4589 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004590 context->handleError(InvalidValue()
4591 << "index must be smaller than MAX_VERTEX_ATTRIB_BINDINGS.");
Shao80957d92017-02-20 21:25:59 +08004592 return false;
4593 }
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004594 }
4595
4596 // [OpenGL ES 3.0.2] Section 2.8 page 24:
4597 // An INVALID_OPERATION error is generated when a non-zero vertex array object
4598 // is bound, zero is bound to the ARRAY_BUFFER buffer object binding point,
4599 // and the pointer argument is not NULL.
Geoff Langfeb8c682017-02-13 16:07:35 -05004600 bool nullBufferAllowed = context->getGLState().areClientArraysEnabled() &&
4601 context->getGLState().getVertexArray()->id() == 0;
Shao80957d92017-02-20 21:25:59 +08004602 if (!nullBufferAllowed && context->getGLState().getArrayBufferId() == 0 && ptr != nullptr)
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004603 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004604 context
4605 ->handleError(InvalidOperation()
4606 << "Client data cannot be used with a non-default vertex array object.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004607 return false;
4608 }
4609
4610 if (context->getExtensions().webglCompatibility)
4611 {
4612 // WebGL 1.0 [Section 6.14] Fixed point support
4613 // The WebGL API does not support the GL_FIXED data type.
4614 if (type == GL_FIXED)
4615 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004616 context->handleError(InvalidEnum() << "GL_FIXED is not supported in WebGL.");
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004617 return false;
4618 }
4619
Geoff Lang2d62ab72017-03-23 16:54:40 -04004620 if (!ValidateWebGLVertexAttribPointer(context, type, normalized, stride, ptr, false))
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004621 {
Corentin Wallez0c7baf12016-12-19 15:43:10 -05004622 return false;
4623 }
4624 }
4625
4626 return true;
4627}
4628
Jamie Madill876429b2017-04-20 15:46:24 -04004629bool ValidateDepthRangef(ValidationContext *context, GLfloat zNear, GLfloat zFar)
Frank Henigman6137ddc2017-02-10 18:55:07 -05004630{
4631 if (context->getExtensions().webglCompatibility && zNear > zFar)
4632 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004633 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidDepthRange);
Frank Henigman6137ddc2017-02-10 18:55:07 -05004634 return false;
4635 }
4636
4637 return true;
4638}
4639
Jamie Madille8fb6402017-02-14 17:56:40 -05004640bool ValidateRenderbufferStorage(ValidationContext *context,
4641 GLenum target,
4642 GLenum internalformat,
4643 GLsizei width,
4644 GLsizei height)
4645{
4646 return ValidateRenderbufferStorageParametersBase(context, target, 0, internalformat, width,
4647 height);
4648}
4649
4650bool ValidateRenderbufferStorageMultisampleANGLE(ValidationContext *context,
4651 GLenum target,
4652 GLsizei samples,
4653 GLenum internalformat,
4654 GLsizei width,
4655 GLsizei height)
4656{
4657 if (!context->getExtensions().framebufferMultisample)
4658 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004659 context->handleError(InvalidOperation()
4660 << "GL_ANGLE_framebuffer_multisample not available");
Jamie Madille8fb6402017-02-14 17:56:40 -05004661 return false;
4662 }
4663
4664 // ANGLE_framebuffer_multisample states that the value of samples must be less than or equal
4665 // to MAX_SAMPLES_ANGLE (Context::getCaps().maxSamples) otherwise GL_INVALID_OPERATION is
4666 // generated.
4667 if (static_cast<GLuint>(samples) > context->getCaps().maxSamples)
4668 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004669 context->handleError(InvalidValue());
Jamie Madille8fb6402017-02-14 17:56:40 -05004670 return false;
4671 }
4672
4673 // ANGLE_framebuffer_multisample states GL_OUT_OF_MEMORY is generated on a failure to create
4674 // the specified storage. This is different than ES 3.0 in which a sample number higher
4675 // than the maximum sample number supported by this format generates a GL_INVALID_VALUE.
4676 // The TextureCaps::getMaxSamples method is only guarenteed to be valid when the context is ES3.
4677 if (context->getClientMajorVersion() >= 3)
4678 {
4679 const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
4680 if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
4681 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05004682 context->handleError(OutOfMemory());
Jamie Madille8fb6402017-02-14 17:56:40 -05004683 return false;
4684 }
4685 }
4686
4687 return ValidateRenderbufferStorageParametersBase(context, target, samples, internalformat,
4688 width, height);
4689}
4690
Jamie Madillc1d770e2017-04-13 17:31:24 -04004691bool ValidateCheckFramebufferStatus(ValidationContext *context, GLenum target)
4692{
4693 if (!ValidFramebufferTarget(target))
4694 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004695 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004696 return false;
4697 }
4698
4699 return true;
4700}
4701
4702bool ValidateClearColor(ValidationContext *context,
Jamie Madill876429b2017-04-20 15:46:24 -04004703 GLfloat red,
4704 GLfloat green,
4705 GLfloat blue,
4706 GLfloat alpha)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004707{
4708 return true;
4709}
4710
Jamie Madill876429b2017-04-20 15:46:24 -04004711bool ValidateClearDepthf(ValidationContext *context, GLfloat depth)
Jamie Madillc1d770e2017-04-13 17:31:24 -04004712{
4713 return true;
4714}
4715
4716bool ValidateClearStencil(ValidationContext *context, GLint s)
4717{
4718 return true;
4719}
4720
4721bool ValidateColorMask(ValidationContext *context,
4722 GLboolean red,
4723 GLboolean green,
4724 GLboolean blue,
4725 GLboolean alpha)
4726{
4727 return true;
4728}
4729
4730bool ValidateCompileShader(ValidationContext *context, GLuint shader)
4731{
4732 return true;
4733}
4734
4735bool ValidateCreateProgram(ValidationContext *context)
4736{
4737 return true;
4738}
4739
4740bool ValidateCullFace(ValidationContext *context, GLenum mode)
4741{
4742 switch (mode)
4743 {
4744 case GL_FRONT:
4745 case GL_BACK:
4746 case GL_FRONT_AND_BACK:
4747 break;
4748
4749 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004750 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidCullMode);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004751 return false;
4752 }
4753
4754 return true;
4755}
4756
4757bool ValidateDeleteProgram(ValidationContext *context, GLuint program)
4758{
4759 if (program == 0)
4760 {
4761 return false;
4762 }
4763
4764 if (!context->getProgram(program))
4765 {
4766 if (context->getShader(program))
4767 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004768 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004769 return false;
4770 }
4771 else
4772 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004773 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004774 return false;
4775 }
4776 }
4777
4778 return true;
4779}
4780
4781bool ValidateDeleteShader(ValidationContext *context, GLuint shader)
4782{
4783 if (shader == 0)
4784 {
4785 return false;
4786 }
4787
4788 if (!context->getShader(shader))
4789 {
4790 if (context->getProgram(shader))
4791 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004792 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004793 return false;
4794 }
4795 else
4796 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004797 ANGLE_VALIDATION_ERR(context, InvalidValue(), ExpectedShaderName);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004798 return false;
4799 }
4800 }
4801
4802 return true;
4803}
4804
4805bool ValidateDepthFunc(ValidationContext *context, GLenum func)
4806{
4807 switch (func)
4808 {
4809 case GL_NEVER:
4810 case GL_ALWAYS:
4811 case GL_LESS:
4812 case GL_LEQUAL:
4813 case GL_EQUAL:
4814 case GL_GREATER:
4815 case GL_GEQUAL:
4816 case GL_NOTEQUAL:
4817 break;
4818
4819 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004820 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004821 return false;
4822 }
4823
4824 return true;
4825}
4826
4827bool ValidateDepthMask(ValidationContext *context, GLboolean flag)
4828{
4829 return true;
4830}
4831
4832bool ValidateDetachShader(ValidationContext *context, GLuint program, GLuint shader)
4833{
4834 Program *programObject = GetValidProgram(context, program);
4835 if (!programObject)
4836 {
4837 return false;
4838 }
4839
4840 Shader *shaderObject = GetValidShader(context, shader);
4841 if (!shaderObject)
4842 {
4843 return false;
4844 }
4845
4846 const Shader *attachedShader = nullptr;
4847
4848 switch (shaderObject->getType())
4849 {
4850 case GL_VERTEX_SHADER:
4851 {
4852 attachedShader = programObject->getAttachedVertexShader();
4853 break;
4854 }
4855 case GL_FRAGMENT_SHADER:
4856 {
4857 attachedShader = programObject->getAttachedFragmentShader();
4858 break;
4859 }
4860 case GL_COMPUTE_SHADER:
4861 {
4862 attachedShader = programObject->getAttachedComputeShader();
4863 break;
4864 }
4865 default:
4866 UNREACHABLE();
4867 return false;
4868 }
4869
4870 if (attachedShader != shaderObject)
4871 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004872 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ShaderToDetachMustBeAttached);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004873 return false;
4874 }
4875
4876 return true;
4877}
4878
4879bool ValidateDisableVertexAttribArray(ValidationContext *context, GLuint index)
4880{
4881 if (index >= MAX_VERTEX_ATTRIBS)
4882 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004883 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004884 return false;
4885 }
4886
4887 return true;
4888}
4889
4890bool ValidateEnableVertexAttribArray(ValidationContext *context, GLuint index)
4891{
4892 if (index >= MAX_VERTEX_ATTRIBS)
4893 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004894 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004895 return false;
4896 }
4897
4898 return true;
4899}
4900
4901bool ValidateFinish(ValidationContext *context)
4902{
4903 return true;
4904}
4905
4906bool ValidateFlush(ValidationContext *context)
4907{
4908 return true;
4909}
4910
4911bool ValidateFrontFace(ValidationContext *context, GLenum mode)
4912{
4913 switch (mode)
4914 {
4915 case GL_CW:
4916 case GL_CCW:
4917 break;
4918 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07004919 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004920 return false;
4921 }
4922
4923 return true;
4924}
4925
4926bool ValidateGetActiveAttrib(ValidationContext *context,
4927 GLuint program,
4928 GLuint index,
4929 GLsizei bufsize,
4930 GLsizei *length,
4931 GLint *size,
4932 GLenum *type,
4933 GLchar *name)
4934{
4935 if (bufsize < 0)
4936 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004937 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004938 return false;
4939 }
4940
4941 Program *programObject = GetValidProgram(context, program);
4942
4943 if (!programObject)
4944 {
4945 return false;
4946 }
4947
4948 if (index >= static_cast<GLuint>(programObject->getActiveAttributeCount()))
4949 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004950 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004951 return false;
4952 }
4953
4954 return true;
4955}
4956
4957bool ValidateGetActiveUniform(ValidationContext *context,
4958 GLuint program,
4959 GLuint index,
4960 GLsizei bufsize,
4961 GLsizei *length,
4962 GLint *size,
4963 GLenum *type,
4964 GLchar *name)
4965{
4966 if (bufsize < 0)
4967 {
Brandon Jones6cad5662017-06-14 13:25:13 -07004968 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004969 return false;
4970 }
4971
4972 Program *programObject = GetValidProgram(context, program);
4973
4974 if (!programObject)
4975 {
4976 return false;
4977 }
4978
4979 if (index >= static_cast<GLuint>(programObject->getActiveUniformCount()))
4980 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004981 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxActiveUniform);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004982 return false;
4983 }
4984
4985 return true;
4986}
4987
4988bool ValidateGetAttachedShaders(ValidationContext *context,
4989 GLuint program,
4990 GLsizei maxcount,
4991 GLsizei *count,
4992 GLuint *shaders)
4993{
4994 if (maxcount < 0)
4995 {
Brandon Jonesafa75152017-07-21 13:11:29 -07004996 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeMaxCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04004997 return false;
4998 }
4999
5000 Program *programObject = GetValidProgram(context, program);
5001
5002 if (!programObject)
5003 {
5004 return false;
5005 }
5006
5007 return true;
5008}
5009
5010bool ValidateGetAttribLocation(ValidationContext *context, GLuint program, const GLchar *name)
5011{
Geoff Langfc32e8b2017-05-31 14:16:59 -04005012 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5013 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005014 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005015 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005016 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005017 return false;
5018 }
5019
Jamie Madillc1d770e2017-04-13 17:31:24 -04005020 Program *programObject = GetValidProgram(context, program);
5021
5022 if (!programObject)
5023 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005024 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotBound);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005025 return false;
5026 }
5027
5028 if (!programObject->isLinked())
5029 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005030 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005031 return false;
5032 }
5033
5034 return true;
5035}
5036
5037bool ValidateGetBooleanv(ValidationContext *context, GLenum pname, GLboolean *params)
5038{
5039 GLenum nativeType;
5040 unsigned int numParams = 0;
5041 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5042}
5043
5044bool ValidateGetError(ValidationContext *context)
5045{
5046 return true;
5047}
5048
5049bool ValidateGetFloatv(ValidationContext *context, GLenum pname, GLfloat *params)
5050{
5051 GLenum nativeType;
5052 unsigned int numParams = 0;
5053 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5054}
5055
5056bool ValidateGetIntegerv(ValidationContext *context, GLenum pname, GLint *params)
5057{
5058 GLenum nativeType;
5059 unsigned int numParams = 0;
5060 return ValidateStateQuery(context, pname, &nativeType, &numParams);
5061}
5062
5063bool ValidateGetProgramInfoLog(ValidationContext *context,
5064 GLuint program,
5065 GLsizei bufsize,
5066 GLsizei *length,
5067 GLchar *infolog)
5068{
5069 if (bufsize < 0)
5070 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005071 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005072 return false;
5073 }
5074
5075 Program *programObject = GetValidProgram(context, program);
5076 if (!programObject)
5077 {
5078 return false;
5079 }
5080
5081 return true;
5082}
5083
5084bool ValidateGetShaderInfoLog(ValidationContext *context,
5085 GLuint shader,
5086 GLsizei bufsize,
5087 GLsizei *length,
5088 GLchar *infolog)
5089{
5090 if (bufsize < 0)
5091 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005092 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005093 return false;
5094 }
5095
5096 Shader *shaderObject = GetValidShader(context, shader);
5097 if (!shaderObject)
5098 {
5099 return false;
5100 }
5101
5102 return true;
5103}
5104
5105bool ValidateGetShaderPrecisionFormat(ValidationContext *context,
5106 GLenum shadertype,
5107 GLenum precisiontype,
5108 GLint *range,
5109 GLint *precision)
5110{
5111 switch (shadertype)
5112 {
5113 case GL_VERTEX_SHADER:
5114 case GL_FRAGMENT_SHADER:
5115 break;
5116 case GL_COMPUTE_SHADER:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005117 context->handleError(InvalidOperation()
5118 << "compute shader precision not yet implemented.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005119 return false;
5120 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005121 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidShaderType);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005122 return false;
5123 }
5124
5125 switch (precisiontype)
5126 {
5127 case GL_LOW_FLOAT:
5128 case GL_MEDIUM_FLOAT:
5129 case GL_HIGH_FLOAT:
5130 case GL_LOW_INT:
5131 case GL_MEDIUM_INT:
5132 case GL_HIGH_INT:
5133 break;
5134
5135 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005136 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidPrecision);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005137 return false;
5138 }
5139
5140 return true;
5141}
5142
5143bool ValidateGetShaderSource(ValidationContext *context,
5144 GLuint shader,
5145 GLsizei bufsize,
5146 GLsizei *length,
5147 GLchar *source)
5148{
5149 if (bufsize < 0)
5150 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005151 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeBufferSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005152 return false;
5153 }
5154
5155 Shader *shaderObject = GetValidShader(context, shader);
5156 if (!shaderObject)
5157 {
5158 return false;
5159 }
5160
5161 return true;
5162}
5163
5164bool ValidateGetUniformLocation(ValidationContext *context, GLuint program, const GLchar *name)
5165{
5166 if (strstr(name, "gl_") == name)
5167 {
5168 return false;
5169 }
5170
Geoff Langfc32e8b2017-05-31 14:16:59 -04005171 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5172 // shader-related entry points
Geoff Langcab92ee2017-07-19 17:32:07 -04005173 if (context->getExtensions().webglCompatibility && !IsValidESSLString(name, strlen(name)))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005174 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005175 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidNameCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005176 return false;
5177 }
5178
Jamie Madillc1d770e2017-04-13 17:31:24 -04005179 Program *programObject = GetValidProgram(context, program);
5180
5181 if (!programObject)
5182 {
5183 return false;
5184 }
5185
5186 if (!programObject->isLinked())
5187 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005188 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005189 return false;
5190 }
5191
5192 return true;
5193}
5194
5195bool ValidateHint(ValidationContext *context, GLenum target, GLenum mode)
5196{
5197 switch (mode)
5198 {
5199 case GL_FASTEST:
5200 case GL_NICEST:
5201 case GL_DONT_CARE:
5202 break;
5203
5204 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005205 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005206 return false;
5207 }
5208
5209 switch (target)
5210 {
5211 case GL_GENERATE_MIPMAP_HINT:
5212 break;
5213
Geoff Lange7bd2182017-06-16 16:13:13 -04005214 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
5215 if (context->getClientVersion() < ES_3_0 &&
5216 !context->getExtensions().standardDerivatives)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005217 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005218 context->handleError(InvalidOperation()
5219 << "hint requires OES_standard_derivatives.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005220 return false;
5221 }
5222 break;
5223
5224 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005225 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005226 return false;
5227 }
5228
5229 return true;
5230}
5231
5232bool ValidateIsBuffer(ValidationContext *context, GLuint buffer)
5233{
5234 return true;
5235}
5236
5237bool ValidateIsFramebuffer(ValidationContext *context, GLuint framebuffer)
5238{
5239 return true;
5240}
5241
5242bool ValidateIsProgram(ValidationContext *context, GLuint program)
5243{
5244 return true;
5245}
5246
5247bool ValidateIsRenderbuffer(ValidationContext *context, GLuint renderbuffer)
5248{
5249 return true;
5250}
5251
5252bool ValidateIsShader(ValidationContext *context, GLuint shader)
5253{
5254 return true;
5255}
5256
5257bool ValidateIsTexture(ValidationContext *context, GLuint texture)
5258{
5259 return true;
5260}
5261
5262bool ValidatePixelStorei(ValidationContext *context, GLenum pname, GLint param)
5263{
5264 if (context->getClientMajorVersion() < 3)
5265 {
5266 switch (pname)
5267 {
5268 case GL_UNPACK_IMAGE_HEIGHT:
5269 case GL_UNPACK_SKIP_IMAGES:
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005270 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005271 return false;
5272
5273 case GL_UNPACK_ROW_LENGTH:
5274 case GL_UNPACK_SKIP_ROWS:
5275 case GL_UNPACK_SKIP_PIXELS:
5276 if (!context->getExtensions().unpackSubimage)
5277 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005278 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005279 return false;
5280 }
5281 break;
5282
5283 case GL_PACK_ROW_LENGTH:
5284 case GL_PACK_SKIP_ROWS:
5285 case GL_PACK_SKIP_PIXELS:
5286 if (!context->getExtensions().packSubimage)
5287 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005288 context->handleError(InvalidEnum());
Jamie Madillc1d770e2017-04-13 17:31:24 -04005289 return false;
5290 }
5291 break;
5292 }
5293 }
5294
5295 if (param < 0)
5296 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005297 context->handleError(InvalidValue() << "Cannot use negative values in PixelStorei");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005298 return false;
5299 }
5300
5301 switch (pname)
5302 {
5303 case GL_UNPACK_ALIGNMENT:
5304 if (param != 1 && param != 2 && param != 4 && param != 8)
5305 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005306 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005307 return false;
5308 }
5309 break;
5310
5311 case GL_PACK_ALIGNMENT:
5312 if (param != 1 && param != 2 && param != 4 && param != 8)
5313 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005314 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidUnpackAlignment);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005315 return false;
5316 }
5317 break;
5318
5319 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
5320 case GL_UNPACK_ROW_LENGTH:
5321 case GL_UNPACK_IMAGE_HEIGHT:
5322 case GL_UNPACK_SKIP_IMAGES:
5323 case GL_UNPACK_SKIP_ROWS:
5324 case GL_UNPACK_SKIP_PIXELS:
5325 case GL_PACK_ROW_LENGTH:
5326 case GL_PACK_SKIP_ROWS:
5327 case GL_PACK_SKIP_PIXELS:
5328 break;
5329
5330 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005331 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005332 return false;
5333 }
5334
5335 return true;
5336}
5337
5338bool ValidatePolygonOffset(ValidationContext *context, GLfloat factor, GLfloat units)
5339{
5340 return true;
5341}
5342
5343bool ValidateReleaseShaderCompiler(ValidationContext *context)
5344{
5345 return true;
5346}
5347
Jamie Madill876429b2017-04-20 15:46:24 -04005348bool ValidateSampleCoverage(ValidationContext *context, GLfloat value, GLboolean invert)
Jamie Madillc1d770e2017-04-13 17:31:24 -04005349{
5350 return true;
5351}
5352
5353bool ValidateScissor(ValidationContext *context, GLint x, GLint y, GLsizei width, GLsizei height)
5354{
5355 if (width < 0 || height < 0)
5356 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005357 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005358 return false;
5359 }
5360
5361 return true;
5362}
5363
5364bool ValidateShaderBinary(ValidationContext *context,
5365 GLsizei n,
5366 const GLuint *shaders,
5367 GLenum binaryformat,
Jamie Madill876429b2017-04-20 15:46:24 -04005368 const void *binary,
Jamie Madillc1d770e2017-04-13 17:31:24 -04005369 GLsizei length)
5370{
5371 const std::vector<GLenum> &shaderBinaryFormats = context->getCaps().shaderBinaryFormats;
5372 if (std::find(shaderBinaryFormats.begin(), shaderBinaryFormats.end(), binaryformat) ==
5373 shaderBinaryFormats.end())
5374 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005375 context->handleError(InvalidEnum() << "Invalid shader binary format.");
Jamie Madillc1d770e2017-04-13 17:31:24 -04005376 return false;
5377 }
5378
5379 return true;
5380}
5381
5382bool ValidateShaderSource(ValidationContext *context,
5383 GLuint shader,
5384 GLsizei count,
5385 const GLchar *const *string,
5386 const GLint *length)
5387{
5388 if (count < 0)
5389 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005390 ANGLE_VALIDATION_ERR(context, InvalidValue(), NegativeCount);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005391 return false;
5392 }
5393
Geoff Langfc32e8b2017-05-31 14:16:59 -04005394 // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
5395 // shader-related entry points
5396 if (context->getExtensions().webglCompatibility)
5397 {
5398 for (GLsizei i = 0; i < count; i++)
5399 {
Geoff Langcab92ee2017-07-19 17:32:07 -04005400 size_t len =
5401 (length && length[i] >= 0) ? static_cast<size_t>(length[i]) : strlen(string[i]);
Geoff Langa71a98e2017-06-19 15:15:00 -04005402
5403 // Backslash as line-continuation is allowed in WebGL 2.0.
Geoff Langcab92ee2017-07-19 17:32:07 -04005404 if (!IsValidESSLShaderSourceString(string[i], len,
5405 context->getClientVersion() >= ES_3_0))
Geoff Langfc32e8b2017-05-31 14:16:59 -04005406 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005407 ANGLE_VALIDATION_ERR(context, InvalidValue(), ShaderSourceInvalidCharacters);
Geoff Langfc32e8b2017-05-31 14:16:59 -04005408 return false;
5409 }
5410 }
5411 }
5412
Jamie Madillc1d770e2017-04-13 17:31:24 -04005413 Shader *shaderObject = GetValidShader(context, shader);
5414 if (!shaderObject)
5415 {
5416 return false;
5417 }
5418
5419 return true;
5420}
5421
5422bool ValidateStencilFunc(ValidationContext *context, GLenum func, GLint ref, GLuint mask)
5423{
5424 if (!IsValidStencilFunc(func))
5425 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005426 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005427 return false;
5428 }
5429
5430 return true;
5431}
5432
5433bool ValidateStencilFuncSeparate(ValidationContext *context,
5434 GLenum face,
5435 GLenum func,
5436 GLint ref,
5437 GLuint mask)
5438{
5439 if (!IsValidStencilFace(face))
5440 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005441 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005442 return false;
5443 }
5444
5445 if (!IsValidStencilFunc(func))
5446 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005447 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005448 return false;
5449 }
5450
5451 return true;
5452}
5453
5454bool ValidateStencilMask(ValidationContext *context, GLuint mask)
5455{
5456 return true;
5457}
5458
5459bool ValidateStencilMaskSeparate(ValidationContext *context, GLenum face, GLuint mask)
5460{
5461 if (!IsValidStencilFace(face))
5462 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005463 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005464 return false;
5465 }
5466
5467 return true;
5468}
5469
5470bool ValidateStencilOp(ValidationContext *context, GLenum fail, GLenum zfail, GLenum zpass)
5471{
5472 if (!IsValidStencilOp(fail))
5473 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005474 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005475 return false;
5476 }
5477
5478 if (!IsValidStencilOp(zfail))
5479 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005480 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005481 return false;
5482 }
5483
5484 if (!IsValidStencilOp(zpass))
5485 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005486 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005487 return false;
5488 }
5489
5490 return true;
5491}
5492
5493bool ValidateStencilOpSeparate(ValidationContext *context,
5494 GLenum face,
5495 GLenum fail,
5496 GLenum zfail,
5497 GLenum zpass)
5498{
5499 if (!IsValidStencilFace(face))
5500 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005501 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidStencil);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005502 return false;
5503 }
5504
5505 return ValidateStencilOp(context, fail, zfail, zpass);
5506}
5507
5508bool ValidateUniform1f(ValidationContext *context, GLint location, GLfloat x)
5509{
5510 return ValidateUniform(context, GL_FLOAT, location, 1);
5511}
5512
5513bool ValidateUniform1fv(ValidationContext *context, GLint location, GLsizei count, const GLfloat *v)
5514{
5515 return ValidateUniform(context, GL_FLOAT, location, count);
5516}
5517
Jamie Madillbe849e42017-05-02 15:49:00 -04005518bool ValidateUniform1i(ValidationContext *context, GLint location, GLint x)
5519{
5520 return ValidateUniform1iv(context, location, 1, &x);
5521}
5522
Jamie Madillc1d770e2017-04-13 17:31:24 -04005523bool ValidateUniform2f(ValidationContext *context, GLint location, GLfloat x, GLfloat y)
5524{
5525 return ValidateUniform(context, GL_FLOAT_VEC2, location, 1);
5526}
5527
5528bool ValidateUniform2fv(ValidationContext *context, GLint location, GLsizei count, const GLfloat *v)
5529{
5530 return ValidateUniform(context, GL_FLOAT_VEC2, location, count);
5531}
5532
5533bool ValidateUniform2i(ValidationContext *context, GLint location, GLint x, GLint y)
5534{
5535 return ValidateUniform(context, GL_INT_VEC2, location, 1);
5536}
5537
5538bool ValidateUniform2iv(ValidationContext *context, GLint location, GLsizei count, const GLint *v)
5539{
5540 return ValidateUniform(context, GL_INT_VEC2, location, count);
5541}
5542
5543bool ValidateUniform3f(ValidationContext *context, GLint location, GLfloat x, GLfloat y, GLfloat z)
5544{
5545 return ValidateUniform(context, GL_FLOAT_VEC3, location, 1);
5546}
5547
5548bool ValidateUniform3fv(ValidationContext *context, GLint location, GLsizei count, const GLfloat *v)
5549{
5550 return ValidateUniform(context, GL_FLOAT_VEC3, location, count);
5551}
5552
5553bool ValidateUniform3i(ValidationContext *context, GLint location, GLint x, GLint y, GLint z)
5554{
5555 return ValidateUniform(context, GL_INT_VEC3, location, 1);
5556}
5557
5558bool ValidateUniform3iv(ValidationContext *context, GLint location, GLsizei count, const GLint *v)
5559{
5560 return ValidateUniform(context, GL_INT_VEC3, location, count);
5561}
5562
5563bool ValidateUniform4f(ValidationContext *context,
5564 GLint location,
5565 GLfloat x,
5566 GLfloat y,
5567 GLfloat z,
5568 GLfloat w)
5569{
5570 return ValidateUniform(context, GL_FLOAT_VEC4, location, 1);
5571}
5572
5573bool ValidateUniform4fv(ValidationContext *context, GLint location, GLsizei count, const GLfloat *v)
5574{
5575 return ValidateUniform(context, GL_FLOAT_VEC4, location, count);
5576}
5577
5578bool ValidateUniform4i(ValidationContext *context,
5579 GLint location,
5580 GLint x,
5581 GLint y,
5582 GLint z,
5583 GLint w)
5584{
5585 return ValidateUniform(context, GL_INT_VEC4, location, 1);
5586}
5587
5588bool ValidateUniform4iv(ValidationContext *context, GLint location, GLsizei count, const GLint *v)
5589{
5590 return ValidateUniform(context, GL_INT_VEC4, location, count);
5591}
5592
5593bool ValidateUniformMatrix2fv(ValidationContext *context,
5594 GLint location,
5595 GLsizei count,
5596 GLboolean transpose,
5597 const GLfloat *value)
5598{
5599 return ValidateUniformMatrix(context, GL_FLOAT_MAT2, location, count, transpose);
5600}
5601
5602bool ValidateUniformMatrix3fv(ValidationContext *context,
5603 GLint location,
5604 GLsizei count,
5605 GLboolean transpose,
5606 const GLfloat *value)
5607{
5608 return ValidateUniformMatrix(context, GL_FLOAT_MAT3, location, count, transpose);
5609}
5610
5611bool ValidateUniformMatrix4fv(ValidationContext *context,
5612 GLint location,
5613 GLsizei count,
5614 GLboolean transpose,
5615 const GLfloat *value)
5616{
5617 return ValidateUniformMatrix(context, GL_FLOAT_MAT4, location, count, transpose);
5618}
5619
5620bool ValidateValidateProgram(ValidationContext *context, GLuint program)
5621{
5622 Program *programObject = GetValidProgram(context, program);
5623
5624 if (!programObject)
5625 {
5626 return false;
5627 }
5628
5629 return true;
5630}
5631
5632bool ValidateVertexAttribIndex(ValidationContext *context, GLuint index)
5633{
5634 if (index >= MAX_VERTEX_ATTRIBS)
5635 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005636 ANGLE_VALIDATION_ERR(context, InvalidValue(), IndexExceedsMaxVertexAttribute);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005637 return false;
5638 }
5639
5640 return true;
5641}
5642
5643bool ValidateVertexAttrib1f(ValidationContext *context, GLuint index, GLfloat x)
5644{
5645 return ValidateVertexAttribIndex(context, index);
5646}
5647
5648bool ValidateVertexAttrib1fv(ValidationContext *context, GLuint index, const GLfloat *values)
5649{
5650 return ValidateVertexAttribIndex(context, index);
5651}
5652
5653bool ValidateVertexAttrib2f(ValidationContext *context, GLuint index, GLfloat x, GLfloat y)
5654{
5655 return ValidateVertexAttribIndex(context, index);
5656}
5657
5658bool ValidateVertexAttrib2fv(ValidationContext *context, GLuint index, const GLfloat *values)
5659{
5660 return ValidateVertexAttribIndex(context, index);
5661}
5662
5663bool ValidateVertexAttrib3f(ValidationContext *context,
5664 GLuint index,
5665 GLfloat x,
5666 GLfloat y,
5667 GLfloat z)
5668{
5669 return ValidateVertexAttribIndex(context, index);
5670}
5671
5672bool ValidateVertexAttrib3fv(ValidationContext *context, GLuint index, const GLfloat *values)
5673{
5674 return ValidateVertexAttribIndex(context, index);
5675}
5676
5677bool ValidateVertexAttrib4f(ValidationContext *context,
5678 GLuint index,
5679 GLfloat x,
5680 GLfloat y,
5681 GLfloat z,
5682 GLfloat w)
5683{
5684 return ValidateVertexAttribIndex(context, index);
5685}
5686
5687bool ValidateVertexAttrib4fv(ValidationContext *context, GLuint index, const GLfloat *values)
5688{
5689 return ValidateVertexAttribIndex(context, index);
5690}
5691
5692bool ValidateViewport(ValidationContext *context, GLint x, GLint y, GLsizei width, GLsizei height)
5693{
5694 if (width < 0 || height < 0)
5695 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005696 ANGLE_VALIDATION_ERR(context, InvalidValue(), ViewportNegativeSize);
Jamie Madillc1d770e2017-04-13 17:31:24 -04005697 return false;
5698 }
5699
5700 return true;
5701}
5702
5703bool ValidateDrawArrays(ValidationContext *context, GLenum mode, GLint first, GLsizei count)
5704{
5705 return ValidateDrawArraysCommon(context, mode, first, count, 1);
5706}
5707
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005708bool ValidateDrawElements(ValidationContext *context,
5709 GLenum mode,
5710 GLsizei count,
5711 GLenum type,
Jamie Madill876429b2017-04-20 15:46:24 -04005712 const void *indices)
Jamie Madill9c9b40a2017-04-26 16:31:57 -04005713{
5714 return ValidateDrawElementsCommon(context, mode, count, type, indices, 1);
5715}
5716
Jamie Madillbe849e42017-05-02 15:49:00 -04005717bool ValidateGetFramebufferAttachmentParameteriv(ValidationContext *context,
5718 GLenum target,
5719 GLenum attachment,
5720 GLenum pname,
5721 GLint *params)
5722{
5723 return ValidateGetFramebufferAttachmentParameterivBase(context, target, attachment, pname,
5724 nullptr);
5725}
5726
5727bool ValidateGetProgramiv(ValidationContext *context, GLuint program, GLenum pname, GLint *params)
5728{
5729 return ValidateGetProgramivBase(context, program, pname, nullptr);
5730}
5731
5732bool ValidateCopyTexImage2D(ValidationContext *context,
5733 GLenum target,
5734 GLint level,
5735 GLenum internalformat,
5736 GLint x,
5737 GLint y,
5738 GLsizei width,
5739 GLsizei height,
5740 GLint border)
5741{
5742 if (context->getClientMajorVersion() < 3)
5743 {
5744 return ValidateES2CopyTexImageParameters(context, target, level, internalformat, false, 0,
5745 0, x, y, width, height, border);
5746 }
5747
5748 ASSERT(context->getClientMajorVersion() == 3);
5749 return ValidateES3CopyTexImage2DParameters(context, target, level, internalformat, false, 0, 0,
5750 0, x, y, width, height, border);
5751}
5752
5753bool ValidateCopyTexSubImage2D(Context *context,
5754 GLenum target,
5755 GLint level,
5756 GLint xoffset,
5757 GLint yoffset,
5758 GLint x,
5759 GLint y,
5760 GLsizei width,
5761 GLsizei height)
5762{
5763 if (context->getClientMajorVersion() < 3)
5764 {
5765 return ValidateES2CopyTexImageParameters(context, target, level, GL_NONE, true, xoffset,
5766 yoffset, x, y, width, height, 0);
5767 }
5768
5769 return ValidateES3CopyTexImage2DParameters(context, target, level, GL_NONE, true, xoffset,
5770 yoffset, 0, x, y, width, height, 0);
5771}
5772
5773bool ValidateDeleteBuffers(Context *context, GLint n, const GLuint *)
5774{
5775 return ValidateGenOrDelete(context, n);
5776}
5777
5778bool ValidateDeleteFramebuffers(Context *context, GLint n, const GLuint *)
5779{
5780 return ValidateGenOrDelete(context, n);
5781}
5782
5783bool ValidateDeleteRenderbuffers(Context *context, GLint n, const GLuint *)
5784{
5785 return ValidateGenOrDelete(context, n);
5786}
5787
5788bool ValidateDeleteTextures(Context *context, GLint n, const GLuint *)
5789{
5790 return ValidateGenOrDelete(context, n);
5791}
5792
5793bool ValidateDisable(Context *context, GLenum cap)
5794{
5795 if (!ValidCap(context, cap, false))
5796 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005797 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005798 return false;
5799 }
5800
5801 return true;
5802}
5803
5804bool ValidateEnable(Context *context, GLenum cap)
5805{
5806 if (!ValidCap(context, cap, false))
5807 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005808 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04005809 return false;
5810 }
5811
5812 if (context->getLimitations().noSampleAlphaToCoverageSupport &&
5813 cap == GL_SAMPLE_ALPHA_TO_COVERAGE)
5814 {
5815 const char *errorMessage = "Current renderer doesn't support alpha-to-coverage";
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005816 context->handleError(InvalidOperation() << errorMessage);
Jamie Madillbe849e42017-05-02 15:49:00 -04005817
5818 // We also output an error message to the debugger window if tracing is active, so that
5819 // developers can see the error message.
5820 ERR() << errorMessage;
5821 return false;
5822 }
5823
5824 return true;
5825}
5826
5827bool ValidateFramebufferRenderbuffer(Context *context,
5828 GLenum target,
5829 GLenum attachment,
5830 GLenum renderbuffertarget,
5831 GLuint renderbuffer)
5832{
Brandon Jones6cad5662017-06-14 13:25:13 -07005833 if (!ValidFramebufferTarget(target))
Jamie Madillbe849e42017-05-02 15:49:00 -04005834 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005835 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidFramebufferTarget);
5836 return false;
5837 }
5838
5839 if (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0)
5840 {
5841 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidRenderbufferTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005842 return false;
5843 }
5844
5845 return ValidateFramebufferRenderbufferParameters(context, target, attachment,
5846 renderbuffertarget, renderbuffer);
5847}
5848
5849bool ValidateFramebufferTexture2D(Context *context,
5850 GLenum target,
5851 GLenum attachment,
5852 GLenum textarget,
5853 GLuint texture,
5854 GLint level)
5855{
5856 // Attachments are required to be bound to level 0 without ES3 or the GL_OES_fbo_render_mipmap
5857 // extension
5858 if (context->getClientMajorVersion() < 3 && !context->getExtensions().fboRenderMipmap &&
5859 level != 0)
5860 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005861 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidFramebufferTextureLevel);
Jamie Madillbe849e42017-05-02 15:49:00 -04005862 return false;
5863 }
5864
5865 if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
5866 {
5867 return false;
5868 }
5869
5870 if (texture != 0)
5871 {
5872 gl::Texture *tex = context->getTexture(texture);
5873 ASSERT(tex);
5874
5875 const gl::Caps &caps = context->getCaps();
5876
5877 switch (textarget)
5878 {
5879 case GL_TEXTURE_2D:
5880 {
5881 if (level > gl::log2(caps.max2DTextureSize))
5882 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005883 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04005884 return false;
5885 }
5886 if (tex->getTarget() != GL_TEXTURE_2D)
5887 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005888 ANGLE_VALIDATION_ERR(context, InvalidOperation(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005889 return false;
5890 }
5891 }
5892 break;
5893
Corentin Wallez13c0dd42017-07-04 18:27:01 -04005894 case GL_TEXTURE_RECTANGLE_ANGLE:
5895 {
5896 if (level != 0)
5897 {
5898 context->handleError(InvalidValue());
5899 return false;
5900 }
5901 if (tex->getTarget() != GL_TEXTURE_RECTANGLE_ANGLE)
5902 {
5903 context->handleError(InvalidOperation()
5904 << "Textarget must match the texture target type.");
5905 return false;
5906 }
5907 }
5908 break;
5909
Jamie Madillbe849e42017-05-02 15:49:00 -04005910 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
5911 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
5912 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
5913 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
5914 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
5915 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
5916 {
5917 if (level > gl::log2(caps.maxCubeMapTextureSize))
5918 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005919 context->handleError(InvalidValue());
Jamie Madillbe849e42017-05-02 15:49:00 -04005920 return false;
5921 }
5922 if (tex->getTarget() != GL_TEXTURE_CUBE_MAP)
5923 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005924 context->handleError(InvalidOperation()
5925 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005926 return false;
5927 }
5928 }
5929 break;
5930
5931 case GL_TEXTURE_2D_MULTISAMPLE:
5932 {
5933 if (context->getClientVersion() < ES_3_1)
5934 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005935 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ES31Required);
Jamie Madillbe849e42017-05-02 15:49:00 -04005936 return false;
5937 }
5938
5939 if (level != 0)
5940 {
Brandon Jonesafa75152017-07-21 13:11:29 -07005941 ANGLE_VALIDATION_ERR(context, InvalidValue(), LevelNotZero);
Jamie Madillbe849e42017-05-02 15:49:00 -04005942 return false;
5943 }
5944 if (tex->getTarget() != GL_TEXTURE_2D_MULTISAMPLE)
5945 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005946 context->handleError(InvalidOperation()
5947 << "Textarget must match the texture target type.");
Jamie Madillbe849e42017-05-02 15:49:00 -04005948 return false;
5949 }
5950 }
5951 break;
5952
5953 default:
Brandon Jones6cad5662017-06-14 13:25:13 -07005954 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005955 return false;
5956 }
5957
5958 const Format &format = tex->getFormat(textarget, level);
5959 if (format.info->compressed)
5960 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05005961 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -04005962 return false;
5963 }
5964 }
5965
5966 return true;
5967}
5968
5969bool ValidateGenBuffers(Context *context, GLint n, GLuint *)
5970{
5971 return ValidateGenOrDelete(context, n);
5972}
5973
5974bool ValidateGenFramebuffers(Context *context, GLint n, GLuint *)
5975{
5976 return ValidateGenOrDelete(context, n);
5977}
5978
5979bool ValidateGenRenderbuffers(Context *context, GLint n, GLuint *)
5980{
5981 return ValidateGenOrDelete(context, n);
5982}
5983
5984bool ValidateGenTextures(Context *context, GLint n, GLuint *)
5985{
5986 return ValidateGenOrDelete(context, n);
5987}
5988
5989bool ValidateGenerateMipmap(Context *context, GLenum target)
5990{
5991 if (!ValidTextureTarget(context, target))
5992 {
Brandon Jones6cad5662017-06-14 13:25:13 -07005993 ANGLE_VALIDATION_ERR(context, InvalidEnum(), InvalidTextureTarget);
Jamie Madillbe849e42017-05-02 15:49:00 -04005994 return false;
5995 }
5996
5997 Texture *texture = context->getTargetTexture(target);
5998
5999 if (texture == nullptr)
6000 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006001 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotBound);
Jamie Madillbe849e42017-05-02 15:49:00 -04006002 return false;
6003 }
6004
6005 const GLuint effectiveBaseLevel = texture->getTextureState().getEffectiveBaseLevel();
6006
6007 // This error isn't spelled out in the spec in a very explicit way, but we interpret the spec so
6008 // that out-of-range base level has a non-color-renderable / non-texture-filterable format.
6009 if (effectiveBaseLevel >= gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
6010 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006011 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -04006012 return false;
6013 }
6014
6015 GLenum baseTarget = (target == GL_TEXTURE_CUBE_MAP) ? GL_TEXTURE_CUBE_MAP_POSITIVE_X : target;
6016 const auto &format = texture->getFormat(baseTarget, effectiveBaseLevel);
6017 const TextureCaps &formatCaps = context->getTextureCaps().get(format.info->sizedInternalFormat);
6018
Brandon Jones6cad5662017-06-14 13:25:13 -07006019 if (format.info->compressed)
6020 {
6021 ANGLE_VALIDATION_ERR(context, InvalidOperation(), GenerateMipmapNotAllowed);
6022 return false;
6023 }
6024
Jamie Madillbe849e42017-05-02 15:49:00 -04006025 // GenerateMipmap should not generate an INVALID_OPERATION for textures created with
Brandon Jones6cad5662017-06-14 13:25:13 -07006026 // unsized formats or that are color renderable and filterable. Since we do not track if
Jamie Madillbe849e42017-05-02 15:49:00 -04006027 // the texture was created with sized or unsized format (only sized formats are stored),
6028 // it is not possible to make sure the the LUMA formats can generate mipmaps (they should
6029 // be able to) because they aren't color renderable. Simply do a special case for LUMA
6030 // textures since they're the only texture format that can be created with unsized formats
6031 // that is not color renderable. New unsized formats are unlikely to be added, since ES2
6032 // was the last version to use add them.
6033 if (format.info->depthBits > 0 || format.info->stencilBits > 0 || !formatCaps.filterable ||
Brandon Jones6cad5662017-06-14 13:25:13 -07006034 (!formatCaps.renderable && !format.info->isLUMA()))
Jamie Madillbe849e42017-05-02 15:49:00 -04006035 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006036 context->handleError(InvalidOperation());
Jamie Madillbe849e42017-05-02 15:49:00 -04006037 return false;
6038 }
6039
Geoff Lang65ac5b92017-05-01 13:16:30 -04006040 // ES3 and WebGL grant mipmap generation for sRGB textures but GL_EXT_sRGB does not.
6041 bool supportsSRGBMipmapGeneration =
6042 context->getClientVersion() >= ES_3_0 || context->getExtensions().webglCompatibility;
6043 if (!supportsSRGBMipmapGeneration && format.info->colorEncoding == GL_SRGB)
Jamie Madillbe849e42017-05-02 15:49:00 -04006044 {
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006045 context->handleError(InvalidOperation()
6046 << "Mipmap generation of sRGB textures is not allowed.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006047 return false;
6048 }
6049
6050 // Non-power of 2 ES2 check
6051 if (context->getClientVersion() < Version(3, 0) && !context->getExtensions().textureNPOT &&
6052 (!isPow2(static_cast<int>(texture->getWidth(baseTarget, 0))) ||
6053 !isPow2(static_cast<int>(texture->getHeight(baseTarget, 0)))))
6054 {
Corentin Wallez13c0dd42017-07-04 18:27:01 -04006055 ASSERT(target == GL_TEXTURE_2D || target == GL_TEXTURE_RECTANGLE_ANGLE ||
6056 target == GL_TEXTURE_CUBE_MAP);
Brandon Jones6cad5662017-06-14 13:25:13 -07006057 ANGLE_VALIDATION_ERR(context, InvalidOperation(), TextureNotPow2);
Jamie Madillbe849e42017-05-02 15:49:00 -04006058 return false;
6059 }
6060
6061 // Cube completeness check
6062 if (target == GL_TEXTURE_CUBE_MAP && !texture->getTextureState().isCubeComplete())
6063 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006064 ANGLE_VALIDATION_ERR(context, InvalidOperation(), CubemapIncomplete);
Jamie Madillbe849e42017-05-02 15:49:00 -04006065 return false;
6066 }
6067
6068 return true;
6069}
6070
6071bool ValidateGetBufferParameteriv(ValidationContext *context,
6072 GLenum target,
6073 GLenum pname,
6074 GLint *params)
6075{
6076 return ValidateGetBufferParameterBase(context, target, pname, false, nullptr);
6077}
6078
6079bool ValidateGetRenderbufferParameteriv(Context *context,
6080 GLenum target,
6081 GLenum pname,
6082 GLint *params)
6083{
6084 return ValidateGetRenderbufferParameterivBase(context, target, pname, nullptr);
6085}
6086
6087bool ValidateGetShaderiv(Context *context, GLuint shader, GLenum pname, GLint *params)
6088{
6089 return ValidateGetShaderivBase(context, shader, pname, nullptr);
6090}
6091
6092bool ValidateGetTexParameterfv(Context *context, GLenum target, GLenum pname, GLfloat *params)
6093{
6094 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6095}
6096
6097bool ValidateGetTexParameteriv(Context *context, GLenum target, GLenum pname, GLint *params)
6098{
6099 return ValidateGetTexParameterBase(context, target, pname, nullptr);
6100}
6101
6102bool ValidateGetUniformfv(Context *context, GLuint program, GLint location, GLfloat *params)
6103{
6104 return ValidateGetUniformBase(context, program, location);
6105}
6106
6107bool ValidateGetUniformiv(Context *context, GLuint program, GLint location, GLint *params)
6108{
6109 return ValidateGetUniformBase(context, program, location);
6110}
6111
6112bool ValidateGetVertexAttribfv(Context *context, GLuint index, GLenum pname, GLfloat *params)
6113{
6114 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6115}
6116
6117bool ValidateGetVertexAttribiv(Context *context, GLuint index, GLenum pname, GLint *params)
6118{
6119 return ValidateGetVertexAttribBase(context, index, pname, nullptr, false, false);
6120}
6121
6122bool ValidateGetVertexAttribPointerv(Context *context, GLuint index, GLenum pname, void **pointer)
6123{
6124 return ValidateGetVertexAttribBase(context, index, pname, nullptr, true, false);
6125}
6126
6127bool ValidateIsEnabled(Context *context, GLenum cap)
6128{
6129 if (!ValidCap(context, cap, true))
6130 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006131 ANGLE_VALIDATION_ERR(context, InvalidEnum(), EnumNotSupported);
Jamie Madillbe849e42017-05-02 15:49:00 -04006132 return false;
6133 }
6134
6135 return true;
6136}
6137
6138bool ValidateLinkProgram(Context *context, GLuint program)
6139{
6140 if (context->hasActiveTransformFeedback(program))
6141 {
6142 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006143 context->handleError(InvalidOperation() << "Cannot link program while program is "
6144 "associated with an active transform "
6145 "feedback object.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006146 return false;
6147 }
6148
6149 Program *programObject = GetValidProgram(context, program);
6150 if (!programObject)
6151 {
6152 return false;
6153 }
6154
6155 return true;
6156}
6157
Jamie Madill4928b7c2017-06-20 12:57:39 -04006158bool ValidateReadPixels(Context *context,
Jamie Madillbe849e42017-05-02 15:49:00 -04006159 GLint x,
6160 GLint y,
6161 GLsizei width,
6162 GLsizei height,
6163 GLenum format,
6164 GLenum type,
6165 void *pixels)
6166{
6167 return ValidateReadPixelsBase(context, x, y, width, height, format, type, -1, nullptr, nullptr,
6168 nullptr, pixels);
6169}
6170
6171bool ValidateTexParameterf(Context *context, GLenum target, GLenum pname, GLfloat param)
6172{
6173 return ValidateTexParameterBase(context, target, pname, -1, &param);
6174}
6175
6176bool ValidateTexParameterfv(Context *context, GLenum target, GLenum pname, const GLfloat *params)
6177{
6178 return ValidateTexParameterBase(context, target, pname, -1, params);
6179}
6180
6181bool ValidateTexParameteri(Context *context, GLenum target, GLenum pname, GLint param)
6182{
6183 return ValidateTexParameterBase(context, target, pname, -1, &param);
6184}
6185
6186bool ValidateTexParameteriv(Context *context, GLenum target, GLenum pname, const GLint *params)
6187{
6188 return ValidateTexParameterBase(context, target, pname, -1, params);
6189}
6190
6191bool ValidateUseProgram(Context *context, GLuint program)
6192{
6193 if (program != 0)
6194 {
6195 Program *programObject = context->getProgram(program);
6196 if (!programObject)
6197 {
6198 // ES 3.1.0 section 7.3 page 72
6199 if (context->getShader(program))
6200 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006201 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ExpectedProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006202 return false;
6203 }
6204 else
6205 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006206 ANGLE_VALIDATION_ERR(context, InvalidValue(), InvalidProgramName);
Jamie Madillbe849e42017-05-02 15:49:00 -04006207 return false;
6208 }
6209 }
6210 if (!programObject->isLinked())
6211 {
Brandon Jones6cad5662017-06-14 13:25:13 -07006212 ANGLE_VALIDATION_ERR(context, InvalidOperation(), ProgramNotLinked);
Jamie Madillbe849e42017-05-02 15:49:00 -04006213 return false;
6214 }
6215 }
6216 if (context->getGLState().isTransformFeedbackActiveUnpaused())
6217 {
6218 // ES 3.0.4 section 2.15 page 91
Yuly Novikovc4d18aa2017-03-09 18:45:02 -05006219 context
6220 ->handleError(InvalidOperation()
6221 << "Cannot change active program while transform feedback is unpaused.");
Jamie Madillbe849e42017-05-02 15:49:00 -04006222 return false;
6223 }
6224
6225 return true;
6226}
6227
Jamie Madillc29968b2016-01-20 11:17:23 -05006228} // namespace gl