• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2013 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 
7 // validationES3.cpp: Validation functions for OpenGL ES 3.0 entry point parameters
8 
9 #include "libANGLE/validationES3_autogen.h"
10 
11 #include "anglebase/numerics/safe_conversions.h"
12 #include "common/mathutil.h"
13 #include "common/utilities.h"
14 #include "libANGLE/Context.h"
15 #include "libANGLE/ErrorStrings.h"
16 #include "libANGLE/Framebuffer.h"
17 #include "libANGLE/FramebufferAttachment.h"
18 #include "libANGLE/PixelLocalStorage.h"
19 #include "libANGLE/Renderbuffer.h"
20 #include "libANGLE/Texture.h"
21 #include "libANGLE/VertexArray.h"
22 #include "libANGLE/formatutils.h"
23 #include "libANGLE/validationES.h"
24 #include "libANGLE/validationES3.h"
25 
26 using namespace angle;
27 
28 namespace gl
29 {
30 using namespace err;
31 
32 namespace
33 {
ValidateFramebufferTextureMultiviewBaseANGLE(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLenum attachment,TextureID texture,GLint level,GLsizei numViews)34 bool ValidateFramebufferTextureMultiviewBaseANGLE(const Context *context,
35                                                   angle::EntryPoint entryPoint,
36                                                   GLenum target,
37                                                   GLenum attachment,
38                                                   TextureID texture,
39                                                   GLint level,
40                                                   GLsizei numViews)
41 {
42     if (!(context->getExtensions().multiviewOVR || context->getExtensions().multiview2OVR))
43     {
44         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kMultiviewNotAvailable);
45         return false;
46     }
47 
48     if (!ValidateFramebufferTextureBase(context, entryPoint, target, attachment, texture, level))
49     {
50         return false;
51     }
52 
53     if (texture.value != 0 && numViews < 1)
54     {
55         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kMultiviewViewsTooSmall);
56         return false;
57     }
58 
59     if (static_cast<GLuint>(numViews) > context->getCaps().maxViews)
60     {
61         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kMultiviewViewsTooLarge);
62         return false;
63     }
64 
65     return true;
66 }
67 
ValidateFramebufferTextureMultiviewLevelAndFormat(const Context * context,angle::EntryPoint entryPoint,const Texture * texture,GLint level)68 bool ValidateFramebufferTextureMultiviewLevelAndFormat(const Context *context,
69                                                        angle::EntryPoint entryPoint,
70                                                        const Texture *texture,
71                                                        GLint level)
72 {
73     TextureType type = texture->getType();
74     if (!ValidMipLevel(context, type, level))
75     {
76         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidMipLevel);
77         return false;
78     }
79 
80     const auto &format = texture->getFormat(NonCubeTextureTypeToTarget(type), level);
81     if (format.info->compressed)
82     {
83         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kCompressedTexturesNotAttachable);
84         return false;
85     }
86     return true;
87 }
88 
ValidateUniformES3(const Context * context,angle::EntryPoint entryPoint,GLenum uniformType,UniformLocation location,GLint count)89 bool ValidateUniformES3(const Context *context,
90                         angle::EntryPoint entryPoint,
91                         GLenum uniformType,
92                         UniformLocation location,
93                         GLint count)
94 {
95     if (context->getClientMajorVersion() < 3)
96     {
97         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
98         return false;
99     }
100 
101     return ValidateUniform(context, entryPoint, uniformType, location, count);
102 }
103 
ValidateUniformMatrixES3(const Context * context,angle::EntryPoint entryPoint,GLenum valueType,UniformLocation location,GLsizei count,GLboolean transpose)104 bool ValidateUniformMatrixES3(const Context *context,
105                               angle::EntryPoint entryPoint,
106                               GLenum valueType,
107                               UniformLocation location,
108                               GLsizei count,
109                               GLboolean transpose)
110 {
111     // Check for ES3 uniform entry points
112     if (context->getClientMajorVersion() < 3)
113     {
114         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
115         return false;
116     }
117 
118     return ValidateUniformMatrix(context, entryPoint, valueType, location, count, transpose);
119 }
120 
ValidateGenOrDeleteES3(const Context * context,angle::EntryPoint entryPoint,GLint n,const void * ids)121 bool ValidateGenOrDeleteES3(const Context *context,
122                             angle::EntryPoint entryPoint,
123                             GLint n,
124                             const void *ids)
125 {
126     if (context->getClientMajorVersion() < 3)
127     {
128         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
129         return false;
130     }
131     return ValidateGenOrDelete(context, entryPoint, n, ids);
132 }
133 
ValidateGenOrDeleteCountES3(const Context * context,angle::EntryPoint entryPoint,GLint count)134 bool ValidateGenOrDeleteCountES3(const Context *context, angle::EntryPoint entryPoint, GLint count)
135 {
136     if (context->getClientMajorVersion() < 3)
137     {
138         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
139         return false;
140     }
141     if (count < 0)
142     {
143         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeCount);
144         return false;
145     }
146     return true;
147 }
148 
ValidateCopyTexture3DCommon(const Context * context,angle::EntryPoint entryPoint,const Texture * source,GLint sourceLevel,GLint srcInternalFormat,const Texture * dest,GLint destLevel,GLint internalFormat,TextureTarget destTarget)149 bool ValidateCopyTexture3DCommon(const Context *context,
150                                  angle::EntryPoint entryPoint,
151                                  const Texture *source,
152                                  GLint sourceLevel,
153                                  GLint srcInternalFormat,
154                                  const Texture *dest,
155                                  GLint destLevel,
156                                  GLint internalFormat,
157                                  TextureTarget destTarget)
158 {
159     if (context->getClientMajorVersion() < 3)
160     {
161         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
162         return false;
163     }
164 
165     if (!context->getExtensions().copyTexture3dANGLE)
166     {
167         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kANGLECopyTexture3DUnavailable);
168         return false;
169     }
170 
171     if (!ValidTexture3DTarget(context, source->getType()))
172     {
173         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidTextureTarget);
174         return false;
175     }
176 
177     // Table 1.1 from the ANGLE_copy_texture_3d spec
178     switch (GetUnsizedFormat(srcInternalFormat))
179     {
180         case GL_ALPHA:
181         case GL_LUMINANCE:
182         case GL_LUMINANCE_ALPHA:
183         case GL_RED:
184         case GL_RED_INTEGER:
185         case GL_RG:
186         case GL_RG_INTEGER:
187         case GL_RGB:
188         case GL_RGB_INTEGER:
189         case GL_RGBA:
190         case GL_RGBA_INTEGER:
191         case GL_DEPTH_COMPONENT:
192         case GL_DEPTH_STENCIL:
193             break;
194         default:
195             ANGLE_VALIDATION_ERRORF(GL_INVALID_OPERATION, kInvalidInternalFormat,
196                                     srcInternalFormat);
197             return false;
198     }
199 
200     if (!ValidTexture3DTarget(context, TextureTargetToType(destTarget)))
201     {
202         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidTextureTarget);
203         return false;
204     }
205 
206     // Table 1.0 from the ANGLE_copy_texture_3d spec
207     switch (internalFormat)
208     {
209         case GL_RGB:
210         case GL_RGBA:
211         case GL_LUMINANCE:
212         case GL_LUMINANCE_ALPHA:
213         case GL_ALPHA:
214         case GL_R8:
215         case GL_R8_SNORM:
216         case GL_R16F:
217         case GL_R32F:
218         case GL_R8UI:
219         case GL_R8I:
220         case GL_R16UI:
221         case GL_R16I:
222         case GL_R32UI:
223         case GL_R32I:
224         case GL_RG:
225         case GL_RG8:
226         case GL_RG8_SNORM:
227         case GL_RG16F:
228         case GL_RG32F:
229         case GL_RG8UI:
230         case GL_RG8I:
231         case GL_RG16UI:
232         case GL_RG16I:
233         case GL_RG32UI:
234         case GL_RG32I:
235         case GL_RGB8:
236         case GL_RGBX8_ANGLE:
237         case GL_SRGB8:
238         case GL_RGB565:
239         case GL_RGB8_SNORM:
240         case GL_R11F_G11F_B10F:
241         case GL_RGB9_E5:
242         case GL_RGB16F:
243         case GL_RGB32F:
244         case GL_RGB8UI:
245         case GL_RGB8I:
246         case GL_RGB16UI:
247         case GL_RGB16I:
248         case GL_RGB32UI:
249         case GL_RGB32I:
250         case GL_RGBA8:
251         case GL_SRGB8_ALPHA8:
252         case GL_RGBA8_SNORM:
253         case GL_RGB5_A1:
254         case GL_RGBA4:
255         case GL_RGB10_A2:
256         case GL_RGBA16F:
257         case GL_RGBA32F:
258         case GL_RGBA8UI:
259         case GL_RGBA8I:
260         case GL_RGB10_A2UI:
261         case GL_RGBA16UI:
262         case GL_RGBA16I:
263         case GL_RGBA32I:
264         case GL_RGBA32UI:
265             break;
266         default:
267             ANGLE_VALIDATION_ERRORF(GL_INVALID_OPERATION, kInvalidInternalFormat, internalFormat);
268             return false;
269     }
270 
271     return true;
272 }
273 
ValidateColorMaskForSharedExponentColorBuffer(const Context * context,angle::EntryPoint entryPoint,GLint drawbuffer)274 bool ValidateColorMaskForSharedExponentColorBuffer(const Context *context,
275                                                    angle::EntryPoint entryPoint,
276                                                    GLint drawbuffer)
277 {
278     const State &state                      = context->getState();
279     const FramebufferAttachment *attachment = state.getDrawFramebuffer()->getDrawBuffer(drawbuffer);
280     if (attachment && attachment->getFormat().info->internalFormat == GL_RGB9_E5)
281     {
282         bool r, g, b, a;
283         state.getBlendStateExt().getColorMaskIndexed(drawbuffer, &r, &g, &b, &a);
284         if (r != g || g != b)
285         {
286             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION,
287                                    kUnsupportedColorMaskForSharedExponentColorBuffer);
288             return false;
289         }
290     }
291 
292     return true;
293 }
294 }  // anonymous namespace
295 
ValidateTexImageFormatCombination(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLenum internalFormat,GLenum format,GLenum type)296 bool ValidateTexImageFormatCombination(const Context *context,
297                                        angle::EntryPoint entryPoint,
298                                        TextureType target,
299                                        GLenum internalFormat,
300                                        GLenum format,
301                                        GLenum type)
302 {
303     // The type and format are valid if any supported internal format has that type and format.
304     // ANGLE_texture_external_yuv_sampling extension adds support for YUV formats
305     if (gl::IsYuvFormat(format))
306     {
307         if (!context->getExtensions().yuvInternalFormatANGLE)
308         {
309             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidFormat);
310             return false;
311         }
312     }
313     else
314     {
315         if (!ValidES3Format(format))
316         {
317             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidFormat);
318             return false;
319         }
320     }
321 
322     if (!ValidES3Type(type) || (type == GL_HALF_FLOAT_OES && context->isWebGL()))
323     {
324         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidType);
325         return false;
326     }
327 
328     // For historical reasons, glTexImage2D and glTexImage3D pass in their internal format as a
329     // GLint instead of a GLenum. Therefor an invalid internal format gives a GL_INVALID_VALUE
330     // error instead of a GL_INVALID_ENUM error. As this validation function is only called in
331     // the validation codepaths for glTexImage2D/3D, we record a GL_INVALID_VALUE error.
332     if (!ValidES3InternalFormat(internalFormat))
333     {
334         ANGLE_VALIDATION_ERRORF(GL_INVALID_VALUE, kInvalidInternalFormat, internalFormat);
335         return false;
336     }
337 
338     // From the ES 3.0 spec section 3.8.3:
339     // Textures with a base internal format of DEPTH_COMPONENT or DEPTH_STENCIL are supported by
340     // texture image specification commands only if target is TEXTURE_2D, TEXTURE_2D_ARRAY, or
341     // TEXTURE_CUBE_MAP.Using these formats in conjunction with any other target will result in an
342     // INVALID_OPERATION error.
343     //
344     // Similar language exists in OES_texture_stencil8.
345     if (target == TextureType::_3D &&
346         (format == GL_DEPTH_COMPONENT || format == GL_DEPTH_STENCIL || format == GL_STENCIL_INDEX))
347     {
348         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, k3DDepthStencil);
349         return false;
350     }
351 
352     // Check if this is a valid format combination to load texture data
353     // ANGLE_texture_external_yuv_sampling extension adds support for YUV formats
354     if (gl::IsYuvFormat(format))
355     {
356         if (type != GL_UNSIGNED_BYTE)
357         {
358             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidFormatCombination);
359             return false;
360         }
361     }
362     else
363     {
364         if (!ValidES3FormatCombination(format, type, internalFormat))
365         {
366             bool extensionFormatsAllowed = false;
367             switch (internalFormat)
368             {
369                 case GL_LUMINANCE4_ALPHA4_OES:
370                     if (context->getExtensions().requiredInternalformatOES &&
371                         type == GL_UNSIGNED_BYTE && format == GL_LUMINANCE_ALPHA)
372                     {
373                         extensionFormatsAllowed = true;
374                     }
375                     break;
376                 case GL_DEPTH_COMPONENT32_OES:
377                     if ((context->getExtensions().requiredInternalformatOES &&
378                          context->getExtensions().depth32OES) &&
379                         type == GL_UNSIGNED_INT && format == GL_DEPTH_COMPONENT)
380                     {
381                         extensionFormatsAllowed = true;
382                     }
383                     break;
384                 case GL_RGB10_EXT:
385                 case GL_RGB8_OES:
386                 case GL_RGB565_OES:
387                     if (context->getExtensions().requiredInternalformatOES &&
388                         context->getExtensions().textureType2101010REVEXT &&
389                         type == GL_UNSIGNED_INT_2_10_10_10_REV_EXT && format == GL_RGB)
390                     {
391                         extensionFormatsAllowed = true;
392                     }
393                     break;
394                 default:
395                     break;
396             }
397             if (!extensionFormatsAllowed)
398             {
399                 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidFormatCombination);
400                 return false;
401             }
402         }
403     }
404 
405     const InternalFormat &formatInfo = GetInternalFormatInfo(internalFormat, type);
406     if (!formatInfo.textureSupport(context->getClientVersion(), context->getExtensions()))
407     {
408         ANGLE_VALIDATION_ERRORF(GL_INVALID_OPERATION, kInvalidInternalFormat, internalFormat);
409         return false;
410     }
411 
412     return true;
413 }
414 
ValidateES3CompressedFormatForTexture2DArray(const Context * context,angle::EntryPoint entryPoint,GLenum format)415 static bool ValidateES3CompressedFormatForTexture2DArray(const Context *context,
416                                                          angle::EntryPoint entryPoint,
417                                                          GLenum format)
418 {
419     if ((IsETC1Format(format) && !context->getExtensions().compressedETC1RGB8SubTextureEXT) ||
420         IsPVRTC1Format(format))
421     {
422         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInternalFormatRequiresTexture2D);
423         return false;
424     }
425 
426     return true;
427 }
428 
ValidateES3CompressedFormatForTexture3D(const Context * context,angle::EntryPoint entryPoint,GLenum format)429 static bool ValidateES3CompressedFormatForTexture3D(const Context *context,
430                                                     angle::EntryPoint entryPoint,
431                                                     GLenum format)
432 {
433     if (IsETC1Format(format) || IsPVRTC1Format(format))
434     {
435         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInternalFormatRequiresTexture2D);
436         return false;
437     }
438 
439     if (IsETC2EACFormat(format))
440     {
441         // ES 3.1, Section 8.7, page 169.
442         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInternalFormatRequiresTexture2DArray);
443         return false;
444     }
445 
446     if (IsASTC2DFormat(format) && !(context->getExtensions().textureCompressionAstcHdrKHR ||
447                                     context->getExtensions().textureCompressionAstcSliced3dKHR))
448     {
449         // GL_KHR_texture_compression_astc_hdr, TEXTURE_3D is not supported without HDR profile
450         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInternalFormatRequiresTexture2DArrayASTC);
451         return false;
452     }
453 
454     if (IsS3TCFormat(format))
455     {
456         // GL_EXT_texture_compression_s3tc
457         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInternalFormatRequiresTexture2DArrayS3TC);
458         return false;
459     }
460 
461     if (IsRGTCFormat(format))
462     {
463         // GL_EXT_texture_compression_rgtc
464         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInternalFormatRequiresTexture2DArrayRGTC);
465         return false;
466     }
467 
468     if (IsBPTCFormat(format) && (context->getLimitations().noCompressedTexture3D))
469     {
470         // GL_EXT_texture_compression_bptc
471         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInternalFormatRequiresTexture2DArrayBPTC);
472         return false;
473     }
474 
475     return true;
476 }
477 
ValidateES3TexImageParametersBase(const Context * context,angle::EntryPoint entryPoint,TextureTarget target,GLint level,GLenum internalformat,bool isCompressed,bool isSubImage,GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLsizei depth,GLint border,GLenum format,GLenum type,GLsizei imageSize,const void * pixels)478 bool ValidateES3TexImageParametersBase(const Context *context,
479                                        angle::EntryPoint entryPoint,
480                                        TextureTarget target,
481                                        GLint level,
482                                        GLenum internalformat,
483                                        bool isCompressed,
484                                        bool isSubImage,
485                                        GLint xoffset,
486                                        GLint yoffset,
487                                        GLint zoffset,
488                                        GLsizei width,
489                                        GLsizei height,
490                                        GLsizei depth,
491                                        GLint border,
492                                        GLenum format,
493                                        GLenum type,
494                                        GLsizei imageSize,
495                                        const void *pixels)
496 {
497     TextureType texType = TextureTargetToType(target);
498 
499     if (gl::IsYuvFormat(format))
500     {
501         // According to ANGLE_yuv_internal_format, the texture needs to be an immutable
502         // texture, texture target can only be TEXTURE_2D and there is no mipmap support
503         if (!context->getExtensions().yuvInternalFormatANGLE || !isSubImage)
504         {
505             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidFormat);
506             return false;
507         }
508 
509         if (target != TextureTarget::_2D)
510         {
511             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidTextureTarget);
512             return false;
513         }
514 
515         if (level != 0)
516         {
517             ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidMipLevel);
518             return false;
519         }
520     }
521 
522     // Validate image size
523     if (!ValidImageSizeParameters(context, entryPoint, texType, level, width, height, depth,
524                                   isSubImage))
525     {
526         // Error already processed.
527         return false;
528     }
529 
530     // Verify zero border
531     if (border != 0)
532     {
533         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidBorder);
534         return false;
535     }
536 
537     if (xoffset < 0 || yoffset < 0 || zoffset < 0)
538     {
539         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeOffset);
540         return false;
541     }
542 
543     if (std::numeric_limits<GLsizei>::max() - xoffset < width ||
544         std::numeric_limits<GLsizei>::max() - yoffset < height ||
545         std::numeric_limits<GLsizei>::max() - zoffset < depth)
546     {
547         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kOffsetOverflow);
548         return false;
549     }
550 
551     const Caps &caps = context->getCaps();
552 
553     switch (texType)
554     {
555         case TextureType::_2D:
556         case TextureType::External:
557         case TextureType::VideoImage:
558             if (width > (caps.max2DTextureSize >> level) ||
559                 height > (caps.max2DTextureSize >> level))
560             {
561                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kResourceMaxTextureSize);
562                 return false;
563             }
564             break;
565 
566         case TextureType::Rectangle:
567             ASSERT(level == 0);
568             if (width > caps.maxRectangleTextureSize || height > caps.maxRectangleTextureSize)
569             {
570                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kResourceMaxTextureSize);
571                 return false;
572             }
573             if (isCompressed)
574             {
575                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kRectangleTextureCompressed);
576                 return false;
577             }
578             break;
579 
580         case TextureType::CubeMap:
581             if (!isSubImage && width != height)
582             {
583                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kCubemapFacesEqualDimensions);
584                 return false;
585             }
586 
587             if (width > (caps.maxCubeMapTextureSize >> level))
588             {
589                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kResourceMaxTextureSize);
590                 return false;
591             }
592             break;
593 
594         case TextureType::_3D:
595             if (width > (caps.max3DTextureSize >> level) ||
596                 height > (caps.max3DTextureSize >> level) ||
597                 depth > (caps.max3DTextureSize >> level))
598             {
599                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kResourceMaxTextureSize);
600                 return false;
601             }
602             break;
603 
604         case TextureType::_2DArray:
605             if (width > (caps.max2DTextureSize >> level) ||
606                 height > (caps.max2DTextureSize >> level) || depth > caps.maxArrayTextureLayers)
607             {
608                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kResourceMaxTextureSize);
609                 return false;
610             }
611             break;
612 
613         case TextureType::CubeMapArray:
614             if (!isSubImage && width != height)
615             {
616                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kCubemapFacesEqualDimensions);
617                 return false;
618             }
619 
620             if (width > (caps.maxCubeMapTextureSize >> level) ||
621                 height > (caps.maxCubeMapTextureSize >> level))
622             {
623                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kResourceMaxTextureSize);
624                 return false;
625             }
626 
627             if (width > (caps.max3DTextureSize >> level) ||
628                 height > (caps.max3DTextureSize >> level) || depth > caps.max3DTextureSize)
629             {
630                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kResourceMaxTextureSize);
631                 return false;
632             }
633 
634             if (!isSubImage && depth % 6 != 0)
635             {
636                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kCubemapInvalidDepth);
637                 return false;
638             }
639             break;
640 
641         case TextureType::InvalidEnum:
642             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kEnumInvalid);
643             return false;
644         default:
645             ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, ToGLenum(texType));
646             return false;
647     }
648 
649     Texture *texture = context->getTextureByType(texType);
650     if (!texture)
651     {
652         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kMissingTexture);
653         return false;
654     }
655 
656     if (context->getState().isTextureBoundToActivePLS(texture->id()))
657     {
658         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kActivePLSBackingTexture);
659         return false;
660     }
661 
662     if (texture->getImmutableFormat() && !isSubImage)
663     {
664         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kTextureIsImmutable);
665         return false;
666     }
667 
668     // Validate texture formats
669     GLenum actualInternalFormat =
670         isSubImage ? texture->getFormat(target, level).info->internalFormat : internalformat;
671     if (isSubImage && actualInternalFormat == GL_NONE)
672     {
673         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidMipLevel);
674         return false;
675     }
676 
677     const InternalFormat &actualFormatInfo = isSubImage
678                                                  ? *texture->getFormat(target, level).info
679                                                  : GetInternalFormatInfo(internalformat, type);
680     if (isCompressed)
681     {
682         // compressedTexSubImage does not generate GL_INVALID_ENUM when format is unknown or invalid
683         if (!isSubImage)
684         {
685             if (!actualFormatInfo.compressed && !actualFormatInfo.paletted)
686             {
687                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kCompressedMismatch);
688                 return false;
689             }
690 
691             if (!actualFormatInfo.textureSupport(context->getClientVersion(),
692                                                  context->getExtensions()))
693             {
694                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidFormat);
695                 return false;
696             }
697         }
698 
699         if (texType == TextureType::_2DArray)
700         {
701             GLenum compressedDataFormat = isSubImage ? format : internalformat;
702             if (!ValidateES3CompressedFormatForTexture2DArray(context, entryPoint,
703                                                               compressedDataFormat))
704             {
705                 // Error already generated.
706                 return false;
707             }
708         }
709 
710         if (texType == TextureType::_3D)
711         {
712             GLenum compressedDataFormat = isSubImage ? format : internalformat;
713             if (!ValidateES3CompressedFormatForTexture3D(context, entryPoint, compressedDataFormat))
714             {
715                 // Error already generated.
716                 return false;
717             }
718         }
719 
720         if (isSubImage)
721         {
722             if (!ValidCompressedSubImageSize(
723                     context, actualFormatInfo.internalFormat, xoffset, yoffset, zoffset, width,
724                     height, depth, texture->getWidth(target, level),
725                     texture->getHeight(target, level), texture->getDepth(target, level)))
726             {
727                 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidCompressedImageSize);
728                 return false;
729             }
730 
731             if (format != actualInternalFormat)
732             {
733                 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kMismatchedFormat);
734                 return false;
735             }
736 
737             // GL_EXT_compressed_ETC1_RGB8_sub_texture allows this format
738             if (IsETC1Format(actualInternalFormat) &&
739                 !context->getExtensions().compressedETC1RGB8SubTextureEXT)
740             {
741                 ANGLE_VALIDATION_ERRORF(GL_INVALID_OPERATION, kInvalidInternalFormat,
742                                         internalformat);
743                 return false;
744             }
745         }
746         else
747         {
748             if (!ValidCompressedImageSize(context, actualInternalFormat, level, width, height,
749                                           depth))
750             {
751                 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidCompressedImageSize);
752                 return false;
753             }
754         }
755 
756         // Disallow 3D-only compressed formats from being set on 2D textures
757         if (actualFormatInfo.compressedBlockDepth > 1 && texType != TextureType::_3D)
758         {
759             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidTextureTarget);
760             return false;
761         }
762     }
763     else
764     {
765         // Compressed formats are not valid internal formats for glTexImage*D
766         if (!isSubImage)
767         {
768             const InternalFormat &internalFormatInfo = GetSizedInternalFormatInfo(internalformat);
769             if (internalFormatInfo.compressed)
770             {
771                 ANGLE_VALIDATION_ERRORF(GL_INVALID_VALUE, kInvalidInternalFormat, internalformat);
772                 return false;
773             }
774         }
775 
776         if (!ValidateTexImageFormatCombination(context, entryPoint, texType, actualInternalFormat,
777                                                format, type))
778         {
779             return false;
780         }
781     }
782 
783     // Validate sub image parameters
784     if (isSubImage)
785     {
786         if (isCompressed != actualFormatInfo.compressed)
787         {
788             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kCompressedMismatch);
789             return false;
790         }
791 
792         // Already validated above
793         ASSERT(xoffset >= 0 && yoffset >= 0 && zoffset >= 0);
794         ASSERT(std::numeric_limits<GLsizei>::max() - xoffset >= width &&
795                std::numeric_limits<GLsizei>::max() - yoffset >= height &&
796                std::numeric_limits<GLsizei>::max() - zoffset >= depth);
797 
798         if (static_cast<size_t>(xoffset + width) > texture->getWidth(target, level) ||
799             static_cast<size_t>(yoffset + height) > texture->getHeight(target, level) ||
800             static_cast<size_t>(zoffset + depth) > texture->getDepth(target, level))
801         {
802             ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kOffsetOverflow);
803             return false;
804         }
805 
806         if (width > 0 && height > 0 && depth > 0 && pixels == nullptr &&
807             context->getState().getTargetBuffer(BufferBinding::PixelUnpack) == nullptr)
808         {
809             ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kPixelDataNull);
810             return false;
811         }
812     }
813 
814     GLenum sizeCheckFormat = isSubImage ? format : internalformat;
815     if (!ValidImageDataSize(context, entryPoint, texType, width, height, depth, sizeCheckFormat,
816                             type, pixels, imageSize))
817     {
818         return false;
819     }
820 
821     // Check for pixel unpack buffer related API errors
822     Buffer *pixelUnpackBuffer = context->getState().getTargetBuffer(BufferBinding::PixelUnpack);
823     if (pixelUnpackBuffer != nullptr)
824     {
825         // ...data is not evenly divisible into the number of bytes needed to store in memory a
826         // datum
827         // indicated by type.
828         if (!isCompressed)
829         {
830             size_t offset            = reinterpret_cast<size_t>(pixels);
831             size_t dataBytesPerPixel = static_cast<size_t>(GetTypeInfo(type).bytes);
832 
833             if ((offset % dataBytesPerPixel) != 0)
834             {
835                 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kDataTypeNotAligned);
836                 return false;
837             }
838         }
839 
840         // ...the buffer object's data store is currently mapped but not persistently.
841         if (pixelUnpackBuffer->isMapped() && !pixelUnpackBuffer->isPersistentlyMapped())
842         {
843             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBufferMapped);
844             return false;
845         }
846     }
847 
848     if (context->getExtensions().webglCompatibilityANGLE)
849     {
850         // Define:
851         //   DataStoreWidth  = (GL_UNPACK_ROW_LENGTH ? GL_UNPACK_ROW_LENGTH : width)
852         //   DataStoreHeight = (GL_UNPACK_IMAGE_HEIGHT ? GL_UNPACK_IMAGE_HEIGHT : height)
853         //
854         // WebGL 2.0 imposes the following additional constraints:
855         //
856         // 1) texImage2D and texSubImage2D generate INVALID_OPERATION if:
857         //      GL_UNPACK_SKIP_PIXELS + width > DataStoreWidth
858         //    except for texImage2D if no GL_PIXEL_UNPACK_BUFFER is
859         //    bound and _pixels_ is null.
860         //
861         // 2) texImage3D and texSubImage3D generate INVALID_OPERATION if:
862         //      GL_UNPACK_SKIP_PIXELS + width > DataStoreWidth
863         //      GL_UNPACK_SKIP_ROWS + height > DataStoreHeight
864         //    except for texImage3D if no GL_PIXEL_UNPACK_BUFFER is
865         //    bound and _pixels_ is null.
866         if (!pixelUnpackBuffer && !pixels && !isSubImage)
867         {
868             // Exception case for texImage2D or texImage3D, above.
869         }
870         else
871         {
872             const auto &unpack   = context->getState().getUnpackState();
873             GLint dataStoreWidth = unpack.rowLength ? unpack.rowLength : width;
874             if (unpack.skipPixels + width > dataStoreWidth)
875             {
876                 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidUnpackParametersForWebGL);
877                 return false;
878             }
879             if (target == TextureTarget::_3D || target == TextureTarget::_2DArray)
880             {
881                 GLint dataStoreHeight = unpack.imageHeight ? unpack.imageHeight : height;
882                 if (unpack.skipRows + height > dataStoreHeight)
883                 {
884                     ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidUnpackParametersForWebGL);
885                     return false;
886                 }
887             }
888         }
889     }
890 
891     return true;
892 }
893 
ValidateES3TexImage2DParameters(const Context * context,angle::EntryPoint entryPoint,TextureTarget target,GLint level,GLenum internalformat,bool isCompressed,bool isSubImage,GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLsizei depth,GLint border,GLenum format,GLenum type,GLsizei imageSize,const void * pixels)894 bool ValidateES3TexImage2DParameters(const Context *context,
895                                      angle::EntryPoint entryPoint,
896                                      TextureTarget target,
897                                      GLint level,
898                                      GLenum internalformat,
899                                      bool isCompressed,
900                                      bool isSubImage,
901                                      GLint xoffset,
902                                      GLint yoffset,
903                                      GLint zoffset,
904                                      GLsizei width,
905                                      GLsizei height,
906                                      GLsizei depth,
907                                      GLint border,
908                                      GLenum format,
909                                      GLenum type,
910                                      GLsizei imageSize,
911                                      const void *pixels)
912 {
913     if (!ValidTexture2DDestinationTarget(context, target))
914     {
915         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidTextureTarget);
916         return false;
917     }
918 
919     return ValidateES3TexImageParametersBase(
920         context, entryPoint, target, level, internalformat, isCompressed, isSubImage, xoffset,
921         yoffset, zoffset, width, height, depth, border, format, type, imageSize, pixels);
922 }
923 
ValidateES3TexImage3DParameters(const Context * context,angle::EntryPoint entryPoint,TextureTarget target,GLint level,GLenum internalformat,bool isCompressed,bool isSubImage,GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLsizei depth,GLint border,GLenum format,GLenum type,GLsizei bufSize,const void * pixels)924 bool ValidateES3TexImage3DParameters(const Context *context,
925                                      angle::EntryPoint entryPoint,
926                                      TextureTarget target,
927                                      GLint level,
928                                      GLenum internalformat,
929                                      bool isCompressed,
930                                      bool isSubImage,
931                                      GLint xoffset,
932                                      GLint yoffset,
933                                      GLint zoffset,
934                                      GLsizei width,
935                                      GLsizei height,
936                                      GLsizei depth,
937                                      GLint border,
938                                      GLenum format,
939                                      GLenum type,
940                                      GLsizei bufSize,
941                                      const void *pixels)
942 {
943     if (!ValidTexture3DDestinationTarget(context, target))
944     {
945         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidTextureTarget);
946         return false;
947     }
948 
949     return ValidateES3TexImageParametersBase(
950         context, entryPoint, target, level, internalformat, isCompressed, isSubImage, xoffset,
951         yoffset, zoffset, width, height, depth, border, format, type, bufSize, pixels);
952 }
953 
954 struct EffectiveInternalFormatInfo
955 {
956     GLenum effectiveFormat;
957     GLenum destFormat;
958     GLuint minRedBits;
959     GLuint maxRedBits;
960     GLuint minGreenBits;
961     GLuint maxGreenBits;
962     GLuint minBlueBits;
963     GLuint maxBlueBits;
964     GLuint minAlphaBits;
965     GLuint maxAlphaBits;
966 };
967 
QueryEffectiveFormatList(const InternalFormat & srcFormat,GLenum targetFormat,const EffectiveInternalFormatInfo * list,size_t size,GLenum * outEffectiveFormat)968 static bool QueryEffectiveFormatList(const InternalFormat &srcFormat,
969                                      GLenum targetFormat,
970                                      const EffectiveInternalFormatInfo *list,
971                                      size_t size,
972                                      GLenum *outEffectiveFormat)
973 {
974     for (size_t curFormat = 0; curFormat < size; ++curFormat)
975     {
976         const EffectiveInternalFormatInfo &formatInfo = list[curFormat];
977         if ((formatInfo.destFormat == targetFormat) &&
978             (formatInfo.minRedBits <= srcFormat.redBits &&
979              formatInfo.maxRedBits >= srcFormat.redBits) &&
980             (formatInfo.minGreenBits <= srcFormat.greenBits &&
981              formatInfo.maxGreenBits >= srcFormat.greenBits) &&
982             (formatInfo.minBlueBits <= srcFormat.blueBits &&
983              formatInfo.maxBlueBits >= srcFormat.blueBits) &&
984             (formatInfo.minAlphaBits <= srcFormat.alphaBits &&
985              formatInfo.maxAlphaBits >= srcFormat.alphaBits))
986         {
987             *outEffectiveFormat = formatInfo.effectiveFormat;
988             return true;
989         }
990     }
991 
992     *outEffectiveFormat = GL_NONE;
993     return false;
994 }
995 
GetSizedEffectiveInternalFormatInfo(const InternalFormat & srcFormat,GLenum * outEffectiveFormat)996 bool GetSizedEffectiveInternalFormatInfo(const InternalFormat &srcFormat,
997                                          GLenum *outEffectiveFormat)
998 {
999     // OpenGL ES 3.0.3 Specification, Table 3.17, pg 141:
1000     // Effective internal format coresponding to destination internal format and linear source
1001     // buffer component sizes.
1002     //                                       | Source channel min/max sizes |
1003     //   Effective Internal Format   |  N/A  |  R   |  G   |  B   |  A      |
1004     // clang-format off
1005     constexpr EffectiveInternalFormatInfo list[] = {
1006         { GL_ALPHA8_EXT,              GL_NONE, 0,  0, 0,  0, 0,  0, 1, 8 },
1007         { GL_R8,                      GL_NONE, 1,  8, 0,  0, 0,  0, 0, 0 },
1008         { GL_RG8,                     GL_NONE, 1,  8, 1,  8, 0,  0, 0, 0 },
1009         { GL_RGB565,                  GL_NONE, 1,  5, 1,  6, 1,  5, 0, 0 },
1010         { GL_RGB8,                    GL_NONE, 6,  8, 7,  8, 6,  8, 0, 0 },
1011         { GL_RGBA4,                   GL_NONE, 1,  4, 1,  4, 1,  4, 1, 4 },
1012         { GL_RGB5_A1,                 GL_NONE, 5,  5, 5,  5, 5,  5, 1, 1 },
1013         { GL_RGBA8,                   GL_NONE, 5,  8, 5,  8, 5,  8, 2, 8 },
1014         { GL_RGB10_A2,                GL_NONE, 9, 10, 9, 10, 9, 10, 2, 2 },
1015     };
1016     // clang-format on
1017 
1018     return QueryEffectiveFormatList(srcFormat, GL_NONE, list, ArraySize(list), outEffectiveFormat);
1019 }
1020 
GetUnsizedEffectiveInternalFormatInfo(const InternalFormat & srcFormat,const InternalFormat & destFormat,GLenum * outEffectiveFormat)1021 bool GetUnsizedEffectiveInternalFormatInfo(const InternalFormat &srcFormat,
1022                                            const InternalFormat &destFormat,
1023                                            GLenum *outEffectiveFormat)
1024 {
1025     constexpr GLuint umax = UINT_MAX;
1026 
1027     // OpenGL ES 3.0.3 Specification, Table 3.17, pg 141:
1028     // Effective internal format coresponding to destination internal format andlinear source buffer
1029     // component sizes.
1030     //                                                   |   Source channel min/max sizes   |
1031     //     Effective Internal Format |   Dest Format     |   R   |    G   |    B   |    A   |
1032     // clang-format off
1033     constexpr EffectiveInternalFormatInfo list[] = {
1034         { GL_ALPHA8_EXT,             GL_ALPHA,           0, umax, 0, umax, 0, umax, 1,    8 },
1035         { GL_LUMINANCE8_EXT,         GL_LUMINANCE,       1,    8, 0, umax, 0, umax, 0, umax },
1036         { GL_LUMINANCE8_ALPHA8_EXT,  GL_LUMINANCE_ALPHA, 1,    8, 0, umax, 0, umax, 1,    8 },
1037         { GL_RGB565,                 GL_RGB,             1,    5, 1,    6, 1,    5, 0, umax },
1038         { GL_RGB8,                   GL_RGB,             6,    8, 7,    8, 6,    8, 0, umax },
1039         { GL_RGBA4,                  GL_RGBA,            1,    4, 1,    4, 1,    4, 1,    4 },
1040         { GL_RGB5_A1,                GL_RGBA,            5,    5, 5,    5, 5,    5, 1,    1 },
1041         { GL_RGBA8,                  GL_RGBA,            5,    8, 5,    8, 5,    8, 5,    8 },
1042     };
1043     // clang-format on
1044 
1045     return QueryEffectiveFormatList(srcFormat, destFormat.format, list, ArraySize(list),
1046                                     outEffectiveFormat);
1047 }
1048 
GetEffectiveInternalFormat(const InternalFormat & srcFormat,const InternalFormat & destFormat,GLenum * outEffectiveFormat)1049 static bool GetEffectiveInternalFormat(const InternalFormat &srcFormat,
1050                                        const InternalFormat &destFormat,
1051                                        GLenum *outEffectiveFormat)
1052 {
1053     if (destFormat.sized)
1054     {
1055         return GetSizedEffectiveInternalFormatInfo(srcFormat, outEffectiveFormat);
1056     }
1057     else
1058     {
1059         return GetUnsizedEffectiveInternalFormatInfo(srcFormat, destFormat, outEffectiveFormat);
1060     }
1061 }
1062 
EqualOrFirstZero(GLuint first,GLuint second)1063 static bool EqualOrFirstZero(GLuint first, GLuint second)
1064 {
1065     return first == 0 || first == second;
1066 }
1067 
IsValidES3CopyTexImageCombination(const InternalFormat & textureFormatInfo,const InternalFormat & framebufferFormatInfo,FramebufferID readBufferHandle)1068 static bool IsValidES3CopyTexImageCombination(const InternalFormat &textureFormatInfo,
1069                                               const InternalFormat &framebufferFormatInfo,
1070                                               FramebufferID readBufferHandle)
1071 {
1072     if (!ValidES3CopyConversion(textureFormatInfo.format, framebufferFormatInfo.format))
1073     {
1074         return false;
1075     }
1076 
1077     // Section 3.8.5 of the GLES 3.0.3 spec states that source and destination formats
1078     // must both be signed, unsigned, or fixed point and both source and destinations
1079     // must be either both SRGB or both not SRGB. EXT_color_buffer_float adds allowed
1080     // conversion between fixed and floating point.
1081 
1082     if ((textureFormatInfo.colorEncoding == GL_SRGB) !=
1083         (framebufferFormatInfo.colorEncoding == GL_SRGB))
1084     {
1085         return false;
1086     }
1087 
1088     if (((textureFormatInfo.componentType == GL_INT) !=
1089          (framebufferFormatInfo.componentType == GL_INT)) ||
1090         ((textureFormatInfo.componentType == GL_UNSIGNED_INT) !=
1091          (framebufferFormatInfo.componentType == GL_UNSIGNED_INT)))
1092     {
1093         return false;
1094     }
1095 
1096     if ((textureFormatInfo.componentType == GL_UNSIGNED_NORMALIZED ||
1097          textureFormatInfo.componentType == GL_SIGNED_NORMALIZED) &&
1098         !(framebufferFormatInfo.componentType == GL_UNSIGNED_NORMALIZED ||
1099           framebufferFormatInfo.componentType == GL_SIGNED_NORMALIZED))
1100     {
1101         return false;
1102     }
1103 
1104     if ((textureFormatInfo.componentType == GL_SIGNED_NORMALIZED) !=
1105         (framebufferFormatInfo.componentType == GL_SIGNED_NORMALIZED))
1106     {
1107         return false;
1108     }
1109 
1110     // Section 3.8.5 of the GLES 3.0.3 (and section 8.6 of the GLES 3.2) spec has a caveat, that
1111     // the KHR dEQP tests enforce:
1112     //
1113     // Note that the above rules disallow matches where some components sizes are smaller and
1114     // others are larger (such as RGB10_A2).
1115     if (!textureFormatInfo.sized && (framebufferFormatInfo.internalFormat == GL_RGB10_A2))
1116     {
1117         return false;
1118     }
1119 
1120     // GLES specification 3.0.3, sec 3.8.5, pg 139-140:
1121     // The effective internal format of the source buffer is determined with the following rules
1122     // applied in order:
1123     //    * If the source buffer is a texture or renderbuffer that was created with a sized internal
1124     //      format then the effective internal format is the source buffer's sized internal format.
1125     //    * If the source buffer is a texture that was created with an unsized base internal format,
1126     //      then the effective internal format is the source image array's effective internal
1127     //      format, as specified by table 3.12, which is determined from the <format> and <type>
1128     //      that were used when the source image array was specified by TexImage*.
1129     //    * Otherwise the effective internal format is determined by the row in table 3.17 or 3.18
1130     //      where Destination Internal Format matches internalformat and where the [source channel
1131     //      sizes] are consistent with the values of the source buffer's [channel sizes]. Table 3.17
1132     //      is used if the FRAMEBUFFER_ATTACHMENT_ENCODING is LINEAR and table 3.18 is used if the
1133     //      FRAMEBUFFER_ATTACHMENT_ENCODING is SRGB.
1134     const InternalFormat *sourceEffectiveFormat = nullptr;
1135     if (readBufferHandle.value != 0)
1136     {
1137         // Not the default framebuffer, therefore the read buffer must be a user-created texture or
1138         // renderbuffer
1139         if (framebufferFormatInfo.sized)
1140         {
1141             sourceEffectiveFormat = &framebufferFormatInfo;
1142         }
1143         else
1144         {
1145             // Renderbuffers cannot be created with an unsized internal format, so this must be an
1146             // unsized-format texture. We can use the same table we use when creating textures to
1147             // get its effective sized format.
1148             sourceEffectiveFormat =
1149                 &GetSizedInternalFormatInfo(framebufferFormatInfo.sizedInternalFormat);
1150         }
1151     }
1152     else
1153     {
1154         // The effective internal format must be derived from the source framebuffer's channel
1155         // sizes. This is done in GetEffectiveInternalFormat for linear buffers (table 3.17)
1156         if (framebufferFormatInfo.colorEncoding == GL_LINEAR)
1157         {
1158             GLenum effectiveFormat;
1159             if (GetEffectiveInternalFormat(framebufferFormatInfo, textureFormatInfo,
1160                                            &effectiveFormat))
1161             {
1162                 sourceEffectiveFormat = &GetSizedInternalFormatInfo(effectiveFormat);
1163             }
1164             else
1165             {
1166                 return false;
1167             }
1168         }
1169         else if (framebufferFormatInfo.colorEncoding == GL_SRGB)
1170         {
1171             // SRGB buffers can only be copied to sized format destinations according to table 3.18
1172             if (textureFormatInfo.sized &&
1173                 (framebufferFormatInfo.redBits >= 1 && framebufferFormatInfo.redBits <= 8) &&
1174                 (framebufferFormatInfo.greenBits >= 1 && framebufferFormatInfo.greenBits <= 8) &&
1175                 (framebufferFormatInfo.blueBits >= 1 && framebufferFormatInfo.blueBits <= 8) &&
1176                 (framebufferFormatInfo.alphaBits >= 1 && framebufferFormatInfo.alphaBits <= 8))
1177             {
1178                 sourceEffectiveFormat = &GetSizedInternalFormatInfo(GL_SRGB8_ALPHA8);
1179             }
1180             else
1181             {
1182                 return false;
1183             }
1184         }
1185         else
1186         {
1187             UNREACHABLE();
1188             return false;
1189         }
1190     }
1191 
1192     if (textureFormatInfo.sized)
1193     {
1194         // Section 3.8.5 of the GLES 3.0.3 spec, pg 139, requires that, if the destination format is
1195         // sized, component sizes of the source and destination formats must exactly match if the
1196         // destination format exists.
1197         if (!EqualOrFirstZero(textureFormatInfo.redBits, sourceEffectiveFormat->redBits) ||
1198             !EqualOrFirstZero(textureFormatInfo.greenBits, sourceEffectiveFormat->greenBits) ||
1199             !EqualOrFirstZero(textureFormatInfo.blueBits, sourceEffectiveFormat->blueBits) ||
1200             !EqualOrFirstZero(textureFormatInfo.alphaBits, sourceEffectiveFormat->alphaBits))
1201         {
1202             return false;
1203         }
1204     }
1205 
1206     return true;  // A conversion function exists, and no rule in the specification has precluded
1207                   // conversion between these formats.
1208 }
1209 
ValidateES3CopyTexImageParametersBase(const Context * context,angle::EntryPoint entryPoint,TextureTarget target,GLint level,GLenum internalformat,bool isSubImage,GLint xoffset,GLint yoffset,GLint zoffset,GLint x,GLint y,GLsizei width,GLsizei height,GLint border)1210 bool ValidateES3CopyTexImageParametersBase(const Context *context,
1211                                            angle::EntryPoint entryPoint,
1212                                            TextureTarget target,
1213                                            GLint level,
1214                                            GLenum internalformat,
1215                                            bool isSubImage,
1216                                            GLint xoffset,
1217                                            GLint yoffset,
1218                                            GLint zoffset,
1219                                            GLint x,
1220                                            GLint y,
1221                                            GLsizei width,
1222                                            GLsizei height,
1223                                            GLint border)
1224 {
1225     Format textureFormat = Format::Invalid();
1226     if (!ValidateCopyTexImageParametersBase(context, entryPoint, target, level, internalformat,
1227                                             isSubImage, xoffset, yoffset, zoffset, x, y, width,
1228                                             height, border, &textureFormat))
1229     {
1230         return false;
1231     }
1232     ASSERT(textureFormat.valid() || !isSubImage);
1233 
1234     const auto &state               = context->getState();
1235     Framebuffer *framebuffer        = state.getReadFramebuffer();
1236     FramebufferID readFramebufferID = framebuffer->id();
1237 
1238     if (!ValidateFramebufferComplete(context, entryPoint, framebuffer))
1239     {
1240         return false;
1241     }
1242 
1243     // needIntrinsic = true. Treat renderToTexture textures as single sample since they will be
1244     // resolved before copying
1245     if (!framebuffer->isDefault() &&
1246         !ValidateFramebufferNotMultisampled(context, entryPoint, framebuffer, true))
1247     {
1248         return false;
1249     }
1250 
1251     const FramebufferAttachment *source = framebuffer->getReadColorAttachment();
1252 
1253     // According to ES 3.x spec, if the internalformat of the texture
1254     // is RGB9_E5 and copy to such a texture, generate INVALID_OPERATION.
1255     if (textureFormat.info->internalFormat == GL_RGB9_E5)
1256     {
1257         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidFormat);
1258         return false;
1259     }
1260 
1261     if (isSubImage)
1262     {
1263         if (!IsValidES3CopyTexImageCombination(*textureFormat.info, *source->getFormat().info,
1264                                                readFramebufferID))
1265         {
1266             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidCopyCombination);
1267             return false;
1268         }
1269     }
1270     else
1271     {
1272         // Use format/type from the source FBO. (Might not be perfect for all cases?)
1273         const InternalFormat &framebufferFormat = *source->getFormat().info;
1274         const InternalFormat &copyFormat = GetInternalFormatInfo(internalformat, GL_UNSIGNED_BYTE);
1275         if (!IsValidES3CopyTexImageCombination(copyFormat, framebufferFormat, readFramebufferID))
1276         {
1277             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidCopyCombination);
1278             return false;
1279         }
1280     }
1281 
1282     // If width or height is zero, it is a no-op.  Return false without setting an error.
1283     return (width > 0 && height > 0);
1284 }
1285 
ValidateES3CopyTexImage2DParameters(const Context * context,angle::EntryPoint entryPoint,TextureTarget target,GLint level,GLenum internalformat,bool isSubImage,GLint xoffset,GLint yoffset,GLint zoffset,GLint x,GLint y,GLsizei width,GLsizei height,GLint border)1286 bool ValidateES3CopyTexImage2DParameters(const Context *context,
1287                                          angle::EntryPoint entryPoint,
1288                                          TextureTarget target,
1289                                          GLint level,
1290                                          GLenum internalformat,
1291                                          bool isSubImage,
1292                                          GLint xoffset,
1293                                          GLint yoffset,
1294                                          GLint zoffset,
1295                                          GLint x,
1296                                          GLint y,
1297                                          GLsizei width,
1298                                          GLsizei height,
1299                                          GLint border)
1300 {
1301     if (!ValidTexture2DDestinationTarget(context, target))
1302     {
1303         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidTextureTarget);
1304         return false;
1305     }
1306 
1307     return ValidateES3CopyTexImageParametersBase(context, entryPoint, target, level, internalformat,
1308                                                  isSubImage, xoffset, yoffset, zoffset, x, y, width,
1309                                                  height, border);
1310 }
1311 
ValidateES3CopyTexImage3DParameters(const Context * context,angle::EntryPoint entryPoint,TextureTarget target,GLint level,GLenum internalformat,bool isSubImage,GLint xoffset,GLint yoffset,GLint zoffset,GLint x,GLint y,GLsizei width,GLsizei height,GLint border)1312 bool ValidateES3CopyTexImage3DParameters(const Context *context,
1313                                          angle::EntryPoint entryPoint,
1314                                          TextureTarget target,
1315                                          GLint level,
1316                                          GLenum internalformat,
1317                                          bool isSubImage,
1318                                          GLint xoffset,
1319                                          GLint yoffset,
1320                                          GLint zoffset,
1321                                          GLint x,
1322                                          GLint y,
1323                                          GLsizei width,
1324                                          GLsizei height,
1325                                          GLint border)
1326 {
1327     if (!ValidTexture3DDestinationTarget(context, target))
1328     {
1329         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidTextureTarget);
1330         return false;
1331     }
1332 
1333     return ValidateES3CopyTexImageParametersBase(context, entryPoint, target, level, internalformat,
1334                                                  isSubImage, xoffset, yoffset, zoffset, x, y, width,
1335                                                  height, border);
1336 }
1337 
ValidateES3TexStorageParametersLevel(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLsizei levels,GLsizei width,GLsizei height,GLsizei depth)1338 bool ValidateES3TexStorageParametersLevel(const Context *context,
1339                                           angle::EntryPoint entryPoint,
1340                                           TextureType target,
1341                                           GLsizei levels,
1342                                           GLsizei width,
1343                                           GLsizei height,
1344                                           GLsizei depth)
1345 {
1346     GLsizei maxDim = std::max(width, height);
1347     if (target != TextureType::_2DArray)
1348     {
1349         maxDim = std::max(maxDim, depth);
1350     }
1351 
1352     if (levels > log2(maxDim) + 1)
1353     {
1354         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidMipLevels);
1355         return false;
1356     }
1357 
1358     return true;
1359 }
1360 
ValidateES3TexStorageParametersExtent(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLsizei levels,GLsizei width,GLsizei height,GLsizei depth)1361 bool ValidateES3TexStorageParametersExtent(const Context *context,
1362                                            angle::EntryPoint entryPoint,
1363                                            TextureType target,
1364                                            GLsizei levels,
1365                                            GLsizei width,
1366                                            GLsizei height,
1367                                            GLsizei depth)
1368 {
1369     const Caps &caps = context->getCaps();
1370 
1371     switch (target)
1372     {
1373         case TextureType::_2D:
1374         {
1375             if (width > caps.max2DTextureSize || height > caps.max2DTextureSize)
1376             {
1377                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kResourceMaxTextureSize);
1378                 return false;
1379             }
1380         }
1381         break;
1382 
1383         case TextureType::Rectangle:
1384         {
1385             if (levels != 1)
1386             {
1387                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidMipLevels);
1388                 return false;
1389             }
1390 
1391             if (width > caps.maxRectangleTextureSize || height > caps.maxRectangleTextureSize)
1392             {
1393                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kResourceMaxTextureSize);
1394                 return false;
1395             }
1396         }
1397         break;
1398 
1399         case TextureType::CubeMap:
1400         {
1401             if (width != height)
1402             {
1403                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kCubemapFacesEqualDimensions);
1404                 return false;
1405             }
1406 
1407             if (width > caps.maxCubeMapTextureSize)
1408             {
1409                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kResourceMaxTextureSize);
1410                 return false;
1411             }
1412         }
1413         break;
1414 
1415         case TextureType::_3D:
1416         {
1417             if (width > caps.max3DTextureSize || height > caps.max3DTextureSize ||
1418                 depth > caps.max3DTextureSize)
1419             {
1420                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kResourceMaxTextureSize);
1421                 return false;
1422             }
1423         }
1424         break;
1425 
1426         case TextureType::_2DArray:
1427         {
1428             if (width > caps.max2DTextureSize || height > caps.max2DTextureSize ||
1429                 depth > caps.maxArrayTextureLayers)
1430             {
1431                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kResourceMaxTextureSize);
1432                 return false;
1433             }
1434         }
1435         break;
1436 
1437         case TextureType::CubeMapArray:
1438         {
1439             if (width != height)
1440             {
1441                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kCubemapFacesEqualDimensions);
1442                 return false;
1443             }
1444 
1445             if (width > caps.maxCubeMapTextureSize)
1446             {
1447                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kResourceMaxTextureSize);
1448                 return false;
1449             }
1450 
1451             if (width > caps.max3DTextureSize || height > caps.max3DTextureSize ||
1452                 depth > caps.max3DTextureSize)
1453             {
1454                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kResourceMaxTextureSize);
1455                 return false;
1456             }
1457 
1458             if (depth % 6 != 0)
1459             {
1460                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kCubemapInvalidDepth);
1461                 return false;
1462             }
1463         }
1464         break;
1465 
1466         default:
1467             UNREACHABLE();
1468             return false;
1469     }
1470 
1471     return true;
1472 }
1473 
ValidateES3TexStorageParametersTexObject(const Context * context,angle::EntryPoint entryPoint,TextureType target)1474 bool ValidateES3TexStorageParametersTexObject(const Context *context,
1475                                               angle::EntryPoint entryPoint,
1476                                               TextureType target)
1477 {
1478     Texture *texture = context->getTextureByType(target);
1479     if (!texture || texture->id().value == 0)
1480     {
1481         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kMissingTexture);
1482         return false;
1483     }
1484 
1485     if (texture->getImmutableFormat())
1486     {
1487         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kTextureIsImmutable);
1488         return false;
1489     }
1490 
1491     return true;
1492 }
1493 
ValidateES3TexStorageParametersFormat(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLsizei levels,GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth)1494 bool ValidateES3TexStorageParametersFormat(const Context *context,
1495                                            angle::EntryPoint entryPoint,
1496                                            TextureType target,
1497                                            GLsizei levels,
1498                                            GLenum internalformat,
1499                                            GLsizei width,
1500                                            GLsizei height,
1501                                            GLsizei depth)
1502 {
1503     // From ANGLE_texture_external_yuv_sampling:
1504     // Texture target can only be TEXTURE_2D, there is no mipmap support
1505     if (gl::IsYuvFormat(internalformat))
1506     {
1507         if (!context->getExtensions().yuvInternalFormatANGLE)
1508         {
1509             ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kInvalidInternalFormat, internalformat);
1510             return false;
1511         }
1512 
1513         if (target != TextureType::_2D)
1514         {
1515             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidTextureTarget);
1516             return false;
1517         }
1518 
1519         if (levels != 1)
1520         {
1521             ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidMipLevel);
1522             return false;
1523         }
1524     }
1525 
1526     const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalformat);
1527     if (!formatInfo.textureSupport(context->getClientVersion(), context->getExtensions()))
1528     {
1529         ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kInvalidInternalFormat, internalformat);
1530         return false;
1531     }
1532 
1533     if (!formatInfo.sized)
1534     {
1535         ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kInvalidInternalFormat, internalformat);
1536         return false;
1537     }
1538 
1539     if (formatInfo.compressed)
1540     {
1541         if (target == TextureType::Rectangle)
1542         {
1543             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kRectangleTextureCompressed);
1544             return false;
1545         }
1546 
1547         if (target == TextureType::_2DArray)
1548         {
1549             if (!ValidateES3CompressedFormatForTexture2DArray(context, entryPoint,
1550                                                               formatInfo.internalFormat))
1551             {
1552                 // Error already generated.
1553                 return false;
1554             }
1555         }
1556 
1557         if (target == TextureType::_3D)
1558         {
1559             if (!ValidateES3CompressedFormatForTexture3D(context, entryPoint,
1560                                                          formatInfo.internalFormat))
1561             {
1562                 // Error already generated.
1563                 return false;
1564             }
1565         }
1566 
1567         if (!ValidCompressedImageSize(context, formatInfo.internalFormat, 0, width, height, depth))
1568         {
1569             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidCompressedImageSize);
1570             return false;
1571         }
1572     }
1573 
1574     // From the ES 3.0 spec section 3.8.3:
1575     // Textures with a base internal format of DEPTH_COMPONENT or DEPTH_STENCIL are supported by
1576     // texture image specification commands only if target is TEXTURE_2D, TEXTURE_2D_ARRAY, or
1577     // TEXTURE_CUBE_MAP.Using these formats in conjunction with any other target will result in an
1578     // INVALID_OPERATION error.
1579     //
1580     // Similar language exists in OES_texture_stencil8.
1581     if (target == TextureType::_3D && formatInfo.isDepthOrStencil())
1582     {
1583         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, k3DDepthStencil);
1584         return false;
1585     }
1586 
1587     return true;
1588 }
1589 
ValidateES3TexStorageParametersBase(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLsizei levels,GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth)1590 bool ValidateES3TexStorageParametersBase(const Context *context,
1591                                          angle::EntryPoint entryPoint,
1592                                          TextureType target,
1593                                          GLsizei levels,
1594                                          GLenum internalformat,
1595                                          GLsizei width,
1596                                          GLsizei height,
1597                                          GLsizei depth)
1598 {
1599     if (width < 1 || height < 1 || depth < 1 || levels < 1)
1600     {
1601         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kTextureSizeTooSmall);
1602         return false;
1603     }
1604 
1605     if (!ValidateES3TexStorageParametersLevel(context, entryPoint, target, levels, width, height,
1606                                               depth))
1607     {
1608         // Error already generated.
1609         return false;
1610     }
1611 
1612     if (!ValidateES3TexStorageParametersExtent(context, entryPoint, target, levels, width, height,
1613                                                depth))
1614     {
1615         // Error already generated.
1616         return false;
1617     }
1618 
1619     if (!ValidateES3TexStorageParametersTexObject(context, entryPoint, target))
1620     {
1621         // Error already generated.
1622         return false;
1623     }
1624 
1625     if (!ValidateES3TexStorageParametersFormat(context, entryPoint, target, levels, internalformat,
1626                                                width, height, depth))
1627     {
1628         // Error already generated.
1629         return false;
1630     }
1631 
1632     return true;
1633 }
1634 
ValidateES3TexStorage2DParameters(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLsizei levels,GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth)1635 bool ValidateES3TexStorage2DParameters(const Context *context,
1636                                        angle::EntryPoint entryPoint,
1637                                        TextureType target,
1638                                        GLsizei levels,
1639                                        GLenum internalformat,
1640                                        GLsizei width,
1641                                        GLsizei height,
1642                                        GLsizei depth)
1643 {
1644     if (!ValidTexture2DTarget(context, target))
1645     {
1646         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidTextureTarget);
1647         return false;
1648     }
1649 
1650     return ValidateES3TexStorageParametersBase(context, entryPoint, target, levels, internalformat,
1651                                                width, height, depth);
1652 }
1653 
ValidateES3TexStorage3DParameters(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLsizei levels,GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth)1654 bool ValidateES3TexStorage3DParameters(const Context *context,
1655                                        angle::EntryPoint entryPoint,
1656                                        TextureType target,
1657                                        GLsizei levels,
1658                                        GLenum internalformat,
1659                                        GLsizei width,
1660                                        GLsizei height,
1661                                        GLsizei depth)
1662 {
1663     if (!ValidTexture3DTarget(context, target))
1664     {
1665         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidTextureTarget);
1666         return false;
1667     }
1668 
1669     return ValidateES3TexStorageParametersBase(context, entryPoint, target, levels, internalformat,
1670                                                width, height, depth);
1671 }
1672 
ValidateBeginQuery(const Context * context,angle::EntryPoint entryPoint,QueryType target,QueryID id)1673 bool ValidateBeginQuery(const Context *context,
1674                         angle::EntryPoint entryPoint,
1675                         QueryType target,
1676                         QueryID id)
1677 {
1678     if (context->getClientMajorVersion() < 3)
1679     {
1680         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
1681         return false;
1682     }
1683 
1684     return ValidateBeginQueryBase(context, entryPoint, target, id);
1685 }
1686 
ValidateEndQuery(const Context * context,angle::EntryPoint entryPoint,QueryType target)1687 bool ValidateEndQuery(const Context *context, angle::EntryPoint entryPoint, QueryType target)
1688 {
1689     if (context->getClientMajorVersion() < 3)
1690     {
1691         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
1692         return false;
1693     }
1694 
1695     return ValidateEndQueryBase(context, entryPoint, target);
1696 }
1697 
ValidateGetQueryiv(const Context * context,angle::EntryPoint entryPoint,QueryType target,GLenum pname,const GLint * params)1698 bool ValidateGetQueryiv(const Context *context,
1699                         angle::EntryPoint entryPoint,
1700                         QueryType target,
1701                         GLenum pname,
1702                         const GLint *params)
1703 {
1704     if (context->getClientMajorVersion() < 3)
1705     {
1706         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
1707         return false;
1708     }
1709 
1710     return ValidateGetQueryivBase(context, entryPoint, target, pname, nullptr);
1711 }
1712 
ValidateGetQueryObjectuiv(const Context * context,angle::EntryPoint entryPoint,QueryID id,GLenum pname,const GLuint * params)1713 bool ValidateGetQueryObjectuiv(const Context *context,
1714                                angle::EntryPoint entryPoint,
1715                                QueryID id,
1716                                GLenum pname,
1717                                const GLuint *params)
1718 {
1719     if (context->getClientMajorVersion() < 3)
1720     {
1721         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
1722         return false;
1723     }
1724 
1725     return ValidateGetQueryObjectValueBase(context, entryPoint, id, pname, nullptr);
1726 }
1727 
ValidateFramebufferTextureLayer(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLenum attachment,TextureID texture,GLint level,GLint layer)1728 bool ValidateFramebufferTextureLayer(const Context *context,
1729                                      angle::EntryPoint entryPoint,
1730                                      GLenum target,
1731                                      GLenum attachment,
1732                                      TextureID texture,
1733                                      GLint level,
1734                                      GLint layer)
1735 {
1736     if (context->getClientMajorVersion() < 3)
1737     {
1738         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
1739         return false;
1740     }
1741 
1742     if (!ValidateFramebufferTextureBase(context, entryPoint, target, attachment, texture, level))
1743     {
1744         return false;
1745     }
1746 
1747     const Caps &caps = context->getCaps();
1748     if (texture.value != 0)
1749     {
1750         if (layer < 0)
1751         {
1752             ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeLayer);
1753             return false;
1754         }
1755 
1756         Texture *tex = context->getTexture(texture);
1757         ASSERT(tex);
1758 
1759         switch (tex->getType())
1760         {
1761             case TextureType::_2DArray:
1762             {
1763                 if (level > log2(caps.max2DTextureSize))
1764                 {
1765                     ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kFramebufferTextureInvalidMipLevel);
1766                     return false;
1767                 }
1768 
1769                 if (layer >= caps.maxArrayTextureLayers)
1770                 {
1771                     ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kFramebufferTextureInvalidLayer);
1772                     return false;
1773                 }
1774             }
1775             break;
1776 
1777             case TextureType::_3D:
1778             {
1779                 if (level > log2(caps.max3DTextureSize))
1780                 {
1781                     ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kFramebufferTextureInvalidMipLevel);
1782                     return false;
1783                 }
1784 
1785                 if (layer >= caps.max3DTextureSize)
1786                 {
1787                     ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kFramebufferTextureInvalidLayer);
1788                     return false;
1789                 }
1790             }
1791             break;
1792 
1793             case TextureType::_2DMultisampleArray:
1794             {
1795                 if (level != 0)
1796                 {
1797                     ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kFramebufferTextureInvalidMipLevel);
1798                     return false;
1799                 }
1800 
1801                 if (layer >= caps.maxArrayTextureLayers)
1802                 {
1803                     ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kFramebufferTextureInvalidLayer);
1804                     return false;
1805                 }
1806             }
1807             break;
1808 
1809             case TextureType::CubeMap:
1810             {
1811                 if (level > log2(caps.maxCubeMapTextureSize))
1812                 {
1813                     ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kFramebufferTextureInvalidMipLevel);
1814                     return false;
1815                 }
1816 
1817                 if (layer >= static_cast<GLint>(kCubeFaceCount))
1818                 {
1819                     ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kFramebufferTextureInvalidLayer);
1820                     return false;
1821                 }
1822             }
1823             break;
1824 
1825             case TextureType::CubeMapArray:
1826             {
1827                 if (level > log2(caps.maxCubeMapTextureSize))
1828                 {
1829                     ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kFramebufferTextureInvalidMipLevel);
1830                     return false;
1831                 }
1832 
1833                 if (layer >= caps.maxArrayTextureLayers)
1834                 {
1835                     ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kFramebufferTextureInvalidLayer);
1836                     return false;
1837                 }
1838             }
1839             break;
1840 
1841             default:
1842                 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION,
1843                                        kFramebufferTextureLayerIncorrectTextureType);
1844                 return false;
1845         }
1846 
1847         const auto &format = tex->getFormat(TextureTypeToTarget(tex->getType(), layer), level);
1848         if (format.info->compressed)
1849         {
1850             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kCompressedTexturesNotAttachable);
1851             return false;
1852         }
1853     }
1854 
1855     return true;
1856 }
1857 
ValidateInvalidateFramebuffer(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLsizei numAttachments,const GLenum * attachments)1858 bool ValidateInvalidateFramebuffer(const Context *context,
1859                                    angle::EntryPoint entryPoint,
1860                                    GLenum target,
1861                                    GLsizei numAttachments,
1862                                    const GLenum *attachments)
1863 {
1864     if (context->getClientMajorVersion() < 3)
1865     {
1866         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
1867         return false;
1868     }
1869 
1870     bool defaultFramebuffer = false;
1871 
1872     switch (target)
1873     {
1874         case GL_DRAW_FRAMEBUFFER:
1875         case GL_FRAMEBUFFER:
1876             defaultFramebuffer = context->getState().getDrawFramebuffer()->isDefault();
1877             break;
1878         case GL_READ_FRAMEBUFFER:
1879             defaultFramebuffer = context->getState().getReadFramebuffer()->isDefault();
1880             break;
1881         default:
1882             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidFramebufferTarget);
1883             return false;
1884     }
1885 
1886     return ValidateDiscardFramebufferBase(context, entryPoint, target, numAttachments, attachments,
1887                                           defaultFramebuffer);
1888 }
1889 
ValidateInvalidateSubFramebuffer(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLsizei numAttachments,const GLenum * attachments,GLint x,GLint y,GLsizei width,GLsizei height)1890 bool ValidateInvalidateSubFramebuffer(const Context *context,
1891                                       angle::EntryPoint entryPoint,
1892                                       GLenum target,
1893                                       GLsizei numAttachments,
1894                                       const GLenum *attachments,
1895                                       GLint x,
1896                                       GLint y,
1897                                       GLsizei width,
1898                                       GLsizei height)
1899 {
1900     if (width < 0 || height < 0)
1901     {
1902         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeSize);
1903         return false;
1904     }
1905 
1906     return ValidateInvalidateFramebuffer(context, entryPoint, target, numAttachments, attachments);
1907 }
1908 
ValidateClearBuffer(const Context * context,angle::EntryPoint entryPoint)1909 bool ValidateClearBuffer(const Context *context, angle::EntryPoint entryPoint)
1910 {
1911     if (context->getClientMajorVersion() < 3)
1912     {
1913         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
1914         return false;
1915     }
1916 
1917     Framebuffer *drawFramebuffer = context->getState().getDrawFramebuffer();
1918     if (!ValidateFramebufferComplete(context, entryPoint, drawFramebuffer))
1919     {
1920         return false;
1921     }
1922 
1923     // The QCOM_framebuffer_foveated spec:
1924     if (drawFramebuffer->isFoveationEnabled())
1925     {
1926         // INVALID_OPERATION is generated by any API call which causes a framebuffer
1927         // attachment to be written to if the framebuffer attachments have changed for
1928         // a foveated fbo.
1929         if (drawFramebuffer->hasAnyAttachmentChanged())
1930         {
1931             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kFramebufferFoveationAttachmentChanged);
1932             return false;
1933         }
1934     }
1935 
1936     return true;
1937 }
1938 
ValidateDrawRangeElements(const Context * context,angle::EntryPoint entryPoint,PrimitiveMode mode,GLuint start,GLuint end,GLsizei count,DrawElementsType type,const void * indices)1939 bool ValidateDrawRangeElements(const Context *context,
1940                                angle::EntryPoint entryPoint,
1941                                PrimitiveMode mode,
1942                                GLuint start,
1943                                GLuint end,
1944                                GLsizei count,
1945                                DrawElementsType type,
1946                                const void *indices)
1947 {
1948     if (context->getClientMajorVersion() < 3)
1949     {
1950         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
1951         return false;
1952     }
1953 
1954     if (end < start)
1955     {
1956         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidElementRange);
1957         return false;
1958     }
1959 
1960     if (!ValidateDrawElementsCommon(context, entryPoint, mode, count, type, indices, 1))
1961     {
1962         return false;
1963     }
1964 
1965     // Skip range checks for no-op calls.
1966     if (count <= 0)
1967     {
1968         return true;
1969     }
1970 
1971     return true;
1972 }
1973 
ValidateGetUniformuiv(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,UniformLocation location,const GLuint * params)1974 bool ValidateGetUniformuiv(const Context *context,
1975                            angle::EntryPoint entryPoint,
1976                            ShaderProgramID program,
1977                            UniformLocation location,
1978                            const GLuint *params)
1979 {
1980     if (context->getClientMajorVersion() < 3)
1981     {
1982         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
1983         return false;
1984     }
1985 
1986     return ValidateGetUniformBase(context, entryPoint, program, location);
1987 }
1988 
ValidateReadBuffer(const Context * context,angle::EntryPoint entryPoint,GLenum src)1989 bool ValidateReadBuffer(const Context *context, angle::EntryPoint entryPoint, GLenum src)
1990 {
1991     if (context->getClientMajorVersion() < 3)
1992     {
1993         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
1994         return false;
1995     }
1996 
1997     const Framebuffer *readFBO = context->getState().getReadFramebuffer();
1998 
1999     if (readFBO == nullptr)
2000     {
2001         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kNoReadFramebuffer);
2002         return false;
2003     }
2004 
2005     if (src == GL_NONE)
2006     {
2007         return true;
2008     }
2009 
2010     if (src != GL_BACK && (src < GL_COLOR_ATTACHMENT0 || src > GL_COLOR_ATTACHMENT31))
2011     {
2012         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidReadBuffer);
2013         return false;
2014     }
2015 
2016     if (readFBO->isDefault())
2017     {
2018         if (src != GL_BACK)
2019         {
2020             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidDefaultReadBuffer);
2021             return false;
2022         }
2023     }
2024     else
2025     {
2026         GLuint drawBuffer = static_cast<GLuint>(src - GL_COLOR_ATTACHMENT0);
2027 
2028         if (drawBuffer >= static_cast<GLuint>(context->getCaps().maxColorAttachments))
2029         {
2030             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExceedsMaxColorAttachments);
2031             return false;
2032         }
2033     }
2034 
2035     return true;
2036 }
2037 
ValidateCompressedTexImage3D(const Context * context,angle::EntryPoint entryPoint,TextureTarget target,GLint level,GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth,GLint border,GLsizei imageSize,const void * data)2038 bool ValidateCompressedTexImage3D(const Context *context,
2039                                   angle::EntryPoint entryPoint,
2040                                   TextureTarget target,
2041                                   GLint level,
2042                                   GLenum internalformat,
2043                                   GLsizei width,
2044                                   GLsizei height,
2045                                   GLsizei depth,
2046                                   GLint border,
2047                                   GLsizei imageSize,
2048                                   const void *data)
2049 {
2050     if ((context->getClientMajorVersion() < 3) && !context->getExtensions().texture3DOES)
2051     {
2052         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
2053         return false;
2054     }
2055 
2056     if (!ValidTextureTarget(context, TextureTargetToType(target)))
2057     {
2058         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidTextureTarget);
2059         return false;
2060     }
2061 
2062     // Validate image size
2063     if (!ValidImageSizeParameters(context, entryPoint, TextureTargetToType(target), level, width,
2064                                   height, depth, false))
2065     {
2066         // Error already generated.
2067         return false;
2068     }
2069 
2070     const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalformat);
2071     if (!formatInfo.compressed)
2072     {
2073         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidCompressedFormat);
2074         return false;
2075     }
2076 
2077     GLuint blockSize = 0;
2078     if (!formatInfo.computeCompressedImageSize(Extents(width, height, depth), &blockSize))
2079     {
2080         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kIntegerOverflow);
2081         return false;
2082     }
2083 
2084     if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSize)
2085     {
2086         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidCompressedImageSize);
2087         return false;
2088     }
2089 
2090     // 3D texture target validation
2091     if (target != TextureTarget::_3D && target != TextureTarget::_2DArray)
2092     {
2093         if (context->getClientVersion() < ES_3_2 || target != TextureTarget::CubeMapArray)
2094         {
2095             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidTextureTarget);
2096             return false;
2097         }
2098     }
2099 
2100     // validateES3TexImageFormat sets the error code if there is an error
2101     if (!ValidateES3TexImage3DParameters(context, entryPoint, target, level, internalformat, true,
2102                                          false, 0, 0, 0, width, height, depth, border, GL_NONE,
2103                                          GL_NONE, -1, data))
2104     {
2105         return false;
2106     }
2107 
2108     return true;
2109 }
2110 
ValidateCompressedTexImage3DRobustANGLE(const Context * context,angle::EntryPoint entryPoint,TextureTarget target,GLint level,GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth,GLint border,GLsizei imageSize,GLsizei dataSize,const void * data)2111 bool ValidateCompressedTexImage3DRobustANGLE(const Context *context,
2112                                              angle::EntryPoint entryPoint,
2113                                              TextureTarget target,
2114                                              GLint level,
2115                                              GLenum internalformat,
2116                                              GLsizei width,
2117                                              GLsizei height,
2118                                              GLsizei depth,
2119                                              GLint border,
2120                                              GLsizei imageSize,
2121                                              GLsizei dataSize,
2122                                              const void *data)
2123 {
2124     if (!ValidateRobustCompressedTexImageBase(context, entryPoint, imageSize, dataSize))
2125     {
2126         return false;
2127     }
2128 
2129     return ValidateCompressedTexImage3D(context, entryPoint, target, level, internalformat, width,
2130                                         height, depth, border, imageSize, data);
2131 }
2132 
ValidateBindVertexArray(const Context * context,angle::EntryPoint entryPoint,VertexArrayID array)2133 bool ValidateBindVertexArray(const Context *context,
2134                              angle::EntryPoint entryPoint,
2135                              VertexArrayID array)
2136 {
2137     if (context->getClientMajorVersion() < 3)
2138     {
2139         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
2140         return false;
2141     }
2142 
2143     return ValidateBindVertexArrayBase(context, entryPoint, array);
2144 }
2145 
ValidateIsVertexArray(const Context * context,angle::EntryPoint entryPoint,VertexArrayID array)2146 bool ValidateIsVertexArray(const Context *context,
2147                            angle::EntryPoint entryPoint,
2148                            VertexArrayID array)
2149 {
2150     if (context->getClientMajorVersion() < 3)
2151     {
2152         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
2153         return false;
2154     }
2155 
2156     return true;
2157 }
2158 
ValidateBindBufferCommon(const Context * context,angle::EntryPoint entryPoint,BufferBinding target,GLuint index,BufferID buffer,GLintptr offset,GLsizeiptr size)2159 static bool ValidateBindBufferCommon(const Context *context,
2160                                      angle::EntryPoint entryPoint,
2161                                      BufferBinding target,
2162                                      GLuint index,
2163                                      BufferID buffer,
2164                                      GLintptr offset,
2165                                      GLsizeiptr size)
2166 {
2167     if (context->getClientMajorVersion() < 3)
2168     {
2169         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
2170         return false;
2171     }
2172 
2173     if (buffer.value != 0 && offset < 0)
2174     {
2175         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeOffset);
2176         return false;
2177     }
2178 
2179     if (!context->getState().isBindGeneratesResourceEnabled() &&
2180         !context->isBufferGenerated(buffer))
2181     {
2182         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kObjectNotGenerated);
2183         return false;
2184     }
2185 
2186     const Caps &caps = context->getCaps();
2187     switch (target)
2188     {
2189         case BufferBinding::TransformFeedback:
2190         {
2191             if (index >= static_cast<GLuint>(caps.maxTransformFeedbackSeparateAttributes))
2192             {
2193                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE,
2194                                        kIndexExceedsTransformFeedbackBufferBindings);
2195                 return false;
2196             }
2197             if (buffer.value != 0 && ((offset % 4) != 0 || (size % 4) != 0))
2198             {
2199                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kOffsetAndSizeAlignment);
2200                 return false;
2201             }
2202 
2203             if (context->getState().isTransformFeedbackActive())
2204             {
2205                 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kTransformFeedbackTargetActive);
2206                 return false;
2207             }
2208             break;
2209         }
2210         case BufferBinding::Uniform:
2211         {
2212             if (index >= static_cast<GLuint>(caps.maxUniformBufferBindings))
2213             {
2214                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kIndexExceedsMaxUniformBufferBindings);
2215                 return false;
2216             }
2217 
2218             ASSERT(caps.uniformBufferOffsetAlignment);
2219             if (buffer.value != 0 && (offset % caps.uniformBufferOffsetAlignment) != 0)
2220             {
2221                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kUniformBufferOffsetAlignment);
2222                 return false;
2223             }
2224             break;
2225         }
2226         case BufferBinding::AtomicCounter:
2227         {
2228             if (context->getClientVersion() < ES_3_1)
2229             {
2230                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kEnumRequiresGLES31);
2231                 return false;
2232             }
2233             if (index >= static_cast<GLuint>(caps.maxAtomicCounterBufferBindings))
2234             {
2235                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE,
2236                                        kIndexExceedsMaxAtomicCounterBufferBindings);
2237                 return false;
2238             }
2239             if (buffer.value != 0 && (offset % 4) != 0)
2240             {
2241                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kOffsetAlignment);
2242                 return false;
2243             }
2244             break;
2245         }
2246         case BufferBinding::ShaderStorage:
2247         {
2248             if (context->getClientVersion() < ES_3_1)
2249             {
2250                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kEnumRequiresGLES31);
2251                 return false;
2252             }
2253             if (index >= static_cast<GLuint>(caps.maxShaderStorageBufferBindings))
2254             {
2255                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kExceedsMaxShaderStorageBufferBindings);
2256                 return false;
2257             }
2258             ASSERT(caps.shaderStorageBufferOffsetAlignment);
2259             if (buffer.value != 0 && (offset % caps.shaderStorageBufferOffsetAlignment) != 0)
2260             {
2261                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kShaderStorageBufferOffsetAlignment);
2262                 return false;
2263             }
2264             break;
2265         }
2266         case BufferBinding::Texture:
2267         {
2268             if (!context->getExtensions().textureBufferAny())
2269             {
2270                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kTextureBufferExtensionNotAvailable);
2271                 return false;
2272             }
2273             if (index != 0)
2274             {
2275                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kIndexExceedsMaxUniformBufferBindings);
2276                 return false;
2277             }
2278             if (buffer.value != 0 && (offset % caps.textureBufferOffsetAlignment) != 0)
2279             {
2280                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kTextureBufferOffsetAlignment);
2281                 return false;
2282             }
2283             break;
2284         }
2285         case BufferBinding::InvalidEnum:
2286             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kEnumInvalid);
2287             return false;
2288         default:
2289             ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, ToGLenum(target));
2290             return false;
2291     }
2292 
2293     return true;
2294 }
2295 
ValidateBindBufferBase(const Context * context,angle::EntryPoint entryPoint,BufferBinding target,GLuint index,BufferID buffer)2296 bool ValidateBindBufferBase(const Context *context,
2297                             angle::EntryPoint entryPoint,
2298                             BufferBinding target,
2299                             GLuint index,
2300                             BufferID buffer)
2301 {
2302     return ValidateBindBufferCommon(context, entryPoint, target, index, buffer, 0, 0);
2303 }
2304 
ValidateBindBufferRange(const Context * context,angle::EntryPoint entryPoint,BufferBinding target,GLuint index,BufferID buffer,GLintptr offset,GLsizeiptr size)2305 bool ValidateBindBufferRange(const Context *context,
2306                              angle::EntryPoint entryPoint,
2307                              BufferBinding target,
2308                              GLuint index,
2309                              BufferID buffer,
2310                              GLintptr offset,
2311                              GLsizeiptr size)
2312 {
2313     if (buffer.value != 0 && size <= 0)
2314     {
2315         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidBindBufferSize);
2316         return false;
2317     }
2318     return ValidateBindBufferCommon(context, entryPoint, target, index, buffer, offset, size);
2319 }
2320 
ValidateProgramBinary(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,GLenum binaryFormat,const void * binary,GLsizei length)2321 bool ValidateProgramBinary(const Context *context,
2322                            angle::EntryPoint entryPoint,
2323                            ShaderProgramID program,
2324                            GLenum binaryFormat,
2325                            const void *binary,
2326                            GLsizei length)
2327 {
2328     if (context->getClientMajorVersion() < 3)
2329     {
2330         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
2331         return false;
2332     }
2333 
2334     return ValidateProgramBinaryBase(context, entryPoint, program, binaryFormat, binary, length);
2335 }
2336 
ValidateGetProgramBinary(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,GLsizei bufSize,const GLsizei * length,const GLenum * binaryFormat,const void * binary)2337 bool ValidateGetProgramBinary(const Context *context,
2338                               angle::EntryPoint entryPoint,
2339                               ShaderProgramID program,
2340                               GLsizei bufSize,
2341                               const GLsizei *length,
2342                               const GLenum *binaryFormat,
2343                               const void *binary)
2344 {
2345     if (context->getClientMajorVersion() < 3)
2346     {
2347         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
2348         return false;
2349     }
2350 
2351     return ValidateGetProgramBinaryBase(context, entryPoint, program, bufSize, length, binaryFormat,
2352                                         binary);
2353 }
2354 
ValidateProgramParameteriBase(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,GLenum pname,GLint value)2355 bool ValidateProgramParameteriBase(const Context *context,
2356                                    angle::EntryPoint entryPoint,
2357                                    ShaderProgramID program,
2358                                    GLenum pname,
2359                                    GLint value)
2360 {
2361     if (GetValidProgram(context, entryPoint, program) == nullptr)
2362     {
2363         return false;
2364     }
2365 
2366     switch (pname)
2367     {
2368         case GL_PROGRAM_BINARY_RETRIEVABLE_HINT:
2369             if (value != GL_FALSE && value != GL_TRUE)
2370             {
2371                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidBooleanValue);
2372                 return false;
2373             }
2374             break;
2375 
2376         case GL_PROGRAM_SEPARABLE:
2377             if (context->getClientVersion() < ES_3_1)
2378             {
2379                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kES31Required);
2380                 return false;
2381             }
2382 
2383             if (value != GL_FALSE && value != GL_TRUE)
2384             {
2385                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidBooleanValue);
2386                 return false;
2387             }
2388             break;
2389 
2390         default:
2391             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidPname);
2392             return false;
2393     }
2394 
2395     return true;
2396 }
2397 
ValidateProgramParameteri(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,GLenum pname,GLint value)2398 bool ValidateProgramParameteri(const Context *context,
2399                                angle::EntryPoint entryPoint,
2400                                ShaderProgramID program,
2401                                GLenum pname,
2402                                GLint value)
2403 {
2404     if (context->getClientMajorVersion() < 3)
2405     {
2406         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
2407         return false;
2408     }
2409 
2410     return ValidateProgramParameteriBase(context, entryPoint, program, pname, value);
2411 }
2412 
ValidateBlitFramebuffer(const Context * context,angle::EntryPoint entryPoint,GLint srcX0,GLint srcY0,GLint srcX1,GLint srcY1,GLint dstX0,GLint dstY0,GLint dstX1,GLint dstY1,GLbitfield mask,GLenum filter)2413 bool ValidateBlitFramebuffer(const Context *context,
2414                              angle::EntryPoint entryPoint,
2415                              GLint srcX0,
2416                              GLint srcY0,
2417                              GLint srcX1,
2418                              GLint srcY1,
2419                              GLint dstX0,
2420                              GLint dstY0,
2421                              GLint dstX1,
2422                              GLint dstY1,
2423                              GLbitfield mask,
2424                              GLenum filter)
2425 {
2426     if (context->getClientMajorVersion() < 3 && !context->getExtensions().framebufferBlitNV)
2427     {
2428         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
2429         return false;
2430     }
2431 
2432     return ValidateBlitFramebufferParameters(context, entryPoint, srcX0, srcY0, srcX1, srcY1, dstX0,
2433                                              dstY0, dstX1, dstY1, mask, filter);
2434 }
2435 
ValidateClearBufferiv(const Context * context,angle::EntryPoint entryPoint,GLenum buffer,GLint drawbuffer,const GLint * value)2436 bool ValidateClearBufferiv(const Context *context,
2437                            angle::EntryPoint entryPoint,
2438                            GLenum buffer,
2439                            GLint drawbuffer,
2440                            const GLint *value)
2441 {
2442     // INVALID_VALUE is generated if the value pointer is NULL
2443     if (value == nullptr)
2444     {
2445         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kPLSParamsNULL);
2446         return false;
2447     }
2448 
2449     switch (buffer)
2450     {
2451         case GL_COLOR:
2452             if (drawbuffer < 0 || drawbuffer >= context->getCaps().maxDrawBuffers)
2453             {
2454                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kIndexExceedsMaxDrawBuffer);
2455                 return false;
2456             }
2457             if (static_cast<size_t>(drawbuffer) >=
2458                 context->getState().getDrawFramebuffer()->getDrawbufferStateCount())
2459             {
2460                 // Clearing a non-existent draw buffer is a no-op.
2461                 break;
2462             }
2463             if (context->getExtensions().webglCompatibilityANGLE)
2464             {
2465                 const gl::ComponentTypeMask mask =
2466                     context->getState().getDrawFramebuffer()->getDrawBufferTypeMask();
2467                 if (IsComponentTypeFloatOrUnsignedInt(mask, drawbuffer))
2468                 {
2469                     ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kNoDefinedClearConversion);
2470                     return false;
2471                 }
2472             }
2473             if (context->getExtensions().renderSharedExponentQCOM)
2474             {
2475                 if (!ValidateColorMaskForSharedExponentColorBuffer(context, entryPoint, drawbuffer))
2476                 {
2477                     return false;
2478                 }
2479             }
2480             break;
2481 
2482         case GL_STENCIL:
2483             if (drawbuffer != 0)
2484             {
2485                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidDepthStencilDrawBuffer);
2486                 return false;
2487             }
2488             break;
2489 
2490         default:
2491             ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, buffer);
2492             return false;
2493     }
2494 
2495     return ValidateClearBuffer(context, entryPoint);
2496 }
2497 
ValidateClearBufferuiv(const Context * context,angle::EntryPoint entryPoint,GLenum buffer,GLint drawbuffer,const GLuint * value)2498 bool ValidateClearBufferuiv(const Context *context,
2499                             angle::EntryPoint entryPoint,
2500                             GLenum buffer,
2501                             GLint drawbuffer,
2502                             const GLuint *value)
2503 {
2504     switch (buffer)
2505     {
2506         case GL_COLOR:
2507             if (drawbuffer < 0 || drawbuffer >= context->getCaps().maxDrawBuffers)
2508             {
2509                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kIndexExceedsMaxDrawBuffer);
2510                 return false;
2511             }
2512             if (static_cast<size_t>(drawbuffer) >=
2513                 context->getState().getDrawFramebuffer()->getDrawbufferStateCount())
2514             {
2515                 // Clearing a non-existent draw buffer is a no-op.
2516                 break;
2517             }
2518             if (context->getExtensions().webglCompatibilityANGLE)
2519             {
2520                 const gl::ComponentTypeMask mask =
2521                     context->getState().getDrawFramebuffer()->getDrawBufferTypeMask();
2522                 if (IsComponentTypeFloatOrInt(mask, drawbuffer))
2523                 {
2524                     ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kNoDefinedClearConversion);
2525                     return false;
2526                 }
2527             }
2528             if (context->getExtensions().renderSharedExponentQCOM)
2529             {
2530                 if (!ValidateColorMaskForSharedExponentColorBuffer(context, entryPoint, drawbuffer))
2531                 {
2532                     return false;
2533                 }
2534             }
2535             break;
2536 
2537         default:
2538             ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, buffer);
2539             return false;
2540     }
2541 
2542     if (value == nullptr)
2543     {
2544         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kPLSParamsNULL);
2545         return false;
2546     }
2547 
2548     return ValidateClearBuffer(context, entryPoint);
2549 }
2550 
ValidateClearBufferfv(const Context * context,angle::EntryPoint entryPoint,GLenum buffer,GLint drawbuffer,const GLfloat * value)2551 bool ValidateClearBufferfv(const Context *context,
2552                            angle::EntryPoint entryPoint,
2553                            GLenum buffer,
2554                            GLint drawbuffer,
2555                            const GLfloat *value)
2556 {
2557     switch (buffer)
2558     {
2559         case GL_COLOR:
2560             if (drawbuffer < 0 || drawbuffer >= context->getCaps().maxDrawBuffers)
2561             {
2562                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kIndexExceedsMaxDrawBuffer);
2563                 return false;
2564             }
2565             if (static_cast<size_t>(drawbuffer) >=
2566                 context->getState().getDrawFramebuffer()->getDrawbufferStateCount())
2567             {
2568                 // Clearing a non-existent draw buffer is a no-op.
2569                 break;
2570             }
2571             if (context->getExtensions().webglCompatibilityANGLE)
2572             {
2573                 const gl::ComponentTypeMask mask =
2574                     context->getState().getDrawFramebuffer()->getDrawBufferTypeMask();
2575                 if (IsComponentTypeIntOrUnsignedInt(mask, drawbuffer))
2576                 {
2577                     ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kNoDefinedClearConversion);
2578                     return false;
2579                 }
2580             }
2581             if (context->getExtensions().renderSharedExponentQCOM)
2582             {
2583                 if (!ValidateColorMaskForSharedExponentColorBuffer(context, entryPoint, drawbuffer))
2584                 {
2585                     return false;
2586                 }
2587             }
2588             break;
2589 
2590         case GL_DEPTH:
2591             if (drawbuffer != 0)
2592             {
2593                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidDepthStencilDrawBuffer);
2594                 return false;
2595             }
2596             break;
2597 
2598         default:
2599             ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, buffer);
2600             return false;
2601     }
2602 
2603     if (value == nullptr)
2604     {
2605         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kPLSParamsNULL);
2606         return false;
2607     }
2608 
2609     return ValidateClearBuffer(context, entryPoint);
2610 }
2611 
ValidateClearBufferfi(const Context * context,angle::EntryPoint entryPoint,GLenum buffer,GLint drawbuffer,GLfloat depth,GLint stencil)2612 bool ValidateClearBufferfi(const Context *context,
2613                            angle::EntryPoint entryPoint,
2614                            GLenum buffer,
2615                            GLint drawbuffer,
2616                            GLfloat depth,
2617                            GLint stencil)
2618 {
2619     switch (buffer)
2620     {
2621         case GL_DEPTH_STENCIL:
2622             if (drawbuffer != 0)
2623             {
2624                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidDepthStencilDrawBuffer);
2625                 return false;
2626             }
2627             break;
2628 
2629         default:
2630             ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, buffer);
2631             return false;
2632     }
2633 
2634     return ValidateClearBuffer(context, entryPoint);
2635 }
2636 
ValidateDrawBuffers(const Context * context,angle::EntryPoint entryPoint,GLsizei n,const GLenum * bufs)2637 bool ValidateDrawBuffers(const Context *context,
2638                          angle::EntryPoint entryPoint,
2639                          GLsizei n,
2640                          const GLenum *bufs)
2641 {
2642     if (context->getClientMajorVersion() < 3)
2643     {
2644         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
2645         return false;
2646     }
2647 
2648     return ValidateDrawBuffersBase(context, entryPoint, n, bufs);
2649 }
2650 
ValidateCopyTexSubImage3D(const Context * context,angle::EntryPoint entryPoint,TextureTarget target,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLint x,GLint y,GLsizei width,GLsizei height)2651 bool ValidateCopyTexSubImage3D(const Context *context,
2652                                angle::EntryPoint entryPoint,
2653                                TextureTarget target,
2654                                GLint level,
2655                                GLint xoffset,
2656                                GLint yoffset,
2657                                GLint zoffset,
2658                                GLint x,
2659                                GLint y,
2660                                GLsizei width,
2661                                GLsizei height)
2662 {
2663     if ((context->getClientMajorVersion() < 3) && !context->getExtensions().texture3DOES)
2664     {
2665         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
2666         return false;
2667     }
2668 
2669     return ValidateES3CopyTexImage3DParameters(context, entryPoint, target, level, GL_NONE, true,
2670                                                xoffset, yoffset, zoffset, x, y, width, height, 0);
2671 }
2672 
ValidateCopyTexture3DANGLE(const Context * context,angle::EntryPoint entryPoint,TextureID sourceId,GLint sourceLevel,TextureTarget destTarget,TextureID destId,GLint destLevel,GLint internalFormat,GLenum destType,GLboolean unpackFlipY,GLboolean unpackPremultiplyAlpha,GLboolean unpackUnmultiplyAlpha)2673 bool ValidateCopyTexture3DANGLE(const Context *context,
2674                                 angle::EntryPoint entryPoint,
2675                                 TextureID sourceId,
2676                                 GLint sourceLevel,
2677                                 TextureTarget destTarget,
2678                                 TextureID destId,
2679                                 GLint destLevel,
2680                                 GLint internalFormat,
2681                                 GLenum destType,
2682                                 GLboolean unpackFlipY,
2683                                 GLboolean unpackPremultiplyAlpha,
2684                                 GLboolean unpackUnmultiplyAlpha)
2685 {
2686     const Texture *source = context->getTexture(sourceId);
2687     if (source == nullptr)
2688     {
2689         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidSourceTexture);
2690         return false;
2691     }
2692 
2693     TextureType sourceType = source->getType();
2694     ASSERT(sourceType != TextureType::CubeMap);
2695     TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
2696     const Format &sourceFormat = source->getFormat(sourceTarget, sourceLevel);
2697 
2698     const Texture *dest = context->getTexture(destId);
2699     if (dest == nullptr)
2700     {
2701         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidDestinationTexture);
2702         return false;
2703     }
2704 
2705     if (!ValidateCopyTexture3DCommon(context, entryPoint, source, sourceLevel,
2706                                      sourceFormat.info->internalFormat, dest, destLevel,
2707                                      internalFormat, destTarget))
2708     {
2709         return false;
2710     }
2711 
2712     if (!ValidMipLevel(context, source->getType(), sourceLevel))
2713     {
2714         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidSourceTextureLevel);
2715         return false;
2716     }
2717 
2718     GLsizei sourceWidth  = static_cast<GLsizei>(source->getWidth(sourceTarget, sourceLevel));
2719     GLsizei sourceHeight = static_cast<GLsizei>(source->getHeight(sourceTarget, sourceLevel));
2720     if (sourceWidth == 0 || sourceHeight == 0)
2721     {
2722         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidSourceTextureSize);
2723         return false;
2724     }
2725 
2726     if (dest->getImmutableFormat())
2727     {
2728         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kDestinationImmutable);
2729         return false;
2730     }
2731 
2732     return true;
2733 }
2734 
ValidateCopySubTexture3DANGLE(const Context * context,angle::EntryPoint entryPoint,TextureID sourceId,GLint sourceLevel,TextureTarget destTarget,TextureID destId,GLint destLevel,GLint xoffset,GLint yoffset,GLint zoffset,GLint x,GLint y,GLint z,GLsizei width,GLsizei height,GLsizei depth,GLboolean unpackFlipY,GLboolean unpackPremultiplyAlpha,GLboolean unpackUnmultiplyAlpha)2735 bool ValidateCopySubTexture3DANGLE(const Context *context,
2736                                    angle::EntryPoint entryPoint,
2737                                    TextureID sourceId,
2738                                    GLint sourceLevel,
2739                                    TextureTarget destTarget,
2740                                    TextureID destId,
2741                                    GLint destLevel,
2742                                    GLint xoffset,
2743                                    GLint yoffset,
2744                                    GLint zoffset,
2745                                    GLint x,
2746                                    GLint y,
2747                                    GLint z,
2748                                    GLsizei width,
2749                                    GLsizei height,
2750                                    GLsizei depth,
2751                                    GLboolean unpackFlipY,
2752                                    GLboolean unpackPremultiplyAlpha,
2753                                    GLboolean unpackUnmultiplyAlpha)
2754 {
2755     const Texture *source = context->getTexture(sourceId);
2756     if (source == nullptr)
2757     {
2758         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidSourceTexture);
2759         return false;
2760     }
2761 
2762     TextureType sourceType = source->getType();
2763     ASSERT(sourceType != TextureType::CubeMap);
2764     TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
2765     const Format &sourceFormat = source->getFormat(sourceTarget, sourceLevel);
2766 
2767     const Texture *dest = context->getTexture(destId);
2768     if (dest == nullptr)
2769     {
2770         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidDestinationTexture);
2771         return false;
2772     }
2773 
2774     const InternalFormat &destFormat = *dest->getFormat(destTarget, destLevel).info;
2775 
2776     if (!ValidateCopyTexture3DCommon(context, entryPoint, source, sourceLevel,
2777                                      sourceFormat.info->internalFormat, dest, destLevel,
2778                                      destFormat.internalFormat, destTarget))
2779     {
2780         return false;
2781     }
2782 
2783     if (x < 0 || y < 0 || z < 0)
2784     {
2785         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeXYZ);
2786         return false;
2787     }
2788 
2789     if (width < 0 || height < 0 || depth < 0)
2790     {
2791         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeHeightWidthDepth);
2792         return false;
2793     }
2794 
2795     if (static_cast<size_t>(x + width) > source->getWidth(sourceTarget, sourceLevel) ||
2796         static_cast<size_t>(y + height) > source->getHeight(sourceTarget, sourceLevel) ||
2797         static_cast<size_t>(z + depth) > source->getDepth(sourceTarget, sourceLevel))
2798     {
2799         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kSourceTextureTooSmall);
2800         return false;
2801     }
2802 
2803     if (TextureTargetToType(destTarget) != dest->getType())
2804     {
2805         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidDestinationTextureType);
2806         return false;
2807     }
2808 
2809     if (xoffset < 0 || yoffset < 0 || zoffset < 0)
2810     {
2811         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeOffset);
2812         return false;
2813     }
2814 
2815     if (static_cast<size_t>(xoffset + width) > dest->getWidth(destTarget, destLevel) ||
2816         static_cast<size_t>(yoffset + height) > dest->getHeight(destTarget, destLevel) ||
2817         static_cast<size_t>(zoffset + depth) > dest->getDepth(destTarget, destLevel))
2818     {
2819         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kDestinationTextureTooSmall);
2820         return false;
2821     }
2822 
2823     return true;
2824 }
2825 
ValidateTexImage3D(const Context * context,angle::EntryPoint entryPoint,TextureTarget target,GLint level,GLint internalformat,GLsizei width,GLsizei height,GLsizei depth,GLint border,GLenum format,GLenum type,const void * pixels)2826 bool ValidateTexImage3D(const Context *context,
2827                         angle::EntryPoint entryPoint,
2828                         TextureTarget target,
2829                         GLint level,
2830                         GLint internalformat,
2831                         GLsizei width,
2832                         GLsizei height,
2833                         GLsizei depth,
2834                         GLint border,
2835                         GLenum format,
2836                         GLenum type,
2837                         const void *pixels)
2838 {
2839     if ((context->getClientMajorVersion() < 3) && !context->getExtensions().texture3DOES)
2840     {
2841         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
2842         return false;
2843     }
2844 
2845     return ValidateES3TexImage3DParameters(context, entryPoint, target, level, internalformat,
2846                                            false, false, 0, 0, 0, width, height, depth, border,
2847                                            format, type, -1, pixels);
2848 }
2849 
ValidateTexImage3DRobustANGLE(const Context * context,angle::EntryPoint entryPoint,TextureTarget target,GLint level,GLint internalformat,GLsizei width,GLsizei height,GLsizei depth,GLint border,GLenum format,GLenum type,GLsizei bufSize,const void * pixels)2850 bool ValidateTexImage3DRobustANGLE(const Context *context,
2851                                    angle::EntryPoint entryPoint,
2852                                    TextureTarget target,
2853                                    GLint level,
2854                                    GLint internalformat,
2855                                    GLsizei width,
2856                                    GLsizei height,
2857                                    GLsizei depth,
2858                                    GLint border,
2859                                    GLenum format,
2860                                    GLenum type,
2861                                    GLsizei bufSize,
2862                                    const void *pixels)
2863 {
2864     if (context->getClientMajorVersion() < 3)
2865     {
2866         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
2867         return false;
2868     }
2869 
2870     if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
2871     {
2872         return false;
2873     }
2874 
2875     return ValidateES3TexImage3DParameters(context, entryPoint, target, level, internalformat,
2876                                            false, false, 0, 0, 0, width, height, depth, border,
2877                                            format, type, bufSize, pixels);
2878 }
2879 
ValidateTexSubImage3D(const Context * context,angle::EntryPoint entryPoint,TextureTarget target,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLsizei depth,GLenum format,GLenum type,const void * pixels)2880 bool ValidateTexSubImage3D(const Context *context,
2881                            angle::EntryPoint entryPoint,
2882                            TextureTarget target,
2883                            GLint level,
2884                            GLint xoffset,
2885                            GLint yoffset,
2886                            GLint zoffset,
2887                            GLsizei width,
2888                            GLsizei height,
2889                            GLsizei depth,
2890                            GLenum format,
2891                            GLenum type,
2892                            const void *pixels)
2893 {
2894     if ((context->getClientMajorVersion() < 3) && !context->getExtensions().texture3DOES)
2895     {
2896         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
2897         return false;
2898     }
2899 
2900     return ValidateES3TexImage3DParameters(context, entryPoint, target, level, GL_NONE, false, true,
2901                                            xoffset, yoffset, zoffset, width, height, depth, 0,
2902                                            format, type, -1, pixels);
2903 }
2904 
ValidateTexSubImage3DRobustANGLE(const Context * context,angle::EntryPoint entryPoint,TextureTarget target,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLsizei depth,GLenum format,GLenum type,GLsizei bufSize,const void * pixels)2905 bool ValidateTexSubImage3DRobustANGLE(const Context *context,
2906                                       angle::EntryPoint entryPoint,
2907                                       TextureTarget target,
2908                                       GLint level,
2909                                       GLint xoffset,
2910                                       GLint yoffset,
2911                                       GLint zoffset,
2912                                       GLsizei width,
2913                                       GLsizei height,
2914                                       GLsizei depth,
2915                                       GLenum format,
2916                                       GLenum type,
2917                                       GLsizei bufSize,
2918                                       const void *pixels)
2919 {
2920     if (context->getClientMajorVersion() < 3)
2921     {
2922         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
2923         return false;
2924     }
2925 
2926     if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
2927     {
2928         return false;
2929     }
2930 
2931     return ValidateES3TexImage3DParameters(context, entryPoint, target, level, GL_NONE, false, true,
2932                                            xoffset, yoffset, zoffset, width, height, depth, 0,
2933                                            format, type, bufSize, pixels);
2934 }
2935 
ValidateCompressedTexSubImage3D(const Context * context,angle::EntryPoint entryPoint,TextureTarget target,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLsizei depth,GLenum format,GLsizei imageSize,const void * data)2936 bool ValidateCompressedTexSubImage3D(const Context *context,
2937                                      angle::EntryPoint entryPoint,
2938                                      TextureTarget target,
2939                                      GLint level,
2940                                      GLint xoffset,
2941                                      GLint yoffset,
2942                                      GLint zoffset,
2943                                      GLsizei width,
2944                                      GLsizei height,
2945                                      GLsizei depth,
2946                                      GLenum format,
2947                                      GLsizei imageSize,
2948                                      const void *data)
2949 {
2950     if ((context->getClientMajorVersion() < 3) && !context->getExtensions().texture3DOES)
2951     {
2952         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
2953         return false;
2954     }
2955 
2956     if (!ValidateES3TexImage3DParameters(context, entryPoint, target, level, GL_NONE, true, true,
2957                                          xoffset, yoffset, zoffset, width, height, depth, 0, format,
2958                                          GL_NONE, -1, data))
2959     {
2960         return false;
2961     }
2962 
2963     const InternalFormat &formatInfo = GetSizedInternalFormatInfo(format);
2964 
2965     if (!formatInfo.compressed)
2966     {
2967         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidCompressedFormat);
2968         return false;
2969     }
2970 
2971     GLuint blockSize = 0;
2972     if (!formatInfo.computeCompressedImageSize(Extents(width, height, depth), &blockSize))
2973     {
2974         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kIntegerOverflow);
2975         return false;
2976     }
2977 
2978     if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSize)
2979     {
2980         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidCompressedImageSize);
2981         return false;
2982     }
2983 
2984     if (data == nullptr)
2985     {
2986         if (context->getState().getTargetBuffer(BufferBinding::PixelUnpack) == nullptr)
2987         {
2988             // If data is null, we need an unpack buffer to read from
2989             ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kPixelDataNull);
2990             return false;
2991         }
2992     }
2993 
2994     return true;
2995 }
2996 
ValidateCompressedTexSubImage3DRobustANGLE(const Context * context,angle::EntryPoint entryPoint,TextureTarget target,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLsizei depth,GLenum format,GLsizei imageSize,GLsizei dataSize,const void * data)2997 bool ValidateCompressedTexSubImage3DRobustANGLE(const Context *context,
2998                                                 angle::EntryPoint entryPoint,
2999                                                 TextureTarget target,
3000                                                 GLint level,
3001                                                 GLint xoffset,
3002                                                 GLint yoffset,
3003                                                 GLint zoffset,
3004                                                 GLsizei width,
3005                                                 GLsizei height,
3006                                                 GLsizei depth,
3007                                                 GLenum format,
3008                                                 GLsizei imageSize,
3009                                                 GLsizei dataSize,
3010                                                 const void *data)
3011 {
3012     if (!ValidateRobustCompressedTexImageBase(context, entryPoint, imageSize, dataSize))
3013     {
3014         return false;
3015     }
3016 
3017     return ValidateCompressedTexSubImage3D(context, entryPoint, target, level, xoffset, yoffset,
3018                                            zoffset, width, height, depth, format, imageSize, data);
3019 }
3020 
ValidateGenQueries(const Context * context,angle::EntryPoint entryPoint,GLsizei n,const QueryID * queries)3021 bool ValidateGenQueries(const Context *context,
3022                         angle::EntryPoint entryPoint,
3023                         GLsizei n,
3024                         const QueryID *queries)
3025 {
3026     return ValidateGenOrDeleteES3(context, entryPoint, n, queries);
3027 }
3028 
ValidateDeleteQueries(const Context * context,angle::EntryPoint entryPoint,GLsizei n,const QueryID * queries)3029 bool ValidateDeleteQueries(const Context *context,
3030                            angle::EntryPoint entryPoint,
3031                            GLsizei n,
3032                            const QueryID *queries)
3033 {
3034     return ValidateGenOrDeleteES3(context, entryPoint, n, queries);
3035 }
3036 
ValidateGenSamplers(const Context * context,angle::EntryPoint entryPoint,GLsizei count,const SamplerID * samplers)3037 bool ValidateGenSamplers(const Context *context,
3038                          angle::EntryPoint entryPoint,
3039                          GLsizei count,
3040                          const SamplerID *samplers)
3041 {
3042     if (samplers == nullptr)
3043     {
3044         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kPLSParamsNULL);
3045         return false;
3046     }
3047 
3048     return ValidateGenOrDeleteCountES3(context, entryPoint, count);
3049 }
3050 
ValidateDeleteSamplers(const Context * context,angle::EntryPoint entryPoint,GLsizei count,const SamplerID * samplers)3051 bool ValidateDeleteSamplers(const Context *context,
3052                             angle::EntryPoint entryPoint,
3053                             GLsizei count,
3054                             const SamplerID *samplers)
3055 {
3056     if (samplers == nullptr)
3057     {
3058         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kPLSParamsNULL);
3059         return false;
3060     }
3061 
3062     return ValidateGenOrDeleteCountES3(context, entryPoint, count);
3063 }
3064 
ValidateGenTransformFeedbacks(const Context * context,angle::EntryPoint entryPoint,GLsizei n,const TransformFeedbackID * ids)3065 bool ValidateGenTransformFeedbacks(const Context *context,
3066                                    angle::EntryPoint entryPoint,
3067                                    GLsizei n,
3068                                    const TransformFeedbackID *ids)
3069 {
3070     return ValidateGenOrDeleteES3(context, entryPoint, n, ids);
3071 }
3072 
ValidateDeleteTransformFeedbacks(const Context * context,angle::EntryPoint entryPoint,GLsizei n,const TransformFeedbackID * ids)3073 bool ValidateDeleteTransformFeedbacks(const Context *context,
3074                                       angle::EntryPoint entryPoint,
3075                                       GLsizei n,
3076                                       const TransformFeedbackID *ids)
3077 {
3078     if (!ValidateGenOrDeleteES3(context, entryPoint, n, ids))
3079     {
3080         return false;
3081     }
3082     for (GLint i = 0; i < n; ++i)
3083     {
3084         auto *transformFeedback = context->getTransformFeedback(ids[i]);
3085         if (transformFeedback != nullptr && transformFeedback->isActive())
3086         {
3087             // ES 3.0.4 section 2.15.1 page 86
3088             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kTransformFeedbackActiveDelete);
3089             return false;
3090         }
3091     }
3092     return true;
3093 }
3094 
ValidateGenVertexArrays(const Context * context,angle::EntryPoint entryPoint,GLsizei n,const VertexArrayID * arrays)3095 bool ValidateGenVertexArrays(const Context *context,
3096                              angle::EntryPoint entryPoint,
3097                              GLsizei n,
3098                              const VertexArrayID *arrays)
3099 {
3100     return ValidateGenOrDeleteES3(context, entryPoint, n, arrays);
3101 }
3102 
ValidateDeleteVertexArrays(const Context * context,angle::EntryPoint entryPoint,GLsizei n,const VertexArrayID * arrays)3103 bool ValidateDeleteVertexArrays(const Context *context,
3104                                 angle::EntryPoint entryPoint,
3105                                 GLsizei n,
3106                                 const VertexArrayID *arrays)
3107 {
3108     return ValidateGenOrDeleteES3(context, entryPoint, n, arrays);
3109 }
3110 
ValidateBeginTransformFeedback(const Context * context,angle::EntryPoint entryPoint,PrimitiveMode primitiveMode)3111 bool ValidateBeginTransformFeedback(const Context *context,
3112                                     angle::EntryPoint entryPoint,
3113                                     PrimitiveMode primitiveMode)
3114 {
3115     if (context->getClientMajorVersion() < 3)
3116     {
3117         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
3118         return false;
3119     }
3120     switch (primitiveMode)
3121     {
3122         case PrimitiveMode::Triangles:
3123         case PrimitiveMode::Lines:
3124         case PrimitiveMode::Points:
3125             break;
3126 
3127         default:
3128             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidPrimitiveMode);
3129             return false;
3130     }
3131 
3132     TransformFeedback *transformFeedback = context->getState().getCurrentTransformFeedback();
3133     ASSERT(transformFeedback != nullptr);
3134 
3135     if (transformFeedback->isActive())
3136     {
3137         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kTransfomFeedbackAlreadyActive);
3138         return false;
3139     }
3140 
3141     for (size_t i = 0; i < transformFeedback->getIndexedBufferCount(); i++)
3142     {
3143         const OffsetBindingPointer<Buffer> &buffer = transformFeedback->getIndexedBuffer(i);
3144         if (buffer.get())
3145         {
3146             if (buffer->isMapped())
3147             {
3148                 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBufferMapped);
3149                 return false;
3150             }
3151             if ((context->getLimitations().noDoubleBoundTransformFeedbackBuffers ||
3152                  context->getExtensions().webglCompatibilityANGLE) &&
3153                 buffer->isDoubleBoundForTransformFeedback())
3154             {
3155                 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION,
3156                                        kTransformFeedbackBufferMultipleOutputs);
3157                 return false;
3158             }
3159         }
3160     }
3161 
3162     const ProgramExecutable *programExecutable =
3163         context->getState().getLinkedProgramExecutable(context);
3164     if (!programExecutable)
3165     {
3166         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kProgramNotBound);
3167         return false;
3168     }
3169 
3170     if (programExecutable->getLinkedTransformFeedbackVaryings().empty())
3171     {
3172         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kNoTransformFeedbackOutputVariables);
3173         return false;
3174     }
3175 
3176     if (!ValidateProgramExecutableXFBBuffersPresent(context, programExecutable))
3177     {
3178         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kTransformFeedbackBufferMissing);
3179         return false;
3180     }
3181 
3182     return true;
3183 }
3184 
ValidateGetBufferPointerv(const Context * context,angle::EntryPoint entryPoint,BufferBinding target,GLenum pname,void * const * params)3185 bool ValidateGetBufferPointerv(const Context *context,
3186                                angle::EntryPoint entryPoint,
3187                                BufferBinding target,
3188                                GLenum pname,
3189                                void *const *params)
3190 {
3191     if (context->getClientMajorVersion() < 3)
3192     {
3193         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
3194         return false;
3195     }
3196 
3197     return ValidateGetBufferPointervBase(context, entryPoint, target, pname, nullptr, params);
3198 }
3199 
ValidateGetBufferPointervRobustANGLE(const Context * context,angle::EntryPoint entryPoint,BufferBinding target,GLenum pname,GLsizei bufSize,const GLsizei * length,void * const * params)3200 bool ValidateGetBufferPointervRobustANGLE(const Context *context,
3201                                           angle::EntryPoint entryPoint,
3202                                           BufferBinding target,
3203                                           GLenum pname,
3204                                           GLsizei bufSize,
3205                                           const GLsizei *length,
3206                                           void *const *params)
3207 {
3208     if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
3209     {
3210         return false;
3211     }
3212 
3213     GLsizei numParams = 0;
3214 
3215     if (context->getClientMajorVersion() < 3 && !context->getExtensions().mapbufferOES)
3216     {
3217         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3218         return false;
3219     }
3220 
3221     if (!ValidateGetBufferPointervBase(context, entryPoint, target, pname, &numParams, params))
3222     {
3223         return false;
3224     }
3225 
3226     if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams))
3227     {
3228         return false;
3229     }
3230 
3231     SetRobustLengthParam(length, numParams);
3232 
3233     return true;
3234 }
3235 
ValidateUnmapBuffer(const Context * context,angle::EntryPoint entryPoint,BufferBinding target)3236 bool ValidateUnmapBuffer(const Context *context, angle::EntryPoint entryPoint, BufferBinding target)
3237 {
3238     if (context->getClientMajorVersion() < 3)
3239     {
3240         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
3241         return false;
3242     }
3243 
3244     return ValidateUnmapBufferBase(context, entryPoint, target);
3245 }
3246 
ValidateMapBufferRange(const Context * context,angle::EntryPoint entryPoint,BufferBinding target,GLintptr offset,GLsizeiptr length,GLbitfield access)3247 bool ValidateMapBufferRange(const Context *context,
3248                             angle::EntryPoint entryPoint,
3249                             BufferBinding target,
3250                             GLintptr offset,
3251                             GLsizeiptr length,
3252                             GLbitfield access)
3253 {
3254     if (context->getClientMajorVersion() < 3)
3255     {
3256         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
3257         return false;
3258     }
3259 
3260     return ValidateMapBufferRangeBase(context, entryPoint, target, offset, length, access);
3261 }
3262 
ValidateFlushMappedBufferRange(const Context * context,angle::EntryPoint entryPoint,BufferBinding target,GLintptr offset,GLsizeiptr length)3263 bool ValidateFlushMappedBufferRange(const Context *context,
3264                                     angle::EntryPoint entryPoint,
3265                                     BufferBinding target,
3266                                     GLintptr offset,
3267                                     GLsizeiptr length)
3268 {
3269     if (context->getClientMajorVersion() < 3)
3270     {
3271         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
3272         return false;
3273     }
3274 
3275     return ValidateFlushMappedBufferRangeBase(context, entryPoint, target, offset, length);
3276 }
3277 
ValidateIndexedStateQuery(const Context * context,angle::EntryPoint entryPoint,GLenum pname,GLuint index,GLsizei * length)3278 bool ValidateIndexedStateQuery(const Context *context,
3279                                angle::EntryPoint entryPoint,
3280                                GLenum pname,
3281                                GLuint index,
3282                                GLsizei *length)
3283 {
3284     if (length)
3285     {
3286         *length = 0;
3287     }
3288 
3289     GLenum nativeType;
3290     unsigned int numParams;
3291     if (!context->getIndexedQueryParameterInfo(pname, &nativeType, &numParams))
3292     {
3293         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidPname);
3294         return false;
3295     }
3296 
3297     const Caps &caps = context->getCaps();
3298     switch (pname)
3299     {
3300         case GL_BLEND_SRC_RGB:
3301         case GL_BLEND_SRC_ALPHA:
3302         case GL_BLEND_DST_RGB:
3303         case GL_BLEND_DST_ALPHA:
3304         case GL_BLEND_EQUATION_RGB:
3305         case GL_BLEND_EQUATION_ALPHA:
3306         case GL_COLOR_WRITEMASK:
3307             ASSERT(context->getClientVersion() >= ES_3_2 ||
3308                    context->getExtensions().drawBuffersIndexedAny());
3309             if (index >= static_cast<GLuint>(caps.maxDrawBuffers))
3310             {
3311                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kIndexExceedsMaxDrawBuffer);
3312                 return false;
3313             }
3314             break;
3315         case GL_TRANSFORM_FEEDBACK_BUFFER_START:
3316         case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
3317         case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
3318             if (index >= static_cast<GLuint>(caps.maxTransformFeedbackSeparateAttributes))
3319             {
3320                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kIndexExceedsMaxTransformFeedbackAttribs);
3321                 return false;
3322             }
3323             break;
3324 
3325         case GL_UNIFORM_BUFFER_START:
3326         case GL_UNIFORM_BUFFER_SIZE:
3327         case GL_UNIFORM_BUFFER_BINDING:
3328             if (index >= static_cast<GLuint>(caps.maxUniformBufferBindings))
3329             {
3330                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kIndexExceedsMaxUniformBufferBindings);
3331                 return false;
3332             }
3333             break;
3334 
3335         case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
3336         case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
3337             ASSERT(context->getClientVersion() >= ES_3_1);
3338             if (index >= 3u)
3339             {
3340                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kIndexExceedsMaxWorkgroupDimensions);
3341                 return false;
3342             }
3343             break;
3344 
3345         case GL_ATOMIC_COUNTER_BUFFER_START:
3346         case GL_ATOMIC_COUNTER_BUFFER_SIZE:
3347         case GL_ATOMIC_COUNTER_BUFFER_BINDING:
3348             ASSERT(context->getClientVersion() >= ES_3_1);
3349             if (index >= static_cast<GLuint>(caps.maxAtomicCounterBufferBindings))
3350             {
3351                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE,
3352                                        kIndexExceedsMaxAtomicCounterBufferBindings);
3353                 return false;
3354             }
3355             break;
3356 
3357         case GL_SHADER_STORAGE_BUFFER_START:
3358         case GL_SHADER_STORAGE_BUFFER_SIZE:
3359         case GL_SHADER_STORAGE_BUFFER_BINDING:
3360             ASSERT(context->getClientVersion() >= ES_3_1);
3361             if (index >= static_cast<GLuint>(caps.maxShaderStorageBufferBindings))
3362             {
3363                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kExceedsMaxShaderStorageBufferBindings);
3364                 return false;
3365             }
3366             break;
3367 
3368         case GL_VERTEX_BINDING_BUFFER:
3369         case GL_VERTEX_BINDING_DIVISOR:
3370         case GL_VERTEX_BINDING_OFFSET:
3371         case GL_VERTEX_BINDING_STRIDE:
3372             ASSERT(context->getClientVersion() >= ES_3_1);
3373             if (index >= static_cast<GLuint>(caps.maxVertexAttribBindings))
3374             {
3375                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kExceedsMaxVertexAttribBindings);
3376                 return false;
3377             }
3378             break;
3379         case GL_SAMPLE_MASK_VALUE:
3380             ASSERT(context->getClientVersion() >= ES_3_1 ||
3381                    context->getExtensions().textureMultisampleANGLE);
3382             if (index >= static_cast<GLuint>(caps.maxSampleMaskWords))
3383             {
3384                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidSampleMaskNumber);
3385                 return false;
3386             }
3387             break;
3388         case GL_IMAGE_BINDING_NAME:
3389         case GL_IMAGE_BINDING_LEVEL:
3390         case GL_IMAGE_BINDING_LAYERED:
3391         case GL_IMAGE_BINDING_LAYER:
3392         case GL_IMAGE_BINDING_ACCESS:
3393         case GL_IMAGE_BINDING_FORMAT:
3394             ASSERT(context->getClientVersion() >= ES_3_1);
3395             if (index >= static_cast<GLuint>(caps.maxImageUnits))
3396             {
3397                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kExceedsMaxImageUnits);
3398                 return false;
3399             }
3400             break;
3401         default:
3402             UNREACHABLE();
3403             return false;
3404     }
3405 
3406     if (length)
3407     {
3408         if (pname == GL_COLOR_WRITEMASK)
3409         {
3410             *length = 4;
3411         }
3412         else
3413         {
3414             *length = 1;
3415         }
3416     }
3417 
3418     return true;
3419 }
3420 
ValidateGetIntegeri_v(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLuint index,const GLint * data)3421 bool ValidateGetIntegeri_v(const Context *context,
3422                            angle::EntryPoint entryPoint,
3423                            GLenum target,
3424                            GLuint index,
3425                            const GLint *data)
3426 {
3427     if (context->getClientVersion() < ES_3_0)
3428     {
3429         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
3430         return false;
3431     }
3432     return ValidateIndexedStateQuery(context, entryPoint, target, index, nullptr);
3433 }
3434 
ValidateGetIntegeri_vRobustANGLE(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLuint index,GLsizei bufSize,const GLsizei * length,const GLint * data)3435 bool ValidateGetIntegeri_vRobustANGLE(const Context *context,
3436                                       angle::EntryPoint entryPoint,
3437                                       GLenum target,
3438                                       GLuint index,
3439                                       GLsizei bufSize,
3440                                       const GLsizei *length,
3441                                       const GLint *data)
3442 {
3443     if (context->getClientVersion() < ES_3_0)
3444     {
3445         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
3446         return false;
3447     }
3448 
3449     if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
3450     {
3451         return false;
3452     }
3453 
3454     GLsizei numParams = 0;
3455 
3456     if (!ValidateIndexedStateQuery(context, entryPoint, target, index, &numParams))
3457     {
3458         return false;
3459     }
3460 
3461     if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams))
3462     {
3463         return false;
3464     }
3465 
3466     SetRobustLengthParam(length, numParams);
3467 
3468     return true;
3469 }
3470 
ValidateGetInteger64i_v(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLuint index,const GLint64 * data)3471 bool ValidateGetInteger64i_v(const Context *context,
3472                              angle::EntryPoint entryPoint,
3473                              GLenum target,
3474                              GLuint index,
3475                              const GLint64 *data)
3476 {
3477     if (context->getClientVersion() < ES_3_0)
3478     {
3479         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
3480         return false;
3481     }
3482     return ValidateIndexedStateQuery(context, entryPoint, target, index, nullptr);
3483 }
3484 
ValidateGetInteger64i_vRobustANGLE(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLuint index,GLsizei bufSize,const GLsizei * length,const GLint64 * data)3485 bool ValidateGetInteger64i_vRobustANGLE(const Context *context,
3486                                         angle::EntryPoint entryPoint,
3487                                         GLenum target,
3488                                         GLuint index,
3489                                         GLsizei bufSize,
3490                                         const GLsizei *length,
3491                                         const GLint64 *data)
3492 {
3493     if (context->getClientVersion() < ES_3_0)
3494     {
3495         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
3496         return false;
3497     }
3498 
3499     if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
3500     {
3501         return false;
3502     }
3503 
3504     GLsizei numParams = 0;
3505 
3506     if (!ValidateIndexedStateQuery(context, entryPoint, target, index, &numParams))
3507     {
3508         return false;
3509     }
3510 
3511     if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams))
3512     {
3513         return false;
3514     }
3515 
3516     SetRobustLengthParam(length, numParams);
3517 
3518     return true;
3519 }
3520 
ValidateCopyBufferSubData(const Context * context,angle::EntryPoint entryPoint,BufferBinding readTarget,BufferBinding writeTarget,GLintptr readOffset,GLintptr writeOffset,GLsizeiptr size)3521 bool ValidateCopyBufferSubData(const Context *context,
3522                                angle::EntryPoint entryPoint,
3523                                BufferBinding readTarget,
3524                                BufferBinding writeTarget,
3525                                GLintptr readOffset,
3526                                GLintptr writeOffset,
3527                                GLsizeiptr size)
3528 {
3529     if (context->getClientMajorVersion() < 3)
3530     {
3531         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
3532         return false;
3533     }
3534 
3535     if (!context->isValidBufferBinding(readTarget) || !context->isValidBufferBinding(writeTarget))
3536     {
3537         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidBufferTypes);
3538         return false;
3539     }
3540 
3541     Buffer *readBuffer  = context->getState().getTargetBuffer(readTarget);
3542     Buffer *writeBuffer = context->getState().getTargetBuffer(writeTarget);
3543 
3544     if (!readBuffer || !writeBuffer)
3545     {
3546         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBufferNotBound);
3547         return false;
3548     }
3549 
3550     // EXT_buffer_storage allows persistently mapped buffers to be updated via glCopyBufferSubData
3551     bool isReadPersistent  = (readBuffer->getAccessFlags() & GL_MAP_PERSISTENT_BIT_EXT) != 0;
3552     bool isWritePersistent = (writeBuffer->getAccessFlags() & GL_MAP_PERSISTENT_BIT_EXT) != 0;
3553 
3554     // Verify that readBuffer and writeBuffer are not currently mapped unless persistent
3555     if ((readBuffer->isMapped() && !isReadPersistent) ||
3556         (writeBuffer->isMapped() && !isWritePersistent))
3557     {
3558         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBufferMapped);
3559         return false;
3560     }
3561 
3562     if (readBuffer->hasWebGLXFBBindingConflict(context->isWebGL()) ||
3563         writeBuffer->hasWebGLXFBBindingConflict(context->isWebGL()))
3564     {
3565         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBufferBoundForTransformFeedback);
3566         return false;
3567     }
3568 
3569     CheckedNumeric<GLintptr> checkedReadOffset(readOffset);
3570     CheckedNumeric<GLintptr> checkedWriteOffset(writeOffset);
3571     CheckedNumeric<GLintptr> checkedSize(size);
3572 
3573     auto checkedReadSum  = checkedReadOffset + checkedSize;
3574     auto checkedWriteSum = checkedWriteOffset + checkedSize;
3575 
3576     if (!checkedReadSum.IsValid() || !checkedWriteSum.IsValid() ||
3577         !IsValueInRangeForNumericType<GLintptr>(readBuffer->getSize()) ||
3578         !IsValueInRangeForNumericType<GLintptr>(writeBuffer->getSize()))
3579     {
3580         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kIntegerOverflow);
3581         return false;
3582     }
3583 
3584     if (readOffset < 0 || writeOffset < 0)
3585     {
3586         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeOffset);
3587         return false;
3588     }
3589 
3590     if (size < 0)
3591     {
3592         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeSize);
3593         return false;
3594     }
3595 
3596     if (checkedReadSum.ValueOrDie() > readBuffer->getSize() ||
3597         checkedWriteSum.ValueOrDie() > writeBuffer->getSize())
3598     {
3599         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kBufferOffsetOverflow);
3600         return false;
3601     }
3602 
3603     if (readBuffer == writeBuffer)
3604     {
3605         auto checkedOffsetDiff = (checkedReadOffset - checkedWriteOffset).Abs();
3606         if (!checkedOffsetDiff.IsValid())
3607         {
3608             // This shold not be possible.
3609             UNREACHABLE();
3610             ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kIntegerOverflow);
3611             return false;
3612         }
3613 
3614         if (checkedOffsetDiff.ValueOrDie() < size)
3615         {
3616             ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kCopyAlias);
3617             return false;
3618         }
3619     }
3620 
3621     return true;
3622 }
3623 
ValidateGetStringi(const Context * context,angle::EntryPoint entryPoint,GLenum name,GLuint index)3624 bool ValidateGetStringi(const Context *context,
3625                         angle::EntryPoint entryPoint,
3626                         GLenum name,
3627                         GLuint index)
3628 {
3629     if (context->getClientMajorVersion() < 3)
3630     {
3631         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
3632         return false;
3633     }
3634 
3635     switch (name)
3636     {
3637         case GL_EXTENSIONS:
3638             if (index >= context->getExtensionStringCount())
3639             {
3640                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kExceedsNumExtensions);
3641                 return false;
3642             }
3643             break;
3644 
3645         case GL_REQUESTABLE_EXTENSIONS_ANGLE:
3646             if (!context->getExtensions().requestExtensionANGLE)
3647             {
3648                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidName);
3649                 return false;
3650             }
3651             if (index >= context->getRequestableExtensionStringCount())
3652             {
3653                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kExceedsNumRequestableExtensions);
3654                 return false;
3655             }
3656             break;
3657 
3658         default:
3659             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidName);
3660             return false;
3661     }
3662 
3663     return true;
3664 }
3665 
ValidateRenderbufferStorageMultisample(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLsizei samples,GLenum internalformat,GLsizei width,GLsizei height)3666 bool ValidateRenderbufferStorageMultisample(const Context *context,
3667                                             angle::EntryPoint entryPoint,
3668                                             GLenum target,
3669                                             GLsizei samples,
3670                                             GLenum internalformat,
3671                                             GLsizei width,
3672                                             GLsizei height)
3673 {
3674     if (context->getClientMajorVersion() < 3)
3675     {
3676         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
3677         return false;
3678     }
3679 
3680     if (!ValidateRenderbufferStorageParametersBase(context, entryPoint, target, samples,
3681                                                    internalformat, width, height))
3682     {
3683         return false;
3684     }
3685 
3686     // The ES3 spec(section 4.4.2) states that the internal format must be sized and not an integer
3687     // format if samples is greater than zero. In ES3.1(section 9.2.5), it can support integer
3688     // multisample renderbuffer, but the samples should not be greater than MAX_INTEGER_SAMPLES.
3689     const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalformat);
3690     if (formatInfo.isInt())
3691     {
3692         if ((samples > 0 && context->getClientVersion() == ES_3_0) ||
3693             samples > context->getCaps().maxIntegerSamples)
3694         {
3695             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kSamplesOutOfRange);
3696             return false;
3697         }
3698     }
3699 
3700     // The behavior is different than the ANGLE version, which would generate a GL_OUT_OF_MEMORY.
3701     const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
3702     if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
3703     {
3704         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kSamplesOutOfRange);
3705         return false;
3706     }
3707 
3708     return true;
3709 }
3710 
ValidateVertexAttribIPointer(const Context * context,angle::EntryPoint entryPoint,GLuint index,GLint size,VertexAttribType type,GLsizei stride,const void * pointer)3711 bool ValidateVertexAttribIPointer(const Context *context,
3712                                   angle::EntryPoint entryPoint,
3713                                   GLuint index,
3714                                   GLint size,
3715                                   VertexAttribType type,
3716                                   GLsizei stride,
3717                                   const void *pointer)
3718 {
3719     if (context->getClientMajorVersion() < 3)
3720     {
3721         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
3722         return false;
3723     }
3724 
3725     if (!ValidateIntegerVertexFormat(context, entryPoint, index, size, type))
3726     {
3727         return false;
3728     }
3729 
3730     if (stride < 0)
3731     {
3732         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeStride);
3733         return false;
3734     }
3735 
3736     const Caps &caps = context->getCaps();
3737     if (context->getClientVersion() >= ES_3_1)
3738     {
3739         if (stride > caps.maxVertexAttribStride)
3740         {
3741             ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kExceedsMaxVertexAttribStride);
3742             return false;
3743         }
3744 
3745         // [OpenGL ES 3.1] Section 10.3.1 page 245:
3746         // glVertexAttribBinding is part of the equivalent code of VertexAttribIPointer, so its
3747         // validation should be inherited.
3748         if (index >= static_cast<GLuint>(caps.maxVertexAttribBindings))
3749         {
3750             ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kExceedsMaxVertexAttribBindings);
3751             return false;
3752         }
3753     }
3754 
3755     // [OpenGL ES 3.0.2] Section 2.8 page 24:
3756     // An INVALID_OPERATION error is generated when a non-zero vertex array object
3757     // is bound, zero is bound to the ARRAY_BUFFER buffer object binding point,
3758     // and the pointer argument is not NULL.
3759     if (context->getState().getVertexArrayId().value != 0 &&
3760         context->getState().getTargetBuffer(BufferBinding::Array) == 0 && pointer != nullptr)
3761     {
3762         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kClientDataInVertexArray);
3763         return false;
3764     }
3765 
3766     if (context->getExtensions().webglCompatibilityANGLE)
3767     {
3768         if (!ValidateWebGLVertexAttribPointer(context, entryPoint, type, false, stride, pointer,
3769                                               true))
3770         {
3771             return false;
3772         }
3773     }
3774 
3775     return true;
3776 }
3777 
ValidateGetSynciv(const Context * context,angle::EntryPoint entryPoint,SyncID syncPacked,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLint * values)3778 bool ValidateGetSynciv(const Context *context,
3779                        angle::EntryPoint entryPoint,
3780                        SyncID syncPacked,
3781                        GLenum pname,
3782                        GLsizei bufSize,
3783                        const GLsizei *length,
3784                        const GLint *values)
3785 {
3786     if ((context->getClientMajorVersion() < 3) && !context->getExtensions().syncARB)
3787     {
3788         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
3789         return false;
3790     }
3791 
3792     if (bufSize < 0)
3793     {
3794         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeBufSize);
3795         return false;
3796     }
3797 
3798     if (context->isContextLost())
3799     {
3800         ANGLE_VALIDATION_ERROR(GL_CONTEXT_LOST, kContextLost);
3801 
3802         if (pname == GL_SYNC_STATUS)
3803         {
3804             // Generate an error but still return true, the context still needs to return a
3805             // value in this case.
3806             return true;
3807         }
3808         else
3809         {
3810             return false;
3811         }
3812     }
3813 
3814     Sync *syncObject = context->getSync(syncPacked);
3815     if (!syncObject)
3816     {
3817         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kSyncMissing);
3818         return false;
3819     }
3820 
3821     switch (pname)
3822     {
3823         case GL_OBJECT_TYPE:
3824         case GL_SYNC_CONDITION:
3825         case GL_SYNC_FLAGS:
3826         case GL_SYNC_STATUS:
3827             break;
3828 
3829         default:
3830             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidPname);
3831             return false;
3832     }
3833 
3834     return true;
3835 }
3836 
ValidateDrawElementsInstanced(const Context * context,angle::EntryPoint entryPoint,PrimitiveMode mode,GLsizei count,DrawElementsType type,const void * indices,GLsizei instanceCount)3837 bool ValidateDrawElementsInstanced(const Context *context,
3838                                    angle::EntryPoint entryPoint,
3839                                    PrimitiveMode mode,
3840                                    GLsizei count,
3841                                    DrawElementsType type,
3842                                    const void *indices,
3843                                    GLsizei instanceCount)
3844 {
3845     if (context->getClientMajorVersion() < 3)
3846     {
3847         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
3848         return false;
3849     }
3850 
3851     return ValidateDrawElementsInstancedBase(context, entryPoint, mode, count, type, indices,
3852                                              instanceCount, 0);
3853 }
3854 
ValidateMultiDrawArraysInstancedANGLE(const Context * context,angle::EntryPoint entryPoint,PrimitiveMode mode,const GLint * firsts,const GLsizei * counts,const GLsizei * instanceCounts,GLsizei drawcount)3855 bool ValidateMultiDrawArraysInstancedANGLE(const Context *context,
3856                                            angle::EntryPoint entryPoint,
3857                                            PrimitiveMode mode,
3858                                            const GLint *firsts,
3859                                            const GLsizei *counts,
3860                                            const GLsizei *instanceCounts,
3861                                            GLsizei drawcount)
3862 {
3863     if (!context->getExtensions().multiDrawANGLE)
3864     {
3865         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3866         return false;
3867     }
3868     if (context->getClientMajorVersion() < 3)
3869     {
3870         if (!context->getExtensions().instancedArraysAny())
3871         {
3872             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3873             return false;
3874         }
3875         if (!ValidateDrawInstancedANGLE(context, entryPoint))
3876         {
3877             return false;
3878         }
3879     }
3880     for (GLsizei drawID = 0; drawID < drawcount; ++drawID)
3881     {
3882         if (!ValidateDrawArraysInstancedBase(context, entryPoint, mode, firsts[drawID],
3883                                              counts[drawID], instanceCounts[drawID], 0))
3884         {
3885             return false;
3886         }
3887     }
3888     return true;
3889 }
3890 
ValidateMultiDrawElementsInstancedANGLE(const Context * context,angle::EntryPoint entryPoint,PrimitiveMode mode,const GLsizei * counts,DrawElementsType type,const GLvoid * const * indices,const GLsizei * instanceCounts,GLsizei drawcount)3891 bool ValidateMultiDrawElementsInstancedANGLE(const Context *context,
3892                                              angle::EntryPoint entryPoint,
3893                                              PrimitiveMode mode,
3894                                              const GLsizei *counts,
3895                                              DrawElementsType type,
3896                                              const GLvoid *const *indices,
3897                                              const GLsizei *instanceCounts,
3898                                              GLsizei drawcount)
3899 {
3900     if (!context->getExtensions().multiDrawANGLE)
3901     {
3902         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3903         return false;
3904     }
3905     if (context->getClientMajorVersion() < 3)
3906     {
3907         if (!context->getExtensions().instancedArraysAny())
3908         {
3909             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3910             return false;
3911         }
3912         if (!ValidateDrawInstancedANGLE(context, entryPoint))
3913         {
3914             return false;
3915         }
3916     }
3917     for (GLsizei drawID = 0; drawID < drawcount; ++drawID)
3918     {
3919         if (!ValidateDrawElementsInstancedBase(context, entryPoint, mode, counts[drawID], type,
3920                                                indices[drawID], instanceCounts[drawID], 0))
3921         {
3922             return false;
3923         }
3924     }
3925     return true;
3926 }
3927 
ValidateDrawArraysInstancedBaseInstanceANGLE(const Context * context,angle::EntryPoint entryPoint,PrimitiveMode mode,GLint first,GLsizei count,GLsizei instanceCount,GLuint baseInstance)3928 bool ValidateDrawArraysInstancedBaseInstanceANGLE(const Context *context,
3929                                                   angle::EntryPoint entryPoint,
3930                                                   PrimitiveMode mode,
3931                                                   GLint first,
3932                                                   GLsizei count,
3933                                                   GLsizei instanceCount,
3934                                                   GLuint baseInstance)
3935 {
3936     if (!context->getExtensions().baseVertexBaseInstanceANGLE)
3937     {
3938         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3939         return false;
3940     }
3941 
3942     return ValidateDrawArraysInstancedBase(context, entryPoint, mode, first, count, instanceCount,
3943                                            baseInstance);
3944 }
3945 
ValidateDrawElementsInstancedBaseVertexBaseInstanceANGLE(const Context * context,angle::EntryPoint entryPoint,PrimitiveMode mode,GLsizei count,DrawElementsType type,const GLvoid * indices,GLsizei instanceCount,GLint baseVertex,GLuint baseInstance)3946 bool ValidateDrawElementsInstancedBaseVertexBaseInstanceANGLE(const Context *context,
3947                                                               angle::EntryPoint entryPoint,
3948                                                               PrimitiveMode mode,
3949                                                               GLsizei count,
3950                                                               DrawElementsType type,
3951                                                               const GLvoid *indices,
3952                                                               GLsizei instanceCount,
3953                                                               GLint baseVertex,
3954                                                               GLuint baseInstance)
3955 {
3956     if (!context->getExtensions().baseVertexBaseInstanceANGLE)
3957     {
3958         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3959         return false;
3960     }
3961 
3962     return ValidateDrawElementsInstancedBase(context, entryPoint, mode, count, type, indices,
3963                                              instanceCount, baseInstance);
3964 }
3965 
ValidateMultiDrawArraysInstancedBaseInstanceANGLE(const Context * context,angle::EntryPoint entryPoint,PrimitiveMode modePacked,const GLint * firsts,const GLsizei * counts,const GLsizei * instanceCounts,const GLuint * baseInstances,GLsizei drawcount)3966 bool ValidateMultiDrawArraysInstancedBaseInstanceANGLE(const Context *context,
3967                                                        angle::EntryPoint entryPoint,
3968                                                        PrimitiveMode modePacked,
3969                                                        const GLint *firsts,
3970                                                        const GLsizei *counts,
3971                                                        const GLsizei *instanceCounts,
3972                                                        const GLuint *baseInstances,
3973                                                        GLsizei drawcount)
3974 {
3975     if (!context->getExtensions().multiDrawANGLE)
3976     {
3977         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3978         return false;
3979     }
3980     if (drawcount < 0)
3981     {
3982         return false;
3983     }
3984     for (GLsizei drawID = 0; drawID < drawcount; ++drawID)
3985     {
3986         if (!ValidateDrawArraysInstancedBase(context, entryPoint, modePacked, firsts[drawID],
3987                                              counts[drawID], instanceCounts[drawID],
3988                                              baseInstances[drawID]))
3989         {
3990             return false;
3991         }
3992     }
3993     return true;
3994 }
3995 
ValidateMultiDrawElementsInstancedBaseVertexBaseInstanceANGLE(const Context * context,angle::EntryPoint entryPoint,PrimitiveMode modePacked,const GLsizei * counts,DrawElementsType typePacked,const GLvoid * const * indices,const GLsizei * instanceCounts,const GLint * baseVertices,const GLuint * baseInstances,GLsizei drawcount)3996 bool ValidateMultiDrawElementsInstancedBaseVertexBaseInstanceANGLE(const Context *context,
3997                                                                    angle::EntryPoint entryPoint,
3998                                                                    PrimitiveMode modePacked,
3999                                                                    const GLsizei *counts,
4000                                                                    DrawElementsType typePacked,
4001                                                                    const GLvoid *const *indices,
4002                                                                    const GLsizei *instanceCounts,
4003                                                                    const GLint *baseVertices,
4004                                                                    const GLuint *baseInstances,
4005                                                                    GLsizei drawcount)
4006 {
4007     if (!context->getExtensions().multiDrawANGLE)
4008     {
4009         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
4010         return false;
4011     }
4012     if (drawcount < 0)
4013     {
4014         return false;
4015     }
4016     for (GLsizei drawID = 0; drawID < drawcount; ++drawID)
4017     {
4018         if (!ValidateDrawElementsInstancedBase(context, entryPoint, modePacked, counts[drawID],
4019                                                typePacked, indices[drawID], instanceCounts[drawID],
4020                                                baseInstances[drawID]))
4021         {
4022             return false;
4023         }
4024     }
4025     return true;
4026 }
4027 
ValidateFramebufferTextureMultiviewOVR(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLenum attachment,TextureID texture,GLint level,GLint baseViewIndex,GLsizei numViews)4028 bool ValidateFramebufferTextureMultiviewOVR(const Context *context,
4029                                             angle::EntryPoint entryPoint,
4030                                             GLenum target,
4031                                             GLenum attachment,
4032                                             TextureID texture,
4033                                             GLint level,
4034                                             GLint baseViewIndex,
4035                                             GLsizei numViews)
4036 {
4037     if (!ValidateFramebufferTextureMultiviewBaseANGLE(context, entryPoint, target, attachment,
4038                                                       texture, level, numViews))
4039     {
4040         return false;
4041     }
4042 
4043     if (texture.value != 0)
4044     {
4045         if (baseViewIndex < 0)
4046         {
4047             ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeBaseViewIndex);
4048             return false;
4049         }
4050 
4051         Texture *tex = context->getTexture(texture);
4052         ASSERT(tex);
4053 
4054         switch (tex->getType())
4055         {
4056             case TextureType::_2DArray:
4057             case TextureType::_2DMultisampleArray:
4058             {
4059                 if (tex->getType() == TextureType::_2DMultisampleArray)
4060                 {
4061                     if (!context->getExtensions().multiviewMultisampleANGLE)
4062                     {
4063                         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidTextureType);
4064                         return false;
4065                     }
4066                 }
4067 
4068                 const Caps &caps = context->getCaps();
4069                 if (baseViewIndex + numViews > caps.maxArrayTextureLayers)
4070                 {
4071                     ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kViewsExceedMaxArrayLayers);
4072                     return false;
4073                 }
4074 
4075                 break;
4076             }
4077             default:
4078                 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidTextureType);
4079                 return false;
4080         }
4081 
4082         if (!ValidateFramebufferTextureMultiviewLevelAndFormat(context, entryPoint, tex, level))
4083         {
4084             return false;
4085         }
4086     }
4087 
4088     return true;
4089 }
4090 
ValidateUniform1ui(const Context * context,angle::EntryPoint entryPoint,UniformLocation location,GLuint v0)4091 bool ValidateUniform1ui(const Context *context,
4092                         angle::EntryPoint entryPoint,
4093                         UniformLocation location,
4094                         GLuint v0)
4095 {
4096     return ValidateUniformES3(context, entryPoint, GL_UNSIGNED_INT, location, 1);
4097 }
4098 
ValidateUniform2ui(const Context * context,angle::EntryPoint entryPoint,UniformLocation location,GLuint v0,GLuint v1)4099 bool ValidateUniform2ui(const Context *context,
4100                         angle::EntryPoint entryPoint,
4101                         UniformLocation location,
4102                         GLuint v0,
4103                         GLuint v1)
4104 {
4105     return ValidateUniformES3(context, entryPoint, GL_UNSIGNED_INT_VEC2, location, 1);
4106 }
4107 
ValidateUniform3ui(const Context * context,angle::EntryPoint entryPoint,UniformLocation location,GLuint v0,GLuint v1,GLuint v2)4108 bool ValidateUniform3ui(const Context *context,
4109                         angle::EntryPoint entryPoint,
4110                         UniformLocation location,
4111                         GLuint v0,
4112                         GLuint v1,
4113                         GLuint v2)
4114 {
4115     return ValidateUniformES3(context, entryPoint, GL_UNSIGNED_INT_VEC3, location, 1);
4116 }
4117 
ValidateUniform4ui(const Context * context,angle::EntryPoint entryPoint,UniformLocation location,GLuint v0,GLuint v1,GLuint v2,GLuint v3)4118 bool ValidateUniform4ui(const Context *context,
4119                         angle::EntryPoint entryPoint,
4120                         UniformLocation location,
4121                         GLuint v0,
4122                         GLuint v1,
4123                         GLuint v2,
4124                         GLuint v3)
4125 {
4126     return ValidateUniformES3(context, entryPoint, GL_UNSIGNED_INT_VEC4, location, 1);
4127 }
4128 
ValidateUniform1uiv(const Context * context,angle::EntryPoint entryPoint,UniformLocation location,GLsizei count,const GLuint * value)4129 bool ValidateUniform1uiv(const Context *context,
4130                          angle::EntryPoint entryPoint,
4131                          UniformLocation location,
4132                          GLsizei count,
4133                          const GLuint *value)
4134 {
4135     return ValidateUniformES3(context, entryPoint, GL_UNSIGNED_INT, location, count);
4136 }
4137 
ValidateUniform2uiv(const Context * context,angle::EntryPoint entryPoint,UniformLocation location,GLsizei count,const GLuint * value)4138 bool ValidateUniform2uiv(const Context *context,
4139                          angle::EntryPoint entryPoint,
4140                          UniformLocation location,
4141                          GLsizei count,
4142                          const GLuint *value)
4143 {
4144     return ValidateUniformES3(context, entryPoint, GL_UNSIGNED_INT_VEC2, location, count);
4145 }
4146 
ValidateUniform3uiv(const Context * context,angle::EntryPoint entryPoint,UniformLocation location,GLsizei count,const GLuint * value)4147 bool ValidateUniform3uiv(const Context *context,
4148                          angle::EntryPoint entryPoint,
4149                          UniformLocation location,
4150                          GLsizei count,
4151                          const GLuint *value)
4152 {
4153     return ValidateUniformES3(context, entryPoint, GL_UNSIGNED_INT_VEC3, location, count);
4154 }
4155 
ValidateUniform4uiv(const Context * context,angle::EntryPoint entryPoint,UniformLocation location,GLsizei count,const GLuint * value)4156 bool ValidateUniform4uiv(const Context *context,
4157                          angle::EntryPoint entryPoint,
4158                          UniformLocation location,
4159                          GLsizei count,
4160                          const GLuint *value)
4161 {
4162     return ValidateUniformES3(context, entryPoint, GL_UNSIGNED_INT_VEC4, location, count);
4163 }
4164 
ValidateIsQuery(const Context * context,angle::EntryPoint entryPoint,QueryID id)4165 bool ValidateIsQuery(const Context *context, angle::EntryPoint entryPoint, QueryID id)
4166 {
4167     if (context->getClientMajorVersion() < 3)
4168     {
4169         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
4170         return false;
4171     }
4172 
4173     return true;
4174 }
4175 
ValidateUniformMatrix2x3fv(const Context * context,angle::EntryPoint entryPoint,UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)4176 bool ValidateUniformMatrix2x3fv(const Context *context,
4177                                 angle::EntryPoint entryPoint,
4178                                 UniformLocation location,
4179                                 GLsizei count,
4180                                 GLboolean transpose,
4181                                 const GLfloat *value)
4182 {
4183     return ValidateUniformMatrixES3(context, entryPoint, GL_FLOAT_MAT2x3, location, count,
4184                                     transpose);
4185 }
4186 
ValidateUniformMatrix3x2fv(const Context * context,angle::EntryPoint entryPoint,UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)4187 bool ValidateUniformMatrix3x2fv(const Context *context,
4188                                 angle::EntryPoint entryPoint,
4189                                 UniformLocation location,
4190                                 GLsizei count,
4191                                 GLboolean transpose,
4192                                 const GLfloat *value)
4193 {
4194     return ValidateUniformMatrixES3(context, entryPoint, GL_FLOAT_MAT3x2, location, count,
4195                                     transpose);
4196 }
4197 
ValidateUniformMatrix2x4fv(const Context * context,angle::EntryPoint entryPoint,UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)4198 bool ValidateUniformMatrix2x4fv(const Context *context,
4199                                 angle::EntryPoint entryPoint,
4200                                 UniformLocation location,
4201                                 GLsizei count,
4202                                 GLboolean transpose,
4203                                 const GLfloat *value)
4204 {
4205     return ValidateUniformMatrixES3(context, entryPoint, GL_FLOAT_MAT2x4, location, count,
4206                                     transpose);
4207 }
4208 
ValidateUniformMatrix4x2fv(const Context * context,angle::EntryPoint entryPoint,UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)4209 bool ValidateUniformMatrix4x2fv(const Context *context,
4210                                 angle::EntryPoint entryPoint,
4211                                 UniformLocation location,
4212                                 GLsizei count,
4213                                 GLboolean transpose,
4214                                 const GLfloat *value)
4215 {
4216     return ValidateUniformMatrixES3(context, entryPoint, GL_FLOAT_MAT4x2, location, count,
4217                                     transpose);
4218 }
4219 
ValidateUniformMatrix3x4fv(const Context * context,angle::EntryPoint entryPoint,UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)4220 bool ValidateUniformMatrix3x4fv(const Context *context,
4221                                 angle::EntryPoint entryPoint,
4222                                 UniformLocation location,
4223                                 GLsizei count,
4224                                 GLboolean transpose,
4225                                 const GLfloat *value)
4226 {
4227     return ValidateUniformMatrixES3(context, entryPoint, GL_FLOAT_MAT3x4, location, count,
4228                                     transpose);
4229 }
4230 
ValidateUniformMatrix4x3fv(const Context * context,angle::EntryPoint entryPoint,UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)4231 bool ValidateUniformMatrix4x3fv(const Context *context,
4232                                 angle::EntryPoint entryPoint,
4233                                 UniformLocation location,
4234                                 GLsizei count,
4235                                 GLboolean transpose,
4236                                 const GLfloat *value)
4237 {
4238     return ValidateUniformMatrixES3(context, entryPoint, GL_FLOAT_MAT4x3, location, count,
4239                                     transpose);
4240 }
4241 
ValidateEndTransformFeedback(const Context * context,angle::EntryPoint entryPoint)4242 bool ValidateEndTransformFeedback(const Context *context, angle::EntryPoint entryPoint)
4243 {
4244     if (context->getClientMajorVersion() < 3)
4245     {
4246         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
4247         return false;
4248     }
4249 
4250     TransformFeedback *transformFeedback = context->getState().getCurrentTransformFeedback();
4251     ASSERT(transformFeedback != nullptr);
4252 
4253     if (!transformFeedback->isActive())
4254     {
4255         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kTransformFeedbackNotActive);
4256         return false;
4257     }
4258 
4259     return true;
4260 }
4261 
ValidateTransformFeedbackVaryings(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,GLsizei count,const GLchar * const * varyings,GLenum bufferMode)4262 bool ValidateTransformFeedbackVaryings(const Context *context,
4263                                        angle::EntryPoint entryPoint,
4264                                        ShaderProgramID program,
4265                                        GLsizei count,
4266                                        const GLchar *const *varyings,
4267                                        GLenum bufferMode)
4268 {
4269     if (context->getClientMajorVersion() < 3)
4270     {
4271         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
4272         return false;
4273     }
4274 
4275     if (count < 0)
4276     {
4277         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeCount);
4278         return false;
4279     }
4280 
4281     switch (bufferMode)
4282     {
4283         case GL_INTERLEAVED_ATTRIBS:
4284             break;
4285         case GL_SEPARATE_ATTRIBS:
4286         {
4287             const Caps &caps = context->getCaps();
4288             if (count > caps.maxTransformFeedbackSeparateAttributes)
4289             {
4290                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidTransformFeedbackAttribsCount);
4291                 return false;
4292             }
4293             break;
4294         }
4295         default:
4296             ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, bufferMode);
4297             return false;
4298     }
4299 
4300     Program *programObject = GetValidProgram(context, entryPoint, program);
4301     if (!programObject)
4302     {
4303         return false;
4304     }
4305 
4306     return true;
4307 }
4308 
ValidateGetTransformFeedbackVarying(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,GLuint index,GLsizei bufSize,const GLsizei * length,const GLsizei * size,const GLenum * type,const GLchar * name)4309 bool ValidateGetTransformFeedbackVarying(const Context *context,
4310                                          angle::EntryPoint entryPoint,
4311                                          ShaderProgramID program,
4312                                          GLuint index,
4313                                          GLsizei bufSize,
4314                                          const GLsizei *length,
4315                                          const GLsizei *size,
4316                                          const GLenum *type,
4317                                          const GLchar *name)
4318 {
4319     if (context->getClientMajorVersion() < 3)
4320     {
4321         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
4322         return false;
4323     }
4324 
4325     if (bufSize < 0)
4326     {
4327         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeBufSize);
4328         return false;
4329     }
4330 
4331     Program *programObject = GetValidProgram(context, entryPoint, program);
4332     if (!programObject)
4333     {
4334         return false;
4335     }
4336 
4337     if (index >= static_cast<GLuint>(
4338                      programObject->getExecutable().getLinkedTransformFeedbackVaryings().size()))
4339     {
4340         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kTransformFeedbackVaryingIndexOutOfRange);
4341         return false;
4342     }
4343 
4344     return true;
4345 }
4346 
ValidateBindTransformFeedback(const Context * context,angle::EntryPoint entryPoint,GLenum target,TransformFeedbackID id)4347 bool ValidateBindTransformFeedback(const Context *context,
4348                                    angle::EntryPoint entryPoint,
4349                                    GLenum target,
4350                                    TransformFeedbackID id)
4351 {
4352     if (context->getClientMajorVersion() < 3)
4353     {
4354         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
4355         return false;
4356     }
4357 
4358     switch (target)
4359     {
4360         case GL_TRANSFORM_FEEDBACK:
4361         {
4362             // Cannot bind a transform feedback object if the current one is started and not
4363             // paused (3.0.2 pg 85 section 2.14.1)
4364             if (context->getState().isTransformFeedbackActiveUnpaused())
4365             {
4366                 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kTransformFeedbackNotPaused);
4367                 return false;
4368             }
4369 
4370             // Cannot bind a transform feedback object that does not exist (3.0.2 pg 85 section
4371             // 2.14.1)
4372             if (!context->isTransformFeedbackGenerated(id))
4373             {
4374                 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kTransformFeedbackDoesNotExist);
4375                 return false;
4376             }
4377         }
4378         break;
4379 
4380         default:
4381             ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, target);
4382             return false;
4383     }
4384 
4385     return true;
4386 }
4387 
ValidateIsTransformFeedback(const Context * context,angle::EntryPoint entryPoint,TransformFeedbackID id)4388 bool ValidateIsTransformFeedback(const Context *context,
4389                                  angle::EntryPoint entryPoint,
4390                                  TransformFeedbackID id)
4391 {
4392     if (context->getClientMajorVersion() < 3)
4393     {
4394         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
4395         return false;
4396     }
4397 
4398     return true;
4399 }
4400 
ValidatePauseTransformFeedback(const Context * context,angle::EntryPoint entryPoint)4401 bool ValidatePauseTransformFeedback(const Context *context, angle::EntryPoint entryPoint)
4402 {
4403     if (context->getClientMajorVersion() < 3)
4404     {
4405         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
4406         return false;
4407     }
4408 
4409     TransformFeedback *transformFeedback = context->getState().getCurrentTransformFeedback();
4410     ASSERT(transformFeedback != nullptr);
4411 
4412     // Current transform feedback must be active and not paused in order to pause (3.0.2 pg 86)
4413     if (!transformFeedback->isActive())
4414     {
4415         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kTransformFeedbackNotActive);
4416         return false;
4417     }
4418 
4419     if (transformFeedback->isPaused())
4420     {
4421         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kTransformFeedbackPaused);
4422         return false;
4423     }
4424 
4425     return true;
4426 }
4427 
ValidateResumeTransformFeedback(const Context * context,angle::EntryPoint entryPoint)4428 bool ValidateResumeTransformFeedback(const Context *context, angle::EntryPoint entryPoint)
4429 {
4430     if (context->getClientMajorVersion() < 3)
4431     {
4432         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
4433         return false;
4434     }
4435 
4436     TransformFeedback *transformFeedback = context->getState().getCurrentTransformFeedback();
4437     ASSERT(transformFeedback != nullptr);
4438 
4439     // Current transform feedback must be active and paused in order to resume (3.0.2 pg 86)
4440     if (!transformFeedback->isActive())
4441     {
4442         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kTransformFeedbackNotActive);
4443         return false;
4444     }
4445 
4446     if (!transformFeedback->isPaused())
4447     {
4448         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kTransformFeedbackNotPaused);
4449         return false;
4450     }
4451 
4452     if (!ValidateProgramExecutableXFBBuffersPresent(
4453             context, context->getState().getLinkedProgramExecutable(context)))
4454     {
4455         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kTransformFeedbackBufferMissing);
4456         return false;
4457     }
4458 
4459     return true;
4460 }
4461 
ValidateVertexAttribI4i(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLuint index,GLint x,GLint y,GLint z,GLint w)4462 bool ValidateVertexAttribI4i(const PrivateState &state,
4463                              ErrorSet *errors,
4464                              angle::EntryPoint entryPoint,
4465                              GLuint index,
4466                              GLint x,
4467                              GLint y,
4468                              GLint z,
4469                              GLint w)
4470 {
4471     if (state.getClientMajorVersion() < 3)
4472     {
4473         errors->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
4474         return false;
4475     }
4476 
4477     return ValidateVertexAttribIndex(state, errors, entryPoint, index);
4478 }
4479 
ValidateVertexAttribI4ui(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLuint index,GLuint x,GLuint y,GLuint z,GLuint w)4480 bool ValidateVertexAttribI4ui(const PrivateState &state,
4481                               ErrorSet *errors,
4482                               angle::EntryPoint entryPoint,
4483                               GLuint index,
4484                               GLuint x,
4485                               GLuint y,
4486                               GLuint z,
4487                               GLuint w)
4488 {
4489     if (state.getClientMajorVersion() < 3)
4490     {
4491         errors->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
4492         return false;
4493     }
4494 
4495     return ValidateVertexAttribIndex(state, errors, entryPoint, index);
4496 }
4497 
ValidateVertexAttribI4iv(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLuint index,const GLint * v)4498 bool ValidateVertexAttribI4iv(const PrivateState &state,
4499                               ErrorSet *errors,
4500                               angle::EntryPoint entryPoint,
4501                               GLuint index,
4502                               const GLint *v)
4503 {
4504     if (state.getClientMajorVersion() < 3)
4505     {
4506         errors->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
4507         return false;
4508     }
4509 
4510     if (v == nullptr)
4511     {
4512         errors->validationError(entryPoint, GL_INVALID_VALUE, kVertexAttributeValueNULL);
4513         return false;
4514     }
4515 
4516     return ValidateVertexAttribIndex(state, errors, entryPoint, index);
4517 }
4518 
ValidateVertexAttribI4uiv(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLuint index,const GLuint * v)4519 bool ValidateVertexAttribI4uiv(const PrivateState &state,
4520                                ErrorSet *errors,
4521                                angle::EntryPoint entryPoint,
4522                                GLuint index,
4523                                const GLuint *v)
4524 {
4525     if (state.getClientMajorVersion() < 3)
4526     {
4527         errors->validationError(entryPoint, GL_INVALID_OPERATION, kES3Required);
4528         return false;
4529     }
4530 
4531     if (v == nullptr)
4532     {
4533         errors->validationError(entryPoint, GL_INVALID_VALUE, kVertexAttributeValueNULL);
4534         return false;
4535     }
4536 
4537     return ValidateVertexAttribIndex(state, errors, entryPoint, index);
4538 }
4539 
ValidateGetFragDataLocation(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,const GLchar * name)4540 bool ValidateGetFragDataLocation(const Context *context,
4541                                  angle::EntryPoint entryPoint,
4542                                  ShaderProgramID program,
4543                                  const GLchar *name)
4544 {
4545     if (context->getClientMajorVersion() < 3)
4546     {
4547         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
4548         return false;
4549     }
4550 
4551     Program *programObject = GetValidProgram(context, entryPoint, program);
4552     if (!programObject)
4553     {
4554         return false;
4555     }
4556 
4557     if (!programObject->isLinked())
4558     {
4559         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kProgramNotLinked);
4560         return false;
4561     }
4562 
4563     return true;
4564 }
4565 
ValidateGetUniformIndices(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,GLsizei uniformCount,const GLchar * const * uniformNames,const GLuint * uniformIndices)4566 bool ValidateGetUniformIndices(const Context *context,
4567                                angle::EntryPoint entryPoint,
4568                                ShaderProgramID program,
4569                                GLsizei uniformCount,
4570                                const GLchar *const *uniformNames,
4571                                const GLuint *uniformIndices)
4572 {
4573     if (context->getClientMajorVersion() < 3)
4574     {
4575         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
4576         return false;
4577     }
4578 
4579     if (uniformCount < 0)
4580     {
4581         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeCount);
4582         return false;
4583     }
4584 
4585     Program *programObject = GetValidProgram(context, entryPoint, program);
4586     if (!programObject)
4587     {
4588         return false;
4589     }
4590 
4591     return true;
4592 }
4593 
ValidateGetActiveUniformsiv(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,GLsizei uniformCount,const GLuint * uniformIndices,GLenum pname,const GLint * params)4594 bool ValidateGetActiveUniformsiv(const Context *context,
4595                                  angle::EntryPoint entryPoint,
4596                                  ShaderProgramID program,
4597                                  GLsizei uniformCount,
4598                                  const GLuint *uniformIndices,
4599                                  GLenum pname,
4600                                  const GLint *params)
4601 {
4602     if (context->getClientMajorVersion() < 3)
4603     {
4604         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
4605         return false;
4606     }
4607 
4608     if (uniformCount < 0)
4609     {
4610         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeCount);
4611         return false;
4612     }
4613 
4614     Program *programObject = GetValidProgram(context, entryPoint, program);
4615     if (!programObject)
4616     {
4617         return false;
4618     }
4619 
4620     switch (pname)
4621     {
4622         case GL_UNIFORM_TYPE:
4623         case GL_UNIFORM_SIZE:
4624             break;
4625         case GL_UNIFORM_NAME_LENGTH:
4626             if (context->getExtensions().webglCompatibilityANGLE)
4627             {
4628                 ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
4629                 return false;
4630             }
4631             break;
4632         case GL_UNIFORM_BLOCK_INDEX:
4633         case GL_UNIFORM_OFFSET:
4634         case GL_UNIFORM_ARRAY_STRIDE:
4635         case GL_UNIFORM_MATRIX_STRIDE:
4636         case GL_UNIFORM_IS_ROW_MAJOR:
4637             break;
4638 
4639         default:
4640             ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
4641             return false;
4642     }
4643 
4644     const size_t programUniformCount = programObject->getExecutable().getUniforms().size();
4645     if (uniformCount > static_cast<GLsizei>(programUniformCount))
4646     {
4647         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kIndexExceedsMaxActiveUniform);
4648         return false;
4649     }
4650 
4651     for (int uniformId = 0; uniformId < uniformCount; uniformId++)
4652     {
4653         const GLuint index = uniformIndices[uniformId];
4654 
4655         if (index >= programUniformCount)
4656         {
4657             ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kIndexExceedsMaxActiveUniform);
4658             return false;
4659         }
4660     }
4661 
4662     return true;
4663 }
4664 
ValidateGetUniformBlockIndex(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,const GLchar * uniformBlockName)4665 bool ValidateGetUniformBlockIndex(const Context *context,
4666                                   angle::EntryPoint entryPoint,
4667                                   ShaderProgramID program,
4668                                   const GLchar *uniformBlockName)
4669 {
4670     if (context->getClientMajorVersion() < 3)
4671     {
4672         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
4673         return false;
4674     }
4675 
4676     Program *programObject = GetValidProgram(context, entryPoint, program);
4677     if (!programObject)
4678     {
4679         return false;
4680     }
4681 
4682     return true;
4683 }
4684 
ValidateGetActiveUniformBlockiv(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,UniformBlockIndex uniformBlockIndex,GLenum pname,const GLint * params)4685 bool ValidateGetActiveUniformBlockiv(const Context *context,
4686                                      angle::EntryPoint entryPoint,
4687                                      ShaderProgramID program,
4688                                      UniformBlockIndex uniformBlockIndex,
4689                                      GLenum pname,
4690                                      const GLint *params)
4691 {
4692     return ValidateGetActiveUniformBlockivBase(context, entryPoint, program, uniformBlockIndex,
4693                                                pname, nullptr);
4694 }
4695 
ValidateGetActiveUniformBlockName(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,UniformBlockIndex uniformBlockIndex,GLsizei bufSize,const GLsizei * length,const GLchar * uniformBlockName)4696 bool ValidateGetActiveUniformBlockName(const Context *context,
4697                                        angle::EntryPoint entryPoint,
4698                                        ShaderProgramID program,
4699                                        UniformBlockIndex uniformBlockIndex,
4700                                        GLsizei bufSize,
4701                                        const GLsizei *length,
4702                                        const GLchar *uniformBlockName)
4703 {
4704     if (context->getClientMajorVersion() < 3)
4705     {
4706         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
4707         return false;
4708     }
4709 
4710     Program *programObject = GetValidProgram(context, entryPoint, program);
4711     if (!programObject)
4712     {
4713         return false;
4714     }
4715 
4716     if (uniformBlockIndex.value >= programObject->getExecutable().getUniformBlocks().size())
4717     {
4718         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kIndexExceedsMaxActiveUniformBlock);
4719         return false;
4720     }
4721 
4722     return true;
4723 }
4724 
ValidateUniformBlockBinding(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,UniformBlockIndex uniformBlockIndex,GLuint uniformBlockBinding)4725 bool ValidateUniformBlockBinding(const Context *context,
4726                                  angle::EntryPoint entryPoint,
4727                                  ShaderProgramID program,
4728                                  UniformBlockIndex uniformBlockIndex,
4729                                  GLuint uniformBlockBinding)
4730 {
4731     if (context->getClientMajorVersion() < 3)
4732     {
4733         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
4734         return false;
4735     }
4736 
4737     if (uniformBlockBinding >= static_cast<GLuint>(context->getCaps().maxUniformBufferBindings))
4738     {
4739         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kIndexExceedsMaxUniformBufferBindings);
4740         return false;
4741     }
4742 
4743     Program *programObject = GetValidProgram(context, entryPoint, program);
4744     if (!programObject)
4745     {
4746         return false;
4747     }
4748 
4749     // if never linked, there won't be any uniform blocks
4750     if (uniformBlockIndex.value >= programObject->getExecutable().getUniformBlocks().size())
4751     {
4752         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kIndexExceedsMaxUniformBufferBindings);
4753         return false;
4754     }
4755 
4756     return true;
4757 }
4758 
ValidateDrawArraysInstanced(const Context * context,angle::EntryPoint entryPoint,PrimitiveMode mode,GLint first,GLsizei count,GLsizei primcount)4759 bool ValidateDrawArraysInstanced(const Context *context,
4760                                  angle::EntryPoint entryPoint,
4761                                  PrimitiveMode mode,
4762                                  GLint first,
4763                                  GLsizei count,
4764                                  GLsizei primcount)
4765 {
4766     if (context->getClientMajorVersion() < 3)
4767     {
4768         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
4769         return false;
4770     }
4771 
4772     return ValidateDrawArraysInstancedBase(context, entryPoint, mode, first, count, primcount, 0);
4773 }
4774 
ValidateFenceSync(const Context * context,angle::EntryPoint entryPoint,GLenum condition,GLbitfield flags)4775 bool ValidateFenceSync(const Context *context,
4776                        angle::EntryPoint entryPoint,
4777                        GLenum condition,
4778                        GLbitfield flags)
4779 {
4780     if ((context->getClientMajorVersion() < 3) && !context->getExtensions().syncARB)
4781     {
4782         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
4783         return false;
4784     }
4785 
4786     if (condition != GL_SYNC_GPU_COMMANDS_COMPLETE)
4787     {
4788         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidFenceCondition);
4789         return false;
4790     }
4791 
4792     if (flags != 0)
4793     {
4794         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidFlags);
4795         return false;
4796     }
4797 
4798     return true;
4799 }
4800 
ValidateIsSync(const Context * context,angle::EntryPoint entryPoint,SyncID syncPacked)4801 bool ValidateIsSync(const Context *context, angle::EntryPoint entryPoint, SyncID syncPacked)
4802 {
4803     if ((context->getClientMajorVersion() < 3) && !context->getExtensions().syncARB)
4804     {
4805         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
4806         return false;
4807     }
4808 
4809     return true;
4810 }
4811 
ValidateDeleteSync(const Context * context,angle::EntryPoint entryPoint,SyncID syncPacked)4812 bool ValidateDeleteSync(const Context *context, angle::EntryPoint entryPoint, SyncID syncPacked)
4813 {
4814     if ((context->getClientMajorVersion() < 3) && !context->getExtensions().syncARB)
4815     {
4816         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
4817         return false;
4818     }
4819 
4820     if (syncPacked.value != 0 && !context->getSync(syncPacked))
4821     {
4822         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kSyncMissing);
4823         return false;
4824     }
4825 
4826     return true;
4827 }
4828 
ValidateClientWaitSync(const Context * context,angle::EntryPoint entryPoint,SyncID syncPacked,GLbitfield flags,GLuint64 timeout)4829 bool ValidateClientWaitSync(const Context *context,
4830                             angle::EntryPoint entryPoint,
4831                             SyncID syncPacked,
4832                             GLbitfield flags,
4833                             GLuint64 timeout)
4834 {
4835     if ((context->getClientMajorVersion() < 3) && !context->getExtensions().syncARB)
4836     {
4837         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
4838         return false;
4839     }
4840 
4841     if (context->getState().getPixelLocalStorageActivePlanes() != 0)
4842     {
4843         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPLSActive);
4844         return false;
4845     }
4846 
4847     if ((flags & ~(GL_SYNC_FLUSH_COMMANDS_BIT)) != 0)
4848     {
4849         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidFlags);
4850         return false;
4851     }
4852 
4853     Sync *clientWaitSync = context->getSync(syncPacked);
4854     if (!clientWaitSync)
4855     {
4856         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kSyncMissing);
4857         return false;
4858     }
4859 
4860     return true;
4861 }
4862 
ValidateWaitSync(const Context * context,angle::EntryPoint entryPoint,SyncID syncPacked,GLbitfield flags,GLuint64 timeout)4863 bool ValidateWaitSync(const Context *context,
4864                       angle::EntryPoint entryPoint,
4865                       SyncID syncPacked,
4866                       GLbitfield flags,
4867                       GLuint64 timeout)
4868 {
4869     if ((context->getClientMajorVersion() < 3) && !context->getExtensions().syncARB)
4870     {
4871         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
4872         return false;
4873     }
4874 
4875     if (flags != 0)
4876     {
4877         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidFlags);
4878         return false;
4879     }
4880 
4881     if (timeout != GL_TIMEOUT_IGNORED)
4882     {
4883         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidTimeout);
4884         return false;
4885     }
4886 
4887     Sync *waitSync = context->getSync(syncPacked);
4888     if (!waitSync)
4889     {
4890         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kSyncMissing);
4891         return false;
4892     }
4893 
4894     return true;
4895 }
4896 
ValidateGetInteger64v(const Context * context,angle::EntryPoint entryPoint,GLenum pname,const GLint64 * params)4897 bool ValidateGetInteger64v(const Context *context,
4898                            angle::EntryPoint entryPoint,
4899                            GLenum pname,
4900                            const GLint64 *params)
4901 {
4902     if ((context->getClientMajorVersion() < 3) && !context->getExtensions().syncARB)
4903     {
4904         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
4905         return false;
4906     }
4907 
4908     GLenum nativeType      = GL_NONE;
4909     unsigned int numParams = 0;
4910     if (!ValidateStateQuery(context, entryPoint, pname, &nativeType, &numParams))
4911     {
4912         return false;
4913     }
4914 
4915     return true;
4916 }
4917 
ValidateIsSampler(const Context * context,angle::EntryPoint entryPoint,SamplerID sampler)4918 bool ValidateIsSampler(const Context *context, angle::EntryPoint entryPoint, SamplerID sampler)
4919 {
4920     if (context->getClientMajorVersion() < 3)
4921     {
4922         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
4923         return false;
4924     }
4925 
4926     return true;
4927 }
4928 
ValidateBindSampler(const Context * context,angle::EntryPoint entryPoint,GLuint unit,SamplerID sampler)4929 bool ValidateBindSampler(const Context *context,
4930                          angle::EntryPoint entryPoint,
4931                          GLuint unit,
4932                          SamplerID sampler)
4933 {
4934     if (context->getClientMajorVersion() < 3)
4935     {
4936         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
4937         return false;
4938     }
4939 
4940     if (GetIDValue(sampler) != 0 && !context->isSampler(sampler))
4941     {
4942         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidSampler);
4943         return false;
4944     }
4945 
4946     if (unit >= static_cast<GLuint>(context->getCaps().maxCombinedTextureImageUnits))
4947     {
4948         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidCombinedImageUnit);
4949         return false;
4950     }
4951 
4952     return true;
4953 }
4954 
ValidateVertexAttribDivisor(const Context * context,angle::EntryPoint entryPoint,GLuint index,GLuint divisor)4955 bool ValidateVertexAttribDivisor(const Context *context,
4956                                  angle::EntryPoint entryPoint,
4957                                  GLuint index,
4958                                  GLuint divisor)
4959 {
4960     if (context->getClientMajorVersion() < 3)
4961     {
4962         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
4963         return false;
4964     }
4965 
4966     return ValidateVertexAttribIndex(context->getPrivateState(),
4967                                      context->getMutableErrorSetForValidation(), entryPoint, index);
4968 }
4969 
ValidateTexStorage2D(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLsizei levels,GLenum internalformat,GLsizei width,GLsizei height)4970 bool ValidateTexStorage2D(const Context *context,
4971                           angle::EntryPoint entryPoint,
4972                           TextureType target,
4973                           GLsizei levels,
4974                           GLenum internalformat,
4975                           GLsizei width,
4976                           GLsizei height)
4977 {
4978     if (context->getClientMajorVersion() < 3)
4979     {
4980         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
4981         return false;
4982     }
4983 
4984     if (!ValidateES3TexStorage2DParameters(context, entryPoint, target, levels, internalformat,
4985                                            width, height, 1))
4986     {
4987         return false;
4988     }
4989 
4990     return true;
4991 }
4992 
ValidateTexStorage3D(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLsizei levels,GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth)4993 bool ValidateTexStorage3D(const Context *context,
4994                           angle::EntryPoint entryPoint,
4995                           TextureType target,
4996                           GLsizei levels,
4997                           GLenum internalformat,
4998                           GLsizei width,
4999                           GLsizei height,
5000                           GLsizei depth)
5001 {
5002     if (context->getClientMajorVersion() < 3)
5003     {
5004         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
5005         return false;
5006     }
5007 
5008     if (!ValidateES3TexStorage3DParameters(context, entryPoint, target, levels, internalformat,
5009                                            width, height, depth))
5010     {
5011         return false;
5012     }
5013 
5014     return true;
5015 }
5016 
ValidateGetBufferParameteri64v(const Context * context,angle::EntryPoint entryPoint,BufferBinding target,GLenum pname,const GLint64 * params)5017 bool ValidateGetBufferParameteri64v(const Context *context,
5018                                     angle::EntryPoint entryPoint,
5019                                     BufferBinding target,
5020                                     GLenum pname,
5021                                     const GLint64 *params)
5022 {
5023     return ValidateGetBufferParameterBase(context, entryPoint, target, pname, false, nullptr);
5024 }
5025 
ValidateGetSamplerParameterfv(const Context * context,angle::EntryPoint entryPoint,SamplerID sampler,GLenum pname,const GLfloat * params)5026 bool ValidateGetSamplerParameterfv(const Context *context,
5027                                    angle::EntryPoint entryPoint,
5028                                    SamplerID sampler,
5029                                    GLenum pname,
5030                                    const GLfloat *params)
5031 {
5032     return ValidateGetSamplerParameterBase(context, entryPoint, sampler, pname, nullptr, params);
5033 }
5034 
ValidateGetSamplerParameteriv(const Context * context,angle::EntryPoint entryPoint,SamplerID sampler,GLenum pname,const GLint * params)5035 bool ValidateGetSamplerParameteriv(const Context *context,
5036                                    angle::EntryPoint entryPoint,
5037                                    SamplerID sampler,
5038                                    GLenum pname,
5039                                    const GLint *params)
5040 {
5041     return ValidateGetSamplerParameterBase(context, entryPoint, sampler, pname, nullptr, params);
5042 }
5043 
ValidateSamplerParameterf(const Context * context,angle::EntryPoint entryPoint,SamplerID sampler,GLenum pname,GLfloat param)5044 bool ValidateSamplerParameterf(const Context *context,
5045                                angle::EntryPoint entryPoint,
5046                                SamplerID sampler,
5047                                GLenum pname,
5048                                GLfloat param)
5049 {
5050     return ValidateSamplerParameterBase(context, entryPoint, sampler, pname, -1, false, &param);
5051 }
5052 
ValidateSamplerParameterfv(const Context * context,angle::EntryPoint entryPoint,SamplerID sampler,GLenum pname,const GLfloat * params)5053 bool ValidateSamplerParameterfv(const Context *context,
5054                                 angle::EntryPoint entryPoint,
5055                                 SamplerID sampler,
5056                                 GLenum pname,
5057                                 const GLfloat *params)
5058 {
5059     return ValidateSamplerParameterBase(context, entryPoint, sampler, pname, -1, true, params);
5060 }
5061 
ValidateSamplerParameteri(const Context * context,angle::EntryPoint entryPoint,SamplerID sampler,GLenum pname,GLint param)5062 bool ValidateSamplerParameteri(const Context *context,
5063                                angle::EntryPoint entryPoint,
5064                                SamplerID sampler,
5065                                GLenum pname,
5066                                GLint param)
5067 {
5068     return ValidateSamplerParameterBase(context, entryPoint, sampler, pname, -1, false, &param);
5069 }
5070 
ValidateSamplerParameteriv(const Context * context,angle::EntryPoint entryPoint,SamplerID sampler,GLenum pname,const GLint * params)5071 bool ValidateSamplerParameteriv(const Context *context,
5072                                 angle::EntryPoint entryPoint,
5073                                 SamplerID sampler,
5074                                 GLenum pname,
5075                                 const GLint *params)
5076 {
5077     return ValidateSamplerParameterBase(context, entryPoint, sampler, pname, -1, true, params);
5078 }
5079 
ValidateGetVertexAttribIiv(const Context * context,angle::EntryPoint entryPoint,GLuint index,GLenum pname,const GLint * params)5080 bool ValidateGetVertexAttribIiv(const Context *context,
5081                                 angle::EntryPoint entryPoint,
5082                                 GLuint index,
5083                                 GLenum pname,
5084                                 const GLint *params)
5085 {
5086     return ValidateGetVertexAttribBase(context, entryPoint, index, pname, nullptr, false, true);
5087 }
5088 
ValidateGetVertexAttribIuiv(const Context * context,angle::EntryPoint entryPoint,GLuint index,GLenum pname,const GLuint * params)5089 bool ValidateGetVertexAttribIuiv(const Context *context,
5090                                  angle::EntryPoint entryPoint,
5091                                  GLuint index,
5092                                  GLenum pname,
5093                                  const GLuint *params)
5094 {
5095     return ValidateGetVertexAttribBase(context, entryPoint, index, pname, nullptr, false, true);
5096 }
5097 
ValidateGetInternalformativ(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLenum internalformat,GLenum pname,GLsizei bufSize,const GLint * params)5098 bool ValidateGetInternalformativ(const Context *context,
5099                                  angle::EntryPoint entryPoint,
5100                                  GLenum target,
5101                                  GLenum internalformat,
5102                                  GLenum pname,
5103                                  GLsizei bufSize,
5104                                  const GLint *params)
5105 {
5106     return ValidateGetInternalFormativBase(context, entryPoint, target, internalformat, pname,
5107                                            bufSize, nullptr);
5108 }
5109 
ValidateBindFragDataLocationIndexedEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,GLuint colorNumber,GLuint index,const char * name)5110 bool ValidateBindFragDataLocationIndexedEXT(const Context *context,
5111                                             angle::EntryPoint entryPoint,
5112                                             ShaderProgramID program,
5113                                             GLuint colorNumber,
5114                                             GLuint index,
5115                                             const char *name)
5116 {
5117     if (!context->getExtensions().blendFuncExtendedEXT)
5118     {
5119         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
5120         return false;
5121     }
5122     if (context->getClientMajorVersion() < 3)
5123     {
5124         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
5125         return false;
5126     }
5127     if (index > 1)
5128     {
5129         // This error is not explicitly specified but the spec does say that "<index> may be zero or
5130         // one to specify that the color be used as either the first or second color input to the
5131         // blend equation, respectively"
5132         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kFragDataBindingIndexOutOfRange);
5133         return false;
5134     }
5135     if (index == 1)
5136     {
5137         if (colorNumber >= context->getCaps().maxDualSourceDrawBuffers)
5138         {
5139             ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE,
5140                                    kColorNumberGreaterThanMaxDualSourceDrawBuffers);
5141             return false;
5142         }
5143     }
5144     else
5145     {
5146         if (colorNumber >= static_cast<GLuint>(context->getCaps().maxDrawBuffers))
5147         {
5148             ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kColorNumberGreaterThanMaxDrawBuffers);
5149             return false;
5150         }
5151     }
5152     Program *programObject = GetValidProgram(context, entryPoint, program);
5153     if (!programObject)
5154     {
5155         return false;
5156     }
5157     return true;
5158 }
5159 
ValidateBindFragDataLocationEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,GLuint colorNumber,const char * name)5160 bool ValidateBindFragDataLocationEXT(const Context *context,
5161                                      angle::EntryPoint entryPoint,
5162                                      ShaderProgramID program,
5163                                      GLuint colorNumber,
5164                                      const char *name)
5165 {
5166     return ValidateBindFragDataLocationIndexedEXT(context, entryPoint, program, colorNumber, 0u,
5167                                                   name);
5168 }
5169 
ValidateGetFragDataIndexEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,const char * name)5170 bool ValidateGetFragDataIndexEXT(const Context *context,
5171                                  angle::EntryPoint entryPoint,
5172                                  ShaderProgramID program,
5173                                  const char *name)
5174 {
5175     if (!context->getExtensions().blendFuncExtendedEXT)
5176     {
5177         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
5178         return false;
5179     }
5180     if (context->getClientMajorVersion() < 3)
5181     {
5182         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
5183         return false;
5184     }
5185     Program *programObject = GetValidProgram(context, entryPoint, program);
5186     if (!programObject)
5187     {
5188         return false;
5189     }
5190     if (!programObject->isLinked())
5191     {
5192         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kProgramNotLinked);
5193         return false;
5194     }
5195     return true;
5196 }
5197 
ValidateTexStorage2DMultisampleANGLE(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLsizei samples,GLenum internalFormat,GLsizei width,GLsizei height,GLboolean fixedSampleLocations)5198 bool ValidateTexStorage2DMultisampleANGLE(const Context *context,
5199                                           angle::EntryPoint entryPoint,
5200                                           TextureType target,
5201                                           GLsizei samples,
5202                                           GLenum internalFormat,
5203                                           GLsizei width,
5204                                           GLsizei height,
5205                                           GLboolean fixedSampleLocations)
5206 {
5207     if (!context->getExtensions().textureMultisampleANGLE)
5208     {
5209         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kMultisampleTextureExtensionOrES31Required);
5210         return false;
5211     }
5212 
5213     return ValidateTexStorage2DMultisampleBase(context, entryPoint, target, samples, internalFormat,
5214                                                width, height);
5215 }
5216 
ValidateGetTexLevelParameterfvANGLE(const Context * context,angle::EntryPoint entryPoint,TextureTarget target,GLint level,GLenum pname,const GLfloat * params)5217 bool ValidateGetTexLevelParameterfvANGLE(const Context *context,
5218                                          angle::EntryPoint entryPoint,
5219                                          TextureTarget target,
5220                                          GLint level,
5221                                          GLenum pname,
5222                                          const GLfloat *params)
5223 {
5224     if (!context->getExtensions().getTexLevelParameterANGLE)
5225     {
5226         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
5227         return false;
5228     }
5229 
5230     return ValidateGetTexLevelParameterBase(context, entryPoint, target, level, pname, nullptr);
5231 }
5232 
ValidateGetTexLevelParameterivANGLE(const Context * context,angle::EntryPoint entryPoint,TextureTarget target,GLint level,GLenum pname,const GLint * params)5233 bool ValidateGetTexLevelParameterivANGLE(const Context *context,
5234                                          angle::EntryPoint entryPoint,
5235                                          TextureTarget target,
5236                                          GLint level,
5237                                          GLenum pname,
5238                                          const GLint *params)
5239 {
5240     if (!context->getExtensions().getTexLevelParameterANGLE)
5241     {
5242         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
5243         return false;
5244     }
5245 
5246     return ValidateGetTexLevelParameterBase(context, entryPoint, target, level, pname, nullptr);
5247 }
5248 
ValidateGetMultisamplefvANGLE(const Context * context,angle::EntryPoint entryPoint,GLenum pname,GLuint index,const GLfloat * val)5249 bool ValidateGetMultisamplefvANGLE(const Context *context,
5250                                    angle::EntryPoint entryPoint,
5251                                    GLenum pname,
5252                                    GLuint index,
5253                                    const GLfloat *val)
5254 {
5255     if (!context->getExtensions().textureMultisampleANGLE)
5256     {
5257         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kMultisampleTextureExtensionOrES31Required);
5258         return false;
5259     }
5260 
5261     return ValidateGetMultisamplefvBase(context, entryPoint, pname, index, val);
5262 }
5263 
ValidateSampleMaskiANGLE(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLuint maskNumber,GLbitfield mask)5264 bool ValidateSampleMaskiANGLE(const PrivateState &state,
5265                               ErrorSet *errors,
5266                               angle::EntryPoint entryPoint,
5267                               GLuint maskNumber,
5268                               GLbitfield mask)
5269 {
5270     if (!state.getExtensions().textureMultisampleANGLE)
5271     {
5272         errors->validationError(entryPoint, GL_INVALID_OPERATION,
5273                                 kMultisampleTextureExtensionOrES31Required);
5274         return false;
5275     }
5276 
5277     return ValidateSampleMaskiBase(state, errors, entryPoint, maskNumber, mask);
5278 }
5279 }  // namespace gl
5280