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