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