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