xref: /aosp_15_r20/external/angle/src/libANGLE/validationES2.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 // validationES2.cpp: Validation functions for OpenGL ES 2.0 entry point parameters
8 
9 #include "libANGLE/validationES2_autogen.h"
10 
11 #include <cstdint>
12 
13 #include "common/BinaryStream.h"
14 #include "common/angle_version_info.h"
15 #include "common/mathutil.h"
16 #include "common/string_utils.h"
17 #include "common/utilities.h"
18 #include "libANGLE/Context.h"
19 #include "libANGLE/ErrorStrings.h"
20 #include "libANGLE/Fence.h"
21 #include "libANGLE/Framebuffer.h"
22 #include "libANGLE/FramebufferAttachment.h"
23 #include "libANGLE/MemoryObject.h"
24 #include "libANGLE/Renderbuffer.h"
25 #include "libANGLE/Shader.h"
26 #include "libANGLE/Texture.h"
27 #include "libANGLE/Uniform.h"
28 #include "libANGLE/VertexArray.h"
29 #include "libANGLE/formatutils.h"
30 #include "libANGLE/validationES.h"
31 #include "libANGLE/validationES2.h"
32 #include "libANGLE/validationES32.h"
33 #include "libANGLE/validationES3_autogen.h"
34 
35 namespace gl
36 {
37 using namespace err;
38 
39 namespace
40 {
41 
IsPartialBlit(const Context * context,const FramebufferAttachment * readBuffer,const FramebufferAttachment * writeBuffer,GLint srcX0,GLint srcY0,GLint srcX1,GLint srcY1,GLint dstX0,GLint dstY0,GLint dstX1,GLint dstY1)42 bool IsPartialBlit(const Context *context,
43                    const FramebufferAttachment *readBuffer,
44                    const FramebufferAttachment *writeBuffer,
45                    GLint srcX0,
46                    GLint srcY0,
47                    GLint srcX1,
48                    GLint srcY1,
49                    GLint dstX0,
50                    GLint dstY0,
51                    GLint dstX1,
52                    GLint dstY1)
53 {
54     const Extents &writeSize = writeBuffer->getSize();
55     const Extents &readSize  = readBuffer->getSize();
56 
57     if (srcX0 != 0 || srcY0 != 0 || dstX0 != 0 || dstY0 != 0 || dstX1 != writeSize.width ||
58         dstY1 != writeSize.height || srcX1 != readSize.width || srcY1 != readSize.height)
59     {
60         return true;
61     }
62 
63     if (context->getState().isScissorTestEnabled())
64     {
65         const Rectangle &scissor = context->getState().getScissor();
66         return scissor.x > 0 || scissor.y > 0 || scissor.width < writeSize.width ||
67                scissor.height < writeSize.height;
68     }
69 
70     return false;
71 }
72 
IsValidCopyTextureSourceInternalFormatEnum(GLenum internalFormat)73 bool IsValidCopyTextureSourceInternalFormatEnum(GLenum internalFormat)
74 {
75     // Table 1.1 from the CHROMIUM_copy_texture spec
76     switch (GetUnsizedFormat(internalFormat))
77     {
78         case GL_RED:
79         case GL_ALPHA:
80         case GL_LUMINANCE:
81         case GL_LUMINANCE_ALPHA:
82         case GL_RGB:
83         case GL_RGBA:
84         case GL_RGB8:
85         case GL_RGBA8:
86         case GL_BGRA_EXT:
87         case GL_BGRA8_EXT:
88         case GL_SRGB_ALPHA_EXT:
89             return true;
90 
91         default:
92             return false;
93     }
94 }
95 
IsValidCopySubTextureSourceInternalFormat(GLenum internalFormat)96 bool IsValidCopySubTextureSourceInternalFormat(GLenum internalFormat)
97 {
98     return IsValidCopyTextureSourceInternalFormatEnum(internalFormat);
99 }
100 
IsValidCopyTextureDestinationInternalFormatEnum(GLint internalFormat)101 bool IsValidCopyTextureDestinationInternalFormatEnum(GLint internalFormat)
102 {
103     // Table 1.0 from the CHROMIUM_copy_texture spec
104     switch (internalFormat)
105     {
106         case GL_ALPHA:
107         case GL_BGRA8_EXT:
108         case GL_BGRA_EXT:
109         case GL_LUMINANCE:
110         case GL_LUMINANCE_ALPHA:
111         case GL_R11F_G11F_B10F:
112         case GL_R16F:
113         case GL_R32F:
114         case GL_R8:
115         case GL_R8UI:
116         case GL_RG16F:
117         case GL_RG32F:
118         case GL_RG8:
119         case GL_RG8UI:
120         case GL_RGB:
121         case GL_RGB10_A2:
122         case GL_RGB16F:
123         case GL_RGB32F:
124         case GL_RGB565:
125         case GL_RGB5_A1:
126         case GL_RGB8:
127         case GL_RGB8UI:
128         case GL_RGB9_E5:
129         case GL_RGBA:
130         case GL_RGBA16F:
131         case GL_RGBA32F:
132         case GL_RGBA4:
133         case GL_RGBA8:
134         case GL_RGBA8UI:
135         case GL_RGBX8_ANGLE:
136         case GL_SRGB8:
137         case GL_SRGB8_ALPHA8:
138         case GL_SRGB_ALPHA_EXT:
139         case GL_SRGB_EXT:
140             return true;
141 
142         default:
143             return false;
144     }
145 }
146 
IsValidCopySubTextureDestionationInternalFormat(GLenum internalFormat)147 bool IsValidCopySubTextureDestionationInternalFormat(GLenum internalFormat)
148 {
149     return IsValidCopyTextureDestinationInternalFormatEnum(internalFormat);
150 }
151 
IsValidCopyTextureDestinationFormatType(const Context * context,angle::EntryPoint entryPoint,GLint internalFormat,GLenum type)152 bool IsValidCopyTextureDestinationFormatType(const Context *context,
153                                              angle::EntryPoint entryPoint,
154                                              GLint internalFormat,
155                                              GLenum type)
156 {
157     if (!IsValidCopyTextureDestinationInternalFormatEnum(internalFormat))
158     {
159         ANGLE_VALIDATION_ERRORF(GL_INVALID_OPERATION, kInvalidInternalFormat, internalFormat);
160         return false;
161     }
162 
163     if (!ValidES3FormatCombination(GetUnsizedFormat(internalFormat), type, internalFormat))
164     {
165         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
166         return false;
167     }
168 
169     const InternalFormat &internalFormatInfo = GetInternalFormatInfo(internalFormat, type);
170     if (!internalFormatInfo.textureSupport(context->getClientVersion(), context->getExtensions()))
171     {
172         ANGLE_VALIDATION_ERRORF(GL_INVALID_OPERATION, kInvalidInternalFormat, internalFormat);
173         return false;
174     }
175 
176     return true;
177 }
178 
IsValidCopyTextureDestinationTargetEnum(const Context * context,TextureTarget target)179 bool IsValidCopyTextureDestinationTargetEnum(const Context *context, TextureTarget target)
180 {
181     switch (target)
182     {
183         case TextureTarget::_2D:
184         case TextureTarget::CubeMapNegativeX:
185         case TextureTarget::CubeMapNegativeY:
186         case TextureTarget::CubeMapNegativeZ:
187         case TextureTarget::CubeMapPositiveX:
188         case TextureTarget::CubeMapPositiveY:
189         case TextureTarget::CubeMapPositiveZ:
190             return true;
191 
192         case TextureTarget::Rectangle:
193             return context->getExtensions().textureRectangleANGLE;
194 
195         default:
196             return false;
197     }
198 }
199 
IsValidCopyTextureDestinationTarget(const Context * context,TextureType textureType,TextureTarget target)200 bool IsValidCopyTextureDestinationTarget(const Context *context,
201                                          TextureType textureType,
202                                          TextureTarget target)
203 {
204     return TextureTargetToType(target) == textureType;
205 }
206 
IsValidCopyTextureSourceTarget(const Context * context,TextureType type)207 bool IsValidCopyTextureSourceTarget(const Context *context, TextureType type)
208 {
209     switch (type)
210     {
211         case TextureType::_2D:
212             return true;
213         case TextureType::Rectangle:
214             return context->getExtensions().textureRectangleANGLE;
215         case TextureType::External:
216             return context->getExtensions().EGLImageExternalOES;
217         case TextureType::VideoImage:
218             return context->getExtensions().videoTextureWEBGL;
219         default:
220             return false;
221     }
222 }
223 
IsValidCopyTextureSourceLevel(const Context * context,TextureType type,GLint level)224 bool IsValidCopyTextureSourceLevel(const Context *context, TextureType type, GLint level)
225 {
226     if (!ValidMipLevel(context, type, level))
227     {
228         return false;
229     }
230 
231     if (level > 0 && context->getClientVersion() < ES_3_0)
232     {
233         return false;
234     }
235 
236     return true;
237 }
238 
IsValidCopyTextureDestinationLevel(const Context * context,angle::EntryPoint entryPoint,TextureType type,GLint level,GLsizei width,GLsizei height,bool isSubImage)239 bool IsValidCopyTextureDestinationLevel(const Context *context,
240                                         angle::EntryPoint entryPoint,
241                                         TextureType type,
242                                         GLint level,
243                                         GLsizei width,
244                                         GLsizei height,
245                                         bool isSubImage)
246 {
247     if (!ValidImageSizeParameters(context, entryPoint, type, level, width, height, 1, isSubImage))
248     {
249         return false;
250     }
251 
252     const Caps &caps = context->getCaps();
253     switch (type)
254     {
255         case TextureType::_2D:
256             return width <= (caps.max2DTextureSize >> level) &&
257                    height <= (caps.max2DTextureSize >> level);
258         case TextureType::Rectangle:
259             ASSERT(level == 0);
260             return width <= (caps.max2DTextureSize >> level) &&
261                    height <= (caps.max2DTextureSize >> level);
262 
263         case TextureType::CubeMap:
264             return width <= (caps.maxCubeMapTextureSize >> level) &&
265                    height <= (caps.maxCubeMapTextureSize >> level);
266         default:
267             return true;
268     }
269 }
270 
IsValidStencilFunc(GLenum func)271 bool IsValidStencilFunc(GLenum func)
272 {
273     switch (func)
274     {
275         case GL_NEVER:
276         case GL_ALWAYS:
277         case GL_LESS:
278         case GL_LEQUAL:
279         case GL_EQUAL:
280         case GL_GEQUAL:
281         case GL_GREATER:
282         case GL_NOTEQUAL:
283             return true;
284 
285         default:
286             return false;
287     }
288 }
289 
IsValidStencilFace(GLenum face)290 bool IsValidStencilFace(GLenum face)
291 {
292     switch (face)
293     {
294         case GL_FRONT:
295         case GL_BACK:
296         case GL_FRONT_AND_BACK:
297             return true;
298 
299         default:
300             return false;
301     }
302 }
303 
IsValidStencilOp(GLenum op)304 bool IsValidStencilOp(GLenum op)
305 {
306     switch (op)
307     {
308         case GL_ZERO:
309         case GL_KEEP:
310         case GL_REPLACE:
311         case GL_INCR:
312         case GL_DECR:
313         case GL_INVERT:
314         case GL_INCR_WRAP:
315         case GL_DECR_WRAP:
316             return true;
317 
318         default:
319             return false;
320     }
321 }
322 
Valid1to4ComponentFloatColorBufferFormat(const Context * context,GLenum format)323 static inline bool Valid1to4ComponentFloatColorBufferFormat(const Context *context, GLenum format)
324 {
325     return (context->getExtensions().textureFloatOES &&
326             (format == GL_RGBA32F || format == GL_RGB32F || format == GL_RG32F ||
327              format == GL_R32F)) ||
328            (context->getExtensions().textureHalfFloatOES &&
329             (format == GL_RGBA16F || format == GL_RGB16F || format == GL_RG16F ||
330              format == GL_R16F));
331 }
332 
Valid2to4ComponentFloatColorBufferFormat(const Context * context,GLenum format)333 static inline bool Valid2to4ComponentFloatColorBufferFormat(const Context *context, GLenum format)
334 {
335     return (context->getExtensions().textureFloatOES &&
336             (format == GL_RGBA32F || format == GL_RGB32F || format == GL_RG32F)) ||
337            (context->getExtensions().textureHalfFloatOES &&
338             (format == GL_RGBA16F || format == GL_RGB16F || format == GL_RG16F));
339 }
340 
Valid3to4ComponentFloatColorBufferFormat(const Context * context,GLenum format)341 static inline bool Valid3to4ComponentFloatColorBufferFormat(const Context *context, GLenum format)
342 {
343     return (context->getExtensions().textureFloatOES &&
344             (format == GL_RGBA32F || format == GL_RGB32F)) ||
345            (context->getExtensions().textureHalfFloatOES &&
346             (format == GL_RGBA16F || format == GL_RGB16F));
347 }
348 
Valid4ComponentFloatColorBufferFormat(const Context * context,GLenum format)349 static inline bool Valid4ComponentFloatColorBufferFormat(const Context *context, GLenum format)
350 {
351     return (context->getExtensions().textureFloatOES && format == GL_RGBA32F) ||
352            (context->getExtensions().textureHalfFloatOES && format == GL_RGBA16F);
353 }
354 
ValidateES2CopyTexImageParameters(const Context * context,angle::EntryPoint entryPoint,TextureTarget target,GLint level,GLenum internalformat,bool isSubImage,GLint xoffset,GLint yoffset,GLint x,GLint y,GLsizei width,GLsizei height,GLint border)355 bool ValidateES2CopyTexImageParameters(const Context *context,
356                                        angle::EntryPoint entryPoint,
357                                        TextureTarget target,
358                                        GLint level,
359                                        GLenum internalformat,
360                                        bool isSubImage,
361                                        GLint xoffset,
362                                        GLint yoffset,
363                                        GLint x,
364                                        GLint y,
365                                        GLsizei width,
366                                        GLsizei height,
367                                        GLint border)
368 {
369     if (!ValidTexture2DDestinationTarget(context, target))
370     {
371         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidTextureTarget);
372         return false;
373     }
374 
375     TextureType texType = TextureTargetToType(target);
376     if (!ValidImageSizeParameters(context, entryPoint, texType, level, width, height, 1,
377                                   isSubImage))
378     {
379         // Error is already handled.
380         return false;
381     }
382 
383     Format textureFormat = Format::Invalid();
384     if (!ValidateCopyTexImageParametersBase(context, entryPoint, target, level, internalformat,
385                                             isSubImage, xoffset, yoffset, 0, x, y, width, height,
386                                             border, &textureFormat))
387     {
388         return false;
389     }
390 
391     ASSERT(textureFormat.valid() || !isSubImage);
392 
393     const Framebuffer *framebuffer = context->getState().getReadFramebuffer();
394     GLenum colorbufferFormat =
395         framebuffer->getReadColorAttachment()->getFormat().info->sizedInternalFormat;
396     const auto &formatInfo = *textureFormat.info;
397 
398     // ValidateCopyTexImageParametersBase rejects compressed formats with GL_INVALID_OPERATION.
399     ASSERT(!formatInfo.compressed);
400     ASSERT(!GetInternalFormatInfo(internalformat, GL_UNSIGNED_BYTE).compressed);
401 
402     // ValidateCopyTexImageParametersBase rejects depth formats with GL_INVALID_OPERATION.
403     ASSERT(!formatInfo.depthBits);
404     ASSERT(!GetInternalFormatInfo(internalformat, GL_UNSIGNED_BYTE).depthBits);
405 
406     // [OpenGL ES 2.0.24] table 3.9
407     if (isSubImage)
408     {
409         switch (formatInfo.format)
410         {
411             case GL_ALPHA:
412                 if (colorbufferFormat != GL_ALPHA8_EXT && colorbufferFormat != GL_RGBA4 &&
413                     colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGBA8_OES &&
414                     colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_BGR5_A1_ANGLEX &&
415                     !Valid4ComponentFloatColorBufferFormat(context, colorbufferFormat))
416                 {
417                     ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidFormat);
418                     return false;
419                 }
420                 break;
421             case GL_LUMINANCE:
422                 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
423                     colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
424                     colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
425                     colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGRA8_EXT &&
426                     colorbufferFormat != GL_BGR5_A1_ANGLEX &&
427                     colorbufferFormat != GL_BGRX8_ANGLEX && colorbufferFormat != GL_RGBX8_ANGLE &&
428                     !Valid1to4ComponentFloatColorBufferFormat(context, colorbufferFormat))
429                 {
430                     ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidFormat);
431                     return false;
432                 }
433                 break;
434             case GL_RED_EXT:
435                 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
436                     colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
437                     colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
438                     colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_R32F &&
439                     colorbufferFormat != GL_RG32F && colorbufferFormat != GL_RGB32F &&
440                     colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
441                     colorbufferFormat != GL_BGR5_A1_ANGLEX &&
442                     colorbufferFormat != GL_BGRX8_ANGLEX && colorbufferFormat != GL_RGBX8_ANGLE &&
443                     !Valid1to4ComponentFloatColorBufferFormat(context, colorbufferFormat))
444                 {
445                     ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidFormat);
446                     return false;
447                 }
448                 break;
449             case GL_RG_EXT:
450                 if (colorbufferFormat != GL_RG8_EXT && colorbufferFormat != GL_RGB565 &&
451                     colorbufferFormat != GL_RGB8_OES && colorbufferFormat != GL_RGBA4 &&
452                     colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_RGBA8_OES &&
453                     colorbufferFormat != GL_RG32F && colorbufferFormat != GL_RGB32F &&
454                     colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
455                     colorbufferFormat != GL_BGR5_A1_ANGLEX &&
456                     colorbufferFormat != GL_BGRX8_ANGLEX && colorbufferFormat != GL_RGBX8_ANGLE &&
457                     !Valid2to4ComponentFloatColorBufferFormat(context, colorbufferFormat))
458                 {
459                     ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidFormat);
460                     return false;
461                 }
462                 break;
463             case GL_RGB:
464                 if (colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
465                     colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
466                     colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_RGB32F &&
467                     colorbufferFormat != GL_RGBA32F && colorbufferFormat != GL_BGRA8_EXT &&
468                     colorbufferFormat != GL_BGR5_A1_ANGLEX &&
469                     colorbufferFormat != GL_BGRX8_ANGLEX && colorbufferFormat != GL_RGBX8_ANGLE &&
470                     !Valid3to4ComponentFloatColorBufferFormat(context, colorbufferFormat))
471                 {
472                     ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidFormat);
473                     return false;
474                 }
475                 break;
476             case GL_LUMINANCE_ALPHA:
477             case GL_RGBA:
478             case GL_BGRA_EXT:
479                 if (colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
480                     colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_RGBA32F &&
481                     colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_BGR5_A1_ANGLEX &&
482                     !Valid4ComponentFloatColorBufferFormat(context, colorbufferFormat))
483                 {
484                     ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidFormat);
485                     return false;
486                 }
487                 break;
488             default:
489                 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidFormat);
490                 return false;
491         }
492 
493         if (formatInfo.type == GL_FLOAT && !context->getExtensions().textureFloatOES)
494         {
495             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidFormat);
496             return false;
497         }
498     }
499     else
500     {
501         switch (internalformat)
502         {
503             case GL_ALPHA:
504             case GL_ALPHA8_OES:
505                 if (colorbufferFormat != GL_ALPHA8_EXT && colorbufferFormat != GL_RGBA4 &&
506                     colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_BGRA8_EXT &&
507                     colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGR5_A1_ANGLEX &&
508                     !Valid4ComponentFloatColorBufferFormat(context, colorbufferFormat))
509                 {
510                     ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidFormat);
511                     return false;
512                 }
513                 break;
514             case GL_LUMINANCE:
515             case GL_LUMINANCE8_OES:
516             case GL_RED_EXT:
517                 if (colorbufferFormat != GL_R8_EXT && colorbufferFormat != GL_RG8_EXT &&
518                     colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
519                     colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
520                     colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
521                     colorbufferFormat != GL_BGR5_A1_ANGLEX &&
522                     colorbufferFormat != GL_BGRX8_ANGLEX && colorbufferFormat != GL_RGBX8_ANGLE &&
523                     !Valid1to4ComponentFloatColorBufferFormat(context, colorbufferFormat))
524                 {
525                     ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidFormat);
526                     return false;
527                 }
528                 break;
529             case GL_RG_EXT:
530                 if (colorbufferFormat != GL_RG8_EXT && colorbufferFormat != GL_RGB565 &&
531                     colorbufferFormat != GL_RGB8_OES && colorbufferFormat != GL_RGBA4 &&
532                     colorbufferFormat != GL_RGB5_A1 && colorbufferFormat != GL_BGRA8_EXT &&
533                     colorbufferFormat != GL_RGBA8_OES && colorbufferFormat != GL_BGR5_A1_ANGLEX &&
534                     colorbufferFormat != GL_BGRX8_ANGLEX && colorbufferFormat != GL_RGBX8_ANGLE &&
535                     !Valid2to4ComponentFloatColorBufferFormat(context, colorbufferFormat))
536                 {
537                     ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidFormat);
538                     return false;
539                 }
540                 break;
541             case GL_RGB:
542             case GL_RGB565_OES:
543             case GL_RGB8_OES:
544                 if (colorbufferFormat != GL_RGB565 && colorbufferFormat != GL_RGB8_OES &&
545                     colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
546                     colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
547                     colorbufferFormat != GL_BGR5_A1_ANGLEX &&
548                     colorbufferFormat != GL_BGRX8_ANGLEX && colorbufferFormat != GL_RGBX8_ANGLE &&
549                     !Valid3to4ComponentFloatColorBufferFormat(context, colorbufferFormat))
550                 {
551                     ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidFormat);
552                     return false;
553                 }
554                 break;
555             case GL_LUMINANCE_ALPHA:
556             case GL_LUMINANCE4_ALPHA4_OES:
557             case GL_LUMINANCE8_ALPHA8_OES:
558             case GL_RGBA:
559             case GL_BGRA_EXT:
560             case GL_RGBA4_OES:
561             case GL_RGB5_A1_OES:
562             case GL_RGBA8_OES:
563                 if (colorbufferFormat != GL_RGBA4 && colorbufferFormat != GL_RGB5_A1 &&
564                     colorbufferFormat != GL_BGRA8_EXT && colorbufferFormat != GL_RGBA8_OES &&
565                     colorbufferFormat != GL_BGR5_A1_ANGLEX && colorbufferFormat != GL_RGBA16F &&
566                     !Valid4ComponentFloatColorBufferFormat(context, colorbufferFormat))
567                 {
568                     ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidFormat);
569                     return false;
570                 }
571                 break;
572             default:
573                 ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, internalformat);
574                 return false;
575         }
576     }
577 
578     // If width or height is zero, it is a no-op.  Return false without setting an error.
579     return (width > 0 && height > 0);
580 }
581 
582 // ANGLE_shader_pixel_local_storage: INVALID_OPERATION is generated by Enable(), Disable() if <cap>
583 // is not one of: CULL_FACE, DEBUG_OUTPUT, DEBUG_OUTPUT_SYNCHRONOUS, DEPTH_CLAMP_EXT, DEPTH_TEST,
584 // POLYGON_OFFSET_FILL, PRIMITIVE_RESTART_FIXED_INDEX, SCISSOR_TEST, SCISSOR_TEST_EXCLUSIVE_NV,
585 // STENCIL_TEST, CLIP_DISTANCE[0..7]_EXT
IsCapBannedWithActivePLS(GLenum cap)586 static bool IsCapBannedWithActivePLS(GLenum cap)
587 {
588     switch (cap)
589     {
590         case GL_BLEND:
591         case GL_CULL_FACE:
592         case GL_DEBUG_OUTPUT:
593         case GL_DEBUG_OUTPUT_SYNCHRONOUS:
594         case GL_DEPTH_CLAMP_EXT:
595         case GL_DEPTH_TEST:
596         case GL_POLYGON_OFFSET_POINT_NV:
597         case GL_POLYGON_OFFSET_LINE_NV:  // = GL_POLYGON_OFFSET_LINE_ANGLE
598         case GL_POLYGON_OFFSET_FILL:
599         case GL_PRIMITIVE_RESTART_FIXED_INDEX:
600         case GL_SCISSOR_TEST:
601         case GL_SCISSOR_TEST_EXCLUSIVE_NV:
602         case GL_STENCIL_TEST:
603         case GL_CLIP_DISTANCE0_EXT:
604         case GL_CLIP_DISTANCE1_EXT:
605         case GL_CLIP_DISTANCE2_EXT:
606         case GL_CLIP_DISTANCE3_EXT:
607         case GL_CLIP_DISTANCE4_EXT:
608         case GL_CLIP_DISTANCE5_EXT:
609         case GL_CLIP_DISTANCE6_EXT:
610         case GL_CLIP_DISTANCE7_EXT:
611             return false;
612         default:
613             return true;
614     }
615 }
616 
ValidCap(const PrivateState & state,ErrorSet * errors,GLenum cap,bool queryOnly)617 bool ValidCap(const PrivateState &state, ErrorSet *errors, GLenum cap, bool queryOnly)
618 {
619     switch (cap)
620     {
621         // EXT_multisample_compatibility
622         case GL_MULTISAMPLE_EXT:
623         case GL_SAMPLE_ALPHA_TO_ONE_EXT:
624             return state.getExtensions().multisampleCompatibilityEXT;
625 
626         case GL_CULL_FACE:
627         case GL_POLYGON_OFFSET_FILL:
628         case GL_SAMPLE_ALPHA_TO_COVERAGE:
629         case GL_SAMPLE_COVERAGE:
630         case GL_SCISSOR_TEST:
631         case GL_STENCIL_TEST:
632         case GL_DEPTH_TEST:
633         case GL_BLEND:
634         case GL_DITHER:
635             return true;
636 
637         case GL_POLYGON_OFFSET_POINT_NV:
638             return state.getExtensions().polygonModeNV;
639         case GL_POLYGON_OFFSET_LINE_NV:  // = GL_POLYGON_OFFSET_LINE_ANGLE
640             return state.getExtensions().polygonModeAny();
641 
642         case GL_DEPTH_CLAMP_EXT:
643             return state.getExtensions().depthClampEXT;
644 
645         case GL_PRIMITIVE_RESTART_FIXED_INDEX:
646         case GL_RASTERIZER_DISCARD:
647             return (state.getClientMajorVersion() >= 3);
648 
649         case GL_DEBUG_OUTPUT_SYNCHRONOUS:
650         case GL_DEBUG_OUTPUT:
651             return state.getExtensions().debugKHR;
652 
653         case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
654             return queryOnly && state.getExtensions().bindGeneratesResourceCHROMIUM;
655 
656         case GL_CLIENT_ARRAYS_ANGLE:
657             return queryOnly && state.getExtensions().clientArraysANGLE;
658 
659         case GL_FRAMEBUFFER_SRGB_EXT:
660             return state.getExtensions().sRGBWriteControlEXT;
661 
662         case GL_SAMPLE_MASK:
663             return state.getClientVersion() >= Version(3, 1) ||
664                    state.getExtensions().textureMultisampleANGLE;
665 
666         case GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
667             return queryOnly && state.getExtensions().robustResourceInitializationANGLE;
668 
669         case GL_TEXTURE_RECTANGLE_ANGLE:
670             return state.isWebGL();
671 
672         // GL_APPLE_clip_distance / GL_EXT_clip_cull_distance / GL_ANGLE_clip_cull_distance
673         case GL_CLIP_DISTANCE0_EXT:
674         case GL_CLIP_DISTANCE1_EXT:
675         case GL_CLIP_DISTANCE2_EXT:
676         case GL_CLIP_DISTANCE3_EXT:
677         case GL_CLIP_DISTANCE4_EXT:
678         case GL_CLIP_DISTANCE5_EXT:
679         case GL_CLIP_DISTANCE6_EXT:
680         case GL_CLIP_DISTANCE7_EXT:
681             if (state.getExtensions().clipDistanceAPPLE ||
682                 state.getExtensions().clipCullDistanceAny())
683             {
684                 return true;
685             }
686             break;
687         case GL_SAMPLE_SHADING:
688             return state.getExtensions().sampleShadingOES;
689         case GL_SHADING_RATE_PRESERVE_ASPECT_RATIO_QCOM:
690             return state.getExtensions().shadingRateQCOM;
691 
692         // COLOR_LOGIC_OP is in GLES1, but exposed through an ANGLE extension.
693         case GL_COLOR_LOGIC_OP:
694             return state.getClientVersion() < Version(2, 0) || state.getExtensions().logicOpANGLE;
695 
696         case GL_FETCH_PER_SAMPLE_ARM:
697             return state.getExtensions().shaderFramebufferFetchARM;
698 
699         case GL_FRAGMENT_SHADER_FRAMEBUFFER_FETCH_MRT_ARM:
700             return queryOnly && state.getExtensions().shaderFramebufferFetchARM;
701 
702         case GL_BLEND_ADVANCED_COHERENT_KHR:
703             return state.getClientVersion() >= Version(2, 0) &&
704                    state.getExtensions().blendEquationAdvancedCoherentKHR;
705 
706         default:
707             break;
708     }
709 
710     // GLES1 emulation: GLES1-specific caps after this point
711     if (state.getClientVersion().major != 1)
712     {
713         return false;
714     }
715 
716     switch (cap)
717     {
718         case GL_ALPHA_TEST:
719         case GL_VERTEX_ARRAY:
720         case GL_NORMAL_ARRAY:
721         case GL_COLOR_ARRAY:
722         case GL_TEXTURE_COORD_ARRAY:
723         case GL_TEXTURE_2D:
724         case GL_LIGHTING:
725         case GL_LIGHT0:
726         case GL_LIGHT1:
727         case GL_LIGHT2:
728         case GL_LIGHT3:
729         case GL_LIGHT4:
730         case GL_LIGHT5:
731         case GL_LIGHT6:
732         case GL_LIGHT7:
733         case GL_NORMALIZE:
734         case GL_RESCALE_NORMAL:
735         case GL_COLOR_MATERIAL:
736         case GL_CLIP_PLANE0:
737         case GL_CLIP_PLANE1:
738         case GL_CLIP_PLANE2:
739         case GL_CLIP_PLANE3:
740         case GL_CLIP_PLANE4:
741         case GL_CLIP_PLANE5:
742         case GL_FOG:
743         case GL_POINT_SMOOTH:
744         case GL_LINE_SMOOTH:
745             return state.getClientVersion() < Version(2, 0);
746         case GL_POINT_SIZE_ARRAY_OES:
747             return state.getClientVersion() < Version(2, 0) &&
748                    state.getExtensions().pointSizeArrayOES;
749         case GL_TEXTURE_CUBE_MAP:
750             return state.getClientVersion() < Version(2, 0) &&
751                    state.getExtensions().textureCubeMapOES;
752         case GL_POINT_SPRITE_OES:
753             return state.getClientVersion() < Version(2, 0) && state.getExtensions().pointSpriteOES;
754         default:
755             return false;
756     }
757 }
758 
759 // Return true if a character belongs to the ASCII subset as defined in GLSL ES 1.0 spec section
760 // 3.1.
IsValidESSLCharacter(unsigned char c)761 bool IsValidESSLCharacter(unsigned char c)
762 {
763     // Printing characters are valid except " $ ` @ \ ' DEL.
764     if (c >= 32 && c <= 126 && c != '"' && c != '$' && c != '`' && c != '@' && c != '\\' &&
765         c != '\'')
766     {
767         return true;
768     }
769 
770     // Horizontal tab, line feed, vertical tab, form feed, carriage return are also valid.
771     if (c >= 9 && c <= 13)
772     {
773         return true;
774     }
775 
776     return false;
777 }
778 
IsValidESSLString(const char * str,size_t len)779 bool IsValidESSLString(const char *str, size_t len)
780 {
781     for (size_t i = 0; i < len; i++)
782     {
783         if (!IsValidESSLCharacter(str[i]))
784         {
785             return false;
786         }
787     }
788 
789     return true;
790 }
791 
ValidateWebGLNamePrefix(const Context * context,angle::EntryPoint entryPoint,const GLchar * name)792 bool ValidateWebGLNamePrefix(const Context *context,
793                              angle::EntryPoint entryPoint,
794                              const GLchar *name)
795 {
796     ASSERT(context->isWebGL());
797 
798     // WebGL 1.0 [Section 6.16] GLSL Constructs
799     // Identifiers starting with "webgl_" and "_webgl_" are reserved for use by WebGL.
800     if (strncmp(name, "webgl_", 6) == 0 || strncmp(name, "_webgl_", 7) == 0)
801     {
802         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kWebglBindAttribLocationReservedPrefix);
803         return false;
804     }
805 
806     return true;
807 }
808 
ValidateWebGLNameLength(const Context * context,angle::EntryPoint entryPoint,size_t length)809 bool ValidateWebGLNameLength(const Context *context, angle::EntryPoint entryPoint, size_t length)
810 {
811     ASSERT(context->isWebGL());
812 
813     if (context->isWebGL1() && length > 256)
814     {
815         // WebGL 1.0 [Section 6.21] Maxmimum Uniform and Attribute Location Lengths
816         // WebGL imposes a limit of 256 characters on the lengths of uniform and attribute
817         // locations.
818         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kWebglNameLengthLimitExceeded);
819 
820         return false;
821     }
822     else if (length > 1024)
823     {
824         // WebGL 2.0 [Section 4.3.2] WebGL 2.0 imposes a limit of 1024 characters on the lengths of
825         // uniform and attribute locations.
826         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kWebgl2NameLengthLimitExceeded);
827         return false;
828     }
829 
830     return true;
831 }
832 
ValidateSrcBlendFunc(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLenum val)833 bool ValidateSrcBlendFunc(const PrivateState &state,
834                           ErrorSet *errors,
835                           angle::EntryPoint entryPoint,
836                           GLenum val)
837 {
838     switch (val)
839     {
840         case GL_ZERO:
841         case GL_ONE:
842         case GL_SRC_COLOR:
843         case GL_ONE_MINUS_SRC_COLOR:
844         case GL_DST_COLOR:
845         case GL_ONE_MINUS_DST_COLOR:
846         case GL_SRC_ALPHA:
847         case GL_ONE_MINUS_SRC_ALPHA:
848         case GL_DST_ALPHA:
849         case GL_ONE_MINUS_DST_ALPHA:
850         case GL_CONSTANT_COLOR:
851         case GL_ONE_MINUS_CONSTANT_COLOR:
852         case GL_CONSTANT_ALPHA:
853         case GL_ONE_MINUS_CONSTANT_ALPHA:
854         case GL_SRC_ALPHA_SATURATE:
855             return true;
856 
857         // EXT_blend_func_extended, excluding GL_SRC_ALPHA_SATURATE_EXT, which equals
858         // GL_SRC_ALPHA_SATURATE and is handled above.
859         case GL_SRC1_COLOR_EXT:
860         case GL_SRC1_ALPHA_EXT:
861         case GL_ONE_MINUS_SRC1_COLOR_EXT:
862         case GL_ONE_MINUS_SRC1_ALPHA_EXT:
863             if (!state.getExtensions().blendFuncExtendedEXT)
864             {
865                 break;
866             }
867             if (state.getPixelLocalStorageActivePlanes() != 0)
868             {
869                 // INVALID_OPERATION is generated by BlendFunc*() if <srcRGB>, <dstRGB>, <srcAlpha>,
870                 // or <dstAlpha> is a blend function requiring the secondary color input, as
871                 // specified in EXT_blend_func_extended (SRC1_COLOR_EXT, ONE_MINUS_SRC1_COLOR_EXT,
872                 // SRC1_ALPHA_EXT, ONE_MINUS_SRC1_ALPHA_EXT).
873                 errors->validationError(entryPoint, GL_INVALID_OPERATION,
874                                         kPLSSecondaryBlendNotSupported);
875                 return false;
876             }
877             return true;
878     }
879 
880     errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidBlendFunction);
881     return false;
882 }
883 
ValidateDstBlendFunc(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLenum val)884 bool ValidateDstBlendFunc(const PrivateState &state,
885                           ErrorSet *errors,
886                           angle::EntryPoint entryPoint,
887                           GLenum val)
888 {
889     if (val == GL_SRC_ALPHA_SATURATE)
890     {
891         // Unextended ES2 does not allow GL_SRC_ALPHA_SATURATE as a dst blend func.
892         if (state.getClientMajorVersion() < 3 && !state.getExtensions().blendFuncExtendedEXT)
893         {
894             errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidBlendFunction);
895             return false;
896         }
897     }
898 
899     return ValidateSrcBlendFunc(state, errors, entryPoint, val);
900 }
901 
ValidateES2TexImageParameters(const Context * context,angle::EntryPoint entryPoint,TextureTarget target,GLint level,GLenum internalformat,bool isCompressed,bool isSubImage,GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,GLint border,GLenum format,GLenum type,GLsizei imageSize,const void * pixels)902 bool ValidateES2TexImageParameters(const Context *context,
903                                    angle::EntryPoint entryPoint,
904                                    TextureTarget target,
905                                    GLint level,
906                                    GLenum internalformat,
907                                    bool isCompressed,
908                                    bool isSubImage,
909                                    GLint xoffset,
910                                    GLint yoffset,
911                                    GLsizei width,
912                                    GLsizei height,
913                                    GLint border,
914                                    GLenum format,
915                                    GLenum type,
916                                    GLsizei imageSize,
917                                    const void *pixels)
918 {
919     if (!ValidTexture2DDestinationTarget(context, target))
920     {
921         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidTextureTarget);
922         return false;
923     }
924 
925     return ValidateES2TexImageParametersBase(context, entryPoint, target, level, internalformat,
926                                              isCompressed, isSubImage, xoffset, yoffset, width,
927                                              height, border, format, type, imageSize, pixels);
928 }
929 
930 }  // anonymous namespace
931 
ValidateES2TexImageParametersBase(const Context * context,angle::EntryPoint entryPoint,TextureTarget target,GLint level,GLenum internalformat,bool isCompressed,bool isSubImage,GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,GLint border,GLenum format,GLenum type,GLsizei imageSize,const void * pixels)932 bool ValidateES2TexImageParametersBase(const Context *context,
933                                        angle::EntryPoint entryPoint,
934                                        TextureTarget target,
935                                        GLint level,
936                                        GLenum internalformat,
937                                        bool isCompressed,
938                                        bool isSubImage,
939                                        GLint xoffset,
940                                        GLint yoffset,
941                                        GLsizei width,
942                                        GLsizei height,
943                                        GLint border,
944                                        GLenum format,
945                                        GLenum type,
946                                        GLsizei imageSize,
947                                        const void *pixels)
948 {
949 
950     TextureType texType = TextureTargetToType(target);
951     if (!ValidImageSizeParameters(context, entryPoint, texType, level, width, height, 1,
952                                   isSubImage))
953     {
954         // Error already handled.
955         return false;
956     }
957 
958     if ((xoffset < 0 || std::numeric_limits<GLsizei>::max() - xoffset < width) ||
959         (yoffset < 0 || std::numeric_limits<GLsizei>::max() - yoffset < height))
960     {
961         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kResourceMaxTextureSize);
962         return false;
963     }
964 
965     const Caps &caps = context->getCaps();
966 
967     switch (texType)
968     {
969         case TextureType::_2D:
970         case TextureType::External:
971         case TextureType::VideoImage:
972             if (width > (caps.max2DTextureSize >> level) ||
973                 height > (caps.max2DTextureSize >> level))
974             {
975                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kResourceMaxTextureSize);
976                 return false;
977             }
978             break;
979 
980         case TextureType::Rectangle:
981             ASSERT(level == 0);
982             if (width > caps.maxRectangleTextureSize || height > caps.maxRectangleTextureSize)
983             {
984                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kResourceMaxTextureSize);
985                 return false;
986             }
987             if (isCompressed)
988             {
989                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kRectangleTextureCompressed);
990                 return false;
991             }
992             break;
993 
994         case TextureType::CubeMap:
995             if (!isSubImage && width != height)
996             {
997                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kCubemapFacesEqualDimensions);
998                 return false;
999             }
1000 
1001             if (width > (caps.maxCubeMapTextureSize >> level) ||
1002                 height > (caps.maxCubeMapTextureSize >> level))
1003             {
1004                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kResourceMaxTextureSize);
1005                 return false;
1006             }
1007             break;
1008 
1009         default:
1010             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidTextureTarget);
1011             return false;
1012     }
1013 
1014     Texture *texture = context->getTextureByType(texType);
1015     if (!texture)
1016     {
1017         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBufferNotBound);
1018         return false;
1019     }
1020 
1021     // Verify zero border
1022     if (border != 0)
1023     {
1024         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidBorder);
1025         return false;
1026     }
1027 
1028     bool nonEqualFormatsAllowed = false;
1029 
1030     if (isCompressed)
1031     {
1032         GLenum actualInternalFormat =
1033             isSubImage ? texture->getFormat(target, level).info->sizedInternalFormat
1034                        : internalformat;
1035 
1036         const InternalFormat &internalFormatInfo = GetSizedInternalFormatInfo(actualInternalFormat);
1037 
1038         if (!internalFormatInfo.compressed && !internalFormatInfo.paletted)
1039         {
1040             ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kInvalidInternalFormat, internalformat);
1041             return false;
1042         }
1043 
1044         if (!internalFormatInfo.textureSupport(context->getClientVersion(),
1045                                                context->getExtensions()))
1046         {
1047             ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kInvalidInternalFormat, internalformat);
1048             return false;
1049         }
1050 
1051         if (isSubImage)
1052         {
1053             // From OpenGL ES Version 1.1.12, section 3.7.4 Compressed Paletted
1054             // Textures:
1055             //
1056             // Subimages may not be specified for compressed paletted textures.
1057             // Calling CompressedTexSubImage2D with any of the PALETTE*
1058             // arguments in table 3.11 will generate an INVALID OPERATION error.
1059             if (internalFormatInfo.paletted)
1060             {
1061                 ANGLE_VALIDATION_ERRORF(GL_INVALID_OPERATION, kInvalidInternalFormat,
1062                                         internalformat);
1063                 return false;
1064             }
1065 
1066             // From the OES_compressed_ETC1_RGB8_texture spec:
1067             //
1068             // INVALID_OPERATION is generated by CompressedTexSubImage2D, TexSubImage2D, or
1069             // CopyTexSubImage2D if the texture image <level> bound to <target> has internal format
1070             // ETC1_RGB8_OES.
1071             //
1072             // This is relaxed if GL_EXT_compressed_ETC1_RGB8_sub_texture is supported.
1073             if (IsETC1Format(actualInternalFormat) &&
1074                 !context->getExtensions().compressedETC1RGB8SubTextureEXT)
1075             {
1076                 ANGLE_VALIDATION_ERRORF(GL_INVALID_OPERATION, kInvalidInternalFormat,
1077                                         internalformat);
1078                 return false;
1079             }
1080 
1081             if (!ValidCompressedSubImageSize(context, actualInternalFormat, xoffset, yoffset, 0,
1082                                              width, height, 1, texture->getWidth(target, level),
1083                                              texture->getHeight(target, level),
1084                                              texture->getDepth(target, level)))
1085             {
1086                 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidCompressedImageSize);
1087                 return false;
1088             }
1089 
1090             if (format != actualInternalFormat)
1091             {
1092                 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidFormat);
1093                 return false;
1094             }
1095         }
1096         else
1097         {
1098             if (!ValidCompressedImageSize(context, actualInternalFormat, level, width, height, 1))
1099             {
1100                 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidCompressedImageSize);
1101                 return false;
1102             }
1103         }
1104     }
1105     else
1106     {
1107         // validate <type> by itself (used as secondary key below)
1108         switch (type)
1109         {
1110             case GL_UNSIGNED_BYTE:
1111             case GL_UNSIGNED_SHORT_5_6_5:
1112             case GL_UNSIGNED_SHORT_4_4_4_4:
1113             case GL_UNSIGNED_SHORT_5_5_5_1:
1114             case GL_UNSIGNED_SHORT:
1115             case GL_UNSIGNED_INT:
1116             case GL_UNSIGNED_INT_24_8_OES:
1117             case GL_HALF_FLOAT_OES:
1118             case GL_FLOAT:
1119                 break;
1120             case GL_UNSIGNED_INT_2_10_10_10_REV_EXT:
1121                 if (!context->getExtensions().textureType2101010REVEXT)
1122                 {
1123                     ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, type);
1124                     return false;
1125                 }
1126                 break;
1127             default:
1128                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidType);
1129                 return false;
1130         }
1131 
1132         // validate <format> + <type> combinations
1133         // - invalid <format> -> sets INVALID_ENUM
1134         // - invalid <format>+<type> combination -> sets INVALID_OPERATION
1135         switch (format)
1136         {
1137             case GL_ALPHA:
1138             case GL_LUMINANCE:
1139             case GL_LUMINANCE_ALPHA:
1140                 switch (type)
1141                 {
1142                     case GL_UNSIGNED_BYTE:
1143                     case GL_FLOAT:
1144                     case GL_HALF_FLOAT_OES:
1145                         break;
1146                     default:
1147                         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
1148                         return false;
1149                 }
1150                 break;
1151             case GL_RED:
1152             case GL_RG:
1153                 if (!context->getExtensions().textureRgEXT)
1154                 {
1155                     ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, format);
1156                     return false;
1157                 }
1158                 switch (type)
1159                 {
1160                     case GL_UNSIGNED_BYTE:
1161                         break;
1162                     case GL_FLOAT:
1163                         if (!context->getExtensions().textureFloatOES)
1164                         {
1165                             ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, type);
1166                             return false;
1167                         }
1168                         break;
1169                     case GL_HALF_FLOAT_OES:
1170                         if (!context->getExtensions().textureFloatOES &&
1171                             !context->getExtensions().textureHalfFloatOES)
1172                         {
1173                             ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, type);
1174                             return false;
1175                         }
1176                         break;
1177                     case GL_SHORT:
1178                     case GL_UNSIGNED_SHORT:
1179                         if (!context->getExtensions().textureNorm16EXT)
1180                         {
1181                             ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, type);
1182                             return false;
1183                         }
1184                         break;
1185                     default:
1186                         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
1187                         return false;
1188                 }
1189                 break;
1190             case GL_RGB:
1191                 switch (type)
1192                 {
1193                     case GL_UNSIGNED_BYTE:
1194                     case GL_UNSIGNED_SHORT_5_6_5:
1195                     case GL_UNSIGNED_INT_2_10_10_10_REV_EXT:
1196                     case GL_FLOAT:
1197                     case GL_HALF_FLOAT_OES:
1198                         break;
1199                     case GL_SHORT:
1200                     case GL_UNSIGNED_SHORT:
1201                         if (!context->getExtensions().textureNorm16EXT)
1202                         {
1203                             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
1204                             return false;
1205                         }
1206                         break;
1207                     default:
1208                         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
1209                         return false;
1210                 }
1211                 break;
1212             case GL_RGBA:
1213                 switch (type)
1214                 {
1215                     case GL_UNSIGNED_BYTE:
1216                     case GL_UNSIGNED_SHORT_4_4_4_4:
1217                     case GL_UNSIGNED_SHORT_5_5_5_1:
1218                     case GL_FLOAT:
1219                     case GL_HALF_FLOAT_OES:
1220                     case GL_UNSIGNED_INT_2_10_10_10_REV_EXT:
1221                         break;
1222                     case GL_SHORT:
1223                     case GL_UNSIGNED_SHORT:
1224                         if (!context->getExtensions().textureNorm16EXT)
1225                         {
1226                             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
1227                             return false;
1228                         }
1229                         break;
1230                     default:
1231                         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
1232                         return false;
1233                 }
1234                 break;
1235             case GL_BGRA_EXT:
1236                 if (!context->getExtensions().textureFormatBGRA8888EXT)
1237                 {
1238                     ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, format);
1239                     return false;
1240                 }
1241                 switch (type)
1242                 {
1243                     case GL_UNSIGNED_BYTE:
1244                         break;
1245                     default:
1246                         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
1247                         return false;
1248                 }
1249                 break;
1250             case GL_SRGB_EXT:
1251             case GL_SRGB_ALPHA_EXT:
1252                 if (!context->getExtensions().sRGBEXT)
1253                 {
1254                     ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, format);
1255                     return false;
1256                 }
1257                 switch (type)
1258                 {
1259                     case GL_UNSIGNED_BYTE:
1260                         break;
1261                     default:
1262                         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
1263                         return false;
1264                 }
1265                 break;
1266             case GL_DEPTH_COMPONENT:
1267                 switch (type)
1268                 {
1269                     case GL_UNSIGNED_SHORT:
1270                     case GL_UNSIGNED_INT:
1271                         break;
1272                     case GL_FLOAT:
1273                         if (!context->getExtensions().depthBufferFloat2NV)
1274                         {
1275                             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
1276                             return false;
1277                         }
1278                         break;
1279                     default:
1280                         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
1281                         return false;
1282                 }
1283                 break;
1284             case GL_DEPTH_STENCIL_OES:
1285                 switch (type)
1286                 {
1287                     case GL_UNSIGNED_INT_24_8_OES:
1288                         break;
1289                     default:
1290                         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
1291                         return false;
1292                 }
1293                 break;
1294             default:
1295                 ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, format);
1296                 return false;
1297         }
1298 
1299         switch (format)
1300         {
1301             case GL_DEPTH_COMPONENT:
1302             case GL_DEPTH_STENCIL_OES:
1303                 if (!context->getExtensions().depthTextureANGLE &&
1304                     !((context->getExtensions().packedDepthStencilOES ||
1305                        context->getExtensions().depthTextureCubeMapOES) &&
1306                       context->getExtensions().depthTextureOES))
1307                 {
1308                     ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, format);
1309                     return false;
1310                 }
1311 
1312                 switch (target)
1313                 {
1314                     case TextureTarget::_2D:
1315                         break;
1316                     case TextureTarget::CubeMapNegativeX:
1317                     case TextureTarget::CubeMapNegativeY:
1318                     case TextureTarget::CubeMapNegativeZ:
1319                     case TextureTarget::CubeMapPositiveX:
1320                     case TextureTarget::CubeMapPositiveY:
1321                     case TextureTarget::CubeMapPositiveZ:
1322                         if (!context->getExtensions().depthTextureCubeMapOES)
1323                         {
1324                             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION,
1325                                                    kMismatchedTargetAndFormat);
1326                             return false;
1327                         }
1328                         break;
1329                     default:
1330                         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kMismatchedTargetAndFormat);
1331                         return false;
1332                 }
1333 
1334                 // OES_depth_texture supports loading depth data and multiple levels,
1335                 // but ANGLE_depth_texture does not
1336                 if (!context->getExtensions().depthTextureOES)
1337                 {
1338                     if (pixels != nullptr)
1339                     {
1340                         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPixelDataNotNull);
1341                         return false;
1342                     }
1343                     if (level != 0)
1344                     {
1345                         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kLevelNotZero);
1346                         return false;
1347                     }
1348                 }
1349                 break;
1350             default:
1351                 break;
1352         }
1353 
1354         if (!isSubImage)
1355         {
1356             switch (internalformat)
1357             {
1358                 // Core ES 2.0 formats
1359                 case GL_ALPHA:
1360                 case GL_LUMINANCE:
1361                 case GL_LUMINANCE_ALPHA:
1362                 case GL_RGB:
1363                 case GL_RGBA:
1364                     break;
1365 
1366                 case GL_RGBA32F:
1367                     if (!context->getExtensions().colorBufferFloatRgbaCHROMIUM)
1368                     {
1369                         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidFormat);
1370                         return false;
1371                     }
1372 
1373                     nonEqualFormatsAllowed = true;
1374 
1375                     if (type != GL_FLOAT)
1376                     {
1377                         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
1378                         return false;
1379                     }
1380                     if (format != GL_RGBA)
1381                     {
1382                         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
1383                         return false;
1384                     }
1385                     break;
1386 
1387                 case GL_RGB32F:
1388                     if (!context->getExtensions().colorBufferFloatRgbCHROMIUM)
1389                     {
1390                         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidFormat);
1391                         return false;
1392                     }
1393 
1394                     nonEqualFormatsAllowed = true;
1395 
1396                     if (type != GL_FLOAT)
1397                     {
1398                         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
1399                         return false;
1400                     }
1401                     if (format != GL_RGB)
1402                     {
1403                         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
1404                         return false;
1405                     }
1406                     break;
1407 
1408                 case GL_BGRA_EXT:
1409                     if (!context->getExtensions().textureFormatBGRA8888EXT)
1410                     {
1411                         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidFormat);
1412                         return false;
1413                     }
1414                     break;
1415 
1416                 case GL_DEPTH_COMPONENT:
1417                     if (!(context->getExtensions().depthTextureAny()))
1418                     {
1419                         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidFormat);
1420                         return false;
1421                     }
1422                     break;
1423 
1424                 case GL_DEPTH_STENCIL:
1425                     if (!(context->getExtensions().depthTextureANGLE ||
1426                           context->getExtensions().packedDepthStencilOES ||
1427                           context->getExtensions().depthTextureCubeMapOES))
1428                     {
1429                         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidFormat);
1430                         return false;
1431                     }
1432                     break;
1433                 // Valid sized internal format for GL_OES_required_internalformat.
1434                 case GL_ALPHA8_OES:
1435                     if (context->getExtensions().requiredInternalformatOES &&
1436                         type == GL_UNSIGNED_BYTE && format == GL_ALPHA)
1437                     {
1438                         nonEqualFormatsAllowed = true;
1439                     }
1440                     break;
1441 
1442                 case GL_LUMINANCE8_OES:
1443                     if (context->getExtensions().requiredInternalformatOES &&
1444                         type == GL_UNSIGNED_BYTE && format == GL_LUMINANCE)
1445                     {
1446                         nonEqualFormatsAllowed = true;
1447                     }
1448                     break;
1449 
1450                 case GL_LUMINANCE4_ALPHA4_OES:
1451                     if (context->getExtensions().requiredInternalformatOES &&
1452                         type == GL_UNSIGNED_BYTE && format == GL_LUMINANCE_ALPHA)
1453                     {
1454                         nonEqualFormatsAllowed = true;
1455                     }
1456                     break;
1457 
1458                 case GL_LUMINANCE8_ALPHA8_OES:
1459                     if (context->getExtensions().requiredInternalformatOES &&
1460                         type == GL_UNSIGNED_BYTE && format == GL_LUMINANCE_ALPHA)
1461                     {
1462                         nonEqualFormatsAllowed = true;
1463                     }
1464                     break;
1465 
1466                 case GL_RGB565_OES:
1467                     if (context->getExtensions().requiredInternalformatOES &&
1468                         (type == GL_UNSIGNED_BYTE || type == GL_UNSIGNED_SHORT_5_6_5) &&
1469                         format == GL_RGB)
1470                     {
1471                         nonEqualFormatsAllowed = true;
1472                     }
1473                     if (context->getExtensions().requiredInternalformatOES &&
1474                         context->getExtensions().textureType2101010REVEXT &&
1475                         GL_UNSIGNED_INT_2_10_10_10_REV_EXT && format == GL_RGB)
1476                     {
1477                         nonEqualFormatsAllowed = true;
1478                     }
1479                     break;
1480 
1481                 case GL_RGB8_OES:
1482                     if (context->getExtensions().requiredInternalformatOES &&
1483                         type == GL_UNSIGNED_BYTE && format == GL_RGB)
1484                     {
1485                         nonEqualFormatsAllowed = true;
1486                     }
1487                     if (context->getExtensions().requiredInternalformatOES &&
1488                         context->getExtensions().textureType2101010REVEXT &&
1489                         GL_UNSIGNED_INT_2_10_10_10_REV_EXT && format == GL_RGB)
1490                     {
1491                         nonEqualFormatsAllowed = true;
1492                     }
1493                     break;
1494 
1495                 case GL_RGBA4_OES:
1496                     if (context->getExtensions().requiredInternalformatOES &&
1497                         (type == GL_UNSIGNED_BYTE || type == GL_UNSIGNED_SHORT_4_4_4_4) &&
1498                         format == GL_RGBA)
1499                     {
1500                         nonEqualFormatsAllowed = true;
1501                     }
1502                     break;
1503 
1504                 case GL_RGB5_A1:
1505                     if (context->getExtensions().requiredInternalformatOES &&
1506                         (type == GL_UNSIGNED_BYTE || type == GL_UNSIGNED_SHORT_5_5_5_1) &&
1507                         format == GL_RGBA)
1508                     {
1509                         nonEqualFormatsAllowed = true;
1510                     }
1511                     if (context->getExtensions().requiredInternalformatOES &&
1512                         context->getExtensions().textureType2101010REVEXT &&
1513                         type == GL_UNSIGNED_INT_2_10_10_10_REV_EXT && format == GL_RGBA)
1514                     {
1515                         nonEqualFormatsAllowed = true;
1516                     }
1517                     break;
1518 
1519                 case GL_RGBA8_OES:
1520                     if (context->getExtensions().requiredInternalformatOES &&
1521                         type == GL_UNSIGNED_BYTE && format == GL_RGBA)
1522                     {
1523                         nonEqualFormatsAllowed = true;
1524                     }
1525                     break;
1526 
1527                 case GL_DEPTH_COMPONENT16_OES:
1528                     if (context->getExtensions().requiredInternalformatOES &&
1529                         (type == GL_UNSIGNED_SHORT || type == GL_UNSIGNED_INT) &&
1530                         format == GL_DEPTH_COMPONENT)
1531                     {
1532                         nonEqualFormatsAllowed = true;
1533                     }
1534                     break;
1535 
1536                 case GL_DEPTH_COMPONENT24_OES:
1537                     if ((context->getExtensions().requiredInternalformatOES &&
1538                          context->getExtensions().depth24OES) &&
1539                         type == GL_UNSIGNED_INT && format == GL_DEPTH_COMPONENT)
1540                     {
1541                         nonEqualFormatsAllowed = true;
1542                     }
1543                     break;
1544 
1545                 case GL_DEPTH_COMPONENT32_OES:
1546                     if ((context->getExtensions().requiredInternalformatOES &&
1547                          context->getExtensions().depth32OES) &&
1548                         type == GL_UNSIGNED_INT && format == GL_DEPTH_COMPONENT)
1549                     {
1550                         nonEqualFormatsAllowed = true;
1551                     }
1552                     break;
1553 
1554                 case GL_DEPTH24_STENCIL8_OES:
1555                     if ((context->getExtensions().requiredInternalformatOES &&
1556                          context->getExtensions().packedDepthStencilOES) &&
1557                         type == GL_UNSIGNED_INT_24_8_OES && format == GL_DEPTH_STENCIL_OES)
1558                     {
1559                         nonEqualFormatsAllowed = true;
1560                     }
1561                     break;
1562 
1563                 case GL_RED:
1564                 case GL_RG:
1565                     if (!context->getExtensions().textureRgEXT)
1566                     {
1567                         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidFormat);
1568                         return false;
1569                     }
1570                     break;
1571 
1572                 case GL_SRGB_EXT:
1573                 case GL_SRGB_ALPHA_EXT:
1574                     if (!context->getExtensions().sRGBEXT)
1575                     {
1576                         ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, internalformat);
1577                         return false;
1578                     }
1579                     break;
1580 
1581                 case GL_RGB10_A2_EXT:
1582                     if (!context->getExtensions().textureType2101010REVEXT)
1583                     {
1584                         ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, internalformat);
1585                         return false;
1586                     }
1587 
1588                     if (type != GL_UNSIGNED_INT_2_10_10_10_REV_EXT || format != GL_RGBA)
1589                     {
1590                         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kMismatchedTypeAndFormat);
1591                         return false;
1592                     }
1593 
1594                     nonEqualFormatsAllowed = true;
1595 
1596                     break;
1597 
1598                 case GL_RGBX8_ANGLE:
1599                     if (context->getExtensions().rgbxInternalFormatANGLE &&
1600                         type == GL_UNSIGNED_BYTE && format == GL_RGB)
1601                     {
1602                         nonEqualFormatsAllowed = true;
1603                     }
1604 
1605                     break;
1606 
1607                 case GL_R16_EXT:
1608                 case GL_RG16_EXT:
1609                 case GL_RGB16_EXT:
1610                 case GL_RGBA16_EXT:
1611                 case GL_R16_SNORM_EXT:
1612                 case GL_RG16_SNORM_EXT:
1613                 case GL_RGB16_SNORM_EXT:
1614                 case GL_RGBA16_SNORM_EXT:
1615                     if (!context->getExtensions().textureNorm16EXT)
1616                     {
1617                         ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, internalformat);
1618                         return false;
1619                     }
1620                     break;
1621                 default:
1622                     // Compressed formats are not valid internal formats for glTexImage*D
1623                     ANGLE_VALIDATION_ERRORF(GL_INVALID_VALUE, kInvalidInternalFormat,
1624                                             internalformat);
1625                     return false;
1626             }
1627         }
1628 
1629         if (type == GL_FLOAT)
1630         {
1631             if (!context->getExtensions().textureFloatOES)
1632             {
1633                 ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, type);
1634                 return false;
1635             }
1636         }
1637         else if (type == GL_HALF_FLOAT_OES)
1638         {
1639             if (!context->getExtensions().textureHalfFloatOES)
1640             {
1641                 ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, type);
1642                 return false;
1643             }
1644         }
1645     }
1646 
1647     if (isSubImage)
1648     {
1649         const InternalFormat &textureInternalFormat = *texture->getFormat(target, level).info;
1650         if (textureInternalFormat.internalFormat == GL_NONE)
1651         {
1652             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidTextureLevel);
1653             return false;
1654         }
1655 
1656         if (format != textureInternalFormat.format)
1657         {
1658             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, err::kTextureFormatMismatch);
1659             return false;
1660         }
1661 
1662         if (context->isWebGL())
1663         {
1664             if (GetInternalFormatInfo(format, type).sizedInternalFormat !=
1665                 textureInternalFormat.sizedInternalFormat)
1666             {
1667                 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kTextureTypeMismatch);
1668                 return false;
1669             }
1670         }
1671 
1672         if (static_cast<size_t>(xoffset + width) > texture->getWidth(target, level) ||
1673             static_cast<size_t>(yoffset + height) > texture->getHeight(target, level))
1674         {
1675             ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kOffsetOverflow);
1676             return false;
1677         }
1678 
1679         if (width > 0 && height > 0 && pixels == nullptr &&
1680             context->getState().getTargetBuffer(BufferBinding::PixelUnpack) == nullptr)
1681         {
1682             ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kPixelDataNull);
1683             return false;
1684         }
1685     }
1686     else
1687     {
1688         if (texture->getImmutableFormat())
1689         {
1690             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kTextureIsImmutable);
1691             return false;
1692         }
1693     }
1694 
1695     // From GL_CHROMIUM_color_buffer_float_rgb[a]:
1696     // GL_RGB[A] / GL_RGB[A]32F becomes an allowable format / internalformat parameter pair for
1697     // TexImage2D. The restriction in section 3.7.1 of the OpenGL ES 2.0 spec that the
1698     // internalformat parameter and format parameter of TexImage2D must match is lifted for this
1699     // case.
1700     if (!isSubImage && !isCompressed && internalformat != format && !nonEqualFormatsAllowed)
1701     {
1702         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidFormatCombination);
1703         return false;
1704     }
1705 
1706     GLenum sizeCheckFormat = isSubImage ? format : internalformat;
1707     return ValidImageDataSize(context, entryPoint, texType, width, height, 1, sizeCheckFormat, type,
1708                               pixels, imageSize);
1709 }
1710 
ValidateES2TexStorageParametersBase(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLsizei levels,GLenum internalformat,GLsizei width,GLsizei height)1711 bool ValidateES2TexStorageParametersBase(const Context *context,
1712                                          angle::EntryPoint entryPoint,
1713                                          TextureType target,
1714                                          GLsizei levels,
1715                                          GLenum internalformat,
1716                                          GLsizei width,
1717                                          GLsizei height)
1718 {
1719     if (target != TextureType::_2D && target != TextureType::CubeMap &&
1720         target != TextureType::Rectangle)
1721     {
1722         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidTextureTarget);
1723         return false;
1724     }
1725 
1726     if (width < 1 || height < 1 || levels < 1)
1727     {
1728         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kTextureSizeTooSmall);
1729         return false;
1730     }
1731 
1732     if (target == TextureType::CubeMap && width != height)
1733     {
1734         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kCubemapFacesEqualDimensions);
1735         return false;
1736     }
1737 
1738     if (levels != 1 && levels != log2(std::max(width, height)) + 1)
1739     {
1740         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidMipLevels);
1741         return false;
1742     }
1743 
1744     const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalformat);
1745     if (formatInfo.format == GL_NONE || formatInfo.type == GL_NONE)
1746     {
1747         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidFormat);
1748         return false;
1749     }
1750 
1751     const Caps &caps = context->getCaps();
1752 
1753     switch (target)
1754     {
1755         case TextureType::_2D:
1756             if (width > caps.max2DTextureSize || height > caps.max2DTextureSize)
1757             {
1758                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kResourceMaxTextureSize);
1759                 return false;
1760             }
1761             break;
1762         case TextureType::Rectangle:
1763             if (levels != 1)
1764             {
1765                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidMipLevel);
1766                 return false;
1767             }
1768 
1769             if (width > caps.maxRectangleTextureSize || height > caps.maxRectangleTextureSize)
1770             {
1771                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kResourceMaxTextureSize);
1772                 return false;
1773             }
1774             if (formatInfo.compressed)
1775             {
1776                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kRectangleTextureCompressed);
1777                 return false;
1778             }
1779             break;
1780         case TextureType::CubeMap:
1781             if (width > caps.maxCubeMapTextureSize || height > caps.maxCubeMapTextureSize)
1782             {
1783                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kResourceMaxTextureSize);
1784                 return false;
1785             }
1786             break;
1787         case TextureType::InvalidEnum:
1788             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kEnumInvalid);
1789             return false;
1790         default:
1791             ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, ToGLenum(target));
1792             return false;
1793     }
1794 
1795     if (levels != 1 && !context->getExtensions().textureNpotOES)
1796     {
1797         if (!isPow2(width) || !isPow2(height))
1798         {
1799             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kDimensionsMustBePow2);
1800             return false;
1801         }
1802     }
1803 
1804     if (!formatInfo.textureSupport(context->getClientVersion(), context->getExtensions()))
1805     {
1806         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidFormat);
1807         return false;
1808     }
1809 
1810     // Even with OES_texture_npot, some compressed formats may impose extra restrictions.
1811     if (formatInfo.compressed)
1812     {
1813         if (!ValidCompressedImageSize(context, formatInfo.internalFormat, 0, width, height, 1))
1814         {
1815             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidCompressedImageSize);
1816             return false;
1817         }
1818     }
1819 
1820     switch (internalformat)
1821     {
1822         case GL_DEPTH_COMPONENT16:
1823         case GL_DEPTH_COMPONENT32_OES:
1824             switch (target)
1825             {
1826                 case TextureType::_2D:
1827                     break;
1828                 case TextureType::CubeMap:
1829                     if (!context->getExtensions().depthTextureCubeMapOES)
1830                     {
1831                         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidTextureTarget);
1832                         return false;
1833                     }
1834                     break;
1835                 default:
1836                     ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidTextureTarget);
1837                     return false;
1838             }
1839 
1840             // ANGLE_depth_texture only supports 1-level textures
1841             if (!context->getExtensions().depthTextureOES)
1842             {
1843                 if (levels != 1)
1844                 {
1845                     ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidMipLevels);
1846                     return false;
1847                 }
1848             }
1849             break;
1850         case GL_DEPTH24_STENCIL8_OES:
1851             switch (target)
1852             {
1853                 case TextureType::_2D:
1854                     break;
1855                 case TextureType::CubeMap:
1856                     if (!context->getExtensions().depthTextureCubeMapOES)
1857                     {
1858                         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidTextureTarget);
1859                         return false;
1860                     }
1861                     break;
1862                 default:
1863                     ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidTextureTarget);
1864                     return false;
1865             }
1866 
1867             if (!context->getExtensions().packedDepthStencilOES &&
1868                 !context->getExtensions().depthTextureCubeMapOES)
1869             {
1870                 // ANGLE_depth_texture only supports 1-level textures
1871                 if (levels != 1)
1872                 {
1873                     ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidMipLevels);
1874                     return false;
1875                 }
1876             }
1877             break;
1878 
1879         default:
1880             break;
1881     }
1882 
1883     Texture *texture = context->getTextureByType(target);
1884     if (!texture || texture->id().value == 0)
1885     {
1886         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kMissingTexture);
1887         return false;
1888     }
1889 
1890     if (texture->getImmutableFormat())
1891     {
1892         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kTextureIsImmutable);
1893         return false;
1894     }
1895 
1896     return true;
1897 }
1898 
ValidateDiscardFramebufferEXT(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLsizei numAttachments,const GLenum * attachments)1899 bool ValidateDiscardFramebufferEXT(const Context *context,
1900                                    angle::EntryPoint entryPoint,
1901                                    GLenum target,
1902                                    GLsizei numAttachments,
1903                                    const GLenum *attachments)
1904 {
1905     if (!context->getExtensions().discardFramebufferEXT)
1906     {
1907         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1908         return false;
1909     }
1910 
1911     bool defaultFramebuffer = false;
1912 
1913     switch (target)
1914     {
1915         case GL_FRAMEBUFFER:
1916             defaultFramebuffer =
1917                 (context->getState().getTargetFramebuffer(GL_FRAMEBUFFER)->isDefault());
1918             break;
1919         default:
1920             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidFramebufferTarget);
1921             return false;
1922     }
1923 
1924     return ValidateDiscardFramebufferBase(context, entryPoint, target, numAttachments, attachments,
1925                                           defaultFramebuffer);
1926 }
1927 
ValidateBindVertexArrayOES(const Context * context,angle::EntryPoint entryPoint,VertexArrayID array)1928 bool ValidateBindVertexArrayOES(const Context *context,
1929                                 angle::EntryPoint entryPoint,
1930                                 VertexArrayID array)
1931 {
1932     if (!context->getExtensions().vertexArrayObjectOES)
1933     {
1934         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1935         return false;
1936     }
1937 
1938     return ValidateBindVertexArrayBase(context, entryPoint, array);
1939 }
1940 
ValidateDeleteVertexArraysOES(const Context * context,angle::EntryPoint entryPoint,GLsizei n,const VertexArrayID * arrays)1941 bool ValidateDeleteVertexArraysOES(const Context *context,
1942                                    angle::EntryPoint entryPoint,
1943                                    GLsizei n,
1944                                    const VertexArrayID *arrays)
1945 {
1946     if (!context->getExtensions().vertexArrayObjectOES)
1947     {
1948         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1949         return false;
1950     }
1951 
1952     return ValidateGenOrDelete(context, entryPoint, n);
1953 }
1954 
ValidateGenVertexArraysOES(const Context * context,angle::EntryPoint entryPoint,GLsizei n,const VertexArrayID * arrays)1955 bool ValidateGenVertexArraysOES(const Context *context,
1956                                 angle::EntryPoint entryPoint,
1957                                 GLsizei n,
1958                                 const VertexArrayID *arrays)
1959 {
1960     if (!context->getExtensions().vertexArrayObjectOES)
1961     {
1962         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1963         return false;
1964     }
1965 
1966     return ValidateGenOrDelete(context, entryPoint, n);
1967 }
1968 
ValidateIsVertexArrayOES(const Context * context,angle::EntryPoint entryPoint,VertexArrayID array)1969 bool ValidateIsVertexArrayOES(const Context *context,
1970                               angle::EntryPoint entryPoint,
1971                               VertexArrayID array)
1972 {
1973     if (!context->getExtensions().vertexArrayObjectOES)
1974     {
1975         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1976         return false;
1977     }
1978 
1979     return true;
1980 }
1981 
ValidateProgramBinaryOES(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,GLenum binaryFormat,const void * binary,GLint length)1982 bool ValidateProgramBinaryOES(const Context *context,
1983                               angle::EntryPoint entryPoint,
1984                               ShaderProgramID program,
1985                               GLenum binaryFormat,
1986                               const void *binary,
1987                               GLint length)
1988 {
1989     if (!context->getExtensions().getProgramBinaryOES)
1990     {
1991         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1992         return false;
1993     }
1994 
1995     return ValidateProgramBinaryBase(context, entryPoint, program, binaryFormat, binary, length);
1996 }
1997 
ValidateGetProgramBinaryOES(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,GLsizei bufSize,const GLsizei * length,const GLenum * binaryFormat,const void * binary)1998 bool ValidateGetProgramBinaryOES(const Context *context,
1999                                  angle::EntryPoint entryPoint,
2000                                  ShaderProgramID program,
2001                                  GLsizei bufSize,
2002                                  const GLsizei *length,
2003                                  const GLenum *binaryFormat,
2004                                  const void *binary)
2005 {
2006     if (!context->getExtensions().getProgramBinaryOES)
2007     {
2008         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
2009         return false;
2010     }
2011 
2012     return ValidateGetProgramBinaryBase(context, entryPoint, program, bufSize, length, binaryFormat,
2013                                         binary);
2014 }
2015 
ValidDebugSource(GLenum source,bool mustBeThirdPartyOrApplication)2016 static bool ValidDebugSource(GLenum source, bool mustBeThirdPartyOrApplication)
2017 {
2018     switch (source)
2019     {
2020         case GL_DEBUG_SOURCE_API:
2021         case GL_DEBUG_SOURCE_SHADER_COMPILER:
2022         case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
2023         case GL_DEBUG_SOURCE_OTHER:
2024             // Only THIRD_PARTY and APPLICATION sources are allowed to be manually inserted
2025             return !mustBeThirdPartyOrApplication;
2026 
2027         case GL_DEBUG_SOURCE_THIRD_PARTY:
2028         case GL_DEBUG_SOURCE_APPLICATION:
2029             return true;
2030 
2031         default:
2032             return false;
2033     }
2034 }
2035 
ValidDebugType(GLenum type)2036 static bool ValidDebugType(GLenum type)
2037 {
2038     switch (type)
2039     {
2040         case GL_DEBUG_TYPE_ERROR:
2041         case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
2042         case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
2043         case GL_DEBUG_TYPE_PERFORMANCE:
2044         case GL_DEBUG_TYPE_PORTABILITY:
2045         case GL_DEBUG_TYPE_OTHER:
2046         case GL_DEBUG_TYPE_MARKER:
2047         case GL_DEBUG_TYPE_PUSH_GROUP:
2048         case GL_DEBUG_TYPE_POP_GROUP:
2049             return true;
2050 
2051         default:
2052             return false;
2053     }
2054 }
2055 
ValidDebugSeverity(GLenum severity)2056 static bool ValidDebugSeverity(GLenum severity)
2057 {
2058     switch (severity)
2059     {
2060         case GL_DEBUG_SEVERITY_HIGH:
2061         case GL_DEBUG_SEVERITY_MEDIUM:
2062         case GL_DEBUG_SEVERITY_LOW:
2063         case GL_DEBUG_SEVERITY_NOTIFICATION:
2064             return true;
2065 
2066         default:
2067             return false;
2068     }
2069 }
2070 
ValidateDebugMessageControlKHR(const Context * context,angle::EntryPoint entryPoint,GLenum source,GLenum type,GLenum severity,GLsizei count,const GLuint * ids,GLboolean enabled)2071 bool ValidateDebugMessageControlKHR(const Context *context,
2072                                     angle::EntryPoint entryPoint,
2073                                     GLenum source,
2074                                     GLenum type,
2075                                     GLenum severity,
2076                                     GLsizei count,
2077                                     const GLuint *ids,
2078                                     GLboolean enabled)
2079 {
2080     if (!context->getExtensions().debugKHR)
2081     {
2082         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
2083         return false;
2084     }
2085 
2086     if (!ValidDebugSource(source, false) && source != GL_DONT_CARE)
2087     {
2088         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidDebugSource);
2089         return false;
2090     }
2091 
2092     if (!ValidDebugType(type) && type != GL_DONT_CARE)
2093     {
2094         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidDebugType);
2095         return false;
2096     }
2097 
2098     if (!ValidDebugSeverity(severity) && severity != GL_DONT_CARE)
2099     {
2100         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidDebugSeverity);
2101         return false;
2102     }
2103 
2104     if (count > 0)
2105     {
2106         if (source == GL_DONT_CARE || type == GL_DONT_CARE)
2107         {
2108             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidDebugSourceType);
2109             return false;
2110         }
2111 
2112         if (severity != GL_DONT_CARE)
2113         {
2114             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidDebugSeverity);
2115             return false;
2116         }
2117     }
2118 
2119     return true;
2120 }
2121 
ValidateDebugMessageInsertKHR(const Context * context,angle::EntryPoint entryPoint,GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar * buf)2122 bool ValidateDebugMessageInsertKHR(const Context *context,
2123                                    angle::EntryPoint entryPoint,
2124                                    GLenum source,
2125                                    GLenum type,
2126                                    GLuint id,
2127                                    GLenum severity,
2128                                    GLsizei length,
2129                                    const GLchar *buf)
2130 {
2131     if (!context->getExtensions().debugKHR)
2132     {
2133         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
2134         return false;
2135     }
2136 
2137     if (!context->getState().getDebug().isOutputEnabled())
2138     {
2139         // If the DEBUG_OUTPUT state is disabled calls to DebugMessageInsert are discarded and do
2140         // not generate an error.
2141         return false;
2142     }
2143 
2144     if (!ValidDebugSeverity(severity))
2145     {
2146         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidDebugSource);
2147         return false;
2148     }
2149 
2150     if (!ValidDebugType(type))
2151     {
2152         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidDebugType);
2153         return false;
2154     }
2155 
2156     if (!ValidDebugSource(source, true))
2157     {
2158         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidDebugSource);
2159         return false;
2160     }
2161 
2162     size_t messageLength = (length < 0) ? strlen(buf) : length;
2163     if (messageLength > context->getCaps().maxDebugMessageLength)
2164     {
2165         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kExceedsMaxDebugMessageLength);
2166         return false;
2167     }
2168 
2169     return true;
2170 }
2171 
ValidateDebugMessageCallbackKHR(const Context * context,angle::EntryPoint entryPoint,GLDEBUGPROCKHR callback,const void * userParam)2172 bool ValidateDebugMessageCallbackKHR(const Context *context,
2173                                      angle::EntryPoint entryPoint,
2174                                      GLDEBUGPROCKHR callback,
2175                                      const void *userParam)
2176 {
2177     if (!context->getExtensions().debugKHR)
2178     {
2179         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
2180         return false;
2181     }
2182 
2183     return true;
2184 }
2185 
ValidateGetDebugMessageLogKHR(const Context * context,angle::EntryPoint entryPoint,GLuint count,GLsizei bufSize,const GLenum * sources,const GLenum * types,const GLuint * ids,const GLenum * severities,const GLsizei * lengths,const GLchar * messageLog)2186 bool ValidateGetDebugMessageLogKHR(const Context *context,
2187                                    angle::EntryPoint entryPoint,
2188                                    GLuint count,
2189                                    GLsizei bufSize,
2190                                    const GLenum *sources,
2191                                    const GLenum *types,
2192                                    const GLuint *ids,
2193                                    const GLenum *severities,
2194                                    const GLsizei *lengths,
2195                                    const GLchar *messageLog)
2196 {
2197     if (!context->getExtensions().debugKHR)
2198     {
2199         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
2200         return false;
2201     }
2202 
2203     if (bufSize < 0 && messageLog != nullptr)
2204     {
2205         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeBufferSize);
2206         return false;
2207     }
2208 
2209     return true;
2210 }
2211 
ValidatePushDebugGroupBase(const Context * context,angle::EntryPoint entryPoint,GLenum source,GLuint id,GLsizei length,const GLchar * message)2212 bool ValidatePushDebugGroupBase(const Context *context,
2213                                 angle::EntryPoint entryPoint,
2214                                 GLenum source,
2215                                 GLuint id,
2216                                 GLsizei length,
2217                                 const GLchar *message)
2218 {
2219     if (!ValidDebugSource(source, true))
2220     {
2221         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidDebugSource);
2222         return false;
2223     }
2224 
2225     size_t messageLength = (length < 0) ? strlen(message) : length;
2226     if (messageLength > context->getCaps().maxDebugMessageLength)
2227     {
2228         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kExceedsMaxDebugMessageLength);
2229         return false;
2230     }
2231 
2232     size_t currentStackSize = context->getState().getDebug().getGroupStackDepth();
2233     if (currentStackSize >= context->getCaps().maxDebugGroupStackDepth)
2234     {
2235         ANGLE_VALIDATION_ERROR(GL_STACK_OVERFLOW, kExceedsMaxDebugGroupStackDepth);
2236         return false;
2237     }
2238 
2239     return true;
2240 }
2241 
ValidatePopDebugGroupBase(const Context * context,angle::EntryPoint entryPoint)2242 bool ValidatePopDebugGroupBase(const Context *context, angle::EntryPoint entryPoint)
2243 {
2244     size_t currentStackSize = context->getState().getDebug().getGroupStackDepth();
2245     if (currentStackSize <= 1)
2246     {
2247         ANGLE_VALIDATION_ERROR(GL_STACK_UNDERFLOW, kCannotPopDefaultDebugGroup);
2248         return false;
2249     }
2250 
2251     return true;
2252 }
2253 
ValidatePushDebugGroupKHR(const Context * context,angle::EntryPoint entryPoint,GLenum source,GLuint id,GLsizei length,const GLchar * message)2254 bool ValidatePushDebugGroupKHR(const Context *context,
2255                                angle::EntryPoint entryPoint,
2256                                GLenum source,
2257                                GLuint id,
2258                                GLsizei length,
2259                                const GLchar *message)
2260 {
2261     if (!context->getExtensions().debugKHR)
2262     {
2263         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
2264         return false;
2265     }
2266 
2267     return ValidatePushDebugGroupBase(context, entryPoint, source, id, length, message);
2268 }
2269 
ValidatePopDebugGroupKHR(const Context * context,angle::EntryPoint entryPoint)2270 bool ValidatePopDebugGroupKHR(const Context *context, angle::EntryPoint entryPoint)
2271 {
2272     if (!context->getExtensions().debugKHR)
2273     {
2274         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
2275         return false;
2276     }
2277 
2278     return ValidatePopDebugGroupBase(context, entryPoint);
2279 }
2280 
ValidateObjectIdentifierAndName(const Context * context,angle::EntryPoint entryPoint,GLenum identifier,GLuint name)2281 static bool ValidateObjectIdentifierAndName(const Context *context,
2282                                             angle::EntryPoint entryPoint,
2283                                             GLenum identifier,
2284                                             GLuint name)
2285 {
2286     switch (identifier)
2287     {
2288         case GL_BUFFER:
2289             if (context->getBuffer({name}) == nullptr)
2290             {
2291                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidBufferName);
2292                 return false;
2293             }
2294             return true;
2295 
2296         case GL_SHADER:
2297             if (context->getShaderNoResolveCompile({name}) == nullptr)
2298             {
2299                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidShaderName);
2300                 return false;
2301             }
2302             return true;
2303 
2304         case GL_PROGRAM:
2305             if (context->getProgramNoResolveLink({name}) == nullptr)
2306             {
2307                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidProgramName);
2308                 return false;
2309             }
2310             return true;
2311 
2312         case GL_VERTEX_ARRAY:
2313             if (context->getVertexArray({name}) == nullptr)
2314             {
2315                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidVertexArrayName);
2316                 return false;
2317             }
2318             return true;
2319 
2320         case GL_QUERY:
2321             if (context->getQuery({name}) == nullptr)
2322             {
2323                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidQueryName);
2324                 return false;
2325             }
2326             return true;
2327 
2328         case GL_TRANSFORM_FEEDBACK:
2329             if (context->getTransformFeedback({name}) == nullptr)
2330             {
2331                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidTransformFeedbackName);
2332                 return false;
2333             }
2334             return true;
2335 
2336         case GL_SAMPLER:
2337             if (context->getSampler({name}) == nullptr)
2338             {
2339                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidSamplerName);
2340                 return false;
2341             }
2342             return true;
2343 
2344         case GL_TEXTURE:
2345             if (context->getTexture({name}) == nullptr)
2346             {
2347                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidTextureName);
2348                 return false;
2349             }
2350             return true;
2351 
2352         case GL_RENDERBUFFER:
2353             if (!context->isRenderbuffer({name}))
2354             {
2355                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidRenderbufferName);
2356                 return false;
2357             }
2358             return true;
2359 
2360         case GL_FRAMEBUFFER:
2361             if (context->getFramebuffer({name}) == nullptr)
2362             {
2363                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidFramebufferName);
2364                 return false;
2365             }
2366             return true;
2367 
2368         case GL_PROGRAM_PIPELINE:
2369             if (context->getProgramPipeline({name}) == nullptr)
2370             {
2371                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidProgramPipelineName);
2372                 return false;
2373             }
2374             return true;
2375 
2376         default:
2377             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidIndentifier);
2378             return false;
2379     }
2380 }
2381 
ValidateLabelLength(const Context * context,angle::EntryPoint entryPoint,GLsizei length,const GLchar * label)2382 static bool ValidateLabelLength(const Context *context,
2383                                 angle::EntryPoint entryPoint,
2384                                 GLsizei length,
2385                                 const GLchar *label)
2386 {
2387     size_t labelLength = 0;
2388 
2389     if (length < 0)
2390     {
2391         if (label != nullptr)
2392         {
2393             labelLength = strlen(label);
2394         }
2395     }
2396     else
2397     {
2398         labelLength = static_cast<size_t>(length);
2399     }
2400 
2401     if (labelLength > context->getCaps().maxLabelLength)
2402     {
2403         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kExceedsMaxLabelLength);
2404         return false;
2405     }
2406 
2407     return true;
2408 }
2409 
ValidateObjectLabelBase(const Context * context,angle::EntryPoint entryPoint,GLenum identifier,GLuint name,GLsizei length,const GLchar * label)2410 bool ValidateObjectLabelBase(const Context *context,
2411                              angle::EntryPoint entryPoint,
2412                              GLenum identifier,
2413                              GLuint name,
2414                              GLsizei length,
2415                              const GLchar *label)
2416 {
2417     if (!ValidateObjectIdentifierAndName(context, entryPoint, identifier, name))
2418     {
2419         return false;
2420     }
2421 
2422     if (!ValidateLabelLength(context, entryPoint, length, label))
2423     {
2424         return false;
2425     }
2426 
2427     return true;
2428 }
2429 
ValidateObjectLabelKHR(const Context * context,angle::EntryPoint entryPoint,GLenum identifier,GLuint name,GLsizei length,const GLchar * label)2430 bool ValidateObjectLabelKHR(const Context *context,
2431                             angle::EntryPoint entryPoint,
2432                             GLenum identifier,
2433                             GLuint name,
2434                             GLsizei length,
2435                             const GLchar *label)
2436 {
2437     if (!context->getExtensions().debugKHR)
2438     {
2439         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
2440         return false;
2441     }
2442 
2443     if (!ValidateObjectLabelBase(context, entryPoint, identifier, name, length, label))
2444     {
2445         return false;
2446     }
2447 
2448     return true;
2449 }
2450 
ValidateGetObjectLabelBase(const Context * context,angle::EntryPoint entryPoint,GLenum identifier,GLuint name,GLsizei bufSize,const GLsizei * length,const GLchar * label)2451 bool ValidateGetObjectLabelBase(const Context *context,
2452                                 angle::EntryPoint entryPoint,
2453                                 GLenum identifier,
2454                                 GLuint name,
2455                                 GLsizei bufSize,
2456                                 const GLsizei *length,
2457                                 const GLchar *label)
2458 {
2459     if (bufSize < 0)
2460     {
2461         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeBufferSize);
2462         return false;
2463     }
2464 
2465     if (!ValidateObjectIdentifierAndName(context, entryPoint, identifier, name))
2466     {
2467         return false;
2468     }
2469 
2470     return true;
2471 }
2472 
ValidateGetObjectLabelKHR(const Context * context,angle::EntryPoint entryPoint,GLenum identifier,GLuint name,GLsizei bufSize,const GLsizei * length,const GLchar * label)2473 bool ValidateGetObjectLabelKHR(const Context *context,
2474                                angle::EntryPoint entryPoint,
2475                                GLenum identifier,
2476                                GLuint name,
2477                                GLsizei bufSize,
2478                                const GLsizei *length,
2479                                const GLchar *label)
2480 {
2481     if (!context->getExtensions().debugKHR)
2482     {
2483         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
2484         return false;
2485     }
2486 
2487     if (!ValidateGetObjectLabelBase(context, entryPoint, identifier, name, bufSize, length, label))
2488     {
2489         return false;
2490     }
2491 
2492     return true;
2493 }
2494 
ValidateObjectPtrName(const Context * context,angle::EntryPoint entryPoint,const void * ptr)2495 static bool ValidateObjectPtrName(const Context *context,
2496                                   angle::EntryPoint entryPoint,
2497                                   const void *ptr)
2498 {
2499     if (!context->getSync({unsafe_pointer_to_int_cast<uint32_t>(ptr)}))
2500     {
2501         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidSyncPointer);
2502         return false;
2503     }
2504 
2505     return true;
2506 }
2507 
ValidateObjectPtrLabelBase(const Context * context,angle::EntryPoint entryPoint,const void * ptr,GLsizei length,const GLchar * label)2508 bool ValidateObjectPtrLabelBase(const Context *context,
2509                                 angle::EntryPoint entryPoint,
2510                                 const void *ptr,
2511                                 GLsizei length,
2512                                 const GLchar *label)
2513 {
2514     if (!ValidateObjectPtrName(context, entryPoint, ptr))
2515     {
2516         return false;
2517     }
2518 
2519     if (!ValidateLabelLength(context, entryPoint, length, label))
2520     {
2521         return false;
2522     }
2523 
2524     return true;
2525 }
2526 
ValidateObjectPtrLabelKHR(const Context * context,angle::EntryPoint entryPoint,const void * ptr,GLsizei length,const GLchar * label)2527 bool ValidateObjectPtrLabelKHR(const Context *context,
2528                                angle::EntryPoint entryPoint,
2529                                const void *ptr,
2530                                GLsizei length,
2531                                const GLchar *label)
2532 {
2533     if (!context->getExtensions().debugKHR)
2534     {
2535         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
2536         return false;
2537     }
2538 
2539     if (!ValidateObjectPtrLabelBase(context, entryPoint, ptr, length, label))
2540     {
2541         return false;
2542     }
2543 
2544     return true;
2545 }
2546 
ValidateGetObjectPtrLabelBase(const Context * context,angle::EntryPoint entryPoint,const void * ptr,GLsizei bufSize,const GLsizei * length,const GLchar * label)2547 bool ValidateGetObjectPtrLabelBase(const Context *context,
2548                                    angle::EntryPoint entryPoint,
2549                                    const void *ptr,
2550                                    GLsizei bufSize,
2551                                    const GLsizei *length,
2552                                    const GLchar *label)
2553 {
2554     if (bufSize < 0)
2555     {
2556         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeBufferSize);
2557         return false;
2558     }
2559 
2560     if (!ValidateObjectPtrName(context, entryPoint, ptr))
2561     {
2562         return false;
2563     }
2564 
2565     return true;
2566 }
2567 
ValidateGetObjectPtrLabelKHR(const Context * context,angle::EntryPoint entryPoint,const void * ptr,GLsizei bufSize,const GLsizei * length,const GLchar * label)2568 bool ValidateGetObjectPtrLabelKHR(const Context *context,
2569                                   angle::EntryPoint entryPoint,
2570                                   const void *ptr,
2571                                   GLsizei bufSize,
2572                                   const GLsizei *length,
2573                                   const GLchar *label)
2574 {
2575     if (!context->getExtensions().debugKHR)
2576     {
2577         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
2578         return false;
2579     }
2580 
2581     if (!ValidateGetObjectPtrLabelBase(context, entryPoint, ptr, bufSize, length, label))
2582     {
2583         return false;
2584     }
2585 
2586     return true;
2587 }
2588 
ValidateGetPointervKHR(const Context * context,angle::EntryPoint entryPoint,GLenum pname,void * const * params)2589 bool ValidateGetPointervKHR(const Context *context,
2590                             angle::EntryPoint entryPoint,
2591                             GLenum pname,
2592                             void *const *params)
2593 {
2594     if (!context->getExtensions().debugKHR)
2595     {
2596         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
2597         return false;
2598     }
2599 
2600     return ValidateGetPointerv(context, entryPoint, pname, params);
2601 }
2602 
ValidateGetPointervRobustANGLERobustANGLE(const Context * context,angle::EntryPoint entryPoint,GLenum pname,GLsizei bufSize,const GLsizei * length,void * const * params)2603 bool ValidateGetPointervRobustANGLERobustANGLE(const Context *context,
2604                                                angle::EntryPoint entryPoint,
2605                                                GLenum pname,
2606                                                GLsizei bufSize,
2607                                                const GLsizei *length,
2608                                                void *const *params)
2609 {
2610     UNIMPLEMENTED();
2611     return false;
2612 }
2613 
ValidateBlitFramebufferANGLE(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)2614 bool ValidateBlitFramebufferANGLE(const Context *context,
2615                                   angle::EntryPoint entryPoint,
2616                                   GLint srcX0,
2617                                   GLint srcY0,
2618                                   GLint srcX1,
2619                                   GLint srcY1,
2620                                   GLint dstX0,
2621                                   GLint dstY0,
2622                                   GLint dstX1,
2623                                   GLint dstY1,
2624                                   GLbitfield mask,
2625                                   GLenum filter)
2626 {
2627     if (!context->getExtensions().framebufferBlitANGLE)
2628     {
2629         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBlitExtensionNotAvailable);
2630         return false;
2631     }
2632 
2633     if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
2634     {
2635         // TODO(jmadill): Determine if this should be available on other implementations.
2636         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBlitExtensionScaleOrFlip);
2637         return false;
2638     }
2639 
2640     if (filter == GL_LINEAR)
2641     {
2642         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kBlitExtensionLinear);
2643         return false;
2644     }
2645 
2646     Framebuffer *readFramebuffer = context->getState().getReadFramebuffer();
2647     Framebuffer *drawFramebuffer = context->getState().getDrawFramebuffer();
2648 
2649     if (mask & GL_COLOR_BUFFER_BIT)
2650     {
2651         const FramebufferAttachment *readColorAttachment =
2652             readFramebuffer->getReadColorAttachment();
2653         const FramebufferAttachment *drawColorAttachment =
2654             drawFramebuffer->getFirstColorAttachment();
2655 
2656         if (readColorAttachment && drawColorAttachment)
2657         {
2658             if (!(readColorAttachment->type() == GL_TEXTURE &&
2659                   (readColorAttachment->getTextureImageIndex().getType() == TextureType::_2D ||
2660                    readColorAttachment->getTextureImageIndex().getType() ==
2661                        TextureType::Rectangle)) &&
2662                 readColorAttachment->type() != GL_RENDERBUFFER &&
2663                 readColorAttachment->type() != GL_FRAMEBUFFER_DEFAULT)
2664             {
2665                 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION,
2666                                        kBlitExtensionFromInvalidAttachmentType);
2667                 return false;
2668             }
2669 
2670             for (size_t drawbufferIdx = 0;
2671                  drawbufferIdx < drawFramebuffer->getDrawbufferStateCount(); ++drawbufferIdx)
2672             {
2673                 const FramebufferAttachment *attachment =
2674                     drawFramebuffer->getDrawBuffer(drawbufferIdx);
2675                 if (attachment)
2676                 {
2677                     if (!(attachment->type() == GL_TEXTURE &&
2678                           (attachment->getTextureImageIndex().getType() == TextureType::_2D ||
2679                            attachment->getTextureImageIndex().getType() ==
2680                                TextureType::Rectangle)) &&
2681                         attachment->type() != GL_RENDERBUFFER &&
2682                         attachment->type() != GL_FRAMEBUFFER_DEFAULT)
2683                     {
2684                         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION,
2685                                                kBlitExtensionToInvalidAttachmentType);
2686                         return false;
2687                     }
2688 
2689                     // Return an error if the destination formats do not match
2690                     if (!Format::EquivalentForBlit(attachment->getFormat(),
2691                                                    readColorAttachment->getFormat()))
2692                     {
2693                         ANGLE_VALIDATION_ERRORF(
2694                             GL_INVALID_OPERATION, kBlitExtensionFormatMismatch,
2695                             readColorAttachment->getFormat().info->sizedInternalFormat,
2696                             attachment->getFormat().info->sizedInternalFormat);
2697                         return false;
2698                     }
2699                 }
2700             }
2701 
2702             GLint samples = readFramebuffer->getSamples(context);
2703             if (samples != 0 &&
2704                 IsPartialBlit(context, readColorAttachment, drawColorAttachment, srcX0, srcY0,
2705                               srcX1, srcY1, dstX0, dstY0, dstX1, dstY1))
2706             {
2707                 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION,
2708                                        kBlitExtensionMultisampledWholeBufferBlit);
2709                 return false;
2710             }
2711         }
2712     }
2713 
2714     GLenum masks[]       = {GL_DEPTH_BUFFER_BIT, GL_STENCIL_BUFFER_BIT};
2715     GLenum attachments[] = {GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT};
2716     for (size_t i = 0; i < 2; i++)
2717     {
2718         if (mask & masks[i])
2719         {
2720             const FramebufferAttachment *readBuffer =
2721                 readFramebuffer->getAttachment(context, attachments[i]);
2722             const FramebufferAttachment *drawBuffer =
2723                 drawFramebuffer->getAttachment(context, attachments[i]);
2724 
2725             if (readBuffer && drawBuffer)
2726             {
2727                 if (IsPartialBlit(context, readBuffer, drawBuffer, srcX0, srcY0, srcX1, srcY1,
2728                                   dstX0, dstY0, dstX1, dstY1))
2729                 {
2730                     // only whole-buffer copies are permitted
2731                     ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION,
2732                                            kBlitExtensionDepthStencilWholeBufferBlit);
2733                     return false;
2734                 }
2735 
2736                 if (readBuffer->getResourceSamples() != 0 || drawBuffer->getResourceSamples() != 0)
2737                 {
2738                     ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION,
2739                                            kBlitExtensionMultisampledDepthOrStencil);
2740                     return false;
2741                 }
2742             }
2743         }
2744     }
2745 
2746     return ValidateBlitFramebufferParameters(context, entryPoint, srcX0, srcY0, srcX1, srcY1, dstX0,
2747                                              dstY0, dstX1, dstY1, mask, filter);
2748 }
2749 
ValidateBlitFramebufferNV(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)2750 bool ValidateBlitFramebufferNV(const Context *context,
2751                                angle::EntryPoint entryPoint,
2752                                GLint srcX0,
2753                                GLint srcY0,
2754                                GLint srcX1,
2755                                GLint srcY1,
2756                                GLint dstX0,
2757                                GLint dstY0,
2758                                GLint dstX1,
2759                                GLint dstY1,
2760                                GLbitfield mask,
2761                                GLenum filter)
2762 {
2763     if (!context->getExtensions().framebufferBlitANGLE)
2764     {
2765         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBlitExtensionNotAvailable);
2766         return false;
2767     }
2768 
2769     return ValidateBlitFramebufferParameters(context, entryPoint, srcX0, srcY0, srcX1, srcY1, dstX0,
2770                                              dstY0, dstX1, dstY1, mask, filter);
2771 }
2772 
ValidateClear(const Context * context,angle::EntryPoint entryPoint,GLbitfield mask)2773 bool ValidateClear(const Context *context, angle::EntryPoint entryPoint, GLbitfield mask)
2774 {
2775     Framebuffer *fbo             = context->getState().getDrawFramebuffer();
2776     const Extensions &extensions = context->getExtensions();
2777 
2778     if (!ValidateFramebufferComplete(context, entryPoint, fbo))
2779     {
2780         return false;
2781     }
2782 
2783     // The QCOM_framebuffer_foveated spec:
2784     if (fbo->isFoveationEnabled())
2785     {
2786         // INVALID_OPERATION is generated by any API call which causes a framebuffer
2787         // attachment to be written to if the framebuffer attachments have changed for
2788         // a foveated fbo.
2789         if (fbo->hasAnyAttachmentChanged())
2790         {
2791             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kFramebufferFoveationAttachmentChanged);
2792             return false;
2793         }
2794     }
2795 
2796     if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
2797     {
2798         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidClearMask);
2799         return false;
2800     }
2801 
2802     if (extensions.webglCompatibilityANGLE && (mask & GL_COLOR_BUFFER_BIT) != 0)
2803     {
2804         if (GetIntOrUnsignedIntDrawBufferMask(fbo->getDrawBufferTypeMask()).any())
2805         {
2806             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kNoDefinedClearConversion);
2807             return false;
2808         }
2809     }
2810 
2811     if (extensions.renderSharedExponentQCOM && (mask & GL_COLOR_BUFFER_BIT) != 0)
2812     {
2813         const State &state = context->getState();
2814         if (!ValidateColorMasksForSharedExponentColorBuffers(state.getBlendStateExt(),
2815                                                              state.getDrawFramebuffer()))
2816         {
2817             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION,
2818                                    kUnsupportedColorMaskForSharedExponentColorBuffer);
2819             return false;
2820         }
2821     }
2822 
2823     if ((extensions.multiviewOVR || extensions.multiview2OVR) && extensions.disjointTimerQueryEXT)
2824     {
2825         const State &state       = context->getState();
2826         Framebuffer *framebuffer = state.getDrawFramebuffer();
2827         if (framebuffer->getNumViews() > 1 && state.isQueryActive(QueryType::TimeElapsed))
2828         {
2829             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kMultiviewTimerQuery);
2830             return false;
2831         }
2832     }
2833 
2834     return true;
2835 }
2836 
ValidateDrawBuffersEXT(const Context * context,angle::EntryPoint entryPoint,GLsizei n,const GLenum * bufs)2837 bool ValidateDrawBuffersEXT(const Context *context,
2838                             angle::EntryPoint entryPoint,
2839                             GLsizei n,
2840                             const GLenum *bufs)
2841 {
2842     if (!context->getExtensions().drawBuffersEXT)
2843     {
2844         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
2845         return false;
2846     }
2847 
2848     return ValidateDrawBuffersBase(context, entryPoint, n, bufs);
2849 }
2850 
ValidateTexImage2D(const Context * context,angle::EntryPoint entryPoint,TextureTarget target,GLint level,GLint internalformat,GLsizei width,GLsizei height,GLint border,GLenum format,GLenum type,const void * pixels)2851 bool ValidateTexImage2D(const Context *context,
2852                         angle::EntryPoint entryPoint,
2853                         TextureTarget target,
2854                         GLint level,
2855                         GLint internalformat,
2856                         GLsizei width,
2857                         GLsizei height,
2858                         GLint border,
2859                         GLenum format,
2860                         GLenum type,
2861                         const void *pixels)
2862 {
2863     if (context->getClientMajorVersion() < 3)
2864     {
2865         return ValidateES2TexImageParameters(context, entryPoint, target, level, internalformat,
2866                                              false, false, 0, 0, width, height, border, format,
2867                                              type, -1, pixels);
2868     }
2869 
2870     ASSERT(context->getClientMajorVersion() >= 3);
2871     return ValidateES3TexImage2DParameters(context, entryPoint, target, level, internalformat,
2872                                            false, false, 0, 0, 0, width, height, 1, border, format,
2873                                            type, -1, pixels);
2874 }
2875 
ValidateTexImage2DRobustANGLE(const Context * context,angle::EntryPoint entryPoint,TextureTarget target,GLint level,GLint internalformat,GLsizei width,GLsizei height,GLint border,GLenum format,GLenum type,GLsizei bufSize,const void * pixels)2876 bool ValidateTexImage2DRobustANGLE(const Context *context,
2877                                    angle::EntryPoint entryPoint,
2878                                    TextureTarget target,
2879                                    GLint level,
2880                                    GLint internalformat,
2881                                    GLsizei width,
2882                                    GLsizei height,
2883                                    GLint border,
2884                                    GLenum format,
2885                                    GLenum type,
2886                                    GLsizei bufSize,
2887                                    const void *pixels)
2888 {
2889     if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
2890     {
2891         return false;
2892     }
2893 
2894     if (context->getClientMajorVersion() < 3)
2895     {
2896         return ValidateES2TexImageParameters(context, entryPoint, target, level, internalformat,
2897                                              false, false, 0, 0, width, height, border, format,
2898                                              type, bufSize, pixels);
2899     }
2900 
2901     ASSERT(context->getClientMajorVersion() >= 3);
2902     return ValidateES3TexImage2DParameters(context, entryPoint, target, level, internalformat,
2903                                            false, false, 0, 0, 0, width, height, 1, border, format,
2904                                            type, bufSize, pixels);
2905 }
2906 
ValidateTexSubImage2D(const Context * context,angle::EntryPoint entryPoint,TextureTarget target,GLint level,GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,GLenum format,GLenum type,const void * pixels)2907 bool ValidateTexSubImage2D(const Context *context,
2908                            angle::EntryPoint entryPoint,
2909                            TextureTarget target,
2910                            GLint level,
2911                            GLint xoffset,
2912                            GLint yoffset,
2913                            GLsizei width,
2914                            GLsizei height,
2915                            GLenum format,
2916                            GLenum type,
2917                            const void *pixels)
2918 {
2919 
2920     if (context->getClientMajorVersion() < 3)
2921     {
2922         return ValidateES2TexImageParameters(context, entryPoint, target, level, GL_NONE, false,
2923                                              true, xoffset, yoffset, width, height, 0, format, type,
2924                                              -1, pixels);
2925     }
2926 
2927     ASSERT(context->getClientMajorVersion() >= 3);
2928     return ValidateES3TexImage2DParameters(context, entryPoint, target, level, GL_NONE, false, true,
2929                                            xoffset, yoffset, 0, width, height, 1, 0, format, type,
2930                                            -1, pixels);
2931 }
2932 
ValidateTexSubImage2DRobustANGLE(const Context * context,angle::EntryPoint entryPoint,TextureTarget target,GLint level,GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,GLenum format,GLenum type,GLsizei bufSize,const void * pixels)2933 bool ValidateTexSubImage2DRobustANGLE(const Context *context,
2934                                       angle::EntryPoint entryPoint,
2935                                       TextureTarget target,
2936                                       GLint level,
2937                                       GLint xoffset,
2938                                       GLint yoffset,
2939                                       GLsizei width,
2940                                       GLsizei height,
2941                                       GLenum format,
2942                                       GLenum type,
2943                                       GLsizei bufSize,
2944                                       const void *pixels)
2945 {
2946     if (!ValidateRobustEntryPoint(context, entryPoint, bufSize))
2947     {
2948         return false;
2949     }
2950 
2951     if (context->getClientMajorVersion() < 3)
2952     {
2953         return ValidateES2TexImageParameters(context, entryPoint, target, level, GL_NONE, false,
2954                                              true, xoffset, yoffset, width, height, 0, format, type,
2955                                              bufSize, pixels);
2956     }
2957 
2958     ASSERT(context->getClientMajorVersion() >= 3);
2959     return ValidateES3TexImage2DParameters(context, entryPoint, target, level, GL_NONE, false, true,
2960                                            xoffset, yoffset, 0, width, height, 1, 0, format, type,
2961                                            bufSize, pixels);
2962 }
2963 
ValidateTexSubImage3DOES(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)2964 bool ValidateTexSubImage3DOES(const Context *context,
2965                               angle::EntryPoint entryPoint,
2966                               TextureTarget target,
2967                               GLint level,
2968                               GLint xoffset,
2969                               GLint yoffset,
2970                               GLint zoffset,
2971                               GLsizei width,
2972                               GLsizei height,
2973                               GLsizei depth,
2974                               GLenum format,
2975                               GLenum type,
2976                               const void *pixels)
2977 {
2978     return ValidateTexSubImage3D(context, entryPoint, target, level, xoffset, yoffset, zoffset,
2979                                  width, height, depth, format, type, pixels);
2980 }
2981 
ValidateCompressedTexImage2D(const Context * context,angle::EntryPoint entryPoint,TextureTarget target,GLint level,GLenum internalformat,GLsizei width,GLsizei height,GLint border,GLsizei imageSize,const void * data)2982 bool ValidateCompressedTexImage2D(const Context *context,
2983                                   angle::EntryPoint entryPoint,
2984                                   TextureTarget target,
2985                                   GLint level,
2986                                   GLenum internalformat,
2987                                   GLsizei width,
2988                                   GLsizei height,
2989                                   GLint border,
2990                                   GLsizei imageSize,
2991                                   const void *data)
2992 {
2993     if (context->getClientMajorVersion() < 3)
2994     {
2995         if (!ValidateES2TexImageParameters(context, entryPoint, target, level, internalformat, true,
2996                                            false, 0, 0, width, height, border, GL_NONE, GL_NONE, -1,
2997                                            data))
2998         {
2999             return false;
3000         }
3001     }
3002     else
3003     {
3004         ASSERT(context->getClientMajorVersion() >= 3);
3005         if (!ValidateES3TexImage2DParameters(context, entryPoint, target, level, internalformat,
3006                                              true, false, 0, 0, 0, width, height, 1, border,
3007                                              GL_NONE, GL_NONE, -1, data))
3008         {
3009             return false;
3010         }
3011     }
3012 
3013     const InternalFormat &formatInfo = GetSizedInternalFormatInfo(internalformat);
3014 
3015     GLuint expectedImageSize = 0;
3016     if (!formatInfo.computeCompressedImageSize(Extents(width, height, 1), &expectedImageSize))
3017     {
3018         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kIntegerOverflow);
3019         return false;
3020     }
3021 
3022     if (imageSize < 0 || static_cast<GLuint>(imageSize) != expectedImageSize)
3023     {
3024         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kCompressedTextureDimensionsMustMatchData);
3025         return false;
3026     }
3027 
3028     if (target == TextureTarget::Rectangle)
3029     {
3030         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kRectangleTextureCompressed);
3031         return false;
3032     }
3033 
3034     return true;
3035 }
3036 
ValidateCompressedTexImage2DRobustANGLE(const Context * context,angle::EntryPoint entryPoint,TextureTarget target,GLint level,GLenum internalformat,GLsizei width,GLsizei height,GLint border,GLsizei imageSize,GLsizei dataSize,const void * data)3037 bool ValidateCompressedTexImage2DRobustANGLE(const Context *context,
3038                                              angle::EntryPoint entryPoint,
3039                                              TextureTarget target,
3040                                              GLint level,
3041                                              GLenum internalformat,
3042                                              GLsizei width,
3043                                              GLsizei height,
3044                                              GLint border,
3045                                              GLsizei imageSize,
3046                                              GLsizei dataSize,
3047                                              const void *data)
3048 {
3049     if (!ValidateRobustCompressedTexImageBase(context, entryPoint, imageSize, dataSize))
3050     {
3051         return false;
3052     }
3053 
3054     return ValidateCompressedTexImage2D(context, entryPoint, target, level, internalformat, width,
3055                                         height, border, imageSize, data);
3056 }
3057 
ValidateCompressedTexImage3DOES(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)3058 bool ValidateCompressedTexImage3DOES(const Context *context,
3059                                      angle::EntryPoint entryPoint,
3060                                      TextureTarget target,
3061                                      GLint level,
3062                                      GLenum internalformat,
3063                                      GLsizei width,
3064                                      GLsizei height,
3065                                      GLsizei depth,
3066                                      GLint border,
3067                                      GLsizei imageSize,
3068                                      const void *data)
3069 {
3070     return ValidateCompressedTexImage3D(context, entryPoint, target, level, internalformat, width,
3071                                         height, depth, border, imageSize, data);
3072 }
3073 
ValidateCompressedTexSubImage2DRobustANGLE(const Context * context,angle::EntryPoint entryPoint,TextureTarget target,GLint level,GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,GLenum format,GLsizei imageSize,GLsizei dataSize,const void * data)3074 bool ValidateCompressedTexSubImage2DRobustANGLE(const Context *context,
3075                                                 angle::EntryPoint entryPoint,
3076                                                 TextureTarget target,
3077                                                 GLint level,
3078                                                 GLint xoffset,
3079                                                 GLint yoffset,
3080                                                 GLsizei width,
3081                                                 GLsizei height,
3082                                                 GLenum format,
3083                                                 GLsizei imageSize,
3084                                                 GLsizei dataSize,
3085                                                 const void *data)
3086 {
3087     if (!ValidateRobustCompressedTexImageBase(context, entryPoint, imageSize, dataSize))
3088     {
3089         return false;
3090     }
3091 
3092     return ValidateCompressedTexSubImage2D(context, entryPoint, target, level, xoffset, yoffset,
3093                                            width, height, format, imageSize, data);
3094 }
3095 
ValidateCompressedTexSubImage2D(const Context * context,angle::EntryPoint entryPoint,TextureTarget target,GLint level,GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,GLenum format,GLsizei imageSize,const void * data)3096 bool ValidateCompressedTexSubImage2D(const Context *context,
3097                                      angle::EntryPoint entryPoint,
3098                                      TextureTarget target,
3099                                      GLint level,
3100                                      GLint xoffset,
3101                                      GLint yoffset,
3102                                      GLsizei width,
3103                                      GLsizei height,
3104                                      GLenum format,
3105                                      GLsizei imageSize,
3106                                      const void *data)
3107 {
3108     if (context->getClientMajorVersion() < 3)
3109     {
3110         if (!ValidateES2TexImageParameters(context, entryPoint, target, level, GL_NONE, true, true,
3111                                            xoffset, yoffset, width, height, 0, format, GL_NONE, -1,
3112                                            data))
3113         {
3114             return false;
3115         }
3116     }
3117     else
3118     {
3119         ASSERT(context->getClientMajorVersion() >= 3);
3120         if (!ValidateES3TexImage2DParameters(context, entryPoint, target, level, GL_NONE, true,
3121                                              true, xoffset, yoffset, 0, width, height, 1, 0, format,
3122                                              GL_NONE, -1, data))
3123         {
3124             return false;
3125         }
3126     }
3127 
3128     const InternalFormat &formatInfo = GetSizedInternalFormatInfo(format);
3129     GLuint blockSize                 = 0;
3130     if (!formatInfo.computeCompressedImageSize(Extents(width, height, 1), &blockSize))
3131     {
3132         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kIntegerOverflow);
3133         return false;
3134     }
3135 
3136     if (imageSize < 0 || static_cast<GLuint>(imageSize) != blockSize)
3137     {
3138         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidCompressedImageSize);
3139         return false;
3140     }
3141 
3142     return true;
3143 }
3144 
ValidateCompressedTexSubImage3DOES(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)3145 bool ValidateCompressedTexSubImage3DOES(const Context *context,
3146                                         angle::EntryPoint entryPoint,
3147                                         TextureTarget target,
3148                                         GLint level,
3149                                         GLint xoffset,
3150                                         GLint yoffset,
3151                                         GLint zoffset,
3152                                         GLsizei width,
3153                                         GLsizei height,
3154                                         GLsizei depth,
3155                                         GLenum format,
3156                                         GLsizei imageSize,
3157                                         const void *data)
3158 {
3159     return ValidateCompressedTexSubImage3D(context, entryPoint, target, level, xoffset, yoffset,
3160                                            zoffset, width, height, depth, format, imageSize, data);
3161 }
3162 
ValidateGetBufferPointervOES(const Context * context,angle::EntryPoint entryPoint,BufferBinding target,GLenum pname,void * const * params)3163 bool ValidateGetBufferPointervOES(const Context *context,
3164                                   angle::EntryPoint entryPoint,
3165                                   BufferBinding target,
3166                                   GLenum pname,
3167                                   void *const *params)
3168 {
3169     if (!context->getExtensions().mapbufferOES)
3170     {
3171         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3172         return false;
3173     }
3174 
3175     return ValidateGetBufferPointervBase(context, entryPoint, target, pname, nullptr, params);
3176 }
3177 
ValidateMapBufferOES(const Context * context,angle::EntryPoint entryPoint,BufferBinding target,GLenum access)3178 bool ValidateMapBufferOES(const Context *context,
3179                           angle::EntryPoint entryPoint,
3180                           BufferBinding target,
3181                           GLenum access)
3182 {
3183     if (!context->getExtensions().mapbufferOES)
3184     {
3185         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3186         return false;
3187     }
3188 
3189     if (!context->isValidBufferBinding(target))
3190     {
3191         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidBufferTypes);
3192         return false;
3193     }
3194 
3195     Buffer *buffer = context->getState().getTargetBuffer(target);
3196 
3197     if (buffer == nullptr)
3198     {
3199         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBufferNotMappable);
3200         return false;
3201     }
3202 
3203     if (access != GL_WRITE_ONLY_OES)
3204     {
3205         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidAccessBits);
3206         return false;
3207     }
3208 
3209     // Though there is no explicit mention of an interaction between GL_EXT_buffer_storage
3210     // and GL_OES_mapbuffer extension, allow it as long as the access type of glmapbufferOES
3211     // is compatible with the buffer's usage flags specified during glBufferStorageEXT
3212     if (buffer->isImmutable() && (buffer->getStorageExtUsageFlags() & GL_MAP_WRITE_BIT) == 0)
3213     {
3214         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBufferNotMappable);
3215         return false;
3216     }
3217 
3218     if (buffer->isMapped())
3219     {
3220         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBufferAlreadyMapped);
3221         return false;
3222     }
3223 
3224     return ValidateMapBufferBase(context, entryPoint, target);
3225 }
3226 
ValidateUnmapBufferOES(const Context * context,angle::EntryPoint entryPoint,BufferBinding target)3227 bool ValidateUnmapBufferOES(const Context *context,
3228                             angle::EntryPoint entryPoint,
3229                             BufferBinding target)
3230 {
3231     if (!context->getExtensions().mapbufferOES)
3232     {
3233         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3234         return false;
3235     }
3236 
3237     return ValidateUnmapBufferBase(context, entryPoint, target);
3238 }
3239 
ValidateMapBufferRangeEXT(const Context * context,angle::EntryPoint entryPoint,BufferBinding target,GLintptr offset,GLsizeiptr length,GLbitfield access)3240 bool ValidateMapBufferRangeEXT(const Context *context,
3241                                angle::EntryPoint entryPoint,
3242                                BufferBinding target,
3243                                GLintptr offset,
3244                                GLsizeiptr length,
3245                                GLbitfield access)
3246 {
3247     if (!context->getExtensions().mapBufferRangeEXT)
3248     {
3249         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3250         return false;
3251     }
3252 
3253     return ValidateMapBufferRangeBase(context, entryPoint, target, offset, length, access);
3254 }
3255 
ValidateMapBufferBase(const Context * context,angle::EntryPoint entryPoint,BufferBinding target)3256 bool ValidateMapBufferBase(const Context *context,
3257                            angle::EntryPoint entryPoint,
3258                            BufferBinding target)
3259 {
3260     Buffer *buffer = context->getState().getTargetBuffer(target);
3261     ASSERT(buffer != nullptr);
3262 
3263     // Check if this buffer is currently being used as a transform feedback output buffer
3264     if (context->getState().isTransformFeedbackActive())
3265     {
3266         TransformFeedback *transformFeedback = context->getState().getCurrentTransformFeedback();
3267         for (size_t i = 0; i < transformFeedback->getIndexedBufferCount(); i++)
3268         {
3269             const auto &transformFeedbackBuffer = transformFeedback->getIndexedBuffer(i);
3270             if (transformFeedbackBuffer.get() == buffer)
3271             {
3272                 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBufferBoundForTransformFeedback);
3273                 return false;
3274             }
3275         }
3276     }
3277 
3278     if (buffer->hasWebGLXFBBindingConflict(context->isWebGL()))
3279     {
3280         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBufferBoundForTransformFeedback);
3281         return false;
3282     }
3283 
3284     return true;
3285 }
3286 
ValidateFlushMappedBufferRangeEXT(const Context * context,angle::EntryPoint entryPoint,BufferBinding target,GLintptr offset,GLsizeiptr length)3287 bool ValidateFlushMappedBufferRangeEXT(const Context *context,
3288                                        angle::EntryPoint entryPoint,
3289                                        BufferBinding target,
3290                                        GLintptr offset,
3291                                        GLsizeiptr length)
3292 {
3293     if (!context->getExtensions().mapBufferRangeEXT)
3294     {
3295         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3296         return false;
3297     }
3298 
3299     return ValidateFlushMappedBufferRangeBase(context, entryPoint, target, offset, length);
3300 }
3301 
ValidateBindUniformLocationCHROMIUM(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,UniformLocation location,const GLchar * name)3302 bool ValidateBindUniformLocationCHROMIUM(const Context *context,
3303                                          angle::EntryPoint entryPoint,
3304                                          ShaderProgramID program,
3305                                          UniformLocation location,
3306                                          const GLchar *name)
3307 {
3308     if (!context->getExtensions().bindUniformLocationCHROMIUM)
3309     {
3310         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3311         return false;
3312     }
3313 
3314     Program *programObject = GetValidProgram(context, entryPoint, program);
3315     if (!programObject)
3316     {
3317         return false;
3318     }
3319 
3320     if (location.value < 0)
3321     {
3322         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeLocation);
3323         return false;
3324     }
3325 
3326     const Caps &caps = context->getCaps();
3327     if (static_cast<long>(location.value) >=
3328         (caps.maxVertexUniformVectors + caps.maxFragmentUniformVectors) * 4)
3329     {
3330         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidBindUniformLocation);
3331         return false;
3332     }
3333 
3334     // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
3335     // shader-related entry points
3336     if (context->isWebGL() && !IsValidESSLString(name, strlen(name)))
3337     {
3338         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidNameCharacters);
3339         return false;
3340     }
3341 
3342     if (strncmp(name, "gl_", 3) == 0)
3343     {
3344         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNameBeginsWithGL);
3345         return false;
3346     }
3347 
3348     return true;
3349 }
3350 
ValidateCoverageModulationCHROMIUM(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLenum components)3351 bool ValidateCoverageModulationCHROMIUM(const PrivateState &state,
3352                                         ErrorSet *errors,
3353                                         angle::EntryPoint entryPoint,
3354                                         GLenum components)
3355 {
3356     if (!state.getExtensions().framebufferMixedSamplesCHROMIUM)
3357     {
3358         errors->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
3359         return false;
3360     }
3361     switch (components)
3362     {
3363         case GL_RGB:
3364         case GL_RGBA:
3365         case GL_ALPHA:
3366         case GL_NONE:
3367             break;
3368         default:
3369             errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidCoverageComponents);
3370             return false;
3371     }
3372 
3373     return true;
3374 }
3375 
ValidateCopyTextureCHROMIUM(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)3376 bool ValidateCopyTextureCHROMIUM(const Context *context,
3377                                  angle::EntryPoint entryPoint,
3378                                  TextureID sourceId,
3379                                  GLint sourceLevel,
3380                                  TextureTarget destTarget,
3381                                  TextureID destId,
3382                                  GLint destLevel,
3383                                  GLint internalFormat,
3384                                  GLenum destType,
3385                                  GLboolean unpackFlipY,
3386                                  GLboolean unpackPremultiplyAlpha,
3387                                  GLboolean unpackUnmultiplyAlpha)
3388 {
3389     if (!context->getExtensions().copyTextureCHROMIUM)
3390     {
3391         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3392         return false;
3393     }
3394 
3395     const Texture *source = context->getTexture(sourceId);
3396     if (source == nullptr)
3397     {
3398         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidSourceTexture);
3399         return false;
3400     }
3401 
3402     if (!IsValidCopyTextureSourceTarget(context, source->getType()))
3403     {
3404         ANGLE_VALIDATION_ERRORF(GL_INVALID_OPERATION, kInvalidInternalFormat, internalFormat);
3405         return false;
3406     }
3407 
3408     TextureType sourceType = source->getType();
3409     ASSERT(sourceType != TextureType::CubeMap);
3410     TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
3411 
3412     if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
3413     {
3414         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidSourceTextureLevel);
3415         return false;
3416     }
3417 
3418     GLsizei sourceWidth  = static_cast<GLsizei>(source->getWidth(sourceTarget, sourceLevel));
3419     GLsizei sourceHeight = static_cast<GLsizei>(source->getHeight(sourceTarget, sourceLevel));
3420     if (sourceWidth == 0 || sourceHeight == 0)
3421     {
3422         ANGLE_VALIDATION_ERRORF(GL_INVALID_OPERATION, kInvalidInternalFormat, internalFormat);
3423         return false;
3424     }
3425 
3426     const InternalFormat &sourceFormat = *source->getFormat(sourceTarget, sourceLevel).info;
3427     if (!IsValidCopyTextureSourceInternalFormatEnum(sourceFormat.internalFormat))
3428     {
3429         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidSourceTextureInternalFormat);
3430         return false;
3431     }
3432 
3433     if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
3434     {
3435         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidTextureTarget);
3436         return false;
3437     }
3438 
3439     const Texture *dest = context->getTexture(destId);
3440     if (dest == nullptr)
3441     {
3442         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidDestinationTexture);
3443         return false;
3444     }
3445 
3446     const InternalFormat &destInternalFormatInfo = GetInternalFormatInfo(internalFormat, destType);
3447     if (sourceType == TextureType::External && destInternalFormatInfo.isInt() &&
3448         !context->getExtensions().EGLImageExternalEssl3OES)
3449     {
3450         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kANGLECopyTextureMissingRequiredExtension);
3451         return false;
3452     }
3453 
3454     if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
3455     {
3456         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidDestinationTextureType);
3457         return false;
3458     }
3459 
3460     if (!IsValidCopyTextureDestinationLevel(context, entryPoint, dest->getType(), destLevel,
3461                                             sourceWidth, sourceHeight, false))
3462     {
3463         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidMipLevel);
3464         return false;
3465     }
3466 
3467     if (!IsValidCopyTextureDestinationFormatType(context, entryPoint, internalFormat, destType))
3468     {
3469         return false;
3470     }
3471 
3472     if (dest->getType() == TextureType::CubeMap && sourceWidth != sourceHeight)
3473     {
3474         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kCubemapFacesEqualDimensions);
3475         return false;
3476     }
3477 
3478     if (dest->getImmutableFormat())
3479     {
3480         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kDestinationImmutable);
3481         return false;
3482     }
3483 
3484     return true;
3485 }
3486 
ValidateCopySubTextureCHROMIUM(const Context * context,angle::EntryPoint entryPoint,TextureID sourceId,GLint sourceLevel,TextureTarget destTarget,TextureID destId,GLint destLevel,GLint xoffset,GLint yoffset,GLint x,GLint y,GLsizei width,GLsizei height,GLboolean unpackFlipY,GLboolean unpackPremultiplyAlpha,GLboolean unpackUnmultiplyAlpha)3487 bool ValidateCopySubTextureCHROMIUM(const Context *context,
3488                                     angle::EntryPoint entryPoint,
3489                                     TextureID sourceId,
3490                                     GLint sourceLevel,
3491                                     TextureTarget destTarget,
3492                                     TextureID destId,
3493                                     GLint destLevel,
3494                                     GLint xoffset,
3495                                     GLint yoffset,
3496                                     GLint x,
3497                                     GLint y,
3498                                     GLsizei width,
3499                                     GLsizei height,
3500                                     GLboolean unpackFlipY,
3501                                     GLboolean unpackPremultiplyAlpha,
3502                                     GLboolean unpackUnmultiplyAlpha)
3503 {
3504     if (!context->getExtensions().copyTextureCHROMIUM)
3505     {
3506         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3507         return false;
3508     }
3509 
3510     const Texture *source = context->getTexture(sourceId);
3511     if (source == nullptr)
3512     {
3513         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidSourceTexture);
3514         return false;
3515     }
3516 
3517     if (!IsValidCopyTextureSourceTarget(context, source->getType()))
3518     {
3519         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidSourceTextureType);
3520         return false;
3521     }
3522 
3523     TextureType sourceType = source->getType();
3524     ASSERT(sourceType != TextureType::CubeMap);
3525     TextureTarget sourceTarget = NonCubeTextureTypeToTarget(sourceType);
3526 
3527     if (!IsValidCopyTextureSourceLevel(context, sourceType, sourceLevel))
3528     {
3529         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidMipLevel);
3530         return false;
3531     }
3532 
3533     if (source->getWidth(sourceTarget, sourceLevel) == 0 ||
3534         source->getHeight(sourceTarget, sourceLevel) == 0)
3535     {
3536         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidSourceTextureLevel);
3537         return false;
3538     }
3539 
3540     if (x < 0 || y < 0)
3541     {
3542         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeOffset);
3543         return false;
3544     }
3545 
3546     if (width < 0 || height < 0)
3547     {
3548         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeSize);
3549         return false;
3550     }
3551 
3552     if (static_cast<size_t>(x + width) > source->getWidth(sourceTarget, sourceLevel) ||
3553         static_cast<size_t>(y + height) > source->getHeight(sourceTarget, sourceLevel))
3554     {
3555         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kSourceTextureTooSmall);
3556         return false;
3557     }
3558 
3559     const Format &sourceFormat = source->getFormat(sourceTarget, sourceLevel);
3560     if (!IsValidCopySubTextureSourceInternalFormat(sourceFormat.info->internalFormat))
3561     {
3562         ANGLE_VALIDATION_ERRORF(GL_INVALID_OPERATION, kInvalidInternalFormat,
3563                                 sourceFormat.info->internalFormat);
3564         return false;
3565     }
3566 
3567     if (!IsValidCopyTextureDestinationTargetEnum(context, destTarget))
3568     {
3569         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidTextureTarget);
3570         return false;
3571     }
3572 
3573     const Texture *dest = context->getTexture(destId);
3574     if (dest == nullptr)
3575     {
3576         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidDestinationTexture);
3577         return false;
3578     }
3579 
3580     if (!IsValidCopyTextureDestinationTarget(context, dest->getType(), destTarget))
3581     {
3582         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidDestinationTextureType);
3583         return false;
3584     }
3585 
3586     if (!IsValidCopyTextureDestinationLevel(context, entryPoint, dest->getType(), destLevel, width,
3587                                             height, true))
3588     {
3589         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidMipLevel);
3590         return false;
3591     }
3592 
3593     if (dest->getWidth(destTarget, destLevel) == 0 || dest->getHeight(destTarget, destLevel) == 0)
3594     {
3595         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kDestinationLevelNotDefined);
3596         return false;
3597     }
3598 
3599     const InternalFormat &destFormat = *dest->getFormat(destTarget, destLevel).info;
3600     if (!IsValidCopySubTextureDestionationInternalFormat(destFormat.internalFormat))
3601     {
3602         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidFormatCombination);
3603         return false;
3604     }
3605 
3606     if (sourceType == TextureType::External && destFormat.isInt() &&
3607         !context->getExtensions().EGLImageExternalEssl3OES)
3608     {
3609         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kANGLECopyTextureMissingRequiredExtension);
3610         return false;
3611     }
3612 
3613     if (xoffset < 0 || yoffset < 0)
3614     {
3615         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeOffset);
3616         return false;
3617     }
3618 
3619     if (static_cast<size_t>(xoffset + width) > dest->getWidth(destTarget, destLevel) ||
3620         static_cast<size_t>(yoffset + height) > dest->getHeight(destTarget, destLevel))
3621     {
3622         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kOffsetOverflow);
3623         return false;
3624     }
3625 
3626     return true;
3627 }
3628 
ValidateCompressedCopyTextureCHROMIUM(const Context * context,angle::EntryPoint entryPoint,TextureID sourceId,TextureID destId)3629 bool ValidateCompressedCopyTextureCHROMIUM(const Context *context,
3630                                            angle::EntryPoint entryPoint,
3631                                            TextureID sourceId,
3632                                            TextureID destId)
3633 {
3634     if (!context->getExtensions().copyCompressedTextureCHROMIUM)
3635     {
3636         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3637         return false;
3638     }
3639 
3640     const Texture *source = context->getTexture(sourceId);
3641     if (source == nullptr)
3642     {
3643         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidSourceTexture);
3644         return false;
3645     }
3646 
3647     if (source->getType() != TextureType::_2D)
3648     {
3649         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidSourceTextureType);
3650         return false;
3651     }
3652 
3653     if (source->getWidth(TextureTarget::_2D, 0) == 0 ||
3654         source->getHeight(TextureTarget::_2D, 0) == 0)
3655     {
3656         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kSourceTextureLevelZeroDefined);
3657         return false;
3658     }
3659 
3660     const Format &sourceFormat = source->getFormat(TextureTarget::_2D, 0);
3661     if (!sourceFormat.info->compressed)
3662     {
3663         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kSourceTextureMustBeCompressed);
3664         return false;
3665     }
3666 
3667     const Texture *dest = context->getTexture(destId);
3668     if (dest == nullptr)
3669     {
3670         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidDestinationTexture);
3671         return false;
3672     }
3673 
3674     if (dest->getType() != TextureType::_2D)
3675     {
3676         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidDestinationTextureType);
3677         return false;
3678     }
3679 
3680     if (dest->getImmutableFormat())
3681     {
3682         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kDestinationImmutable);
3683         return false;
3684     }
3685 
3686     return true;
3687 }
3688 
ValidateCreateShader(const Context * context,angle::EntryPoint entryPoint,ShaderType type)3689 bool ValidateCreateShader(const Context *context, angle::EntryPoint entryPoint, ShaderType type)
3690 {
3691     switch (type)
3692     {
3693         case ShaderType::Vertex:
3694         case ShaderType::Fragment:
3695             break;
3696 
3697         case ShaderType::Compute:
3698             if (context->getClientVersion() < ES_3_1)
3699             {
3700                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kES31Required);
3701                 return false;
3702             }
3703             break;
3704 
3705         case ShaderType::Geometry:
3706             if (!context->getExtensions().geometryShaderAny() &&
3707                 context->getClientVersion() < ES_3_2)
3708             {
3709                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidShaderType);
3710                 return false;
3711             }
3712             break;
3713 
3714         case ShaderType::TessControl:
3715             if (!context->getExtensions().tessellationShaderAny() &&
3716                 context->getClientVersion() < ES_3_2)
3717             {
3718                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidShaderType);
3719                 return false;
3720             }
3721             break;
3722 
3723         case ShaderType::TessEvaluation:
3724             if (!context->getExtensions().tessellationShaderAny() &&
3725                 context->getClientVersion() < ES_3_2)
3726             {
3727                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidShaderType);
3728                 return false;
3729             }
3730             break;
3731 
3732         default:
3733             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidShaderType);
3734             return false;
3735     }
3736 
3737     return true;
3738 }
3739 
ValidateBufferData(const Context * context,angle::EntryPoint entryPoint,BufferBinding target,GLsizeiptr size,const void * data,BufferUsage usage)3740 bool ValidateBufferData(const Context *context,
3741                         angle::EntryPoint entryPoint,
3742                         BufferBinding target,
3743                         GLsizeiptr size,
3744                         const void *data,
3745                         BufferUsage usage)
3746 {
3747     if (size < 0)
3748     {
3749         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeSize);
3750         return false;
3751     }
3752 
3753     switch (usage)
3754     {
3755         case BufferUsage::StreamDraw:
3756         case BufferUsage::StaticDraw:
3757         case BufferUsage::DynamicDraw:
3758             break;
3759 
3760         case BufferUsage::StreamRead:
3761         case BufferUsage::StaticRead:
3762         case BufferUsage::DynamicRead:
3763         case BufferUsage::StreamCopy:
3764         case BufferUsage::StaticCopy:
3765         case BufferUsage::DynamicCopy:
3766             if (context->getClientMajorVersion() < 3)
3767             {
3768                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidBufferUsage);
3769                 return false;
3770             }
3771             break;
3772 
3773         default:
3774             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidBufferUsage);
3775             return false;
3776     }
3777 
3778     if (!context->isValidBufferBinding(target))
3779     {
3780         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidBufferTypes);
3781         return false;
3782     }
3783 
3784     Buffer *buffer = context->getState().getTargetBuffer(target);
3785 
3786     if (!buffer)
3787     {
3788         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBufferNotBound);
3789         return false;
3790     }
3791 
3792     if (buffer->hasWebGLXFBBindingConflict(context->isWebGL()))
3793     {
3794         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBufferBoundForTransformFeedback);
3795         return false;
3796     }
3797 
3798     if (buffer->isImmutable())
3799     {
3800         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBufferImmutable);
3801         return false;
3802     }
3803 
3804     return true;
3805 }
3806 
ValidateBufferSubData(const Context * context,angle::EntryPoint entryPoint,BufferBinding target,GLintptr offset,GLsizeiptr size,const void * data)3807 bool ValidateBufferSubData(const Context *context,
3808                            angle::EntryPoint entryPoint,
3809                            BufferBinding target,
3810                            GLintptr offset,
3811                            GLsizeiptr size,
3812                            const void *data)
3813 {
3814     if (size < 0)
3815     {
3816         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeSize);
3817         return false;
3818     }
3819 
3820     if (offset < 0)
3821     {
3822         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeOffset);
3823         return false;
3824     }
3825 
3826     if (!context->isValidBufferBinding(target))
3827     {
3828         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidBufferTypes);
3829         return false;
3830     }
3831 
3832     Buffer *buffer = context->getState().getTargetBuffer(target);
3833 
3834     if (!buffer)
3835     {
3836         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBufferNotBound);
3837         return false;
3838     }
3839 
3840     // EXT_buffer_storage allows persistently mapped buffers to be updated via glBufferSubData
3841     bool isPersistent = (buffer->getAccessFlags() & GL_MAP_PERSISTENT_BIT_EXT) != 0;
3842 
3843     // Verify that buffer is not currently mapped unless persistent
3844     if (buffer->isMapped() && !isPersistent)
3845     {
3846         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBufferMapped);
3847         return false;
3848     }
3849 
3850     if (buffer->hasWebGLXFBBindingConflict(context->isWebGL()))
3851     {
3852         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBufferBoundForTransformFeedback);
3853         return false;
3854     }
3855 
3856     if (buffer->isImmutable() &&
3857         (buffer->getStorageExtUsageFlags() & GL_DYNAMIC_STORAGE_BIT_EXT) == 0)
3858     {
3859         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBufferNotUpdatable);
3860         return false;
3861     }
3862 
3863     // Check for possible overflow of size + offset
3864     angle::CheckedNumeric<decltype(size + offset)> checkedSize(size);
3865     checkedSize += offset;
3866     if (!checkedSize.IsValid())
3867     {
3868         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kParamOverflow);
3869         return false;
3870     }
3871 
3872     if (size + offset > buffer->getSize())
3873     {
3874         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInsufficientBufferSize);
3875         return false;
3876     }
3877 
3878     return true;
3879 }
3880 
ValidateRequestExtensionANGLE(const Context * context,angle::EntryPoint entryPoint,const GLchar * name)3881 bool ValidateRequestExtensionANGLE(const Context *context,
3882                                    angle::EntryPoint entryPoint,
3883                                    const GLchar *name)
3884 {
3885     if (!context->getExtensions().requestExtensionANGLE)
3886     {
3887         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3888         return false;
3889     }
3890 
3891     if (!context->isExtensionRequestable(name))
3892     {
3893         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotRequestable);
3894         return false;
3895     }
3896 
3897     return true;
3898 }
3899 
ValidateDisableExtensionANGLE(const Context * context,angle::EntryPoint entryPoint,const GLchar * name)3900 bool ValidateDisableExtensionANGLE(const Context *context,
3901                                    angle::EntryPoint entryPoint,
3902                                    const GLchar *name)
3903 {
3904     if (!context->getExtensions().requestExtensionANGLE)
3905     {
3906         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3907         return false;
3908     }
3909 
3910     if (!context->isExtensionDisablable(name))
3911     {
3912         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotDisablable);
3913         return false;
3914     }
3915 
3916     return true;
3917 }
3918 
ValidateActiveTexture(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLenum texture)3919 bool ValidateActiveTexture(const PrivateState &state,
3920                            ErrorSet *errors,
3921                            angle::EntryPoint entryPoint,
3922                            GLenum texture)
3923 {
3924     if (state.getClientMajorVersion() < 2)
3925     {
3926         return ValidateMultitextureUnit(state, errors, entryPoint, texture);
3927     }
3928 
3929     if (texture < GL_TEXTURE0 ||
3930         texture >
3931             GL_TEXTURE0 + static_cast<GLuint>(state.getCaps().maxCombinedTextureImageUnits) - 1)
3932     {
3933         errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidCombinedImageUnit);
3934         return false;
3935     }
3936 
3937     return true;
3938 }
3939 
ValidateAttachShader(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,ShaderProgramID shader)3940 bool ValidateAttachShader(const Context *context,
3941                           angle::EntryPoint entryPoint,
3942                           ShaderProgramID program,
3943                           ShaderProgramID shader)
3944 {
3945     Program *programObject = GetValidProgram(context, entryPoint, program);
3946     if (!programObject)
3947     {
3948         return false;
3949     }
3950 
3951     Shader *shaderObject = GetValidShader(context, entryPoint, shader);
3952     if (!shaderObject)
3953     {
3954         return false;
3955     }
3956 
3957     if (programObject->getAttachedShader(shaderObject->getType()))
3958     {
3959         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kShaderAttachmentHasShader);
3960         return false;
3961     }
3962 
3963     return true;
3964 }
3965 
ValidateBindAttribLocation(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,GLuint index,const GLchar * name)3966 bool ValidateBindAttribLocation(const Context *context,
3967                                 angle::EntryPoint entryPoint,
3968                                 ShaderProgramID program,
3969                                 GLuint index,
3970                                 const GLchar *name)
3971 {
3972     if (index >= static_cast<GLuint>(context->getCaps().maxVertexAttributes))
3973     {
3974         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
3975         return false;
3976     }
3977 
3978     if (strncmp(name, "gl_", 3) == 0)
3979     {
3980         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kNameBeginsWithGL);
3981         return false;
3982     }
3983 
3984     if (context->isWebGL())
3985     {
3986         const size_t length = strlen(name);
3987 
3988         if (!IsValidESSLString(name, length))
3989         {
3990             // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters
3991             // for shader-related entry points
3992             ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidNameCharacters);
3993             return false;
3994         }
3995 
3996         if (!ValidateWebGLNameLength(context, entryPoint, length) ||
3997             !ValidateWebGLNamePrefix(context, entryPoint, name))
3998         {
3999             return false;
4000         }
4001     }
4002 
4003     return GetValidProgram(context, entryPoint, program) != nullptr;
4004 }
4005 
ValidateBindFramebuffer(const Context * context,angle::EntryPoint entryPoint,GLenum target,FramebufferID framebuffer)4006 bool ValidateBindFramebuffer(const Context *context,
4007                              angle::EntryPoint entryPoint,
4008                              GLenum target,
4009                              FramebufferID framebuffer)
4010 {
4011     return ValidateBindFramebufferBase(context, entryPoint, target, framebuffer);
4012 }
4013 
ValidateBindRenderbuffer(const Context * context,angle::EntryPoint entryPoint,GLenum target,RenderbufferID renderbuffer)4014 bool ValidateBindRenderbuffer(const Context *context,
4015                               angle::EntryPoint entryPoint,
4016                               GLenum target,
4017                               RenderbufferID renderbuffer)
4018 {
4019     return ValidateBindRenderbufferBase(context, entryPoint, target, renderbuffer);
4020 }
4021 
ValidBlendEquationMode(const PrivateState & state,ErrorSet * errors,GLenum mode)4022 static bool ValidBlendEquationMode(const PrivateState &state, ErrorSet *errors, GLenum mode)
4023 {
4024     switch (mode)
4025     {
4026         case GL_FUNC_ADD:
4027         case GL_FUNC_SUBTRACT:
4028         case GL_FUNC_REVERSE_SUBTRACT:
4029             return true;
4030 
4031         case GL_MIN:
4032         case GL_MAX:
4033             return state.getClientVersion() >= ES_3_0 || state.getExtensions().blendMinmaxEXT;
4034 
4035         default:
4036             return false;
4037     }
4038 }
4039 
ValidAdvancedBlendEquationMode(const PrivateState & state,GLenum mode)4040 static bool ValidAdvancedBlendEquationMode(const PrivateState &state, GLenum mode)
4041 {
4042     switch (mode)
4043     {
4044         case GL_MULTIPLY_KHR:
4045         case GL_SCREEN_KHR:
4046         case GL_OVERLAY_KHR:
4047         case GL_DARKEN_KHR:
4048         case GL_LIGHTEN_KHR:
4049         case GL_COLORDODGE_KHR:
4050         case GL_COLORBURN_KHR:
4051         case GL_HARDLIGHT_KHR:
4052         case GL_SOFTLIGHT_KHR:
4053         case GL_DIFFERENCE_KHR:
4054         case GL_EXCLUSION_KHR:
4055         case GL_HSL_HUE_KHR:
4056         case GL_HSL_SATURATION_KHR:
4057         case GL_HSL_COLOR_KHR:
4058         case GL_HSL_LUMINOSITY_KHR:
4059             return state.getClientVersion() >= ES_3_2 ||
4060                    state.getExtensions().blendEquationAdvancedKHR;
4061 
4062         default:
4063             return false;
4064     }
4065 }
4066 
ValidateBlendColor(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLfloat red,GLfloat green,GLfloat blue,GLfloat alpha)4067 bool ValidateBlendColor(const PrivateState &state,
4068                         ErrorSet *errors,
4069                         angle::EntryPoint entryPoint,
4070                         GLfloat red,
4071                         GLfloat green,
4072                         GLfloat blue,
4073                         GLfloat alpha)
4074 {
4075     return true;
4076 }
4077 
ValidateBlendEquation(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLenum mode)4078 bool ValidateBlendEquation(const PrivateState &state,
4079                            ErrorSet *errors,
4080                            angle::EntryPoint entryPoint,
4081                            GLenum mode)
4082 {
4083     if (ValidBlendEquationMode(state, errors, mode))
4084     {
4085         return true;
4086     }
4087 
4088     if (ValidAdvancedBlendEquationMode(state, mode))
4089     {
4090         if (state.getPixelLocalStorageActivePlanes() != 0)
4091         {
4092             // INVALID_OPERATION is generated by BlendEquation*() if <mode> is one of the advanced
4093             // blend equations defined in KHR_blend_equation_advanced.
4094             errors->validationError(entryPoint, GL_INVALID_OPERATION,
4095                                     kPLSAdvancedBlendNotSupported);
4096             return false;
4097         }
4098         return true;
4099     }
4100 
4101     errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidBlendEquation);
4102     return false;
4103 }
4104 
ValidateBlendEquationSeparate(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLenum modeRGB,GLenum modeAlpha)4105 bool ValidateBlendEquationSeparate(const PrivateState &state,
4106                                    ErrorSet *errors,
4107                                    angle::EntryPoint entryPoint,
4108                                    GLenum modeRGB,
4109                                    GLenum modeAlpha)
4110 {
4111     if (!ValidBlendEquationMode(state, errors, modeRGB))
4112     {
4113         errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidBlendEquation);
4114         return false;
4115     }
4116 
4117     if (!ValidBlendEquationMode(state, errors, modeAlpha))
4118     {
4119         errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidBlendEquation);
4120         return false;
4121     }
4122 
4123     return true;
4124 }
4125 
ValidateBlendFunc(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLenum sfactor,GLenum dfactor)4126 bool ValidateBlendFunc(const PrivateState &state,
4127                        ErrorSet *errors,
4128                        angle::EntryPoint entryPoint,
4129                        GLenum sfactor,
4130                        GLenum dfactor)
4131 {
4132     return ValidateBlendFuncSeparate(state, errors, entryPoint, sfactor, dfactor, sfactor, dfactor);
4133 }
4134 
ValidateBlendFuncSeparate(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLenum srcRGB,GLenum dstRGB,GLenum srcAlpha,GLenum dstAlpha)4135 bool ValidateBlendFuncSeparate(const PrivateState &state,
4136                                ErrorSet *errors,
4137                                angle::EntryPoint entryPoint,
4138                                GLenum srcRGB,
4139                                GLenum dstRGB,
4140                                GLenum srcAlpha,
4141                                GLenum dstAlpha)
4142 {
4143     if (!ValidateSrcBlendFunc(state, errors, entryPoint, srcRGB) ||
4144         !ValidateDstBlendFunc(state, errors, entryPoint, dstRGB) ||
4145         !ValidateSrcBlendFunc(state, errors, entryPoint, srcAlpha) ||
4146         !ValidateDstBlendFunc(state, errors, entryPoint, dstAlpha))
4147     {
4148         return false;
4149     }
4150 
4151     if (state.getLimitations().noSimultaneousConstantColorAndAlphaBlendFunc || state.isWebGL())
4152     {
4153         bool constantColorUsed =
4154             (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
4155              dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
4156 
4157         bool constantAlphaUsed =
4158             (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
4159              dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
4160 
4161         if (constantColorUsed && constantAlphaUsed)
4162         {
4163             if (state.isWebGL())
4164             {
4165                 errors->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidConstantColor);
4166                 return false;
4167             }
4168 
4169             WARN() << kConstantColorAlphaLimitation;
4170             errors->validationError(entryPoint, GL_INVALID_OPERATION,
4171                                     kConstantColorAlphaLimitation);
4172             return false;
4173         }
4174     }
4175 
4176     return true;
4177 }
4178 
ValidateGetString(const Context * context,angle::EntryPoint entryPoint,GLenum name)4179 bool ValidateGetString(const Context *context, angle::EntryPoint entryPoint, GLenum name)
4180 {
4181     switch (name)
4182     {
4183         case GL_VENDOR:
4184         case GL_RENDERER:
4185         case GL_VERSION:
4186         case GL_SHADING_LANGUAGE_VERSION:
4187         case GL_EXTENSIONS:
4188             break;
4189 
4190         case GL_REQUESTABLE_EXTENSIONS_ANGLE:
4191             if (!context->getExtensions().requestExtensionANGLE)
4192             {
4193                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidName);
4194                 return false;
4195             }
4196             break;
4197 
4198         case GL_SERIALIZED_CONTEXT_STRING_ANGLE:
4199             if (!context->getExtensions().getSerializedContextStringANGLE)
4200             {
4201                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidName);
4202                 return false;
4203             }
4204             break;
4205 
4206         default:
4207             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidName);
4208             return false;
4209     }
4210 
4211     return true;
4212 }
4213 
ValidateLineWidth(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLfloat width)4214 bool ValidateLineWidth(const PrivateState &state,
4215                        ErrorSet *errors,
4216                        angle::EntryPoint entryPoint,
4217                        GLfloat width)
4218 {
4219     if (width <= 0.0f || isNaN(width))
4220     {
4221         errors->validationError(entryPoint, GL_INVALID_VALUE, kInvalidWidth);
4222         return false;
4223     }
4224 
4225     return true;
4226 }
4227 
ValidateDepthRangef(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLfloat zNear,GLfloat zFar)4228 bool ValidateDepthRangef(const PrivateState &state,
4229                          ErrorSet *errors,
4230                          angle::EntryPoint entryPoint,
4231                          GLfloat zNear,
4232                          GLfloat zFar)
4233 {
4234     if (state.isWebGL() && zNear > zFar)
4235     {
4236         errors->validationError(entryPoint, GL_INVALID_OPERATION, kInvalidDepthRange);
4237         return false;
4238     }
4239 
4240     return true;
4241 }
4242 
ValidateRenderbufferStorage(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLenum internalformat,GLsizei width,GLsizei height)4243 bool ValidateRenderbufferStorage(const Context *context,
4244                                  angle::EntryPoint entryPoint,
4245                                  GLenum target,
4246                                  GLenum internalformat,
4247                                  GLsizei width,
4248                                  GLsizei height)
4249 {
4250     return ValidateRenderbufferStorageParametersBase(context, entryPoint, target, 0, internalformat,
4251                                                      width, height);
4252 }
4253 
ValidateRenderbufferStorageMultisampleANGLE(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLsizei samples,GLenum internalformat,GLsizei width,GLsizei height)4254 bool ValidateRenderbufferStorageMultisampleANGLE(const Context *context,
4255                                                  angle::EntryPoint entryPoint,
4256                                                  GLenum target,
4257                                                  GLsizei samples,
4258                                                  GLenum internalformat,
4259                                                  GLsizei width,
4260                                                  GLsizei height)
4261 {
4262     if (!context->getExtensions().framebufferMultisampleANGLE)
4263     {
4264         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
4265         return false;
4266     }
4267 
4268     // ANGLE_framebuffer_multisample states that the value of samples must be less than or equal
4269     // to MAX_SAMPLES_ANGLE (Context::getCaps().maxSamples) otherwise GL_INVALID_VALUE is
4270     // generated.
4271     if (samples > context->getCaps().maxSamples)
4272     {
4273         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kSamplesOutOfRange);
4274         return false;
4275     }
4276 
4277     // ANGLE_framebuffer_multisample states GL_OUT_OF_MEMORY is generated on a failure to create
4278     // the specified storage. This is different than ES 3.0 in which a sample number higher
4279     // than the maximum sample number supported by this format generates a GL_INVALID_VALUE.
4280     // The TextureCaps::getMaxSamples method is only guarenteed to be valid when the context is ES3.
4281     if (context->getClientMajorVersion() >= 3)
4282     {
4283         const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
4284         if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
4285         {
4286             ANGLE_VALIDATION_ERROR(GL_OUT_OF_MEMORY, kSamplesOutOfRange);
4287             return false;
4288         }
4289     }
4290 
4291     return ValidateRenderbufferStorageParametersBase(context, entryPoint, target, samples,
4292                                                      internalformat, width, height);
4293 }
4294 
ValidateCheckFramebufferStatus(const Context * context,angle::EntryPoint entryPoint,GLenum target)4295 bool ValidateCheckFramebufferStatus(const Context *context,
4296                                     angle::EntryPoint entryPoint,
4297                                     GLenum target)
4298 {
4299     if (!ValidFramebufferTarget(context, target))
4300     {
4301         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidFramebufferTarget);
4302         return false;
4303     }
4304 
4305     return true;
4306 }
4307 
ValidateClearColor(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLfloat red,GLfloat green,GLfloat blue,GLfloat alpha)4308 bool ValidateClearColor(const PrivateState &state,
4309                         ErrorSet *errors,
4310                         angle::EntryPoint entryPoint,
4311                         GLfloat red,
4312                         GLfloat green,
4313                         GLfloat blue,
4314                         GLfloat alpha)
4315 {
4316     return true;
4317 }
4318 
ValidateClearDepthf(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLfloat depth)4319 bool ValidateClearDepthf(const PrivateState &state,
4320                          ErrorSet *errors,
4321                          angle::EntryPoint entryPoint,
4322                          GLfloat depth)
4323 {
4324     return true;
4325 }
4326 
ValidateClearStencil(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLint s)4327 bool ValidateClearStencil(const PrivateState &state,
4328                           ErrorSet *errors,
4329                           angle::EntryPoint entryPoint,
4330                           GLint s)
4331 {
4332     return true;
4333 }
4334 
ValidateColorMask(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLboolean red,GLboolean green,GLboolean blue,GLboolean alpha)4335 bool ValidateColorMask(const PrivateState &state,
4336                        ErrorSet *errors,
4337                        angle::EntryPoint entryPoint,
4338                        GLboolean red,
4339                        GLboolean green,
4340                        GLboolean blue,
4341                        GLboolean alpha)
4342 {
4343     return true;
4344 }
4345 
ValidateCompileShader(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID shader)4346 bool ValidateCompileShader(const Context *context,
4347                            angle::EntryPoint entryPoint,
4348                            ShaderProgramID shader)
4349 {
4350     return true;
4351 }
4352 
ValidateCreateProgram(const Context * context,angle::EntryPoint entryPoint)4353 bool ValidateCreateProgram(const Context *context, angle::EntryPoint entryPoint)
4354 {
4355     return true;
4356 }
4357 
ValidateCullFace(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,CullFaceMode mode)4358 bool ValidateCullFace(const PrivateState &state,
4359                       ErrorSet *errors,
4360                       angle::EntryPoint entryPoint,
4361                       CullFaceMode mode)
4362 {
4363     switch (mode)
4364     {
4365         case CullFaceMode::Front:
4366         case CullFaceMode::Back:
4367         case CullFaceMode::FrontAndBack:
4368             break;
4369 
4370         default:
4371             errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidCullMode);
4372             return false;
4373     }
4374 
4375     return true;
4376 }
4377 
ValidateDeleteProgram(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program)4378 bool ValidateDeleteProgram(const Context *context,
4379                            angle::EntryPoint entryPoint,
4380                            ShaderProgramID program)
4381 {
4382     if (program.value == 0)
4383     {
4384         return false;
4385     }
4386 
4387     if (!context->getProgramResolveLink(program))
4388     {
4389         if (context->getShaderNoResolveCompile(program))
4390         {
4391             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExpectedProgramName);
4392             return false;
4393         }
4394         else
4395         {
4396             ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidProgramName);
4397             return false;
4398         }
4399     }
4400 
4401     return true;
4402 }
4403 
ValidateDeleteShader(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID shader)4404 bool ValidateDeleteShader(const Context *context,
4405                           angle::EntryPoint entryPoint,
4406                           ShaderProgramID shader)
4407 {
4408     if (shader.value == 0)
4409     {
4410         return false;
4411     }
4412 
4413     if (!context->getShaderNoResolveCompile(shader))
4414     {
4415         if (context->getProgramResolveLink(shader))
4416         {
4417             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidShaderName);
4418             return false;
4419         }
4420         else
4421         {
4422             ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kExpectedShaderName);
4423             return false;
4424         }
4425     }
4426 
4427     return true;
4428 }
4429 
ValidateDepthFunc(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLenum func)4430 bool ValidateDepthFunc(const PrivateState &state,
4431                        ErrorSet *errors,
4432                        angle::EntryPoint entryPoint,
4433                        GLenum func)
4434 {
4435     switch (func)
4436     {
4437         case GL_NEVER:
4438         case GL_ALWAYS:
4439         case GL_LESS:
4440         case GL_LEQUAL:
4441         case GL_EQUAL:
4442         case GL_GREATER:
4443         case GL_GEQUAL:
4444         case GL_NOTEQUAL:
4445             break;
4446 
4447         default:
4448             errors->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, func);
4449             return false;
4450     }
4451 
4452     return true;
4453 }
4454 
ValidateDepthMask(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLboolean flag)4455 bool ValidateDepthMask(const PrivateState &state,
4456                        ErrorSet *errors,
4457                        angle::EntryPoint entryPoint,
4458                        GLboolean flag)
4459 {
4460     return true;
4461 }
4462 
ValidateDetachShader(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,ShaderProgramID shader)4463 bool ValidateDetachShader(const Context *context,
4464                           angle::EntryPoint entryPoint,
4465                           ShaderProgramID program,
4466                           ShaderProgramID shader)
4467 {
4468     Program *programObject = GetValidProgram(context, entryPoint, program);
4469     if (!programObject)
4470     {
4471         return false;
4472     }
4473 
4474     Shader *shaderObject = GetValidShader(context, entryPoint, shader);
4475     if (!shaderObject)
4476     {
4477         return false;
4478     }
4479 
4480     const Shader *attachedShader = programObject->getAttachedShader(shaderObject->getType());
4481     if (attachedShader != shaderObject)
4482     {
4483         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kShaderToDetachMustBeAttached);
4484         return false;
4485     }
4486 
4487     return true;
4488 }
4489 
ValidateDisableVertexAttribArray(const Context * context,angle::EntryPoint entryPoint,GLuint index)4490 bool ValidateDisableVertexAttribArray(const Context *context,
4491                                       angle::EntryPoint entryPoint,
4492                                       GLuint index)
4493 {
4494     if (index >= static_cast<GLuint>(context->getCaps().maxVertexAttributes))
4495     {
4496         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
4497         return false;
4498     }
4499 
4500     return true;
4501 }
4502 
ValidateEnableVertexAttribArray(const Context * context,angle::EntryPoint entryPoint,GLuint index)4503 bool ValidateEnableVertexAttribArray(const Context *context,
4504                                      angle::EntryPoint entryPoint,
4505                                      GLuint index)
4506 {
4507     if (index >= static_cast<GLuint>(context->getCaps().maxVertexAttributes))
4508     {
4509         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
4510         return false;
4511     }
4512 
4513     return true;
4514 }
4515 
ValidateFinish(const Context * context,angle::EntryPoint entryPoint)4516 bool ValidateFinish(const Context *context, angle::EntryPoint entryPoint)
4517 {
4518     return true;
4519 }
4520 
ValidateFlush(const Context * context,angle::EntryPoint entryPoint)4521 bool ValidateFlush(const Context *context, angle::EntryPoint entryPoint)
4522 {
4523     return true;
4524 }
4525 
ValidateFrontFace(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLenum mode)4526 bool ValidateFrontFace(const PrivateState &state,
4527                        ErrorSet *errors,
4528                        angle::EntryPoint entryPoint,
4529                        GLenum mode)
4530 {
4531     switch (mode)
4532     {
4533         case GL_CW:
4534         case GL_CCW:
4535             break;
4536         default:
4537             errors->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, mode);
4538             return false;
4539     }
4540 
4541     return true;
4542 }
4543 
ValidateGetActiveAttrib(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,GLuint index,GLsizei bufsize,const GLsizei * length,const GLint * size,const GLenum * type,const GLchar * name)4544 bool ValidateGetActiveAttrib(const Context *context,
4545                              angle::EntryPoint entryPoint,
4546                              ShaderProgramID program,
4547                              GLuint index,
4548                              GLsizei bufsize,
4549                              const GLsizei *length,
4550                              const GLint *size,
4551                              const GLenum *type,
4552                              const GLchar *name)
4553 {
4554     if (bufsize < 0)
4555     {
4556         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeBufferSize);
4557         return false;
4558     }
4559 
4560     Program *programObject = GetValidProgram(context, entryPoint, program);
4561 
4562     if (!programObject)
4563     {
4564         return false;
4565     }
4566 
4567     if (index >= static_cast<GLuint>(programObject->getExecutable().getProgramInputs().size()))
4568     {
4569         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kIndexExceedsMaxActiveUniform);
4570         return false;
4571     }
4572 
4573     return true;
4574 }
4575 
ValidateGetActiveUniform(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,GLuint index,GLsizei bufsize,const GLsizei * length,const GLint * size,const GLenum * type,const GLchar * name)4576 bool ValidateGetActiveUniform(const Context *context,
4577                               angle::EntryPoint entryPoint,
4578                               ShaderProgramID program,
4579                               GLuint index,
4580                               GLsizei bufsize,
4581                               const GLsizei *length,
4582                               const GLint *size,
4583                               const GLenum *type,
4584                               const GLchar *name)
4585 {
4586     if (bufsize < 0)
4587     {
4588         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeBufferSize);
4589         return false;
4590     }
4591 
4592     Program *programObject = GetValidProgram(context, entryPoint, program);
4593 
4594     if (!programObject)
4595     {
4596         return false;
4597     }
4598 
4599     if (index >= programObject->getExecutable().getUniforms().size())
4600     {
4601         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kIndexExceedsMaxActiveUniform);
4602         return false;
4603     }
4604 
4605     return true;
4606 }
4607 
ValidateGetAttachedShaders(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,GLsizei maxcount,const GLsizei * count,const ShaderProgramID * shaders)4608 bool ValidateGetAttachedShaders(const Context *context,
4609                                 angle::EntryPoint entryPoint,
4610                                 ShaderProgramID program,
4611                                 GLsizei maxcount,
4612                                 const GLsizei *count,
4613                                 const ShaderProgramID *shaders)
4614 {
4615     if (maxcount < 0)
4616     {
4617         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeMaxCount);
4618         return false;
4619     }
4620 
4621     Program *programObject = GetValidProgram(context, entryPoint, program);
4622 
4623     if (!programObject)
4624     {
4625         return false;
4626     }
4627 
4628     return true;
4629 }
4630 
ValidateGetAttribLocation(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,const GLchar * name)4631 bool ValidateGetAttribLocation(const Context *context,
4632                                angle::EntryPoint entryPoint,
4633                                ShaderProgramID program,
4634                                const GLchar *name)
4635 {
4636     if (strncmp(name, "gl_", 3) == 0)
4637     {
4638         return false;
4639     }
4640 
4641     if (context->isWebGL())
4642     {
4643         const size_t length = strlen(name);
4644 
4645         if (!IsValidESSLString(name, length))
4646         {
4647             // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters
4648             // for shader-related entry points
4649             ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidNameCharacters);
4650             return false;
4651         }
4652 
4653         if (!ValidateWebGLNameLength(context, entryPoint, length) ||
4654             strncmp(name, "webgl_", 6) == 0 || strncmp(name, "_webgl_", 7) == 0)
4655         {
4656             return false;
4657         }
4658     }
4659 
4660     Program *programObject = GetValidProgram(context, entryPoint, program);
4661 
4662     if (!programObject)
4663     {
4664         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kProgramNotBound);
4665         return false;
4666     }
4667 
4668     if (!programObject->isLinked())
4669     {
4670         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kProgramNotLinked);
4671         return false;
4672     }
4673 
4674     return true;
4675 }
4676 
ValidateGetBooleanv(const Context * context,angle::EntryPoint entryPoint,GLenum pname,const GLboolean * params)4677 bool ValidateGetBooleanv(const Context *context,
4678                          angle::EntryPoint entryPoint,
4679                          GLenum pname,
4680                          const GLboolean *params)
4681 {
4682     GLenum nativeType;
4683     unsigned int numParams = 0;
4684     return ValidateStateQuery(context, entryPoint, pname, &nativeType, &numParams);
4685 }
4686 
ValidateGetError(const Context * context,angle::EntryPoint entryPoint)4687 bool ValidateGetError(const Context *context, angle::EntryPoint entryPoint)
4688 {
4689     return true;
4690 }
4691 
ValidateGetFloatv(const Context * context,angle::EntryPoint entryPoint,GLenum pname,const GLfloat * params)4692 bool ValidateGetFloatv(const Context *context,
4693                        angle::EntryPoint entryPoint,
4694                        GLenum pname,
4695                        const GLfloat *params)
4696 {
4697     GLenum nativeType;
4698     unsigned int numParams = 0;
4699     return ValidateStateQuery(context, entryPoint, pname, &nativeType, &numParams);
4700 }
4701 
ValidateGetIntegerv(const Context * context,angle::EntryPoint entryPoint,GLenum pname,const GLint * params)4702 bool ValidateGetIntegerv(const Context *context,
4703                          angle::EntryPoint entryPoint,
4704                          GLenum pname,
4705                          const GLint *params)
4706 {
4707     GLenum nativeType;
4708     unsigned int numParams = 0;
4709     return ValidateStateQuery(context, entryPoint, pname, &nativeType, &numParams);
4710 }
4711 
ValidateGetProgramInfoLog(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,GLsizei bufsize,const GLsizei * length,const GLchar * infolog)4712 bool ValidateGetProgramInfoLog(const Context *context,
4713                                angle::EntryPoint entryPoint,
4714                                ShaderProgramID program,
4715                                GLsizei bufsize,
4716                                const GLsizei *length,
4717                                const GLchar *infolog)
4718 {
4719     if (bufsize < 0)
4720     {
4721         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeBufferSize);
4722         return false;
4723     }
4724 
4725     Program *programObject = GetValidProgram(context, entryPoint, program);
4726     if (!programObject)
4727     {
4728         return false;
4729     }
4730 
4731     return true;
4732 }
4733 
ValidateGetShaderInfoLog(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID shader,GLsizei bufsize,const GLsizei * length,const GLchar * infolog)4734 bool ValidateGetShaderInfoLog(const Context *context,
4735                               angle::EntryPoint entryPoint,
4736                               ShaderProgramID shader,
4737                               GLsizei bufsize,
4738                               const GLsizei *length,
4739                               const GLchar *infolog)
4740 {
4741     if (bufsize < 0)
4742     {
4743         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeBufferSize);
4744         return false;
4745     }
4746 
4747     Shader *shaderObject = GetValidShader(context, entryPoint, shader);
4748     if (!shaderObject)
4749     {
4750         return false;
4751     }
4752 
4753     return true;
4754 }
4755 
ValidateGetShaderPrecisionFormat(const Context * context,angle::EntryPoint entryPoint,GLenum shadertype,GLenum precisiontype,const GLint * range,const GLint * precision)4756 bool ValidateGetShaderPrecisionFormat(const Context *context,
4757                                       angle::EntryPoint entryPoint,
4758                                       GLenum shadertype,
4759                                       GLenum precisiontype,
4760                                       const GLint *range,
4761                                       const GLint *precision)
4762 {
4763     switch (shadertype)
4764     {
4765         case GL_VERTEX_SHADER:
4766         case GL_FRAGMENT_SHADER:
4767             break;
4768         case GL_COMPUTE_SHADER:
4769             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kUnimplementedComputeShaderPrecision);
4770             return false;
4771         default:
4772             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidShaderType);
4773             return false;
4774     }
4775 
4776     switch (precisiontype)
4777     {
4778         case GL_LOW_FLOAT:
4779         case GL_MEDIUM_FLOAT:
4780         case GL_HIGH_FLOAT:
4781         case GL_LOW_INT:
4782         case GL_MEDIUM_INT:
4783         case GL_HIGH_INT:
4784             break;
4785 
4786         default:
4787             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidPrecision);
4788             return false;
4789     }
4790 
4791     return true;
4792 }
4793 
ValidateGetShaderSource(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID shader,GLsizei bufsize,const GLsizei * length,const GLchar * source)4794 bool ValidateGetShaderSource(const Context *context,
4795                              angle::EntryPoint entryPoint,
4796                              ShaderProgramID shader,
4797                              GLsizei bufsize,
4798                              const GLsizei *length,
4799                              const GLchar *source)
4800 {
4801     if (bufsize < 0)
4802     {
4803         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeBufferSize);
4804         return false;
4805     }
4806 
4807     Shader *shaderObject = GetValidShader(context, entryPoint, shader);
4808     if (!shaderObject)
4809     {
4810         return false;
4811     }
4812 
4813     return true;
4814 }
4815 
ValidateGetUniformLocation(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,const GLchar * name)4816 bool ValidateGetUniformLocation(const Context *context,
4817                                 angle::EntryPoint entryPoint,
4818                                 ShaderProgramID program,
4819                                 const GLchar *name)
4820 {
4821     if (strstr(name, "gl_") == name)
4822     {
4823         return false;
4824     }
4825 
4826     // The WebGL spec (section 6.20) disallows strings containing invalid ESSL characters for
4827     // shader-related entry points
4828     if (context->isWebGL() && !IsValidESSLString(name, strlen(name)))
4829     {
4830         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidNameCharacters);
4831         return false;
4832     }
4833 
4834     Program *programObject = GetValidProgram(context, entryPoint, program);
4835 
4836     if (!programObject)
4837     {
4838         return false;
4839     }
4840 
4841     if (!programObject->isLinked())
4842     {
4843         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kProgramNotLinked);
4844         return false;
4845     }
4846 
4847     return true;
4848 }
4849 
ValidateHint(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLenum target,GLenum mode)4850 bool ValidateHint(const PrivateState &state,
4851                   ErrorSet *errors,
4852                   angle::EntryPoint entryPoint,
4853                   GLenum target,
4854                   GLenum mode)
4855 {
4856     switch (mode)
4857     {
4858         case GL_FASTEST:
4859         case GL_NICEST:
4860         case GL_DONT_CARE:
4861             break;
4862 
4863         default:
4864             errors->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, mode);
4865             return false;
4866     }
4867 
4868     switch (target)
4869     {
4870         case GL_GENERATE_MIPMAP_HINT:
4871             break;
4872 
4873         case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
4874             if (state.getClientVersion() < ES_3_0 && !state.getExtensions().standardDerivativesOES)
4875             {
4876                 errors->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, target);
4877                 return false;
4878             }
4879             break;
4880 
4881         case GL_PERSPECTIVE_CORRECTION_HINT:
4882         case GL_POINT_SMOOTH_HINT:
4883         case GL_LINE_SMOOTH_HINT:
4884         case GL_FOG_HINT:
4885             if (state.getClientMajorVersion() >= 2)
4886             {
4887                 errors->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, target);
4888                 return false;
4889             }
4890             break;
4891 
4892         default:
4893             errors->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, target);
4894             return false;
4895     }
4896 
4897     return true;
4898 }
4899 
ValidateIsBuffer(const Context * context,angle::EntryPoint entryPoint,BufferID buffer)4900 bool ValidateIsBuffer(const Context *context, angle::EntryPoint entryPoint, BufferID buffer)
4901 {
4902     return true;
4903 }
4904 
ValidateIsFramebuffer(const Context * context,angle::EntryPoint entryPoint,FramebufferID framebuffer)4905 bool ValidateIsFramebuffer(const Context *context,
4906                            angle::EntryPoint entryPoint,
4907                            FramebufferID framebuffer)
4908 {
4909     return true;
4910 }
4911 
ValidateIsProgram(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program)4912 bool ValidateIsProgram(const Context *context,
4913                        angle::EntryPoint entryPoint,
4914                        ShaderProgramID program)
4915 {
4916     return true;
4917 }
4918 
ValidateIsRenderbuffer(const Context * context,angle::EntryPoint entryPoint,RenderbufferID renderbuffer)4919 bool ValidateIsRenderbuffer(const Context *context,
4920                             angle::EntryPoint entryPoint,
4921                             RenderbufferID renderbuffer)
4922 {
4923     return true;
4924 }
4925 
ValidateIsShader(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID shader)4926 bool ValidateIsShader(const Context *context, angle::EntryPoint entryPoint, ShaderProgramID shader)
4927 {
4928     return true;
4929 }
4930 
ValidateIsTexture(const Context * context,angle::EntryPoint entryPoint,TextureID texture)4931 bool ValidateIsTexture(const Context *context, angle::EntryPoint entryPoint, TextureID texture)
4932 {
4933     return true;
4934 }
4935 
ValidatePixelStorei(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLenum pname,GLint param)4936 bool ValidatePixelStorei(const PrivateState &state,
4937                          ErrorSet *errors,
4938                          angle::EntryPoint entryPoint,
4939                          GLenum pname,
4940                          GLint param)
4941 {
4942     if (state.getClientMajorVersion() < 3)
4943     {
4944         switch (pname)
4945         {
4946             case GL_UNPACK_IMAGE_HEIGHT:
4947             case GL_UNPACK_SKIP_IMAGES:
4948                 errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPname);
4949                 return false;
4950 
4951             case GL_UNPACK_ROW_LENGTH:
4952             case GL_UNPACK_SKIP_ROWS:
4953             case GL_UNPACK_SKIP_PIXELS:
4954                 if (!state.getExtensions().unpackSubimageEXT)
4955                 {
4956                     errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPname);
4957                     return false;
4958                 }
4959                 break;
4960 
4961             case GL_PACK_ROW_LENGTH:
4962             case GL_PACK_SKIP_ROWS:
4963             case GL_PACK_SKIP_PIXELS:
4964                 if (!state.getExtensions().packSubimageNV)
4965                 {
4966                     errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPname);
4967                     return false;
4968                 }
4969                 break;
4970         }
4971     }
4972 
4973     if (param < 0)
4974     {
4975         errors->validationError(entryPoint, GL_INVALID_VALUE, kNegativeParam);
4976         return false;
4977     }
4978 
4979     switch (pname)
4980     {
4981         case GL_UNPACK_ALIGNMENT:
4982             if (param != 1 && param != 2 && param != 4 && param != 8)
4983             {
4984                 errors->validationError(entryPoint, GL_INVALID_VALUE, kInvalidUnpackAlignment);
4985                 return false;
4986             }
4987             break;
4988 
4989         case GL_PACK_ALIGNMENT:
4990             if (param != 1 && param != 2 && param != 4 && param != 8)
4991             {
4992                 errors->validationError(entryPoint, GL_INVALID_VALUE, kInvalidUnpackAlignment);
4993                 return false;
4994             }
4995             break;
4996 
4997         case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
4998             if (!state.getExtensions().packReverseRowOrderANGLE)
4999             {
5000                 errors->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname);
5001             }
5002             break;
5003 
5004         case GL_UNPACK_ROW_LENGTH:
5005         case GL_UNPACK_IMAGE_HEIGHT:
5006         case GL_UNPACK_SKIP_IMAGES:
5007         case GL_UNPACK_SKIP_ROWS:
5008         case GL_UNPACK_SKIP_PIXELS:
5009         case GL_PACK_ROW_LENGTH:
5010         case GL_PACK_SKIP_ROWS:
5011         case GL_PACK_SKIP_PIXELS:
5012             break;
5013 
5014         default:
5015             errors->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, pname);
5016             return false;
5017     }
5018 
5019     return true;
5020 }
5021 
ValidatePolygonOffset(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLfloat factor,GLfloat units)5022 bool ValidatePolygonOffset(const PrivateState &state,
5023                            ErrorSet *errors,
5024                            angle::EntryPoint entryPoint,
5025                            GLfloat factor,
5026                            GLfloat units)
5027 {
5028     return true;
5029 }
5030 
ValidateReleaseShaderCompiler(const Context * context,angle::EntryPoint entryPoint)5031 bool ValidateReleaseShaderCompiler(const Context *context, angle::EntryPoint entryPoint)
5032 {
5033     return true;
5034 }
5035 
ValidateSampleCoverage(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLfloat value,GLboolean invert)5036 bool ValidateSampleCoverage(const PrivateState &state,
5037                             ErrorSet *errors,
5038                             angle::EntryPoint entryPoint,
5039                             GLfloat value,
5040                             GLboolean invert)
5041 {
5042     return true;
5043 }
5044 
ValidateScissor(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLint x,GLint y,GLsizei width,GLsizei height)5045 bool ValidateScissor(const PrivateState &state,
5046                      ErrorSet *errors,
5047                      angle::EntryPoint entryPoint,
5048                      GLint x,
5049                      GLint y,
5050                      GLsizei width,
5051                      GLsizei height)
5052 {
5053     if (width < 0 || height < 0)
5054     {
5055         errors->validationError(entryPoint, GL_INVALID_VALUE, kNegativeSize);
5056         return false;
5057     }
5058 
5059     return true;
5060 }
5061 
ValidateShaderBinary(const Context * context,angle::EntryPoint entryPoint,GLsizei n,const ShaderProgramID * shaders,GLenum binaryformat,const void * binary,GLsizei length)5062 bool ValidateShaderBinary(const Context *context,
5063                           angle::EntryPoint entryPoint,
5064                           GLsizei n,
5065                           const ShaderProgramID *shaders,
5066                           GLenum binaryformat,
5067                           const void *binary,
5068                           GLsizei length)
5069 {
5070     const std::vector<GLenum> &shaderBinaryFormats = context->getCaps().shaderBinaryFormats;
5071     if (std::find(shaderBinaryFormats.begin(), shaderBinaryFormats.end(), binaryformat) ==
5072         shaderBinaryFormats.end())
5073     {
5074         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidShaderBinaryFormat);
5075         return false;
5076     }
5077 
5078     ASSERT(binaryformat == GL_SHADER_BINARY_ANGLE);
5079 
5080     if (n <= 0)
5081     {
5082         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidShaderCount);
5083         return false;
5084     }
5085 
5086     if (length < 0)
5087     {
5088         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeLength);
5089         return false;
5090     }
5091 
5092     // GL_SHADER_BINARY_ANGLE shader binaries contain a single shader.
5093     if (n > 1)
5094     {
5095         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidShaderCount);
5096         return false;
5097     }
5098 
5099     Shader *shaderObject = GetValidShader(context, entryPoint, shaders[0]);
5100     if (!shaderObject)
5101     {
5102         return false;
5103     }
5104 
5105     // Check ANGLE version used to generate binary matches the current version.
5106     BinaryInputStream stream(binary, length);
5107     std::vector<uint8_t> versionString(angle::GetANGLEShaderProgramVersionHashSize(), 0);
5108     stream.readBytes(versionString.data(), versionString.size());
5109     if (memcmp(versionString.data(), angle::GetANGLEShaderProgramVersion(), versionString.size()) !=
5110         0)
5111     {
5112         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidShaderBinary);
5113         return false;
5114     }
5115 
5116     // Check that the shader type of the binary matches the type of target shader.
5117     gl::ShaderType shaderType;
5118     stream.readEnum(&shaderType);
5119     if (shaderObject->getType() != shaderType)
5120     {
5121         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kMismatchedShaderBinaryType);
5122         return false;
5123     }
5124 
5125     return true;
5126 }
5127 
ValidateShaderSource(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID shader,GLsizei count,const GLchar * const * string,const GLint * length)5128 bool ValidateShaderSource(const Context *context,
5129                           angle::EntryPoint entryPoint,
5130                           ShaderProgramID shader,
5131                           GLsizei count,
5132                           const GLchar *const *string,
5133                           const GLint *length)
5134 {
5135     if (count < 0)
5136     {
5137         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeCount);
5138         return false;
5139     }
5140 
5141     Shader *shaderObject = GetValidShader(context, entryPoint, shader);
5142     if (!shaderObject)
5143     {
5144         return false;
5145     }
5146 
5147     return true;
5148 }
5149 
ValidateStencilFunc(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLenum func,GLint ref,GLuint mask)5150 bool ValidateStencilFunc(const PrivateState &state,
5151                          ErrorSet *errors,
5152                          angle::EntryPoint entryPoint,
5153                          GLenum func,
5154                          GLint ref,
5155                          GLuint mask)
5156 {
5157     if (!IsValidStencilFunc(func))
5158     {
5159         errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidStencil);
5160         return false;
5161     }
5162 
5163     return true;
5164 }
5165 
ValidateStencilFuncSeparate(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLenum face,GLenum func,GLint ref,GLuint mask)5166 bool ValidateStencilFuncSeparate(const PrivateState &state,
5167                                  ErrorSet *errors,
5168                                  angle::EntryPoint entryPoint,
5169                                  GLenum face,
5170                                  GLenum func,
5171                                  GLint ref,
5172                                  GLuint mask)
5173 {
5174     if (!IsValidStencilFace(face))
5175     {
5176         errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidStencil);
5177         return false;
5178     }
5179 
5180     if (!IsValidStencilFunc(func))
5181     {
5182         errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidStencil);
5183         return false;
5184     }
5185 
5186     return true;
5187 }
5188 
ValidateStencilMask(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLuint mask)5189 bool ValidateStencilMask(const PrivateState &state,
5190                          ErrorSet *errors,
5191                          angle::EntryPoint entryPoint,
5192                          GLuint mask)
5193 {
5194     return true;
5195 }
5196 
ValidateStencilMaskSeparate(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLenum face,GLuint mask)5197 bool ValidateStencilMaskSeparate(const PrivateState &state,
5198                                  ErrorSet *errors,
5199                                  angle::EntryPoint entryPoint,
5200                                  GLenum face,
5201                                  GLuint mask)
5202 {
5203     if (!IsValidStencilFace(face))
5204     {
5205         errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidStencil);
5206         return false;
5207     }
5208 
5209     return true;
5210 }
5211 
ValidateStencilOp(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLenum fail,GLenum zfail,GLenum zpass)5212 bool ValidateStencilOp(const PrivateState &state,
5213                        ErrorSet *errors,
5214                        angle::EntryPoint entryPoint,
5215                        GLenum fail,
5216                        GLenum zfail,
5217                        GLenum zpass)
5218 {
5219     if (!IsValidStencilOp(fail))
5220     {
5221         errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidStencil);
5222         return false;
5223     }
5224 
5225     if (!IsValidStencilOp(zfail))
5226     {
5227         errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidStencil);
5228         return false;
5229     }
5230 
5231     if (!IsValidStencilOp(zpass))
5232     {
5233         errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidStencil);
5234         return false;
5235     }
5236 
5237     return true;
5238 }
5239 
ValidateStencilOpSeparate(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLenum face,GLenum fail,GLenum zfail,GLenum zpass)5240 bool ValidateStencilOpSeparate(const PrivateState &state,
5241                                ErrorSet *errors,
5242                                angle::EntryPoint entryPoint,
5243                                GLenum face,
5244                                GLenum fail,
5245                                GLenum zfail,
5246                                GLenum zpass)
5247 {
5248     if (!IsValidStencilFace(face))
5249     {
5250         errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidStencil);
5251         return false;
5252     }
5253 
5254     return ValidateStencilOp(state, errors, entryPoint, fail, zfail, zpass);
5255 }
5256 
ValidateUniform1f(const Context * context,angle::EntryPoint entryPoint,UniformLocation location,GLfloat x)5257 bool ValidateUniform1f(const Context *context,
5258                        angle::EntryPoint entryPoint,
5259                        UniformLocation location,
5260                        GLfloat x)
5261 {
5262     return ValidateUniform(context, entryPoint, GL_FLOAT, location, 1);
5263 }
5264 
ValidateUniform1fv(const Context * context,angle::EntryPoint entryPoint,UniformLocation location,GLsizei count,const GLfloat * v)5265 bool ValidateUniform1fv(const Context *context,
5266                         angle::EntryPoint entryPoint,
5267                         UniformLocation location,
5268                         GLsizei count,
5269                         const GLfloat *v)
5270 {
5271     return ValidateUniform(context, entryPoint, GL_FLOAT, location, count);
5272 }
5273 
ValidateUniform1i(const Context * context,angle::EntryPoint entryPoint,UniformLocation location,GLint x)5274 bool ValidateUniform1i(const Context *context,
5275                        angle::EntryPoint entryPoint,
5276                        UniformLocation location,
5277                        GLint x)
5278 {
5279     return ValidateUniform1iv(context, entryPoint, location, 1, &x);
5280 }
5281 
ValidateUniform2fv(const Context * context,angle::EntryPoint entryPoint,UniformLocation location,GLsizei count,const GLfloat * v)5282 bool ValidateUniform2fv(const Context *context,
5283                         angle::EntryPoint entryPoint,
5284                         UniformLocation location,
5285                         GLsizei count,
5286                         const GLfloat *v)
5287 {
5288     return ValidateUniform(context, entryPoint, GL_FLOAT_VEC2, location, count);
5289 }
5290 
ValidateUniform2i(const Context * context,angle::EntryPoint entryPoint,UniformLocation location,GLint x,GLint y)5291 bool ValidateUniform2i(const Context *context,
5292                        angle::EntryPoint entryPoint,
5293                        UniformLocation location,
5294                        GLint x,
5295                        GLint y)
5296 {
5297     return ValidateUniform(context, entryPoint, GL_INT_VEC2, location, 1);
5298 }
5299 
ValidateUniform2iv(const Context * context,angle::EntryPoint entryPoint,UniformLocation location,GLsizei count,const GLint * v)5300 bool ValidateUniform2iv(const Context *context,
5301                         angle::EntryPoint entryPoint,
5302                         UniformLocation location,
5303                         GLsizei count,
5304                         const GLint *v)
5305 {
5306     return ValidateUniform(context, entryPoint, GL_INT_VEC2, location, count);
5307 }
5308 
ValidateUniform3f(const Context * context,angle::EntryPoint entryPoint,UniformLocation location,GLfloat x,GLfloat y,GLfloat z)5309 bool ValidateUniform3f(const Context *context,
5310                        angle::EntryPoint entryPoint,
5311                        UniformLocation location,
5312                        GLfloat x,
5313                        GLfloat y,
5314                        GLfloat z)
5315 {
5316     return ValidateUniform(context, entryPoint, GL_FLOAT_VEC3, location, 1);
5317 }
5318 
ValidateUniform3fv(const Context * context,angle::EntryPoint entryPoint,UniformLocation location,GLsizei count,const GLfloat * v)5319 bool ValidateUniform3fv(const Context *context,
5320                         angle::EntryPoint entryPoint,
5321                         UniformLocation location,
5322                         GLsizei count,
5323                         const GLfloat *v)
5324 {
5325     return ValidateUniform(context, entryPoint, GL_FLOAT_VEC3, location, count);
5326 }
5327 
ValidateUniform3i(const Context * context,angle::EntryPoint entryPoint,UniformLocation location,GLint x,GLint y,GLint z)5328 bool ValidateUniform3i(const Context *context,
5329                        angle::EntryPoint entryPoint,
5330                        UniformLocation location,
5331                        GLint x,
5332                        GLint y,
5333                        GLint z)
5334 {
5335     return ValidateUniform(context, entryPoint, GL_INT_VEC3, location, 1);
5336 }
5337 
ValidateUniform3iv(const Context * context,angle::EntryPoint entryPoint,UniformLocation location,GLsizei count,const GLint * v)5338 bool ValidateUniform3iv(const Context *context,
5339                         angle::EntryPoint entryPoint,
5340                         UniformLocation location,
5341                         GLsizei count,
5342                         const GLint *v)
5343 {
5344     return ValidateUniform(context, entryPoint, GL_INT_VEC3, location, count);
5345 }
5346 
ValidateUniform4f(const Context * context,angle::EntryPoint entryPoint,UniformLocation location,GLfloat x,GLfloat y,GLfloat z,GLfloat w)5347 bool ValidateUniform4f(const Context *context,
5348                        angle::EntryPoint entryPoint,
5349                        UniformLocation location,
5350                        GLfloat x,
5351                        GLfloat y,
5352                        GLfloat z,
5353                        GLfloat w)
5354 {
5355     return ValidateUniform(context, entryPoint, GL_FLOAT_VEC4, location, 1);
5356 }
5357 
ValidateUniform4fv(const Context * context,angle::EntryPoint entryPoint,UniformLocation location,GLsizei count,const GLfloat * v)5358 bool ValidateUniform4fv(const Context *context,
5359                         angle::EntryPoint entryPoint,
5360                         UniformLocation location,
5361                         GLsizei count,
5362                         const GLfloat *v)
5363 {
5364     return ValidateUniform(context, entryPoint, GL_FLOAT_VEC4, location, count);
5365 }
5366 
ValidateUniform4i(const Context * context,angle::EntryPoint entryPoint,UniformLocation location,GLint x,GLint y,GLint z,GLint w)5367 bool ValidateUniform4i(const Context *context,
5368                        angle::EntryPoint entryPoint,
5369                        UniformLocation location,
5370                        GLint x,
5371                        GLint y,
5372                        GLint z,
5373                        GLint w)
5374 {
5375     return ValidateUniform(context, entryPoint, GL_INT_VEC4, location, 1);
5376 }
5377 
ValidateUniform4iv(const Context * context,angle::EntryPoint entryPoint,UniformLocation location,GLsizei count,const GLint * v)5378 bool ValidateUniform4iv(const Context *context,
5379                         angle::EntryPoint entryPoint,
5380                         UniformLocation location,
5381                         GLsizei count,
5382                         const GLint *v)
5383 {
5384     return ValidateUniform(context, entryPoint, GL_INT_VEC4, location, count);
5385 }
5386 
ValidateUniformMatrix2fv(const Context * context,angle::EntryPoint entryPoint,UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)5387 bool ValidateUniformMatrix2fv(const Context *context,
5388                               angle::EntryPoint entryPoint,
5389                               UniformLocation location,
5390                               GLsizei count,
5391                               GLboolean transpose,
5392                               const GLfloat *value)
5393 {
5394     return ValidateUniformMatrix(context, entryPoint, GL_FLOAT_MAT2, location, count, transpose);
5395 }
5396 
ValidateUniformMatrix3fv(const Context * context,angle::EntryPoint entryPoint,UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)5397 bool ValidateUniformMatrix3fv(const Context *context,
5398                               angle::EntryPoint entryPoint,
5399                               UniformLocation location,
5400                               GLsizei count,
5401                               GLboolean transpose,
5402                               const GLfloat *value)
5403 {
5404     return ValidateUniformMatrix(context, entryPoint, GL_FLOAT_MAT3, location, count, transpose);
5405 }
5406 
ValidateUniformMatrix4fv(const Context * context,angle::EntryPoint entryPoint,UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)5407 bool ValidateUniformMatrix4fv(const Context *context,
5408                               angle::EntryPoint entryPoint,
5409                               UniformLocation location,
5410                               GLsizei count,
5411                               GLboolean transpose,
5412                               const GLfloat *value)
5413 {
5414     return ValidateUniformMatrix(context, entryPoint, GL_FLOAT_MAT4, location, count, transpose);
5415 }
5416 
ValidateValidateProgram(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program)5417 bool ValidateValidateProgram(const Context *context,
5418                              angle::EntryPoint entryPoint,
5419                              ShaderProgramID program)
5420 {
5421     Program *programObject = GetValidProgram(context, entryPoint, program);
5422 
5423     if (!programObject)
5424     {
5425         return false;
5426     }
5427 
5428     return true;
5429 }
5430 
ValidateVertexAttrib1f(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLuint index,GLfloat x)5431 bool ValidateVertexAttrib1f(const PrivateState &state,
5432                             ErrorSet *errors,
5433                             angle::EntryPoint entryPoint,
5434                             GLuint index,
5435                             GLfloat x)
5436 {
5437     return ValidateVertexAttribIndex(state, errors, entryPoint, index);
5438 }
5439 
ValidateVertexAttrib1fv(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLuint index,const GLfloat * values)5440 bool ValidateVertexAttrib1fv(const PrivateState &state,
5441                              ErrorSet *errors,
5442                              angle::EntryPoint entryPoint,
5443                              GLuint index,
5444                              const GLfloat *values)
5445 {
5446     return ValidateVertexAttribIndex(state, errors, entryPoint, index);
5447 }
5448 
ValidateVertexAttrib2f(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLuint index,GLfloat x,GLfloat y)5449 bool ValidateVertexAttrib2f(const PrivateState &state,
5450                             ErrorSet *errors,
5451                             angle::EntryPoint entryPoint,
5452                             GLuint index,
5453                             GLfloat x,
5454                             GLfloat y)
5455 {
5456     return ValidateVertexAttribIndex(state, errors, entryPoint, index);
5457 }
5458 
ValidateVertexAttrib2fv(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLuint index,const GLfloat * values)5459 bool ValidateVertexAttrib2fv(const PrivateState &state,
5460                              ErrorSet *errors,
5461                              angle::EntryPoint entryPoint,
5462                              GLuint index,
5463                              const GLfloat *values)
5464 {
5465     return ValidateVertexAttribIndex(state, errors, entryPoint, index);
5466 }
5467 
ValidateVertexAttrib3f(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLuint index,GLfloat x,GLfloat y,GLfloat z)5468 bool ValidateVertexAttrib3f(const PrivateState &state,
5469                             ErrorSet *errors,
5470                             angle::EntryPoint entryPoint,
5471                             GLuint index,
5472                             GLfloat x,
5473                             GLfloat y,
5474                             GLfloat z)
5475 {
5476     return ValidateVertexAttribIndex(state, errors, entryPoint, index);
5477 }
5478 
ValidateVertexAttrib3fv(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLuint index,const GLfloat * values)5479 bool ValidateVertexAttrib3fv(const PrivateState &state,
5480                              ErrorSet *errors,
5481                              angle::EntryPoint entryPoint,
5482                              GLuint index,
5483                              const GLfloat *values)
5484 {
5485     return ValidateVertexAttribIndex(state, errors, entryPoint, index);
5486 }
5487 
ValidateVertexAttrib4f(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLuint index,GLfloat x,GLfloat y,GLfloat z,GLfloat w)5488 bool ValidateVertexAttrib4f(const PrivateState &state,
5489                             ErrorSet *errors,
5490                             angle::EntryPoint entryPoint,
5491                             GLuint index,
5492                             GLfloat x,
5493                             GLfloat y,
5494                             GLfloat z,
5495                             GLfloat w)
5496 {
5497     return ValidateVertexAttribIndex(state, errors, entryPoint, index);
5498 }
5499 
ValidateVertexAttrib4fv(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLuint index,const GLfloat * values)5500 bool ValidateVertexAttrib4fv(const PrivateState &state,
5501                              ErrorSet *errors,
5502                              angle::EntryPoint entryPoint,
5503                              GLuint index,
5504                              const GLfloat *values)
5505 {
5506     return ValidateVertexAttribIndex(state, errors, entryPoint, index);
5507 }
5508 
ValidateViewport(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLint x,GLint y,GLsizei width,GLsizei height)5509 bool ValidateViewport(const PrivateState &state,
5510                       ErrorSet *errors,
5511                       angle::EntryPoint entryPoint,
5512                       GLint x,
5513                       GLint y,
5514                       GLsizei width,
5515                       GLsizei height)
5516 {
5517     if (width < 0 || height < 0)
5518     {
5519         errors->validationError(entryPoint, GL_INVALID_VALUE, kViewportNegativeSize);
5520         return false;
5521     }
5522 
5523     return true;
5524 }
5525 
ValidateGetFramebufferAttachmentParameteriv(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLenum attachment,GLenum pname,const GLint * params)5526 bool ValidateGetFramebufferAttachmentParameteriv(const Context *context,
5527                                                  angle::EntryPoint entryPoint,
5528                                                  GLenum target,
5529                                                  GLenum attachment,
5530                                                  GLenum pname,
5531                                                  const GLint *params)
5532 {
5533     return ValidateGetFramebufferAttachmentParameterivBase(context, entryPoint, target, attachment,
5534                                                            pname, nullptr);
5535 }
5536 
ValidateGetProgramiv(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,GLenum pname,const GLint * params)5537 bool ValidateGetProgramiv(const Context *context,
5538                           angle::EntryPoint entryPoint,
5539                           ShaderProgramID program,
5540                           GLenum pname,
5541                           const GLint *params)
5542 {
5543     return ValidateGetProgramivBase(context, entryPoint, program, pname, nullptr);
5544 }
5545 
ValidateCopyTexImage2D(const Context * context,angle::EntryPoint entryPoint,TextureTarget target,GLint level,GLenum internalformat,GLint x,GLint y,GLsizei width,GLsizei height,GLint border)5546 bool ValidateCopyTexImage2D(const Context *context,
5547                             angle::EntryPoint entryPoint,
5548                             TextureTarget target,
5549                             GLint level,
5550                             GLenum internalformat,
5551                             GLint x,
5552                             GLint y,
5553                             GLsizei width,
5554                             GLsizei height,
5555                             GLint border)
5556 {
5557     if (context->getClientMajorVersion() < 3)
5558     {
5559         return ValidateES2CopyTexImageParameters(context, entryPoint, target, level, internalformat,
5560                                                  false, 0, 0, x, y, width, height, border);
5561     }
5562 
5563     ASSERT(context->getClientMajorVersion() == 3);
5564     return ValidateES3CopyTexImage2DParameters(context, entryPoint, target, level, internalformat,
5565                                                false, 0, 0, 0, x, y, width, height, border);
5566 }
5567 
ValidateCopyTexSubImage2D(const Context * context,angle::EntryPoint entryPoint,TextureTarget target,GLint level,GLint xoffset,GLint yoffset,GLint x,GLint y,GLsizei width,GLsizei height)5568 bool ValidateCopyTexSubImage2D(const Context *context,
5569                                angle::EntryPoint entryPoint,
5570                                TextureTarget target,
5571                                GLint level,
5572                                GLint xoffset,
5573                                GLint yoffset,
5574                                GLint x,
5575                                GLint y,
5576                                GLsizei width,
5577                                GLsizei height)
5578 {
5579     if (context->getClientMajorVersion() < 3)
5580     {
5581         return ValidateES2CopyTexImageParameters(context, entryPoint, target, level, GL_NONE, true,
5582                                                  xoffset, yoffset, x, y, width, height, 0);
5583     }
5584 
5585     return ValidateES3CopyTexImage2DParameters(context, entryPoint, target, level, GL_NONE, true,
5586                                                xoffset, yoffset, 0, x, y, width, height, 0);
5587 }
5588 
ValidateCopyTexSubImage3DOES(const Context * context,angle::EntryPoint entryPoint,TextureTarget target,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLint x,GLint y,GLsizei width,GLsizei height)5589 bool ValidateCopyTexSubImage3DOES(const Context *context,
5590                                   angle::EntryPoint entryPoint,
5591                                   TextureTarget target,
5592                                   GLint level,
5593                                   GLint xoffset,
5594                                   GLint yoffset,
5595                                   GLint zoffset,
5596                                   GLint x,
5597                                   GLint y,
5598                                   GLsizei width,
5599                                   GLsizei height)
5600 {
5601     return ValidateCopyTexSubImage3D(context, entryPoint, target, level, xoffset, yoffset, zoffset,
5602                                      x, y, width, height);
5603 }
5604 
ValidateDeleteBuffers(const Context * context,angle::EntryPoint entryPoint,GLint n,const BufferID * buffers)5605 bool ValidateDeleteBuffers(const Context *context,
5606                            angle::EntryPoint entryPoint,
5607                            GLint n,
5608                            const BufferID *buffers)
5609 {
5610     return ValidateGenOrDelete(context, entryPoint, n);
5611 }
5612 
ValidateDeleteFramebuffers(const Context * context,angle::EntryPoint entryPoint,GLint n,const FramebufferID * framebuffers)5613 bool ValidateDeleteFramebuffers(const Context *context,
5614                                 angle::EntryPoint entryPoint,
5615                                 GLint n,
5616                                 const FramebufferID *framebuffers)
5617 {
5618     return ValidateGenOrDelete(context, entryPoint, n);
5619 }
5620 
ValidateDeleteRenderbuffers(const Context * context,angle::EntryPoint entryPoint,GLint n,const RenderbufferID * renderbuffers)5621 bool ValidateDeleteRenderbuffers(const Context *context,
5622                                  angle::EntryPoint entryPoint,
5623                                  GLint n,
5624                                  const RenderbufferID *renderbuffers)
5625 {
5626     return ValidateGenOrDelete(context, entryPoint, n);
5627 }
5628 
ValidateDeleteTextures(const Context * context,angle::EntryPoint entryPoint,GLint n,const TextureID * textures)5629 bool ValidateDeleteTextures(const Context *context,
5630                             angle::EntryPoint entryPoint,
5631                             GLint n,
5632                             const TextureID *textures)
5633 {
5634     return ValidateGenOrDelete(context, entryPoint, n);
5635 }
5636 
ValidateDisable(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLenum cap)5637 bool ValidateDisable(const PrivateState &state,
5638                      ErrorSet *errors,
5639                      angle::EntryPoint entryPoint,
5640                      GLenum cap)
5641 {
5642     if (!ValidCap(state, errors, cap, false))
5643     {
5644         errors->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, cap);
5645         return false;
5646     }
5647 
5648     if (state.getPixelLocalStorageActivePlanes() != 0)
5649     {
5650         if (IsCapBannedWithActivePLS(cap))
5651         {
5652             errors->validationErrorF(entryPoint, GL_INVALID_OPERATION, kPLSCapNotAllowed, cap);
5653             return false;
5654         }
5655     }
5656 
5657     return true;
5658 }
5659 
ValidateEnable(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLenum cap)5660 bool ValidateEnable(const PrivateState &state,
5661                     ErrorSet *errors,
5662                     angle::EntryPoint entryPoint,
5663                     GLenum cap)
5664 {
5665     if (!ValidCap(state, errors, cap, false))
5666     {
5667         errors->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, cap);
5668         return false;
5669     }
5670 
5671     if (state.getLimitations().noSampleAlphaToCoverageSupport && cap == GL_SAMPLE_ALPHA_TO_COVERAGE)
5672     {
5673         errors->validationError(entryPoint, GL_INVALID_OPERATION,
5674                                 kNoSampleAlphaToCoveragesLimitation);
5675 
5676         // We also output an error message to the debugger window if tracing is active, so that
5677         // developers can see the error message.
5678         ERR() << kNoSampleAlphaToCoveragesLimitation;
5679         return false;
5680     }
5681 
5682     if (state.getPixelLocalStorageActivePlanes() != 0)
5683     {
5684         if (IsCapBannedWithActivePLS(cap))
5685         {
5686             errors->validationErrorF(entryPoint, GL_INVALID_OPERATION, kPLSCapNotAllowed, cap);
5687             return false;
5688         }
5689     }
5690 
5691     return true;
5692 }
5693 
ValidateFramebufferRenderbuffer(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLenum attachment,GLenum renderbuffertarget,RenderbufferID renderbuffer)5694 bool ValidateFramebufferRenderbuffer(const Context *context,
5695                                      angle::EntryPoint entryPoint,
5696                                      GLenum target,
5697                                      GLenum attachment,
5698                                      GLenum renderbuffertarget,
5699                                      RenderbufferID renderbuffer)
5700 {
5701     return ValidateFramebufferRenderbufferBase(context, entryPoint, target, attachment,
5702                                                renderbuffertarget, renderbuffer);
5703 }
5704 
ValidateFramebufferTexture2D(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLenum attachment,TextureTarget textarget,TextureID texture,GLint level)5705 bool ValidateFramebufferTexture2D(const Context *context,
5706                                   angle::EntryPoint entryPoint,
5707                                   GLenum target,
5708                                   GLenum attachment,
5709                                   TextureTarget textarget,
5710                                   TextureID texture,
5711                                   GLint level)
5712 {
5713     // Attachments are required to be bound to level 0 without ES3 or the GL_OES_fbo_render_mipmap
5714     // extension
5715     if (context->getClientMajorVersion() < 3 && !context->getExtensions().fboRenderMipmapOES &&
5716         level != 0)
5717     {
5718         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidFramebufferTextureLevel);
5719         return false;
5720     }
5721 
5722     if (!ValidateFramebufferTextureBase(context, entryPoint, target, attachment, texture, level))
5723     {
5724         return false;
5725     }
5726 
5727     if (texture.value != 0)
5728     {
5729         Texture *tex = context->getTexture(texture);
5730         ASSERT(tex);
5731 
5732         const Caps &caps = context->getCaps();
5733 
5734         switch (textarget)
5735         {
5736             case TextureTarget::_2D:
5737             {
5738                 if (level > log2(caps.max2DTextureSize))
5739                 {
5740                     ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidMipLevel);
5741                     return false;
5742                 }
5743                 if (tex->getType() != TextureType::_2D)
5744                 {
5745                     ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidTextureTarget);
5746                     return false;
5747                 }
5748             }
5749             break;
5750 
5751             case TextureTarget::Rectangle:
5752             {
5753                 if (level != 0)
5754                 {
5755                     ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidMipLevel);
5756                     return false;
5757                 }
5758                 if (tex->getType() != TextureType::Rectangle)
5759                 {
5760                     ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kTextureTargetMismatch);
5761                     return false;
5762                 }
5763             }
5764             break;
5765 
5766             case TextureTarget::CubeMapNegativeX:
5767             case TextureTarget::CubeMapNegativeY:
5768             case TextureTarget::CubeMapNegativeZ:
5769             case TextureTarget::CubeMapPositiveX:
5770             case TextureTarget::CubeMapPositiveY:
5771             case TextureTarget::CubeMapPositiveZ:
5772             {
5773                 if (level > log2(caps.maxCubeMapTextureSize))
5774                 {
5775                     ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidMipLevel);
5776                     return false;
5777                 }
5778                 if (tex->getType() != TextureType::CubeMap)
5779                 {
5780                     ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kTextureTargetMismatch);
5781                     return false;
5782                 }
5783             }
5784             break;
5785 
5786             case TextureTarget::_2DMultisample:
5787             {
5788                 if (context->getClientVersion() < ES_3_1 &&
5789                     !context->getExtensions().textureMultisampleANGLE)
5790                 {
5791                     ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION,
5792                                            kMultisampleTextureExtensionOrES31Required);
5793                     return false;
5794                 }
5795 
5796                 if (level != 0)
5797                 {
5798                     ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kLevelNotZero);
5799                     return false;
5800                 }
5801                 if (tex->getType() != TextureType::_2DMultisample)
5802                 {
5803                     ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kTextureTargetMismatch);
5804                     return false;
5805                 }
5806             }
5807             break;
5808 
5809             case TextureTarget::External:
5810             {
5811                 if (!context->getExtensions().YUVTargetEXT)
5812                 {
5813                     ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kYUVTargetExtensionRequired);
5814                     return false;
5815                 }
5816 
5817                 if (attachment != GL_COLOR_ATTACHMENT0)
5818                 {
5819                     ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidAttachment);
5820                     return false;
5821                 }
5822 
5823                 if (tex->getType() != TextureType::External)
5824                 {
5825                     ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kTextureTargetMismatch);
5826                     return false;
5827                 }
5828             }
5829             break;
5830 
5831             default:
5832                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidTextureTarget);
5833                 return false;
5834         }
5835     }
5836 
5837     return true;
5838 }
5839 
ValidateFramebufferTexture3DOES(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLenum attachment,TextureTarget textargetPacked,TextureID texture,GLint level,GLint zoffset)5840 bool ValidateFramebufferTexture3DOES(const Context *context,
5841                                      angle::EntryPoint entryPoint,
5842                                      GLenum target,
5843                                      GLenum attachment,
5844                                      TextureTarget textargetPacked,
5845                                      TextureID texture,
5846                                      GLint level,
5847                                      GLint zoffset)
5848 {
5849     // We don't call into a base ValidateFramebufferTexture3D here because
5850     // it doesn't exist for OpenGL ES. This function is replaced by
5851     // FramebufferTextureLayer in ES 3.x, which has broader support.
5852     if (!context->getExtensions().texture3DOES)
5853     {
5854         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
5855         return false;
5856     }
5857 
5858     // Attachments are required to be bound to level 0 without ES3 or the
5859     // GL_OES_fbo_render_mipmap extension
5860     if (context->getClientMajorVersion() < 3 && !context->getExtensions().fboRenderMipmapOES &&
5861         level != 0)
5862     {
5863         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidFramebufferTextureLevel);
5864         return false;
5865     }
5866 
5867     if (!ValidateFramebufferTextureBase(context, entryPoint, target, attachment, texture, level))
5868     {
5869         return false;
5870     }
5871 
5872     if (texture.value != 0)
5873     {
5874         Texture *tex = context->getTexture(texture);
5875         ASSERT(tex);
5876 
5877         const Caps &caps = context->getCaps();
5878 
5879         switch (textargetPacked)
5880         {
5881             case TextureTarget::_3D:
5882             {
5883                 if (level > log2(caps.max3DTextureSize))
5884                 {
5885                     ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidMipLevel);
5886                     return false;
5887                 }
5888                 if (zoffset >= caps.max3DTextureSize)
5889                 {
5890                     ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidZOffset);
5891                     return false;
5892                 }
5893                 if (tex->getType() != TextureType::_3D)
5894                 {
5895                     ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidTextureType);
5896                     return false;
5897                 }
5898             }
5899             break;
5900 
5901             default:
5902                 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidTextureTarget);
5903                 return false;
5904         }
5905     }
5906 
5907     return true;
5908 }
5909 
ValidateGenBuffers(const Context * context,angle::EntryPoint entryPoint,GLint n,const BufferID * buffers)5910 bool ValidateGenBuffers(const Context *context,
5911                         angle::EntryPoint entryPoint,
5912                         GLint n,
5913                         const BufferID *buffers)
5914 {
5915     return ValidateGenOrDelete(context, entryPoint, n);
5916 }
5917 
ValidateGenFramebuffers(const Context * context,angle::EntryPoint entryPoint,GLint n,const FramebufferID * framebuffers)5918 bool ValidateGenFramebuffers(const Context *context,
5919                              angle::EntryPoint entryPoint,
5920                              GLint n,
5921                              const FramebufferID *framebuffers)
5922 {
5923     return ValidateGenOrDelete(context, entryPoint, n);
5924 }
5925 
ValidateGenRenderbuffers(const Context * context,angle::EntryPoint entryPoint,GLint n,const RenderbufferID * renderbuffers)5926 bool ValidateGenRenderbuffers(const Context *context,
5927                               angle::EntryPoint entryPoint,
5928                               GLint n,
5929                               const RenderbufferID *renderbuffers)
5930 {
5931     return ValidateGenOrDelete(context, entryPoint, n);
5932 }
5933 
ValidateGenTextures(const Context * context,angle::EntryPoint entryPoint,GLint n,const TextureID * textures)5934 bool ValidateGenTextures(const Context *context,
5935                          angle::EntryPoint entryPoint,
5936                          GLint n,
5937                          const TextureID *textures)
5938 {
5939     return ValidateGenOrDelete(context, entryPoint, n);
5940 }
5941 
ValidateGenerateMipmap(const Context * context,angle::EntryPoint entryPoint,TextureType target)5942 bool ValidateGenerateMipmap(const Context *context,
5943                             angle::EntryPoint entryPoint,
5944                             TextureType target)
5945 {
5946     return ValidateGenerateMipmapBase(context, entryPoint, target);
5947 }
5948 
ValidateGetBufferParameteriv(const Context * context,angle::EntryPoint entryPoint,BufferBinding target,GLenum pname,const GLint * params)5949 bool ValidateGetBufferParameteriv(const Context *context,
5950                                   angle::EntryPoint entryPoint,
5951                                   BufferBinding target,
5952                                   GLenum pname,
5953                                   const GLint *params)
5954 {
5955     return ValidateGetBufferParameterBase(context, entryPoint, target, pname, false, nullptr);
5956 }
5957 
ValidateGetRenderbufferParameteriv(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLenum pname,const GLint * params)5958 bool ValidateGetRenderbufferParameteriv(const Context *context,
5959                                         angle::EntryPoint entryPoint,
5960                                         GLenum target,
5961                                         GLenum pname,
5962                                         const GLint *params)
5963 {
5964     return ValidateGetRenderbufferParameterivBase(context, entryPoint, target, pname, nullptr);
5965 }
5966 
ValidateGetShaderiv(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID shader,GLenum pname,const GLint * params)5967 bool ValidateGetShaderiv(const Context *context,
5968                          angle::EntryPoint entryPoint,
5969                          ShaderProgramID shader,
5970                          GLenum pname,
5971                          const GLint *params)
5972 {
5973     return ValidateGetShaderivBase(context, entryPoint, shader, pname, nullptr);
5974 }
5975 
ValidateGetTexParameterfv(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLenum pname,const GLfloat * params)5976 bool ValidateGetTexParameterfv(const Context *context,
5977                                angle::EntryPoint entryPoint,
5978                                TextureType target,
5979                                GLenum pname,
5980                                const GLfloat *params)
5981 {
5982     return ValidateGetTexParameterBase(context, entryPoint, target, pname, nullptr);
5983 }
5984 
ValidateGetTexParameteriv(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLenum pname,const GLint * params)5985 bool ValidateGetTexParameteriv(const Context *context,
5986                                angle::EntryPoint entryPoint,
5987                                TextureType target,
5988                                GLenum pname,
5989                                const GLint *params)
5990 {
5991     return ValidateGetTexParameterBase(context, entryPoint, target, pname, nullptr);
5992 }
5993 
ValidateGetUniformfv(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,UniformLocation location,const GLfloat * params)5994 bool ValidateGetUniformfv(const Context *context,
5995                           angle::EntryPoint entryPoint,
5996                           ShaderProgramID program,
5997                           UniformLocation location,
5998                           const GLfloat *params)
5999 {
6000     return ValidateGetUniformBase(context, entryPoint, program, location);
6001 }
6002 
ValidateGetUniformiv(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,UniformLocation location,const GLint * params)6003 bool ValidateGetUniformiv(const Context *context,
6004                           angle::EntryPoint entryPoint,
6005                           ShaderProgramID program,
6006                           UniformLocation location,
6007                           const GLint *params)
6008 {
6009     return ValidateGetUniformBase(context, entryPoint, program, location);
6010 }
6011 
ValidateGetVertexAttribfv(const Context * context,angle::EntryPoint entryPoint,GLuint index,GLenum pname,const GLfloat * params)6012 bool ValidateGetVertexAttribfv(const Context *context,
6013                                angle::EntryPoint entryPoint,
6014                                GLuint index,
6015                                GLenum pname,
6016                                const GLfloat *params)
6017 {
6018     return ValidateGetVertexAttribBase(context, entryPoint, index, pname, nullptr, false, false);
6019 }
6020 
ValidateGetVertexAttribiv(const Context * context,angle::EntryPoint entryPoint,GLuint index,GLenum pname,const GLint * params)6021 bool ValidateGetVertexAttribiv(const Context *context,
6022                                angle::EntryPoint entryPoint,
6023                                GLuint index,
6024                                GLenum pname,
6025                                const GLint *params)
6026 {
6027     return ValidateGetVertexAttribBase(context, entryPoint, index, pname, nullptr, false, false);
6028 }
6029 
ValidateGetVertexAttribPointerv(const Context * context,angle::EntryPoint entryPoint,GLuint index,GLenum pname,void * const * pointer)6030 bool ValidateGetVertexAttribPointerv(const Context *context,
6031                                      angle::EntryPoint entryPoint,
6032                                      GLuint index,
6033                                      GLenum pname,
6034                                      void *const *pointer)
6035 {
6036     return ValidateGetVertexAttribBase(context, entryPoint, index, pname, nullptr, true, false);
6037 }
6038 
ValidateIsEnabled(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLenum cap)6039 bool ValidateIsEnabled(const PrivateState &state,
6040                        ErrorSet *errors,
6041                        angle::EntryPoint entryPoint,
6042                        GLenum cap)
6043 {
6044     if (!ValidCap(state, errors, cap, true))
6045     {
6046         errors->validationErrorF(entryPoint, GL_INVALID_ENUM, kEnumNotSupported, cap);
6047         return false;
6048     }
6049 
6050     return true;
6051 }
6052 
ValidateLinkProgram(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program)6053 bool ValidateLinkProgram(const Context *context,
6054                          angle::EntryPoint entryPoint,
6055                          ShaderProgramID program)
6056 {
6057     if (context->hasActiveTransformFeedback(program))
6058     {
6059         // ES 3.0.4 section 2.15 page 91
6060         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kTransformFeedbackActiveDuringLink);
6061         return false;
6062     }
6063 
6064     Program *programObject = GetValidProgram(context, entryPoint, program);
6065     if (!programObject)
6066     {
6067         return false;
6068     }
6069 
6070     return true;
6071 }
6072 
ValidateReadPixels(const Context * context,angle::EntryPoint entryPoint,GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,const void * pixels)6073 bool ValidateReadPixels(const Context *context,
6074                         angle::EntryPoint entryPoint,
6075                         GLint x,
6076                         GLint y,
6077                         GLsizei width,
6078                         GLsizei height,
6079                         GLenum format,
6080                         GLenum type,
6081                         const void *pixels)
6082 {
6083     return ValidateReadPixelsBase(context, entryPoint, x, y, width, height, format, type, -1,
6084                                   nullptr, nullptr, nullptr, pixels);
6085 }
6086 
ValidateTexParameterf(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLenum pname,GLfloat param)6087 bool ValidateTexParameterf(const Context *context,
6088                            angle::EntryPoint entryPoint,
6089                            TextureType target,
6090                            GLenum pname,
6091                            GLfloat param)
6092 {
6093     return ValidateTexParameterBase(context, entryPoint, target, pname, -1, false, &param);
6094 }
6095 
ValidateTexParameterfv(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLenum pname,const GLfloat * params)6096 bool ValidateTexParameterfv(const Context *context,
6097                             angle::EntryPoint entryPoint,
6098                             TextureType target,
6099                             GLenum pname,
6100                             const GLfloat *params)
6101 {
6102     return ValidateTexParameterBase(context, entryPoint, target, pname, -1, true, params);
6103 }
6104 
ValidateTexParameteri(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLenum pname,GLint param)6105 bool ValidateTexParameteri(const Context *context,
6106                            angle::EntryPoint entryPoint,
6107                            TextureType target,
6108                            GLenum pname,
6109                            GLint param)
6110 {
6111     return ValidateTexParameterBase(context, entryPoint, target, pname, -1, false, &param);
6112 }
6113 
ValidateTexParameteriv(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLenum pname,const GLint * params)6114 bool ValidateTexParameteriv(const Context *context,
6115                             angle::EntryPoint entryPoint,
6116                             TextureType target,
6117                             GLenum pname,
6118                             const GLint *params)
6119 {
6120     return ValidateTexParameterBase(context, entryPoint, target, pname, -1, true, params);
6121 }
6122 
ValidateUseProgram(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program)6123 bool ValidateUseProgram(const Context *context,
6124                         angle::EntryPoint entryPoint,
6125                         ShaderProgramID program)
6126 {
6127     if (program.value != 0)
6128     {
6129         Program *programObject = context->getProgramResolveLink(program);
6130         if (!programObject)
6131         {
6132             // ES 3.1.0 section 7.3 page 72
6133             if (context->getShaderNoResolveCompile(program))
6134             {
6135                 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExpectedProgramName);
6136                 return false;
6137             }
6138             else
6139             {
6140                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidProgramName);
6141                 return false;
6142             }
6143         }
6144         if (!programObject->isLinked())
6145         {
6146             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kProgramNotLinked);
6147             return false;
6148         }
6149     }
6150     if (context->getState().isTransformFeedbackActiveUnpaused())
6151     {
6152         // ES 3.0.4 section 2.15 page 91
6153         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kTransformFeedbackUseProgram);
6154         return false;
6155     }
6156 
6157     return true;
6158 }
6159 
ValidateDeleteFencesNV(const Context * context,angle::EntryPoint entryPoint,GLsizei n,const FenceNVID * fences)6160 bool ValidateDeleteFencesNV(const Context *context,
6161                             angle::EntryPoint entryPoint,
6162                             GLsizei n,
6163                             const FenceNVID *fences)
6164 {
6165     if (!context->getExtensions().fenceNV)
6166     {
6167         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kNVFenceNotSupported);
6168         return false;
6169     }
6170 
6171     if (n < 0)
6172     {
6173         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeCount);
6174         return false;
6175     }
6176 
6177     return true;
6178 }
6179 
ValidateFinishFenceNV(const Context * context,angle::EntryPoint entryPoint,FenceNVID fence)6180 bool ValidateFinishFenceNV(const Context *context, angle::EntryPoint entryPoint, FenceNVID fence)
6181 {
6182     if (!context->getExtensions().fenceNV)
6183     {
6184         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kNVFenceNotSupported);
6185         return false;
6186     }
6187 
6188     FenceNV *fenceObject = context->getFenceNV(fence);
6189 
6190     if (fenceObject == nullptr)
6191     {
6192         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidFence);
6193         return false;
6194     }
6195 
6196     if (!fenceObject->isSet())
6197     {
6198         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidFenceState);
6199         return false;
6200     }
6201 
6202     return true;
6203 }
6204 
ValidateGenFencesNV(const Context * context,angle::EntryPoint entryPoint,GLsizei n,const FenceNVID * fences)6205 bool ValidateGenFencesNV(const Context *context,
6206                          angle::EntryPoint entryPoint,
6207                          GLsizei n,
6208                          const FenceNVID *fences)
6209 {
6210     if (!context->getExtensions().fenceNV)
6211     {
6212         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kNVFenceNotSupported);
6213         return false;
6214     }
6215 
6216     if (n < 0)
6217     {
6218         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeCount);
6219         return false;
6220     }
6221 
6222     return true;
6223 }
6224 
ValidateGetFenceivNV(const Context * context,angle::EntryPoint entryPoint,FenceNVID fence,GLenum pname,const GLint * params)6225 bool ValidateGetFenceivNV(const Context *context,
6226                           angle::EntryPoint entryPoint,
6227                           FenceNVID fence,
6228                           GLenum pname,
6229                           const GLint *params)
6230 {
6231     if (!context->getExtensions().fenceNV)
6232     {
6233         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kNVFenceNotSupported);
6234         return false;
6235     }
6236 
6237     FenceNV *fenceObject = context->getFenceNV(fence);
6238 
6239     if (fenceObject == nullptr)
6240     {
6241         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidFence);
6242         return false;
6243     }
6244 
6245     if (!fenceObject->isSet())
6246     {
6247         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidFenceState);
6248         return false;
6249     }
6250 
6251     switch (pname)
6252     {
6253         case GL_FENCE_STATUS_NV:
6254         case GL_FENCE_CONDITION_NV:
6255             break;
6256 
6257         default:
6258             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidPname);
6259             return false;
6260     }
6261 
6262     return true;
6263 }
6264 
ValidateGetGraphicsResetStatusEXT(const Context * context,angle::EntryPoint entryPoint)6265 bool ValidateGetGraphicsResetStatusEXT(const Context *context, angle::EntryPoint entryPoint)
6266 {
6267     if (!context->getExtensions().robustnessEXT)
6268     {
6269         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
6270         return false;
6271     }
6272 
6273     return true;
6274 }
6275 
ValidateGetTranslatedShaderSourceANGLE(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID shader,GLsizei bufsize,const GLsizei * length,const GLchar * source)6276 bool ValidateGetTranslatedShaderSourceANGLE(const Context *context,
6277                                             angle::EntryPoint entryPoint,
6278                                             ShaderProgramID shader,
6279                                             GLsizei bufsize,
6280                                             const GLsizei *length,
6281                                             const GLchar *source)
6282 {
6283     if (!context->getExtensions().translatedShaderSourceANGLE)
6284     {
6285         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
6286         return false;
6287     }
6288 
6289     if (bufsize < 0)
6290     {
6291         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeBufferSize);
6292         return false;
6293     }
6294 
6295     Shader *shaderObject = context->getShaderNoResolveCompile(shader);
6296 
6297     if (!shaderObject)
6298     {
6299         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidShaderName);
6300         return false;
6301     }
6302 
6303     return true;
6304 }
6305 
ValidateIsFenceNV(const Context * context,angle::EntryPoint entryPoint,FenceNVID fence)6306 bool ValidateIsFenceNV(const Context *context, angle::EntryPoint entryPoint, FenceNVID fence)
6307 {
6308     if (!context->getExtensions().fenceNV)
6309     {
6310         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kNVFenceNotSupported);
6311         return false;
6312     }
6313 
6314     return true;
6315 }
6316 
ValidateSetFenceNV(const Context * context,angle::EntryPoint entryPoint,FenceNVID fence,GLenum condition)6317 bool ValidateSetFenceNV(const Context *context,
6318                         angle::EntryPoint entryPoint,
6319                         FenceNVID fence,
6320                         GLenum condition)
6321 {
6322     if (!context->getExtensions().fenceNV)
6323     {
6324         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kNVFenceNotSupported);
6325         return false;
6326     }
6327 
6328     if (condition != GL_ALL_COMPLETED_NV)
6329     {
6330         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidFenceCondition);
6331         return false;
6332     }
6333 
6334     FenceNV *fenceObject = context->getFenceNV(fence);
6335 
6336     if (fenceObject == nullptr)
6337     {
6338         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidFence);
6339         return false;
6340     }
6341 
6342     return true;
6343 }
6344 
ValidateTestFenceNV(const Context * context,angle::EntryPoint entryPoint,FenceNVID fence)6345 bool ValidateTestFenceNV(const Context *context, angle::EntryPoint entryPoint, FenceNVID fence)
6346 {
6347     if (!context->getExtensions().fenceNV)
6348     {
6349         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kNVFenceNotSupported);
6350         return false;
6351     }
6352 
6353     FenceNV *fenceObject = context->getFenceNV(fence);
6354 
6355     if (fenceObject == nullptr)
6356     {
6357         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidFence);
6358         return false;
6359     }
6360 
6361     if (fenceObject->isSet() != GL_TRUE)
6362     {
6363         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidFenceState);
6364         return false;
6365     }
6366 
6367     return true;
6368 }
6369 
ValidateTexStorage2DEXT(const Context * context,angle::EntryPoint entryPoint,TextureType type,GLsizei levels,GLenum internalformat,GLsizei width,GLsizei height)6370 bool ValidateTexStorage2DEXT(const Context *context,
6371                              angle::EntryPoint entryPoint,
6372                              TextureType type,
6373                              GLsizei levels,
6374                              GLenum internalformat,
6375                              GLsizei width,
6376                              GLsizei height)
6377 {
6378     if (!context->getExtensions().textureStorageEXT)
6379     {
6380         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
6381         return false;
6382     }
6383 
6384     if (context->getClientMajorVersion() < 3)
6385     {
6386         return ValidateES2TexStorageParametersBase(context, entryPoint, type, levels,
6387                                                    internalformat, width, height);
6388     }
6389 
6390     ASSERT(context->getClientMajorVersion() >= 3);
6391     return ValidateES3TexStorage2DParameters(context, entryPoint, type, levels, internalformat,
6392                                              width, height, 1);
6393 }
6394 
ValidateVertexAttribDivisorANGLE(const Context * context,angle::EntryPoint entryPoint,GLuint index,GLuint divisor)6395 bool ValidateVertexAttribDivisorANGLE(const Context *context,
6396                                       angle::EntryPoint entryPoint,
6397                                       GLuint index,
6398                                       GLuint divisor)
6399 {
6400     if (!context->getExtensions().instancedArraysANGLE)
6401     {
6402         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
6403         return false;
6404     }
6405 
6406     if (index >= static_cast<GLuint>(context->getCaps().maxVertexAttributes))
6407     {
6408         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
6409         return false;
6410     }
6411 
6412     if (context->getLimitations().attributeZeroRequiresZeroDivisorInEXT)
6413     {
6414         if (index == 0 && divisor != 0)
6415         {
6416             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kAttributeZeroRequiresDivisorLimitation);
6417 
6418             // We also output an error message to the debugger window if tracing is active, so
6419             // that developers can see the error message.
6420             ERR() << kAttributeZeroRequiresDivisorLimitation;
6421             return false;
6422         }
6423     }
6424 
6425     return true;
6426 }
6427 
ValidateVertexAttribDivisorEXT(const Context * context,angle::EntryPoint entryPoint,GLuint index,GLuint divisor)6428 bool ValidateVertexAttribDivisorEXT(const Context *context,
6429                                     angle::EntryPoint entryPoint,
6430                                     GLuint index,
6431                                     GLuint divisor)
6432 {
6433     if (!context->getExtensions().instancedArraysEXT)
6434     {
6435         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
6436         return false;
6437     }
6438 
6439     if (index >= static_cast<GLuint>(context->getCaps().maxVertexAttributes))
6440     {
6441         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
6442         return false;
6443     }
6444 
6445     return true;
6446 }
6447 
ValidateTexImage3DOES(const Context * context,angle::EntryPoint entryPoint,TextureTarget target,GLint level,GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth,GLint border,GLenum format,GLenum type,const void * pixels)6448 bool ValidateTexImage3DOES(const Context *context,
6449                            angle::EntryPoint entryPoint,
6450                            TextureTarget target,
6451                            GLint level,
6452                            GLenum internalformat,
6453                            GLsizei width,
6454                            GLsizei height,
6455                            GLsizei depth,
6456                            GLint border,
6457                            GLenum format,
6458                            GLenum type,
6459                            const void *pixels)
6460 {
6461     return ValidateTexImage3D(context, entryPoint, target, level, internalformat, width, height,
6462                               depth, border, format, type, pixels);
6463 }
6464 
ValidatePopGroupMarkerEXT(const Context * context,angle::EntryPoint entryPoint)6465 bool ValidatePopGroupMarkerEXT(const Context *context, angle::EntryPoint entryPoint)
6466 {
6467     if (!context->getExtensions().debugMarkerEXT)
6468     {
6469         // The debug marker calls should not set error state
6470         // However, it seems reasonable to set an error state if the extension is not enabled
6471         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
6472         return false;
6473     }
6474 
6475     return true;
6476 }
6477 
ValidateTexStorage1DEXT(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLsizei levels,GLenum internalformat,GLsizei width)6478 bool ValidateTexStorage1DEXT(const Context *context,
6479                              angle::EntryPoint entryPoint,
6480                              GLenum target,
6481                              GLsizei levels,
6482                              GLenum internalformat,
6483                              GLsizei width)
6484 {
6485     UNIMPLEMENTED();
6486     ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
6487     return false;
6488 }
6489 
ValidateTexStorage3DEXT(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLsizei levels,GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth)6490 bool ValidateTexStorage3DEXT(const Context *context,
6491                              angle::EntryPoint entryPoint,
6492                              TextureType target,
6493                              GLsizei levels,
6494                              GLenum internalformat,
6495                              GLsizei width,
6496                              GLsizei height,
6497                              GLsizei depth)
6498 {
6499     if (!context->getExtensions().textureStorageEXT)
6500     {
6501         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
6502         return false;
6503     }
6504 
6505     if (context->getClientMajorVersion() < 3)
6506     {
6507         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
6508         return false;
6509     }
6510 
6511     return ValidateES3TexStorage3DParameters(context, entryPoint, target, levels, internalformat,
6512                                              width, height, depth);
6513 }
6514 
ValidateMaxShaderCompilerThreadsKHR(const Context * context,angle::EntryPoint entryPoint,GLuint count)6515 bool ValidateMaxShaderCompilerThreadsKHR(const Context *context,
6516                                          angle::EntryPoint entryPoint,
6517                                          GLuint count)
6518 {
6519     if (!context->getExtensions().parallelShaderCompileKHR)
6520     {
6521         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
6522         return false;
6523     }
6524     return true;
6525 }
6526 
ValidateMultiDrawArraysANGLE(const Context * context,angle::EntryPoint entryPoint,PrimitiveMode mode,const GLint * firsts,const GLsizei * counts,GLsizei drawcount)6527 bool ValidateMultiDrawArraysANGLE(const Context *context,
6528                                   angle::EntryPoint entryPoint,
6529                                   PrimitiveMode mode,
6530                                   const GLint *firsts,
6531                                   const GLsizei *counts,
6532                                   GLsizei drawcount)
6533 {
6534     if (!context->getExtensions().multiDrawANGLE)
6535     {
6536         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
6537         return false;
6538     }
6539     for (GLsizei drawID = 0; drawID < drawcount; ++drawID)
6540     {
6541         if (!ValidateDrawArrays(context, entryPoint, mode, firsts[drawID], counts[drawID]))
6542         {
6543             return false;
6544         }
6545     }
6546     return true;
6547 }
6548 
ValidateMultiDrawElementsANGLE(const Context * context,angle::EntryPoint entryPoint,PrimitiveMode mode,const GLsizei * counts,DrawElementsType type,const GLvoid * const * indices,GLsizei drawcount)6549 bool ValidateMultiDrawElementsANGLE(const Context *context,
6550                                     angle::EntryPoint entryPoint,
6551                                     PrimitiveMode mode,
6552                                     const GLsizei *counts,
6553                                     DrawElementsType type,
6554                                     const GLvoid *const *indices,
6555                                     GLsizei drawcount)
6556 {
6557     if (!context->getExtensions().multiDrawANGLE)
6558     {
6559         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
6560         return false;
6561     }
6562     for (GLsizei drawID = 0; drawID < drawcount; ++drawID)
6563     {
6564         if (!ValidateDrawElements(context, entryPoint, mode, counts[drawID], type, indices[drawID]))
6565         {
6566             return false;
6567         }
6568     }
6569     return true;
6570 }
6571 
ValidateFramebufferTexture2DMultisampleEXT(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLenum attachment,TextureTarget textarget,TextureID texture,GLint level,GLsizei samples)6572 bool ValidateFramebufferTexture2DMultisampleEXT(const Context *context,
6573                                                 angle::EntryPoint entryPoint,
6574                                                 GLenum target,
6575                                                 GLenum attachment,
6576                                                 TextureTarget textarget,
6577                                                 TextureID texture,
6578                                                 GLint level,
6579                                                 GLsizei samples)
6580 {
6581     if (!context->getExtensions().multisampledRenderToTextureEXT)
6582     {
6583         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
6584         return false;
6585     }
6586 
6587     if (samples < 0)
6588     {
6589         return false;
6590     }
6591 
6592     // EXT_multisampled_render_to_texture states that the value of samples
6593     // must be less than or equal to MAX_SAMPLES_EXT (Context::getCaps().maxSamples)
6594     // otherwise GL_INVALID_VALUE is generated.
6595     if (samples > context->getCaps().maxSamples)
6596     {
6597         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kSamplesOutOfRange);
6598         return false;
6599     }
6600 
6601     if (!ValidateFramebufferTextureBase(context, entryPoint, target, attachment, texture, level))
6602     {
6603         return false;
6604     }
6605 
6606     // EXT_multisampled_render_to_texture returns INVALID_OPERATION when a sample number higher than
6607     // the maximum sample number supported by this format is passed.
6608     // The TextureCaps::getMaxSamples method is only guarenteed to be valid when the context is ES3.
6609     if (texture.value != 0 && context->getClientMajorVersion() >= 3)
6610     {
6611         Texture *tex                  = context->getTexture(texture);
6612         GLenum sizedInternalFormat    = tex->getFormat(textarget, level).info->sizedInternalFormat;
6613         const TextureCaps &formatCaps = context->getTextureCaps().get(sizedInternalFormat);
6614         if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
6615         {
6616             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kSamplesOutOfRange);
6617             return false;
6618         }
6619     }
6620 
6621     // Unless EXT_multisampled_render_to_texture2 is enabled, only color attachment 0 can be used.
6622     if (!context->getExtensions().multisampledRenderToTexture2EXT &&
6623         attachment != GL_COLOR_ATTACHMENT0)
6624     {
6625         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidAttachment);
6626         return false;
6627     }
6628 
6629     if (!ValidTexture2DDestinationTarget(context, textarget))
6630     {
6631         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidTextureTarget);
6632         return false;
6633     }
6634 
6635     return true;
6636 }
6637 
ValidateRenderbufferStorageMultisampleEXT(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLsizei samples,GLenum internalformat,GLsizei width,GLsizei height)6638 bool ValidateRenderbufferStorageMultisampleEXT(const Context *context,
6639                                                angle::EntryPoint entryPoint,
6640                                                GLenum target,
6641                                                GLsizei samples,
6642                                                GLenum internalformat,
6643                                                GLsizei width,
6644                                                GLsizei height)
6645 {
6646     if (!context->getExtensions().multisampledRenderToTextureEXT)
6647     {
6648         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
6649         return false;
6650     }
6651     if (!ValidateRenderbufferStorageParametersBase(context, entryPoint, target, samples,
6652                                                    internalformat, width, height))
6653     {
6654         return false;
6655     }
6656 
6657     // EXT_multisampled_render_to_texture states that the value of samples
6658     // must be less than or equal to MAX_SAMPLES_EXT (Context::getCaps().maxSamples)
6659     // otherwise GL_INVALID_VALUE is generated.
6660     if (samples > context->getCaps().maxSamples)
6661     {
6662         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kSamplesOutOfRange);
6663         return false;
6664     }
6665 
6666     // EXT_multisampled_render_to_texture returns GL_OUT_OF_MEMORY on failure to create
6667     // the specified storage. This is different than ES 3.0 in which a sample number higher
6668     // than the maximum sample number supported by this format generates a GL_INVALID_VALUE.
6669     // The TextureCaps::getMaxSamples method is only guarenteed to be valid when the context is ES3.
6670     if (context->getClientMajorVersion() >= 3)
6671     {
6672         const TextureCaps &formatCaps = context->getTextureCaps().get(internalformat);
6673         if (static_cast<GLuint>(samples) > formatCaps.getMaxSamples())
6674         {
6675             ANGLE_VALIDATION_ERROR(GL_OUT_OF_MEMORY, kSamplesOutOfRange);
6676             return false;
6677         }
6678     }
6679 
6680     return true;
6681 }
6682 
ValidateBlobCacheCallbacksANGLE(const Context * context,angle::EntryPoint entryPoint,GLSETBLOBPROCANGLE set,GLGETBLOBPROCANGLE get,const void * userParam)6683 bool ValidateBlobCacheCallbacksANGLE(const Context *context,
6684                                      angle::EntryPoint entryPoint,
6685                                      GLSETBLOBPROCANGLE set,
6686                                      GLGETBLOBPROCANGLE get,
6687                                      const void *userParam)
6688 {
6689     if (!context->getExtensions().blobCacheANGLE)
6690     {
6691         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
6692         return false;
6693     }
6694 
6695     if ((get == nullptr) != (set == nullptr))
6696     {
6697         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBlobCacheCallbacksUnbalanced);
6698         return false;
6699     }
6700 
6701     return true;
6702 }
6703 
ValidateGetPointervANGLE(const Context * context,angle::EntryPoint entryPoint,GLenum pname,void * const * params)6704 bool ValidateGetPointervANGLE(const Context *context,
6705                               angle::EntryPoint entryPoint,
6706                               GLenum pname,
6707                               void *const *params)
6708 {
6709     if (!context->getExtensions().blobCacheANGLE)
6710     {
6711         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
6712         return false;
6713     }
6714 
6715     return ValidateGetPointerv(context, entryPoint, pname, params);
6716 }
6717 
RecordBindTextureTypeError(const Context * context,angle::EntryPoint entryPoint,TextureType target)6718 void RecordBindTextureTypeError(const Context *context,
6719                                 angle::EntryPoint entryPoint,
6720                                 TextureType target)
6721 {
6722     ASSERT(!context->getStateCache().isValidBindTextureType(target));
6723 
6724     switch (target)
6725     {
6726         case TextureType::Rectangle:
6727             ASSERT(!context->getExtensions().textureRectangleANGLE);
6728             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kTextureRectangleNotSupported);
6729             break;
6730 
6731         case TextureType::_3D:
6732         case TextureType::_2DArray:
6733             ASSERT(context->getClientMajorVersion() < 3);
6734             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kES3Required);
6735             break;
6736 
6737         case TextureType::_2DMultisample:
6738             ASSERT(context->getClientVersion() < Version(3, 1) &&
6739                    !context->getExtensions().textureMultisampleANGLE);
6740             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kMultisampleTextureExtensionOrES31Required);
6741             break;
6742 
6743         case TextureType::_2DMultisampleArray:
6744             ASSERT(context->getClientVersion() < Version(3, 2) &&
6745                    !context->getExtensions().textureStorageMultisample2dArrayOES);
6746             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kMultisampleArrayExtensionOrES32Required);
6747             break;
6748 
6749         case TextureType::External:
6750             ASSERT(!context->getExtensions().EGLImageExternalOES &&
6751                    !context->getExtensions().EGLStreamConsumerExternalNV);
6752             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kExternalTextureNotSupported);
6753             break;
6754 
6755         case TextureType::VideoImage:
6756             ASSERT(!context->getExtensions().videoTextureWEBGL);
6757             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kExtensionNotEnabled);
6758             break;
6759 
6760         case TextureType::Buffer:
6761             ASSERT(!context->getExtensions().textureBufferOES &&
6762                    !context->getExtensions().textureBufferEXT);
6763             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kExtensionNotEnabled);
6764             break;
6765 
6766         default:
6767             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidTextureTarget);
6768     }
6769 }
6770 
6771 }  // namespace gl
6772