• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2019 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 // validationESEXT.cpp: Validation functions for OpenGL ES extension entry points.
7 
8 #include "libANGLE/validationESEXT_autogen.h"
9 
10 #include "libANGLE/Context.h"
11 #include "libANGLE/Display.h"
12 #include "libANGLE/ErrorStrings.h"
13 #include "libANGLE/MemoryObject.h"
14 #include "libANGLE/PixelLocalStorage.h"
15 #include "libANGLE/validationES.h"
16 #include "libANGLE/validationES2.h"
17 #include "libANGLE/validationES3.h"
18 #include "libANGLE/validationES31.h"
19 #include "libANGLE/validationES32.h"
20 
21 #include <optional>
22 
23 namespace gl
24 {
25 using namespace err;
26 
27 namespace
28 {
29 template <typename ObjectT>
ValidateGetImageFormatAndType(const Context * context,angle::EntryPoint entryPoint,ObjectT * obj,GLenum format,GLenum type)30 bool ValidateGetImageFormatAndType(const Context *context,
31                                    angle::EntryPoint entryPoint,
32                                    ObjectT *obj,
33                                    GLenum format,
34                                    GLenum type)
35 {
36     GLenum implFormat = obj->getImplementationColorReadFormat(context);
37     if (!ValidES3Format(format) && (format != implFormat || format == GL_NONE))
38     {
39         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidFormat);
40         return false;
41     }
42 
43     GLenum implType = obj->getImplementationColorReadType(context);
44     if (!ValidES3Type(type) && (type != implType || type == GL_NONE))
45     {
46         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidType);
47         return false;
48     }
49 
50     // Format/type combinations are not yet validated.
51 
52     return true;
53 }
54 
IsValidImageLayout(ImageLayout layout)55 bool IsValidImageLayout(ImageLayout layout)
56 {
57     switch (layout)
58     {
59         case ImageLayout::Undefined:
60         case ImageLayout::General:
61         case ImageLayout::ColorAttachment:
62         case ImageLayout::DepthStencilAttachment:
63         case ImageLayout::DepthStencilReadOnlyAttachment:
64         case ImageLayout::ShaderReadOnly:
65         case ImageLayout::TransferSrc:
66         case ImageLayout::TransferDst:
67         case ImageLayout::DepthReadOnlyStencilAttachment:
68         case ImageLayout::DepthAttachmentStencilReadOnly:
69             return true;
70 
71         default:
72             return false;
73     }
74 }
75 
IsValidMemoryObjectParamater(const Context * context,angle::EntryPoint entryPoint,GLenum pname)76 bool IsValidMemoryObjectParamater(const Context *context,
77                                   angle::EntryPoint entryPoint,
78                                   GLenum pname)
79 {
80     switch (pname)
81     {
82         case GL_DEDICATED_MEMORY_OBJECT_EXT:
83             return true;
84 
85         case GL_PROTECTED_MEMORY_OBJECT_EXT:
86             if (!context->getExtensions().protectedTexturesEXT)
87             {
88                 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
89                 return false;
90             }
91             return true;
92 
93         default:
94             return false;
95     }
96 }
97 
ValidateObjectIdentifierAndName(const Context * context,angle::EntryPoint entryPoint,GLenum identifier,GLuint name)98 bool ValidateObjectIdentifierAndName(const Context *context,
99                                      angle::EntryPoint entryPoint,
100                                      GLenum identifier,
101                                      GLuint name)
102 {
103     bool isGLES11 = context->getClientVersion() == Version(1, 1);
104     bool isGLES3  = context->getClientMajorVersion() >= 3;
105     bool isGLES31 = context->getClientVersion() >= Version(3, 1);
106     switch (identifier)
107     {
108         case GL_BUFFER_OBJECT_EXT:
109             if (context->getBuffer({name}) == nullptr)
110             {
111                 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidBufferName);
112                 return false;
113             }
114             return true;
115 
116         case GL_SHADER_OBJECT_EXT:
117             if (isGLES11)
118             {
119                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidType);
120                 return false;
121             }
122             if (context->getShaderNoResolveCompile({name}) == nullptr)
123             {
124                 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidShaderName);
125                 return false;
126             }
127             return true;
128 
129         case GL_PROGRAM_OBJECT_EXT:
130             if (isGLES11)
131             {
132                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidType);
133                 return false;
134             }
135             if (context->getProgramNoResolveLink({name}) == nullptr)
136             {
137                 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidProgramName);
138                 return false;
139             }
140             return true;
141 
142         case GL_VERTEX_ARRAY_OBJECT_EXT:
143             if (!isGLES3 && !context->getExtensions().vertexArrayObjectOES)
144             {
145                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidType);
146                 return false;
147             }
148             if (context->getVertexArray({name}) == nullptr)
149             {
150                 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidVertexArrayName);
151                 return false;
152             }
153             return true;
154 
155         case GL_QUERY_OBJECT_EXT:
156             if (!isGLES3 && !context->getExtensions().occlusionQueryBooleanEXT)
157             {
158                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidType);
159                 return false;
160             }
161             if (context->getQuery({name}) == nullptr)
162             {
163                 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidQueryName);
164                 return false;
165             }
166             return true;
167 
168         case GL_TRANSFORM_FEEDBACK:
169             if (!isGLES3)
170             {
171                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidType);
172                 return false;
173             }
174             if (context->getTransformFeedback({name}) == nullptr)
175             {
176                 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidTransformFeedbackName);
177                 return false;
178             }
179             return true;
180 
181         case GL_SAMPLER:
182             if (!isGLES3)
183             {
184                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidType);
185                 return false;
186             }
187             if (context->getSampler({name}) == nullptr)
188             {
189                 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidSamplerName);
190                 return false;
191             }
192             return true;
193 
194         case GL_TEXTURE:
195             if (context->getTexture({name}) == nullptr)
196             {
197                 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidTextureName);
198                 return false;
199             }
200             return true;
201 
202         case GL_RENDERBUFFER:
203             if (!context->isRenderbuffer({name}))
204             {
205                 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidRenderbufferName);
206                 return false;
207             }
208             return true;
209 
210         case GL_FRAMEBUFFER:
211             if (context->getFramebuffer({name}) == nullptr)
212             {
213                 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidFramebufferName);
214                 return false;
215             }
216             return true;
217 
218         case GL_PROGRAM_PIPELINE_OBJECT_EXT:
219             if (!isGLES31 && !context->getExtensions().separateShaderObjectsEXT)
220             {
221                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidType);
222                 return false;
223             }
224             if (context->getProgramPipeline({name}) == nullptr)
225             {
226                 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidProgramPipelineName);
227                 return false;
228             }
229             return true;
230 
231         default:
232             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidIndentifier);
233             return false;
234     }
235 }
236 
ValidateClearTexImageFormat(const Context * context,angle::EntryPoint entryPoint,TextureType textureType,const Format & textureFormat,GLenum format,GLenum type)237 bool ValidateClearTexImageFormat(const Context *context,
238                                  angle::EntryPoint entryPoint,
239                                  TextureType textureType,
240                                  const Format &textureFormat,
241                                  GLenum format,
242                                  GLenum type)
243 {
244     if (textureFormat.info->compressed)
245     {
246         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kTextureIsCompressed);
247         return false;
248     }
249 
250     if (!ValidateTexImageFormatCombination(context, entryPoint, textureType,
251                                            textureFormat.info->internalFormat, format, type))
252     {
253         return false;
254     }
255 
256     return true;
257 }
258 
ValidateClearTexImageCommon(const Context * context,angle::EntryPoint entryPoint,TextureID texturePacked,GLint level,const std::optional<Box> & area,GLenum format,GLenum type,const void * data)259 bool ValidateClearTexImageCommon(const Context *context,
260                                  angle::EntryPoint entryPoint,
261                                  TextureID texturePacked,
262                                  GLint level,
263                                  const std::optional<Box> &area,
264                                  GLenum format,
265                                  GLenum type,
266                                  const void *data)
267 {
268     if (!context->getExtensions().clearTextureEXT)
269     {
270         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
271         return false;
272     }
273 
274     if (texturePacked.value == 0)
275     {
276         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kMissingTextureName);
277         return false;
278     }
279 
280     Texture *tex = context->getTexture(texturePacked);
281     if (tex == nullptr)
282     {
283         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kMissingTextureName);
284         return false;
285     }
286 
287     if (tex->getType() == TextureType::Buffer)
288     {
289         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBufferTextureNotAllowed);
290         return false;
291     }
292 
293     if (!ValidMipLevel(context, tex->getType(), level))
294     {
295         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidMipLevel);
296         return false;
297     }
298 
299     if (area.has_value() && (area->x < 0 || area->y < 0 || area->z < 0 || area->width < 0 ||
300                              area->height < 0 || area->depth < 0))
301     {
302         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kNegativeOffset);
303         return false;
304     }
305 
306     if (tex->getType() == TextureType::CubeMap)
307     {
308         if (area.has_value() && area->z + area->depth > 6)
309         {
310             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kDestinationTextureTooSmall);
311             return false;
312         }
313 
314         ImageIndexIterator it = ImageIndexIterator::MakeGeneric(
315             tex->getType(), level, level + 1, area.has_value() ? area->z : ImageIndex::kEntireLevel,
316             area.has_value() ? area->z + area->depth : ImageIndex::kEntireLevel);
317         while (it.hasNext())
318         {
319             const ImageIndex index = it.next();
320             TextureTarget target   = index.getTarget();
321             const Extents extents  = tex->getExtents(target, level);
322 
323             if (!tex->getState().getImageDesc(index).format.valid())
324             {
325                 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kDestinationLevelNotDefined);
326                 return false;
327             }
328 
329             if (area.has_value() &&
330                 (area->x + area->width > extents.width || area->y + area->height > extents.height))
331             {
332                 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kDestinationTextureTooSmall);
333                 return false;
334             }
335 
336             if (!ValidateClearTexImageFormat(context, entryPoint, tex->getType(),
337                                              tex->getFormat(target, level), format, type))
338             {
339                 return false;
340             }
341         }
342     }
343     else
344     {
345         TextureTarget target  = NonCubeTextureTypeToTarget(tex->getType());
346         const Extents extents = tex->getExtents(target, level);
347 
348         if (!tex->getState().getImageDesc(target, level).format.valid())
349         {
350             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kDestinationLevelNotDefined);
351             return false;
352         }
353 
354         if (area.has_value() &&
355             (area->x + area->width > extents.width || area->y + area->height > extents.height ||
356              area->z + area->depth > extents.depth))
357         {
358             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kDestinationTextureTooSmall);
359             return false;
360         }
361 
362         if (!ValidateClearTexImageFormat(context, entryPoint, tex->getType(),
363                                          tex->getFormat(target, level), format, type))
364         {
365             return false;
366         }
367     }
368 
369     return true;
370 }
371 
372 }  // namespace
373 
ValidateGetTexImage(const Context * context,angle::EntryPoint entryPoint,TextureTarget target,GLint level)374 bool ValidateGetTexImage(const Context *context,
375                          angle::EntryPoint entryPoint,
376                          TextureTarget target,
377                          GLint level)
378 {
379     if (!context->getExtensions().getImageANGLE)
380     {
381         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kGetImageExtensionNotEnabled);
382         return false;
383     }
384 
385     if (!ValidTexture2DDestinationTarget(context, target) &&
386         !ValidTexture3DDestinationTarget(context, target))
387     {
388         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidTextureTarget);
389         return false;
390     }
391 
392     if (level < 0)
393     {
394         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeLevel);
395         return false;
396     }
397 
398     TextureType textureType = TextureTargetToType(target);
399     if (!ValidMipLevel(context, textureType, level))
400     {
401         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidMipLevel);
402         return false;
403     }
404 
405     return true;
406 }
407 
ValidateGetTexImageANGLE(const Context * context,angle::EntryPoint entryPoint,TextureTarget target,GLint level,GLenum format,GLenum type,const void * pixels)408 bool ValidateGetTexImageANGLE(const Context *context,
409                               angle::EntryPoint entryPoint,
410                               TextureTarget target,
411                               GLint level,
412                               GLenum format,
413                               GLenum type,
414                               const void *pixels)
415 {
416     if (!ValidateGetTexImage(context, entryPoint, target, level))
417     {
418         return false;
419     }
420 
421     Texture *texture = context->getTextureByTarget(target);
422 
423     if (!ValidateGetImageFormatAndType(context, entryPoint, texture, format, type))
424     {
425         return false;
426     }
427 
428     GLsizei width  = static_cast<GLsizei>(texture->getWidth(target, level));
429     GLsizei height = static_cast<GLsizei>(texture->getHeight(target, level));
430     if (!ValidatePixelPack(context, entryPoint, format, type, 0, 0, width, height, -1, nullptr,
431                            pixels))
432     {
433         return false;
434     }
435 
436     if (texture->getFormat(target, level).info->compressed)
437     {
438         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kGetImageCompressed);
439         return false;
440     }
441 
442     return true;
443 }
444 
ValidateGetCompressedTexImageANGLE(const Context * context,angle::EntryPoint entryPoint,TextureTarget target,GLint level,const void * pixels)445 bool ValidateGetCompressedTexImageANGLE(const Context *context,
446                                         angle::EntryPoint entryPoint,
447                                         TextureTarget target,
448                                         GLint level,
449                                         const void *pixels)
450 {
451     if (!ValidateGetTexImage(context, entryPoint, target, level))
452     {
453         return false;
454     }
455 
456     Texture *texture = context->getTextureByTarget(target);
457     if (!texture->getFormat(target, level).info->compressed)
458     {
459         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kGetImageNotCompressed);
460         return false;
461     }
462 
463     return true;
464 }
465 
ValidateGetRenderbufferImageANGLE(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLenum format,GLenum type,const void * pixels)466 bool ValidateGetRenderbufferImageANGLE(const Context *context,
467                                        angle::EntryPoint entryPoint,
468                                        GLenum target,
469                                        GLenum format,
470                                        GLenum type,
471                                        const void *pixels)
472 {
473     if (!context->getExtensions().getImageANGLE)
474     {
475         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kGetImageExtensionNotEnabled);
476         return false;
477     }
478 
479     if (target != GL_RENDERBUFFER)
480     {
481         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidRenderbufferTarget);
482         return false;
483     }
484 
485     Renderbuffer *renderbuffer = context->getState().getCurrentRenderbuffer();
486 
487     if (!ValidateGetImageFormatAndType(context, entryPoint, renderbuffer, format, type))
488     {
489         return false;
490     }
491 
492     GLsizei width  = renderbuffer->getWidth();
493     GLsizei height = renderbuffer->getHeight();
494     if (!ValidatePixelPack(context, entryPoint, format, type, 0, 0, width, height, -1, nullptr,
495                            pixels))
496     {
497         return false;
498     }
499 
500     return true;
501 }
502 
ValidateDrawElementsBaseVertexEXT(const Context * context,angle::EntryPoint entryPoint,PrimitiveMode mode,GLsizei count,DrawElementsType type,const void * indices,GLint basevertex)503 bool ValidateDrawElementsBaseVertexEXT(const Context *context,
504                                        angle::EntryPoint entryPoint,
505                                        PrimitiveMode mode,
506                                        GLsizei count,
507                                        DrawElementsType type,
508                                        const void *indices,
509                                        GLint basevertex)
510 {
511     if (!context->getExtensions().drawElementsBaseVertexAny())
512     {
513         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
514         return false;
515     }
516 
517     return ValidateDrawElementsCommon(context, entryPoint, mode, count, type, indices, 1);
518 }
519 
ValidateDrawElementsInstancedBaseVertexEXT(const Context * context,angle::EntryPoint entryPoint,PrimitiveMode mode,GLsizei count,DrawElementsType type,const void * indices,GLsizei instancecount,GLint basevertex)520 bool ValidateDrawElementsInstancedBaseVertexEXT(const Context *context,
521                                                 angle::EntryPoint entryPoint,
522                                                 PrimitiveMode mode,
523                                                 GLsizei count,
524                                                 DrawElementsType type,
525                                                 const void *indices,
526                                                 GLsizei instancecount,
527                                                 GLint basevertex)
528 {
529     if (!context->getExtensions().drawElementsBaseVertexAny())
530     {
531         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
532         return false;
533     }
534 
535     return ValidateDrawElementsInstancedBase(context, entryPoint, mode, count, type, indices,
536                                              instancecount, 0);
537 }
538 
ValidateDrawRangeElementsBaseVertexEXT(const Context * context,angle::EntryPoint entryPoint,PrimitiveMode mode,GLuint start,GLuint end,GLsizei count,DrawElementsType type,const void * indices,GLint basevertex)539 bool ValidateDrawRangeElementsBaseVertexEXT(const Context *context,
540                                             angle::EntryPoint entryPoint,
541                                             PrimitiveMode mode,
542                                             GLuint start,
543                                             GLuint end,
544                                             GLsizei count,
545                                             DrawElementsType type,
546                                             const void *indices,
547                                             GLint basevertex)
548 {
549     if (!context->getExtensions().drawElementsBaseVertexAny())
550     {
551         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
552         return false;
553     }
554 
555     if (end < start)
556     {
557         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidElementRange);
558         return false;
559     }
560 
561     if (!ValidateDrawElementsCommon(context, entryPoint, mode, count, type, indices, 1))
562     {
563         return false;
564     }
565 
566     // Skip range checks for no-op calls.
567     if (count <= 0)
568     {
569         return true;
570     }
571 
572     // Note that resolving the index range is a bit slow. We should probably optimize this.
573     IndexRange indexRange;
574     ANGLE_VALIDATION_TRY(context->getState().getVertexArray()->getIndexRange(context, type, count,
575                                                                              indices, &indexRange));
576 
577     if (indexRange.end > end || indexRange.start < start)
578     {
579         // GL spec says that behavior in this case is undefined - generating an error is fine.
580         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExceedsElementRange);
581         return false;
582     }
583     return true;
584 }
585 
ValidateMultiDrawElementsBaseVertexEXT(const Context * context,angle::EntryPoint entryPoint,PrimitiveMode mode,const GLsizei * count,DrawElementsType type,const void * const * indices,GLsizei drawcount,const GLint * basevertex)586 bool ValidateMultiDrawElementsBaseVertexEXT(const Context *context,
587                                             angle::EntryPoint entryPoint,
588                                             PrimitiveMode mode,
589                                             const GLsizei *count,
590                                             DrawElementsType type,
591                                             const void *const *indices,
592                                             GLsizei drawcount,
593                                             const GLint *basevertex)
594 {
595     return true;
596 }
597 
ValidateMultiDrawArraysIndirectEXT(const Context * context,angle::EntryPoint entryPoint,PrimitiveMode modePacked,const void * indirect,GLsizei drawcount,GLsizei stride)598 bool ValidateMultiDrawArraysIndirectEXT(const Context *context,
599                                         angle::EntryPoint entryPoint,
600                                         PrimitiveMode modePacked,
601                                         const void *indirect,
602                                         GLsizei drawcount,
603                                         GLsizei stride)
604 {
605     if (!ValidateMultiDrawIndirectBase(context, entryPoint, drawcount, stride))
606     {
607         return false;
608     }
609 
610     if (!ValidateDrawArraysIndirect(context, entryPoint, modePacked, indirect))
611     {
612         return false;
613     }
614 
615     return true;
616 }
617 
ValidateMultiDrawElementsIndirectEXT(const Context * context,angle::EntryPoint entryPoint,PrimitiveMode modePacked,DrawElementsType typePacked,const void * indirect,GLsizei drawcount,GLsizei stride)618 bool ValidateMultiDrawElementsIndirectEXT(const Context *context,
619                                           angle::EntryPoint entryPoint,
620                                           PrimitiveMode modePacked,
621                                           DrawElementsType typePacked,
622                                           const void *indirect,
623                                           GLsizei drawcount,
624                                           GLsizei stride)
625 {
626     if (!ValidateMultiDrawIndirectBase(context, entryPoint, drawcount, stride))
627     {
628         return false;
629     }
630 
631     const State &state                      = context->getState();
632     TransformFeedback *curTransformFeedback = state.getCurrentTransformFeedback();
633     if (!ValidateDrawElementsIndirect(context, entryPoint, modePacked, typePacked, indirect))
634     {
635         return false;
636     }
637 
638     if (curTransformFeedback && curTransformFeedback->isActive() &&
639         !curTransformFeedback->isPaused())
640     {
641         // EXT_geometry_shader allows transform feedback to work with all draw commands.
642         // [EXT_geometry_shader] Section 12.1, "Transform Feedback"
643         if (context->getExtensions().geometryShaderAny() || context->getClientVersion() >= ES_3_2)
644         {
645             if (!ValidateTransformFeedbackPrimitiveMode(
646                     context, entryPoint, curTransformFeedback->getPrimitiveMode(), modePacked))
647             {
648                 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidDrawModeTransformFeedback);
649                 return false;
650             }
651         }
652         else
653         {
654             // An INVALID_OPERATION error is generated if transform feedback is active and not
655             // paused.
656             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kUnsupportedDrawModeForTransformFeedback);
657             return false;
658         }
659     }
660 
661     return true;
662 }
663 
ValidateDrawArraysInstancedBaseInstanceEXT(const Context * context,angle::EntryPoint entryPoint,PrimitiveMode mode,GLint first,GLsizei count,GLsizei instanceCount,GLuint baseInstance)664 bool ValidateDrawArraysInstancedBaseInstanceEXT(const Context *context,
665                                                 angle::EntryPoint entryPoint,
666                                                 PrimitiveMode mode,
667                                                 GLint first,
668                                                 GLsizei count,
669                                                 GLsizei instanceCount,
670                                                 GLuint baseInstance)
671 {
672     if (!context->getExtensions().baseInstanceEXT)
673     {
674         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
675         return false;
676     }
677 
678     return ValidateDrawArraysInstancedBase(context, entryPoint, mode, first, count, instanceCount,
679                                            baseInstance);
680 }
681 
ValidateDrawElementsInstancedBaseInstanceEXT(const Context * context,angle::EntryPoint entryPoint,PrimitiveMode mode,GLsizei count,DrawElementsType type,void const * indices,GLsizei instancecount,GLuint baseinstance)682 bool ValidateDrawElementsInstancedBaseInstanceEXT(const Context *context,
683                                                   angle::EntryPoint entryPoint,
684                                                   PrimitiveMode mode,
685                                                   GLsizei count,
686                                                   DrawElementsType type,
687                                                   void const *indices,
688                                                   GLsizei instancecount,
689                                                   GLuint baseinstance)
690 {
691     if (!context->getExtensions().baseInstanceEXT)
692     {
693         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
694         return false;
695     }
696 
697     return ValidateDrawElementsInstancedBase(context, entryPoint, mode, count, type, indices,
698                                              instancecount, baseinstance);
699 }
700 
ValidateDrawElementsInstancedBaseVertexBaseInstanceEXT(const Context * context,angle::EntryPoint entryPoint,PrimitiveMode mode,GLsizei count,DrawElementsType typePacked,const void * indices,GLsizei instancecount,GLint basevertex,GLuint baseinstance)701 bool ValidateDrawElementsInstancedBaseVertexBaseInstanceEXT(const Context *context,
702                                                             angle::EntryPoint entryPoint,
703                                                             PrimitiveMode mode,
704                                                             GLsizei count,
705                                                             DrawElementsType typePacked,
706                                                             const void *indices,
707                                                             GLsizei instancecount,
708                                                             GLint basevertex,
709                                                             GLuint baseinstance)
710 {
711     if (!context->getExtensions().baseInstanceEXT)
712     {
713         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
714         return false;
715     }
716 
717     return ValidateDrawElementsInstancedBase(context, entryPoint, mode, count, typePacked, indices,
718                                              instancecount, baseinstance);
719 }
720 
ValidateDrawElementsBaseVertexOES(const Context * context,angle::EntryPoint entryPoint,PrimitiveMode mode,GLsizei count,DrawElementsType type,const void * indices,GLint basevertex)721 bool ValidateDrawElementsBaseVertexOES(const Context *context,
722                                        angle::EntryPoint entryPoint,
723                                        PrimitiveMode mode,
724                                        GLsizei count,
725                                        DrawElementsType type,
726                                        const void *indices,
727                                        GLint basevertex)
728 {
729     if (!context->getExtensions().drawElementsBaseVertexAny())
730     {
731         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
732         return false;
733     }
734 
735     return ValidateDrawElementsCommon(context, entryPoint, mode, count, type, indices, 1);
736 }
737 
ValidateDrawElementsInstancedBaseVertexOES(const Context * context,angle::EntryPoint entryPoint,PrimitiveMode mode,GLsizei count,DrawElementsType type,const void * indices,GLsizei instancecount,GLint basevertex)738 bool ValidateDrawElementsInstancedBaseVertexOES(const Context *context,
739                                                 angle::EntryPoint entryPoint,
740                                                 PrimitiveMode mode,
741                                                 GLsizei count,
742                                                 DrawElementsType type,
743                                                 const void *indices,
744                                                 GLsizei instancecount,
745                                                 GLint basevertex)
746 {
747     if (!context->getExtensions().drawElementsBaseVertexAny())
748     {
749         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
750         return false;
751     }
752 
753     return ValidateDrawElementsInstancedBase(context, entryPoint, mode, count, type, indices,
754                                              instancecount, 0);
755 }
756 
ValidateDrawRangeElementsBaseVertexOES(const Context * context,angle::EntryPoint entryPoint,PrimitiveMode mode,GLuint start,GLuint end,GLsizei count,DrawElementsType type,const void * indices,GLint basevertex)757 bool ValidateDrawRangeElementsBaseVertexOES(const Context *context,
758                                             angle::EntryPoint entryPoint,
759                                             PrimitiveMode mode,
760                                             GLuint start,
761                                             GLuint end,
762                                             GLsizei count,
763                                             DrawElementsType type,
764                                             const void *indices,
765                                             GLint basevertex)
766 {
767     if (!context->getExtensions().drawElementsBaseVertexAny())
768     {
769         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
770         return false;
771     }
772 
773     if (end < start)
774     {
775         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidElementRange);
776         return false;
777     }
778 
779     if (!ValidateDrawElementsCommon(context, entryPoint, mode, count, type, indices, 1))
780     {
781         return false;
782     }
783 
784     // Skip range checks for no-op calls.
785     if (count <= 0)
786     {
787         return true;
788     }
789 
790     // Note that resolving the index range is a bit slow. We should probably optimize this.
791     IndexRange indexRange;
792     ANGLE_VALIDATION_TRY(context->getState().getVertexArray()->getIndexRange(context, type, count,
793                                                                              indices, &indexRange));
794 
795     if (indexRange.end > end || indexRange.start < start)
796     {
797         // GL spec says that behavior in this case is undefined - generating an error is fine.
798         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExceedsElementRange);
799         return false;
800     }
801     return true;
802 }
803 
804 // GL_KHR_blend_equation_advanced
ValidateBlendBarrierKHR(const Context * context,angle::EntryPoint entryPoint)805 bool ValidateBlendBarrierKHR(const Context *context, angle::EntryPoint entryPoint)
806 {
807     if (context->getClientVersion() < ES_2_0)
808     {
809         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES2Required);
810         return false;
811     }
812 
813     if (!context->getExtensions().blendEquationAdvancedKHR)
814     {
815         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kAdvancedBlendExtensionNotEnabled);
816     }
817 
818     return true;
819 }
820 
ValidateGetGraphicsResetStatusKHR(const Context * context,angle::EntryPoint entryPoint)821 bool ValidateGetGraphicsResetStatusKHR(const Context *context, angle::EntryPoint entryPoint)
822 {
823     if (context->getClientVersion() < ES_2_0)
824     {
825         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES2Required);
826         return false;
827     }
828 
829     if (!context->getExtensions().robustnessKHR)
830     {
831         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
832         return false;
833     }
834 
835     return true;
836 }
837 
ValidateGetnUniformfvKHR(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei bufSize,const GLfloat * params)838 bool ValidateGetnUniformfvKHR(const Context *context,
839                               angle::EntryPoint entryPoint,
840                               ShaderProgramID programPacked,
841                               UniformLocation locationPacked,
842                               GLsizei bufSize,
843                               const GLfloat *params)
844 {
845     if (context->getClientVersion() < ES_2_0)
846     {
847         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES2Required);
848         return false;
849     }
850 
851     if (!context->getExtensions().robustnessKHR)
852     {
853         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
854         return false;
855     }
856 
857     return ValidateSizedGetUniform(context, entryPoint, programPacked, locationPacked, bufSize,
858                                    nullptr);
859 }
860 
ValidateGetnUniformivKHR(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei bufSize,const GLint * params)861 bool ValidateGetnUniformivKHR(const Context *context,
862                               angle::EntryPoint entryPoint,
863                               ShaderProgramID programPacked,
864                               UniformLocation locationPacked,
865                               GLsizei bufSize,
866                               const GLint *params)
867 {
868     if (context->getClientVersion() < ES_2_0)
869     {
870         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES2Required);
871         return false;
872     }
873 
874     if (!context->getExtensions().robustnessKHR)
875     {
876         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
877         return false;
878     }
879 
880     return ValidateSizedGetUniform(context, entryPoint, programPacked, locationPacked, bufSize,
881                                    nullptr);
882 }
883 
ValidateGetnUniformuivKHR(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei bufSize,const GLuint * params)884 bool ValidateGetnUniformuivKHR(const Context *context,
885                                angle::EntryPoint entryPoint,
886                                ShaderProgramID programPacked,
887                                UniformLocation locationPacked,
888                                GLsizei bufSize,
889                                const GLuint *params)
890 {
891     // Based on the spec, if ES 3.0 or later is not supported, all references to GetnUniformuiv
892     // should be removed.
893     if (context->getClientVersion() < ES_3_0)
894     {
895         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
896         return false;
897     }
898 
899     if (!context->getExtensions().robustnessKHR)
900     {
901         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
902         return false;
903     }
904 
905     return ValidateSizedGetUniform(context, entryPoint, programPacked, locationPacked, bufSize,
906                                    nullptr);
907 }
908 
ValidateReadnPixelsKHR(const Context * context,angle::EntryPoint entryPoint,GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,GLsizei bufSize,const void * data)909 bool ValidateReadnPixelsKHR(const Context *context,
910                             angle::EntryPoint entryPoint,
911                             GLint x,
912                             GLint y,
913                             GLsizei width,
914                             GLsizei height,
915                             GLenum format,
916                             GLenum type,
917                             GLsizei bufSize,
918                             const void *data)
919 {
920     if (context->getClientVersion() < ES_2_0)
921     {
922         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES2Required);
923         return false;
924     }
925 
926     if (!context->getExtensions().robustnessKHR)
927     {
928         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
929         return false;
930     }
931 
932     if (bufSize < 0)
933     {
934         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeBufSize);
935         return false;
936     }
937 
938     return ValidateReadPixelsBase(context, entryPoint, x, y, width, height, format, type, bufSize,
939                                   nullptr, nullptr, nullptr, data);
940 }
941 
ValidateBlendEquationOES(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLenum mode)942 bool ValidateBlendEquationOES(const PrivateState &state,
943                               ErrorSet *errors,
944                               angle::EntryPoint entryPoint,
945                               GLenum mode)
946 {
947     if (!state.getExtensions().blendSubtractOES)
948     {
949         errors->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
950         return false;
951     }
952 
953     switch (mode)
954     {
955         case GL_FUNC_ADD_OES:
956         case GL_FUNC_SUBTRACT_OES:
957         case GL_FUNC_REVERSE_SUBTRACT_OES:
958             return true;
959         default:
960             errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidBlendEquation);
961             return false;
962     }
963 }
964 
ValidateBlendEquationSeparateiEXT(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLuint buf,GLenum modeRGB,GLenum modeAlpha)965 bool ValidateBlendEquationSeparateiEXT(const PrivateState &state,
966                                        ErrorSet *errors,
967                                        angle::EntryPoint entryPoint,
968                                        GLuint buf,
969                                        GLenum modeRGB,
970                                        GLenum modeAlpha)
971 {
972     if (!state.getExtensions().drawBuffersIndexedEXT)
973     {
974         errors->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
975         return false;
976     }
977 
978     return ValidateBlendEquationSeparatei(state, errors, entryPoint, buf, modeRGB, modeAlpha);
979 }
980 
ValidateBlendEquationiEXT(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLuint buf,GLenum mode)981 bool ValidateBlendEquationiEXT(const PrivateState &state,
982                                ErrorSet *errors,
983                                angle::EntryPoint entryPoint,
984                                GLuint buf,
985                                GLenum mode)
986 {
987     if (!state.getExtensions().drawBuffersIndexedEXT)
988     {
989         errors->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
990         return false;
991     }
992 
993     return ValidateBlendEquationi(state, errors, entryPoint, buf, mode);
994 }
995 
ValidateBlendFuncSeparateiEXT(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLuint buf,GLenum srcRGB,GLenum dstRGB,GLenum srcAlpha,GLenum dstAlpha)996 bool ValidateBlendFuncSeparateiEXT(const PrivateState &state,
997                                    ErrorSet *errors,
998                                    angle::EntryPoint entryPoint,
999                                    GLuint buf,
1000                                    GLenum srcRGB,
1001                                    GLenum dstRGB,
1002                                    GLenum srcAlpha,
1003                                    GLenum dstAlpha)
1004 {
1005     if (!state.getExtensions().drawBuffersIndexedEXT)
1006     {
1007         errors->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
1008         return false;
1009     }
1010 
1011     return ValidateBlendFuncSeparatei(state, errors, entryPoint, buf, srcRGB, dstRGB, srcAlpha,
1012                                       dstAlpha);
1013 }
1014 
ValidateBlendFunciEXT(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLuint buf,GLenum src,GLenum dst)1015 bool ValidateBlendFunciEXT(const PrivateState &state,
1016                            ErrorSet *errors,
1017                            angle::EntryPoint entryPoint,
1018                            GLuint buf,
1019                            GLenum src,
1020                            GLenum dst)
1021 {
1022     if (!state.getExtensions().drawBuffersIndexedEXT)
1023     {
1024         errors->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
1025         return false;
1026     }
1027 
1028     return ValidateBlendFunci(state, errors, entryPoint, buf, src, dst);
1029 }
1030 
ValidateColorMaskiEXT(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLuint index,GLboolean r,GLboolean g,GLboolean b,GLboolean a)1031 bool ValidateColorMaskiEXT(const PrivateState &state,
1032                            ErrorSet *errors,
1033                            angle::EntryPoint entryPoint,
1034                            GLuint index,
1035                            GLboolean r,
1036                            GLboolean g,
1037                            GLboolean b,
1038                            GLboolean a)
1039 {
1040     if (!state.getExtensions().drawBuffersIndexedEXT)
1041     {
1042         errors->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
1043         return false;
1044     }
1045 
1046     return ValidateColorMaski(state, errors, entryPoint, index, r, g, b, a);
1047 }
1048 
ValidateDisableiEXT(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLenum target,GLuint index)1049 bool ValidateDisableiEXT(const PrivateState &state,
1050                          ErrorSet *errors,
1051                          angle::EntryPoint entryPoint,
1052                          GLenum target,
1053                          GLuint index)
1054 {
1055     if (!state.getExtensions().drawBuffersIndexedEXT)
1056     {
1057         errors->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
1058         return false;
1059     }
1060 
1061     return ValidateDisablei(state, errors, entryPoint, target, index);
1062 }
1063 
ValidateEnableiEXT(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLenum target,GLuint index)1064 bool ValidateEnableiEXT(const PrivateState &state,
1065                         ErrorSet *errors,
1066                         angle::EntryPoint entryPoint,
1067                         GLenum target,
1068                         GLuint index)
1069 {
1070     if (!state.getExtensions().drawBuffersIndexedEXT)
1071     {
1072         errors->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
1073         return false;
1074     }
1075 
1076     return ValidateEnablei(state, errors, entryPoint, target, index);
1077 }
1078 
ValidateIsEnablediEXT(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLenum target,GLuint index)1079 bool ValidateIsEnablediEXT(const PrivateState &state,
1080                            ErrorSet *errors,
1081                            angle::EntryPoint entryPoint,
1082                            GLenum target,
1083                            GLuint index)
1084 {
1085     if (!state.getExtensions().drawBuffersIndexedEXT)
1086     {
1087         errors->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
1088         return false;
1089     }
1090 
1091     return ValidateIsEnabledi(state, errors, entryPoint, target, index);
1092 }
1093 
ValidateBlendEquationSeparateiOES(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLuint buf,GLenum modeRGB,GLenum modeAlpha)1094 bool ValidateBlendEquationSeparateiOES(const PrivateState &state,
1095                                        ErrorSet *errors,
1096                                        angle::EntryPoint entryPoint,
1097                                        GLuint buf,
1098                                        GLenum modeRGB,
1099                                        GLenum modeAlpha)
1100 {
1101     if (!state.getExtensions().drawBuffersIndexedOES)
1102     {
1103         errors->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
1104         return false;
1105     }
1106 
1107     return ValidateBlendEquationSeparatei(state, errors, entryPoint, buf, modeRGB, modeAlpha);
1108 }
1109 
ValidateBlendEquationiOES(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLuint buf,GLenum mode)1110 bool ValidateBlendEquationiOES(const PrivateState &state,
1111                                ErrorSet *errors,
1112                                angle::EntryPoint entryPoint,
1113                                GLuint buf,
1114                                GLenum mode)
1115 {
1116     if (!state.getExtensions().drawBuffersIndexedOES)
1117     {
1118         errors->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
1119         return false;
1120     }
1121 
1122     return ValidateBlendEquationi(state, errors, entryPoint, buf, mode);
1123 }
1124 
ValidateBlendFuncSeparateiOES(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLuint buf,GLenum srcRGB,GLenum dstRGB,GLenum srcAlpha,GLenum dstAlpha)1125 bool ValidateBlendFuncSeparateiOES(const PrivateState &state,
1126                                    ErrorSet *errors,
1127                                    angle::EntryPoint entryPoint,
1128                                    GLuint buf,
1129                                    GLenum srcRGB,
1130                                    GLenum dstRGB,
1131                                    GLenum srcAlpha,
1132                                    GLenum dstAlpha)
1133 {
1134     if (!state.getExtensions().drawBuffersIndexedOES)
1135     {
1136         errors->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
1137         return false;
1138     }
1139 
1140     return ValidateBlendFuncSeparatei(state, errors, entryPoint, buf, srcRGB, dstRGB, srcAlpha,
1141                                       dstAlpha);
1142 }
1143 
ValidateBlendFunciOES(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLuint buf,GLenum src,GLenum dst)1144 bool ValidateBlendFunciOES(const PrivateState &state,
1145                            ErrorSet *errors,
1146                            angle::EntryPoint entryPoint,
1147                            GLuint buf,
1148                            GLenum src,
1149                            GLenum dst)
1150 {
1151     if (!state.getExtensions().drawBuffersIndexedOES)
1152     {
1153         errors->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
1154         return false;
1155     }
1156 
1157     return ValidateBlendFunci(state, errors, entryPoint, buf, src, dst);
1158 }
1159 
ValidateColorMaskiOES(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLuint index,GLboolean r,GLboolean g,GLboolean b,GLboolean a)1160 bool ValidateColorMaskiOES(const PrivateState &state,
1161                            ErrorSet *errors,
1162                            angle::EntryPoint entryPoint,
1163                            GLuint index,
1164                            GLboolean r,
1165                            GLboolean g,
1166                            GLboolean b,
1167                            GLboolean a)
1168 {
1169     if (!state.getExtensions().drawBuffersIndexedOES)
1170     {
1171         errors->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
1172         return false;
1173     }
1174 
1175     return ValidateColorMaski(state, errors, entryPoint, index, r, g, b, a);
1176 }
1177 
ValidateDisableiOES(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLenum target,GLuint index)1178 bool ValidateDisableiOES(const PrivateState &state,
1179                          ErrorSet *errors,
1180                          angle::EntryPoint entryPoint,
1181                          GLenum target,
1182                          GLuint index)
1183 {
1184     if (!state.getExtensions().drawBuffersIndexedOES)
1185     {
1186         errors->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
1187         return false;
1188     }
1189 
1190     return ValidateDisablei(state, errors, entryPoint, target, index);
1191 }
1192 
ValidateEnableiOES(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLenum target,GLuint index)1193 bool ValidateEnableiOES(const PrivateState &state,
1194                         ErrorSet *errors,
1195                         angle::EntryPoint entryPoint,
1196                         GLenum target,
1197                         GLuint index)
1198 {
1199     if (!state.getExtensions().drawBuffersIndexedOES)
1200     {
1201         errors->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
1202         return false;
1203     }
1204 
1205     return ValidateEnablei(state, errors, entryPoint, target, index);
1206 }
1207 
ValidateIsEnablediOES(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLenum target,GLuint index)1208 bool ValidateIsEnablediOES(const PrivateState &state,
1209                            ErrorSet *errors,
1210                            angle::EntryPoint entryPoint,
1211                            GLenum target,
1212                            GLuint index)
1213 {
1214     if (!state.getExtensions().drawBuffersIndexedOES)
1215     {
1216         errors->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
1217         return false;
1218     }
1219 
1220     return ValidateIsEnabledi(state, errors, entryPoint, target, index);
1221 }
1222 
ValidateProvokingVertexANGLE(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,ProvokingVertexConvention provokeModePacked)1223 bool ValidateProvokingVertexANGLE(const PrivateState &state,
1224                                   ErrorSet *errors,
1225                                   angle::EntryPoint entryPoint,
1226                                   ProvokingVertexConvention provokeModePacked)
1227 {
1228     if (!state.getExtensions().provokingVertexANGLE)
1229     {
1230         errors->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
1231         return false;
1232     }
1233 
1234     switch (provokeModePacked)
1235     {
1236         case ProvokingVertexConvention::FirstVertexConvention:
1237         case ProvokingVertexConvention::LastVertexConvention:
1238             break;
1239         default:
1240             errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidProvokingVertex);
1241             return false;
1242     }
1243 
1244     return true;
1245 }
1246 
ValidateGetInteger64vEXT(const Context * context,angle::EntryPoint entryPoint,GLenum pname,const GLint64 * data)1247 bool ValidateGetInteger64vEXT(const Context *context,
1248                               angle::EntryPoint entryPoint,
1249                               GLenum pname,
1250                               const GLint64 *data)
1251 {
1252     if (!context->getExtensions().disjointTimerQueryEXT)
1253     {
1254         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1255         return false;
1256     }
1257 
1258     GLenum nativeType      = GL_NONE;
1259     unsigned int numParams = 0;
1260     if (!ValidateStateQuery(context, entryPoint, pname, &nativeType, &numParams))
1261     {
1262         return false;
1263     }
1264 
1265     return true;
1266 }
1267 
ValidateCopyImageSubDataEXT(const Context * context,angle::EntryPoint entryPoint,GLuint srcName,GLenum srcTarget,GLint srcLevel,GLint srcX,GLint srcY,GLint srcZ,GLuint dstName,GLenum dstTarget,GLint dstLevel,GLint dstX,GLint dstY,GLint dstZ,GLsizei srcWidth,GLsizei srcHeight,GLsizei srcDepth)1268 bool ValidateCopyImageSubDataEXT(const Context *context,
1269                                  angle::EntryPoint entryPoint,
1270                                  GLuint srcName,
1271                                  GLenum srcTarget,
1272                                  GLint srcLevel,
1273                                  GLint srcX,
1274                                  GLint srcY,
1275                                  GLint srcZ,
1276                                  GLuint dstName,
1277                                  GLenum dstTarget,
1278                                  GLint dstLevel,
1279                                  GLint dstX,
1280                                  GLint dstY,
1281                                  GLint dstZ,
1282                                  GLsizei srcWidth,
1283                                  GLsizei srcHeight,
1284                                  GLsizei srcDepth)
1285 {
1286     if (!context->getExtensions().copyImageEXT)
1287     {
1288         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1289         return false;
1290     }
1291 
1292     return ValidateCopyImageSubDataBase(context, entryPoint, srcName, srcTarget, srcLevel, srcX,
1293                                         srcY, srcZ, dstName, dstTarget, dstLevel, dstX, dstY, dstZ,
1294                                         srcWidth, srcHeight, srcDepth);
1295 }
1296 
ValidateCopyImageSubDataOES(const Context * context,angle::EntryPoint entryPoint,GLuint srcName,GLenum srcTarget,GLint srcLevel,GLint srcX,GLint srcY,GLint srcZ,GLuint dstName,GLenum dstTarget,GLint dstLevel,GLint dstX,GLint dstY,GLint dstZ,GLsizei srcWidth,GLsizei srcHeight,GLsizei srcDepth)1297 bool ValidateCopyImageSubDataOES(const Context *context,
1298                                  angle::EntryPoint entryPoint,
1299                                  GLuint srcName,
1300                                  GLenum srcTarget,
1301                                  GLint srcLevel,
1302                                  GLint srcX,
1303                                  GLint srcY,
1304                                  GLint srcZ,
1305                                  GLuint dstName,
1306                                  GLenum dstTarget,
1307                                  GLint dstLevel,
1308                                  GLint dstX,
1309                                  GLint dstY,
1310                                  GLint dstZ,
1311                                  GLsizei srcWidth,
1312                                  GLsizei srcHeight,
1313                                  GLsizei srcDepth)
1314 {
1315     if (!context->getExtensions().copyImageOES)
1316     {
1317         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1318         return false;
1319     }
1320 
1321     return ValidateCopyImageSubDataBase(context, entryPoint, srcName, srcTarget, srcLevel, srcX,
1322                                         srcY, srcZ, dstName, dstTarget, dstLevel, dstX, dstY, dstZ,
1323                                         srcWidth, srcHeight, srcDepth);
1324 }
1325 
ValidateBufferStorageMemEXT(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLsizeiptr size,MemoryObjectID memory,GLuint64 offset)1326 bool ValidateBufferStorageMemEXT(const Context *context,
1327                                  angle::EntryPoint entryPoint,
1328                                  TextureType target,
1329                                  GLsizeiptr size,
1330                                  MemoryObjectID memory,
1331                                  GLuint64 offset)
1332 {
1333     if (!context->getExtensions().memoryObjectEXT)
1334     {
1335         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1336         return false;
1337     }
1338 
1339     UNIMPLEMENTED();
1340     return false;
1341 }
1342 
ValidateCreateMemoryObjectsEXT(const Context * context,angle::EntryPoint entryPoint,GLsizei n,const MemoryObjectID * memoryObjects)1343 bool ValidateCreateMemoryObjectsEXT(const Context *context,
1344                                     angle::EntryPoint entryPoint,
1345                                     GLsizei n,
1346                                     const MemoryObjectID *memoryObjects)
1347 {
1348     if (!context->getExtensions().memoryObjectEXT)
1349     {
1350         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1351         return false;
1352     }
1353 
1354     return ValidateGenOrDelete(context, entryPoint, n, memoryObjects);
1355 }
1356 
ValidateDeleteMemoryObjectsEXT(const Context * context,angle::EntryPoint entryPoint,GLsizei n,const MemoryObjectID * memoryObjects)1357 bool ValidateDeleteMemoryObjectsEXT(const Context *context,
1358                                     angle::EntryPoint entryPoint,
1359                                     GLsizei n,
1360                                     const MemoryObjectID *memoryObjects)
1361 {
1362     if (!context->getExtensions().memoryObjectEXT)
1363     {
1364         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1365         return false;
1366     }
1367 
1368     return ValidateGenOrDelete(context, entryPoint, n, memoryObjects);
1369 }
1370 
ValidateGetMemoryObjectParameterivEXT(const Context * context,angle::EntryPoint entryPoint,MemoryObjectID memoryObject,GLenum pname,const GLint * params)1371 bool ValidateGetMemoryObjectParameterivEXT(const Context *context,
1372                                            angle::EntryPoint entryPoint,
1373                                            MemoryObjectID memoryObject,
1374                                            GLenum pname,
1375                                            const GLint *params)
1376 {
1377     if (!context->getExtensions().memoryObjectEXT)
1378     {
1379         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1380         return false;
1381     }
1382 
1383     const MemoryObject *memory = context->getMemoryObject(memoryObject);
1384     if (memory == nullptr)
1385     {
1386         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidMemoryObject);
1387     }
1388 
1389     if (!IsValidMemoryObjectParamater(context, entryPoint, pname))
1390     {
1391         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidMemoryObjectParameter);
1392         return false;
1393     }
1394 
1395     return true;
1396 }
1397 
ValidateGetUnsignedBytevEXT(const Context * context,angle::EntryPoint entryPoint,GLenum pname,const GLubyte * data)1398 bool ValidateGetUnsignedBytevEXT(const Context *context,
1399                                  angle::EntryPoint entryPoint,
1400                                  GLenum pname,
1401                                  const GLubyte *data)
1402 {
1403     if (!context->getExtensions().memoryObjectEXT && !context->getExtensions().semaphoreEXT)
1404     {
1405         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1406         return false;
1407     }
1408 
1409     UNIMPLEMENTED();
1410     return false;
1411 }
1412 
ValidateGetUnsignedBytei_vEXT(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLuint index,const GLubyte * data)1413 bool ValidateGetUnsignedBytei_vEXT(const Context *context,
1414                                    angle::EntryPoint entryPoint,
1415                                    GLenum target,
1416                                    GLuint index,
1417                                    const GLubyte *data)
1418 {
1419     if (!context->getExtensions().memoryObjectEXT && !context->getExtensions().semaphoreEXT)
1420     {
1421         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1422         return false;
1423     }
1424 
1425     UNIMPLEMENTED();
1426     return false;
1427 }
1428 
ValidateIsMemoryObjectEXT(const Context * context,angle::EntryPoint entryPoint,MemoryObjectID memoryObject)1429 bool ValidateIsMemoryObjectEXT(const Context *context,
1430                                angle::EntryPoint entryPoint,
1431                                MemoryObjectID memoryObject)
1432 {
1433     if (!context->getExtensions().memoryObjectEXT)
1434     {
1435         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1436         return false;
1437     }
1438 
1439     return true;
1440 }
1441 
ValidateMemoryObjectParameterivEXT(const Context * context,angle::EntryPoint entryPoint,MemoryObjectID memoryObject,GLenum pname,const GLint * params)1442 bool ValidateMemoryObjectParameterivEXT(const Context *context,
1443                                         angle::EntryPoint entryPoint,
1444                                         MemoryObjectID memoryObject,
1445                                         GLenum pname,
1446                                         const GLint *params)
1447 {
1448     if (!context->getExtensions().memoryObjectEXT)
1449     {
1450         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1451         return false;
1452     }
1453 
1454     const MemoryObject *memory = context->getMemoryObject(memoryObject);
1455     if (memory == nullptr)
1456     {
1457         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidMemoryObject);
1458         return false;
1459     }
1460 
1461     if (memory->isImmutable())
1462     {
1463         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kImmutableMemoryObject);
1464         return false;
1465     }
1466 
1467     if (!IsValidMemoryObjectParamater(context, entryPoint, pname))
1468     {
1469         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidMemoryObjectParameter);
1470         return false;
1471     }
1472 
1473     return true;
1474 }
1475 
ValidateTexStorageMem2DEXT(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLsizei levels,GLenum internalFormat,GLsizei width,GLsizei height,MemoryObjectID memory,GLuint64 offset)1476 bool ValidateTexStorageMem2DEXT(const Context *context,
1477                                 angle::EntryPoint entryPoint,
1478                                 TextureType target,
1479                                 GLsizei levels,
1480                                 GLenum internalFormat,
1481                                 GLsizei width,
1482                                 GLsizei height,
1483                                 MemoryObjectID memory,
1484                                 GLuint64 offset)
1485 {
1486     if (!context->getExtensions().memoryObjectEXT)
1487     {
1488         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1489         return false;
1490     }
1491 
1492     if (context->getClientMajorVersion() < 3)
1493     {
1494         return ValidateES2TexStorageParametersBase(context, entryPoint, target, levels,
1495                                                    internalFormat, width, height);
1496     }
1497 
1498     ASSERT(context->getClientMajorVersion() >= 3);
1499     return ValidateES3TexStorage2DParameters(context, entryPoint, target, levels, internalFormat,
1500                                              width, height, 1);
1501 }
1502 
ValidateTexStorageMem3DEXT(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLsizei levels,GLenum internalFormat,GLsizei width,GLsizei height,GLsizei depth,MemoryObjectID memory,GLuint64 offset)1503 bool ValidateTexStorageMem3DEXT(const Context *context,
1504                                 angle::EntryPoint entryPoint,
1505                                 TextureType target,
1506                                 GLsizei levels,
1507                                 GLenum internalFormat,
1508                                 GLsizei width,
1509                                 GLsizei height,
1510                                 GLsizei depth,
1511                                 MemoryObjectID memory,
1512                                 GLuint64 offset)
1513 {
1514     if (!context->getExtensions().memoryObjectEXT)
1515     {
1516         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1517         return false;
1518     }
1519 
1520     UNIMPLEMENTED();
1521     return false;
1522 }
1523 
ValidateImportMemoryFdEXT(const Context * context,angle::EntryPoint entryPoint,MemoryObjectID memory,GLuint64 size,HandleType handleType,GLint fd)1524 bool ValidateImportMemoryFdEXT(const Context *context,
1525                                angle::EntryPoint entryPoint,
1526                                MemoryObjectID memory,
1527                                GLuint64 size,
1528                                HandleType handleType,
1529                                GLint fd)
1530 {
1531     if (!context->getExtensions().memoryObjectFdEXT)
1532     {
1533         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1534         return false;
1535     }
1536 
1537     switch (handleType)
1538     {
1539         case HandleType::OpaqueFd:
1540             break;
1541         default:
1542             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidHandleType);
1543             return false;
1544     }
1545 
1546     return true;
1547 }
1548 
ValidateImportMemoryZirconHandleANGLE(const Context * context,angle::EntryPoint entryPoint,MemoryObjectID memory,GLuint64 size,HandleType handleType,GLuint handle)1549 bool ValidateImportMemoryZirconHandleANGLE(const Context *context,
1550                                            angle::EntryPoint entryPoint,
1551                                            MemoryObjectID memory,
1552                                            GLuint64 size,
1553                                            HandleType handleType,
1554                                            GLuint handle)
1555 {
1556     if (!context->getExtensions().memoryObjectFuchsiaANGLE)
1557     {
1558         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1559         return false;
1560     }
1561 
1562     switch (handleType)
1563     {
1564         case HandleType::ZirconVmo:
1565             break;
1566         default:
1567             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidHandleType);
1568             return false;
1569     }
1570 
1571     return true;
1572 }
1573 
ValidateDeleteSemaphoresEXT(const Context * context,angle::EntryPoint entryPoint,GLsizei n,const SemaphoreID * semaphores)1574 bool ValidateDeleteSemaphoresEXT(const Context *context,
1575                                  angle::EntryPoint entryPoint,
1576                                  GLsizei n,
1577                                  const SemaphoreID *semaphores)
1578 {
1579     if (!context->getExtensions().semaphoreEXT)
1580     {
1581         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1582         return false;
1583     }
1584 
1585     return ValidateGenOrDelete(context, entryPoint, n, semaphores);
1586 }
1587 
ValidateGenSemaphoresEXT(const Context * context,angle::EntryPoint entryPoint,GLsizei n,const SemaphoreID * semaphores)1588 bool ValidateGenSemaphoresEXT(const Context *context,
1589                               angle::EntryPoint entryPoint,
1590                               GLsizei n,
1591                               const SemaphoreID *semaphores)
1592 {
1593     if (!context->getExtensions().semaphoreEXT)
1594     {
1595         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1596         return false;
1597     }
1598 
1599     return ValidateGenOrDelete(context, entryPoint, n, semaphores);
1600 }
1601 
ValidateGetSemaphoreParameterui64vEXT(const Context * context,angle::EntryPoint entryPoint,SemaphoreID semaphore,GLenum pname,const GLuint64 * params)1602 bool ValidateGetSemaphoreParameterui64vEXT(const Context *context,
1603                                            angle::EntryPoint entryPoint,
1604                                            SemaphoreID semaphore,
1605                                            GLenum pname,
1606                                            const GLuint64 *params)
1607 {
1608     if (!context->getExtensions().semaphoreEXT)
1609     {
1610         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1611         return false;
1612     }
1613 
1614     UNIMPLEMENTED();
1615     return false;
1616 }
1617 
ValidateIsSemaphoreEXT(const Context * context,angle::EntryPoint entryPoint,SemaphoreID semaphore)1618 bool ValidateIsSemaphoreEXT(const Context *context,
1619                             angle::EntryPoint entryPoint,
1620                             SemaphoreID semaphore)
1621 {
1622     if (!context->getExtensions().semaphoreEXT)
1623     {
1624         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1625         return false;
1626     }
1627 
1628     return true;
1629 }
1630 
ValidateSemaphoreParameterui64vEXT(const Context * context,angle::EntryPoint entryPoint,SemaphoreID semaphore,GLenum pname,const GLuint64 * params)1631 bool ValidateSemaphoreParameterui64vEXT(const Context *context,
1632                                         angle::EntryPoint entryPoint,
1633                                         SemaphoreID semaphore,
1634                                         GLenum pname,
1635                                         const GLuint64 *params)
1636 {
1637     if (!context->getExtensions().semaphoreEXT)
1638     {
1639         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1640         return false;
1641     }
1642 
1643     UNIMPLEMENTED();
1644     return false;
1645 }
1646 
ValidateSignalSemaphoreEXT(const Context * context,angle::EntryPoint entryPoint,SemaphoreID semaphore,GLuint numBufferBarriers,const BufferID * buffers,GLuint numTextureBarriers,const TextureID * textures,const GLenum * dstLayouts)1647 bool ValidateSignalSemaphoreEXT(const Context *context,
1648                                 angle::EntryPoint entryPoint,
1649                                 SemaphoreID semaphore,
1650                                 GLuint numBufferBarriers,
1651                                 const BufferID *buffers,
1652                                 GLuint numTextureBarriers,
1653                                 const TextureID *textures,
1654                                 const GLenum *dstLayouts)
1655 {
1656     if (!context->getExtensions().semaphoreEXT)
1657     {
1658         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1659         return false;
1660     }
1661 
1662     for (GLuint i = 0; i < numBufferBarriers; ++i)
1663     {
1664         if (!context->getBuffer(buffers[i]))
1665         {
1666             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidBufferName);
1667             return false;
1668         }
1669     }
1670 
1671     for (GLuint i = 0; i < numTextureBarriers; ++i)
1672     {
1673         if (!context->getTexture(textures[i]))
1674         {
1675             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidTextureName);
1676             return false;
1677         }
1678         if (!IsValidImageLayout(FromGLenum<ImageLayout>(dstLayouts[i])))
1679         {
1680             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidImageLayout);
1681             return false;
1682         }
1683     }
1684 
1685     return true;
1686 }
1687 
ValidateWaitSemaphoreEXT(const Context * context,angle::EntryPoint entryPoint,SemaphoreID semaphore,GLuint numBufferBarriers,const BufferID * buffers,GLuint numTextureBarriers,const TextureID * textures,const GLenum * srcLayouts)1688 bool ValidateWaitSemaphoreEXT(const Context *context,
1689                               angle::EntryPoint entryPoint,
1690                               SemaphoreID semaphore,
1691                               GLuint numBufferBarriers,
1692                               const BufferID *buffers,
1693                               GLuint numTextureBarriers,
1694                               const TextureID *textures,
1695                               const GLenum *srcLayouts)
1696 {
1697     if (!context->getExtensions().semaphoreEXT)
1698     {
1699         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1700         return false;
1701     }
1702 
1703     for (GLuint i = 0; i < numBufferBarriers; ++i)
1704     {
1705         if (!context->getBuffer(buffers[i]))
1706         {
1707             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidBufferName);
1708             return false;
1709         }
1710     }
1711 
1712     for (GLuint i = 0; i < numTextureBarriers; ++i)
1713     {
1714         if (!context->getTexture(textures[i]))
1715         {
1716             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidTextureName);
1717             return false;
1718         }
1719         if (!IsValidImageLayout(FromGLenum<ImageLayout>(srcLayouts[i])))
1720         {
1721             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidImageLayout);
1722             return false;
1723         }
1724     }
1725 
1726     return true;
1727 }
1728 
ValidateImportSemaphoreFdEXT(const Context * context,angle::EntryPoint entryPoint,SemaphoreID semaphore,HandleType handleType,GLint fd)1729 bool ValidateImportSemaphoreFdEXT(const Context *context,
1730                                   angle::EntryPoint entryPoint,
1731                                   SemaphoreID semaphore,
1732                                   HandleType handleType,
1733                                   GLint fd)
1734 {
1735     if (!context->getExtensions().semaphoreFdEXT)
1736     {
1737         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1738         return false;
1739     }
1740 
1741     switch (handleType)
1742     {
1743         case HandleType::OpaqueFd:
1744             break;
1745         default:
1746             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidHandleType);
1747             return false;
1748     }
1749 
1750     return true;
1751 }
1752 
ValidateGetTexParameterIivOES(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLenum pname,const GLint * params)1753 bool ValidateGetTexParameterIivOES(const Context *context,
1754                                    angle::EntryPoint entryPoint,
1755                                    TextureType target,
1756                                    GLenum pname,
1757                                    const GLint *params)
1758 {
1759     if (context->getClientMajorVersion() < 3)
1760     {
1761         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
1762     }
1763 
1764     if (!context->getExtensions().textureBorderClampOES)
1765     {
1766         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1767         return false;
1768     }
1769     return ValidateGetTexParameterBase(context, entryPoint, target, pname, nullptr);
1770 }
1771 
ValidateGetTexParameterIuivOES(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLenum pname,const GLuint * params)1772 bool ValidateGetTexParameterIuivOES(const Context *context,
1773                                     angle::EntryPoint entryPoint,
1774                                     TextureType target,
1775                                     GLenum pname,
1776                                     const GLuint *params)
1777 {
1778     if (context->getClientMajorVersion() < 3)
1779     {
1780         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
1781     }
1782 
1783     if (!context->getExtensions().textureBorderClampOES)
1784     {
1785         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1786     }
1787     return ValidateGetTexParameterBase(context, entryPoint, target, pname, nullptr);
1788 }
1789 
ValidateTexParameterIivOES(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLenum pname,const GLint * params)1790 bool ValidateTexParameterIivOES(const Context *context,
1791                                 angle::EntryPoint entryPoint,
1792                                 TextureType target,
1793                                 GLenum pname,
1794                                 const GLint *params)
1795 {
1796     if (context->getClientMajorVersion() < 3)
1797     {
1798         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
1799     }
1800 
1801     if (!context->getExtensions().textureBorderClampOES)
1802     {
1803         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1804         return false;
1805     }
1806     return ValidateTexParameterBase(context, entryPoint, target, pname, -1, true, params);
1807 }
1808 
ValidateTexParameterIuivOES(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLenum pname,const GLuint * params)1809 bool ValidateTexParameterIuivOES(const Context *context,
1810                                  angle::EntryPoint entryPoint,
1811                                  TextureType target,
1812                                  GLenum pname,
1813                                  const GLuint *params)
1814 {
1815     if (context->getClientMajorVersion() < 3)
1816     {
1817         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
1818     }
1819 
1820     if (!context->getExtensions().textureBorderClampOES)
1821     {
1822         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1823         return false;
1824     }
1825 
1826     return ValidateTexParameterBase(context, entryPoint, target, pname, -1, true, params);
1827 }
1828 
ValidateGetSamplerParameterIivOES(const Context * context,angle::EntryPoint entryPoint,SamplerID sampler,GLenum pname,const GLint * params)1829 bool ValidateGetSamplerParameterIivOES(const Context *context,
1830                                        angle::EntryPoint entryPoint,
1831                                        SamplerID sampler,
1832                                        GLenum pname,
1833                                        const GLint *params)
1834 {
1835     if (context->getClientMajorVersion() < 3)
1836     {
1837         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
1838     }
1839 
1840     if (!context->getExtensions().textureBorderClampOES)
1841     {
1842         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1843         return false;
1844     }
1845     return ValidateGetSamplerParameterBase(context, entryPoint, sampler, pname, nullptr, params);
1846 }
1847 
ValidateGetSamplerParameterIuivOES(const Context * context,angle::EntryPoint entryPoint,SamplerID sampler,GLenum pname,const GLuint * params)1848 bool ValidateGetSamplerParameterIuivOES(const Context *context,
1849                                         angle::EntryPoint entryPoint,
1850                                         SamplerID sampler,
1851                                         GLenum pname,
1852                                         const GLuint *params)
1853 {
1854     if (context->getClientMajorVersion() < 3)
1855     {
1856         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
1857     }
1858 
1859     if (!context->getExtensions().textureBorderClampOES)
1860     {
1861         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1862         return false;
1863     }
1864     return ValidateGetSamplerParameterBase(context, entryPoint, sampler, pname, nullptr, params);
1865 }
1866 
ValidateSamplerParameterIivOES(const Context * context,angle::EntryPoint entryPoint,SamplerID sampler,GLenum pname,const GLint * params)1867 bool ValidateSamplerParameterIivOES(const Context *context,
1868                                     angle::EntryPoint entryPoint,
1869                                     SamplerID sampler,
1870                                     GLenum pname,
1871                                     const GLint *params)
1872 {
1873     if (context->getClientMajorVersion() < 3)
1874     {
1875         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
1876     }
1877 
1878     if (!context->getExtensions().textureBorderClampOES)
1879     {
1880         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1881         return false;
1882     }
1883     return ValidateSamplerParameterBase(context, entryPoint, sampler, pname, -1, true, params);
1884 }
1885 
ValidateSamplerParameterIuivOES(const Context * context,angle::EntryPoint entryPoint,SamplerID sampler,GLenum pname,const GLuint * params)1886 bool ValidateSamplerParameterIuivOES(const Context *context,
1887                                      angle::EntryPoint entryPoint,
1888                                      SamplerID sampler,
1889                                      GLenum pname,
1890                                      const GLuint *params)
1891 {
1892     if (context->getClientMajorVersion() < 3)
1893     {
1894         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
1895     }
1896 
1897     if (!context->getExtensions().textureBorderClampOES)
1898     {
1899         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1900         return false;
1901     }
1902     return ValidateSamplerParameterBase(context, entryPoint, sampler, pname, -1, true, params);
1903 }
1904 
ValidateGetSamplerParameterIivEXT(const Context * context,angle::EntryPoint entryPoint,SamplerID samplerPacked,GLenum pname,const GLint * params)1905 bool ValidateGetSamplerParameterIivEXT(const Context *context,
1906                                        angle::EntryPoint entryPoint,
1907                                        SamplerID samplerPacked,
1908                                        GLenum pname,
1909                                        const GLint *params)
1910 {
1911     if (context->getClientMajorVersion() < 3)
1912     {
1913         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
1914     }
1915 
1916     if (!context->getExtensions().textureBorderClampEXT)
1917     {
1918         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1919         return false;
1920     }
1921     return ValidateGetSamplerParameterBase(context, entryPoint, samplerPacked, pname, nullptr,
1922                                            params);
1923 }
1924 
ValidateGetSamplerParameterIuivEXT(const Context * context,angle::EntryPoint entryPoint,SamplerID samplerPacked,GLenum pname,const GLuint * params)1925 bool ValidateGetSamplerParameterIuivEXT(const Context *context,
1926                                         angle::EntryPoint entryPoint,
1927                                         SamplerID samplerPacked,
1928                                         GLenum pname,
1929                                         const GLuint *params)
1930 {
1931     if (context->getClientMajorVersion() < 3)
1932     {
1933         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
1934     }
1935 
1936     if (!context->getExtensions().textureBorderClampEXT)
1937     {
1938         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1939         return false;
1940     }
1941     return ValidateGetSamplerParameterBase(context, entryPoint, samplerPacked, pname, nullptr,
1942                                            params);
1943 }
1944 
ValidateGetTexParameterIivEXT(const Context * context,angle::EntryPoint entryPoint,TextureType targetPacked,GLenum pname,const GLint * params)1945 bool ValidateGetTexParameterIivEXT(const Context *context,
1946                                    angle::EntryPoint entryPoint,
1947                                    TextureType targetPacked,
1948                                    GLenum pname,
1949                                    const GLint *params)
1950 {
1951     if (context->getClientMajorVersion() < 3)
1952     {
1953         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
1954     }
1955 
1956     if (!context->getExtensions().textureBorderClampEXT)
1957     {
1958         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1959         return false;
1960     }
1961     return ValidateGetTexParameterBase(context, entryPoint, targetPacked, pname, nullptr);
1962 }
1963 
ValidateGetTexParameterIuivEXT(const Context * context,angle::EntryPoint entryPoint,TextureType targetPacked,GLenum pname,const GLuint * params)1964 bool ValidateGetTexParameterIuivEXT(const Context *context,
1965                                     angle::EntryPoint entryPoint,
1966                                     TextureType targetPacked,
1967                                     GLenum pname,
1968                                     const GLuint *params)
1969 {
1970     if (context->getClientMajorVersion() < 3)
1971     {
1972         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
1973     }
1974 
1975     if (!context->getExtensions().textureBorderClampEXT)
1976     {
1977         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1978         return false;
1979     }
1980     return ValidateGetTexParameterBase(context, entryPoint, targetPacked, pname, nullptr);
1981 }
1982 
ValidateSamplerParameterIivEXT(const Context * context,angle::EntryPoint entryPoint,SamplerID samplerPacked,GLenum pname,const GLint * param)1983 bool ValidateSamplerParameterIivEXT(const Context *context,
1984                                     angle::EntryPoint entryPoint,
1985                                     SamplerID samplerPacked,
1986                                     GLenum pname,
1987                                     const GLint *param)
1988 {
1989     if (context->getClientMajorVersion() < 3)
1990     {
1991         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
1992     }
1993 
1994     if (!context->getExtensions().textureBorderClampEXT)
1995     {
1996         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1997         return false;
1998     }
1999     return ValidateSamplerParameterBase(context, entryPoint, samplerPacked, pname, -1, true, param);
2000 }
2001 
ValidateSamplerParameterIuivEXT(const Context * context,angle::EntryPoint entryPoint,SamplerID samplerPacked,GLenum pname,const GLuint * param)2002 bool ValidateSamplerParameterIuivEXT(const Context *context,
2003                                      angle::EntryPoint entryPoint,
2004                                      SamplerID samplerPacked,
2005                                      GLenum pname,
2006                                      const GLuint *param)
2007 {
2008     if (context->getClientMajorVersion() < 3)
2009     {
2010         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
2011     }
2012 
2013     if (!context->getExtensions().textureBorderClampEXT)
2014     {
2015         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
2016         return false;
2017     }
2018     return ValidateSamplerParameterBase(context, entryPoint, samplerPacked, pname, -1, true, param);
2019 }
2020 
ValidateTexParameterIivEXT(const Context * context,angle::EntryPoint entryPoint,TextureType targetPacked,GLenum pname,const GLint * params)2021 bool ValidateTexParameterIivEXT(const Context *context,
2022                                 angle::EntryPoint entryPoint,
2023                                 TextureType targetPacked,
2024                                 GLenum pname,
2025                                 const GLint *params)
2026 {
2027     if (context->getClientMajorVersion() < 3)
2028     {
2029         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
2030     }
2031 
2032     if (!context->getExtensions().textureBorderClampEXT)
2033     {
2034         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
2035         return false;
2036     }
2037     return ValidateTexParameterBase(context, entryPoint, targetPacked, pname, -1, true, params);
2038 }
2039 
ValidateTexParameterIuivEXT(const Context * context,angle::EntryPoint entryPoint,TextureType targetPacked,GLenum pname,const GLuint * params)2040 bool ValidateTexParameterIuivEXT(const Context *context,
2041                                  angle::EntryPoint entryPoint,
2042                                  TextureType targetPacked,
2043                                  GLenum pname,
2044                                  const GLuint *params)
2045 {
2046     if (context->getClientMajorVersion() < 3)
2047     {
2048         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
2049     }
2050 
2051     if (!context->getExtensions().textureBorderClampEXT)
2052     {
2053         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
2054         return false;
2055     }
2056     return ValidateTexParameterBase(context, entryPoint, targetPacked, pname, -1, true, params);
2057 }
2058 
ValidateImportSemaphoreZirconHandleANGLE(const Context * context,angle::EntryPoint entryPoint,SemaphoreID semaphore,HandleType handleType,GLuint handle)2059 bool ValidateImportSemaphoreZirconHandleANGLE(const Context *context,
2060                                               angle::EntryPoint entryPoint,
2061                                               SemaphoreID semaphore,
2062                                               HandleType handleType,
2063                                               GLuint handle)
2064 {
2065     if (!context->getExtensions().semaphoreFuchsiaANGLE)
2066     {
2067         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
2068         return false;
2069     }
2070 
2071     switch (handleType)
2072     {
2073         case HandleType::ZirconEvent:
2074             break;
2075         default:
2076             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidHandleType);
2077             return false;
2078     }
2079 
2080     return true;
2081 }
2082 
2083 namespace
2084 {
2085 enum class PLSExpectedStatus
2086 {
2087     Inactive,
2088     Active,
2089     Any
2090 };
2091 
ValidatePLSCommon(const Context * context,angle::EntryPoint entryPoint,PLSExpectedStatus expectedStatus)2092 bool ValidatePLSCommon(const Context *context,
2093                        angle::EntryPoint entryPoint,
2094                        PLSExpectedStatus expectedStatus)
2095 {
2096     // Check that the pixel local storage extension is enabled at all.
2097     if (!context->getExtensions().shaderPixelLocalStorageANGLE)
2098     {
2099         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPLSExtensionNotEnabled);
2100         return false;
2101     }
2102 
2103     Framebuffer *framebuffer = context->getState().getDrawFramebuffer();
2104     if (expectedStatus != PLSExpectedStatus::Active)
2105     {
2106         // INVALID_FRAMEBUFFER_OPERATION is generated if the default framebuffer object name 0 is
2107         // bound to DRAW_FRAMEBUFFER.
2108         if (framebuffer->id().value == 0)
2109         {
2110             ANGLE_VALIDATION_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION, kPLSDefaultFramebufferBound);
2111             return false;
2112         }
2113     }
2114 
2115     // INVALID_FRAMEBUFFER_OPERATION is generated if pixel local storage on the draw framebuffer is
2116     // in an interrupted state.
2117     const PixelLocalStorage *pls = framebuffer->peekPixelLocalStorage();
2118     if (pls != nullptr && pls->interruptCount() != 0)
2119     {
2120         ANGLE_VALIDATION_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION, kPLSInterrupted);
2121         return false;
2122     }
2123 
2124     if (expectedStatus == PLSExpectedStatus::Active)
2125     {
2126         // INVALID_OPERATION is generated if PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE is zero.
2127         if (context->getState().getPixelLocalStorageActivePlanes() == 0)
2128         {
2129             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPLSInactive);
2130             return false;
2131         }
2132     }
2133     else if (expectedStatus == PLSExpectedStatus::Inactive)
2134     {
2135         // INVALID_OPERATION is generated if PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE is nonzero.
2136         if (context->getState().getPixelLocalStorageActivePlanes() != 0)
2137         {
2138             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPLSActive);
2139             return false;
2140         }
2141     }
2142 
2143     return true;
2144 }
2145 
ValidatePLSCommon(const Context * context,angle::EntryPoint entryPoint,GLint plane,PLSExpectedStatus expectedStatus)2146 bool ValidatePLSCommon(const Context *context,
2147                        angle::EntryPoint entryPoint,
2148                        GLint plane,
2149                        PLSExpectedStatus expectedStatus)
2150 {
2151     if (!ValidatePLSCommon(context, entryPoint, expectedStatus))
2152     {
2153         return false;
2154     }
2155 
2156     // INVALID_VALUE is generated if <plane> < 0 or <plane> >= MAX_PIXEL_LOCAL_STORAGE_PLANES_ANGLE.
2157     if (plane < 0)
2158     {
2159         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kPLSPlaneLessThanZero);
2160         return false;
2161     }
2162     if (plane >= static_cast<GLint>(context->getCaps().maxPixelLocalStoragePlanes))
2163     {
2164         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kPLSPlaneOutOfRange);
2165         return false;
2166     }
2167 
2168     return true;
2169 }
2170 
ValidatePLSInternalformat(const Context * context,angle::EntryPoint entryPoint,GLenum internalformat)2171 bool ValidatePLSInternalformat(const Context *context,
2172                                angle::EntryPoint entryPoint,
2173                                GLenum internalformat)
2174 {
2175     // INVALID_ENUM is generated if <internalformat> is not one of the acceptable values in Table
2176     // X.2, or NONE.
2177     switch (internalformat)
2178     {
2179         case GL_RGBA8:
2180         case GL_RGBA8I:
2181         case GL_RGBA8UI:
2182         case GL_R32F:
2183         case GL_R32UI:
2184             return true;
2185         default:
2186             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kPLSInvalidInternalformat);
2187             return false;
2188     }
2189 }
2190 
ValidatePLSTextureType(const Context * context,angle::EntryPoint entryPoint,Texture * tex,size_t * textureDepth)2191 bool ValidatePLSTextureType(const Context *context,
2192                             angle::EntryPoint entryPoint,
2193                             Texture *tex,
2194                             size_t *textureDepth)
2195 {
2196     // INVALID_OPERATION is generated if <backingtexture> is nonzero
2197     // and not of type TEXTURE_2D or TEXTURE_2D_ARRAY.
2198     switch (tex->getType())
2199     {
2200         case TextureType::_2D:
2201             *textureDepth = 1;
2202             return true;
2203         case TextureType::_2DArray:
2204             *textureDepth = tex->getDepth(TextureTarget::_2DArray, 0);
2205             return true;
2206         default:
2207             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPLSInvalidTextureType);
2208             return false;
2209     }
2210 }
2211 
ValidatePLSActiveBlendFunc(const Context * context,angle::EntryPoint entryPoint,gl::BlendFactorType blendFunc)2212 bool ValidatePLSActiveBlendFunc(const Context *context,
2213                                 angle::EntryPoint entryPoint,
2214                                 gl::BlendFactorType blendFunc)
2215 {
2216     // INVALID_OPERATION is generated if BLEND_DST_ALPHA, BLEND_DST_RGB, BLEND_SRC_ALPHA, or
2217     // BLEND_SRC_RGB, for any draw buffer, is a blend function requiring the secondary color input,
2218     // as specified in EXT_blend_func_extended.
2219     ASSERT(context->getState().getExtensions().blendFuncExtendedEXT);
2220     switch (blendFunc)
2221     {
2222         case gl::BlendFactorType::Src1Color:
2223         case gl::BlendFactorType::OneMinusSrc1Color:
2224         case gl::BlendFactorType::Src1Alpha:
2225         case gl::BlendFactorType::OneMinusSrc1Alpha:
2226             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPLSSecondaryBlendEnabled);
2227             return false;
2228         default:
2229             return true;
2230     }
2231 }
ValidatePLSActiveBlendEquation(const Context * context,angle::EntryPoint entryPoint,gl::BlendEquationType blendEquation)2232 bool ValidatePLSActiveBlendEquation(const Context *context,
2233                                     angle::EntryPoint entryPoint,
2234                                     gl::BlendEquationType blendEquation)
2235 {
2236     // INVALID_OPERATION is generated if BLEND_EQUATION_RGB and/or BLEND_EQUATION_ALPHA is an
2237     // advanced blend equation defined in KHR_blend_equation_advanced.
2238     ASSERT(context->getState().getExtensions().blendEquationAdvancedKHR);
2239     switch (blendEquation)
2240     {
2241         case gl::BlendEquationType::Multiply:
2242         case gl::BlendEquationType::Screen:
2243         case gl::BlendEquationType::Overlay:
2244         case gl::BlendEquationType::Darken:
2245         case gl::BlendEquationType::Lighten:
2246         case gl::BlendEquationType::Colordodge:
2247         case gl::BlendEquationType::Colorburn:
2248         case gl::BlendEquationType::Hardlight:
2249         case gl::BlendEquationType::Softlight:
2250         case gl::BlendEquationType::Difference:
2251         case gl::BlendEquationType::Exclusion:
2252         case gl::BlendEquationType::HslHue:
2253         case gl::BlendEquationType::HslSaturation:
2254         case gl::BlendEquationType::HslColor:
2255         case gl::BlendEquationType::HslLuminosity:
2256             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPLSAdvancedBlendEnabled);
2257             return false;
2258         default:
2259             return true;
2260     }
2261 }
2262 
ValidatePLSLoadOperation(const Context * context,angle::EntryPoint entryPoint,GLenum loadop)2263 bool ValidatePLSLoadOperation(const Context *context, angle::EntryPoint entryPoint, GLenum loadop)
2264 {
2265     // INVALID_ENUM is generated if <loadops>[0..<n>-1] is not one of the Load Operations enumerated
2266     // in Table X.1.
2267     switch (loadop)
2268     {
2269         case GL_LOAD_OP_ZERO_ANGLE:
2270         case GL_LOAD_OP_CLEAR_ANGLE:
2271         case GL_LOAD_OP_LOAD_ANGLE:
2272         case GL_DONT_CARE:
2273             return true;
2274         default:
2275             ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kPLSInvalidLoadOperation, loadop);
2276             return false;
2277     }
2278 }
2279 
ValidatePLSStoreOperation(const Context * context,angle::EntryPoint entryPoint,GLenum storeop)2280 bool ValidatePLSStoreOperation(const Context *context, angle::EntryPoint entryPoint, GLenum storeop)
2281 {
2282     // INVALID_ENUM is generated if <storeops>[0..PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE-1] is not
2283     // one of the Store Operations enumerated in Table X.2.
2284     switch (storeop)
2285     {
2286         case GL_STORE_OP_STORE_ANGLE:
2287         case GL_DONT_CARE:
2288             return true;
2289         default:
2290             ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kPLSInvalidStoreOperation, storeop);
2291             return false;
2292     }
2293 }
2294 
ValidatePLSQueryCommon(const Context * context,angle::EntryPoint entryPoint,GLsizei paramCount,GLsizei bufSize,const void * params)2295 bool ValidatePLSQueryCommon(const Context *context,
2296                             angle::EntryPoint entryPoint,
2297                             GLsizei paramCount,
2298                             GLsizei bufSize,
2299                             const void *params)
2300 {
2301     // INVALID_OPERATION is generated if <bufSize> is not large enough to receive the requested
2302     // parameter.
2303     if (paramCount > bufSize)
2304     {
2305         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInsufficientParams);
2306         return false;
2307     }
2308     // INVALID_VALUE is generated if <params> is NULL.
2309     if (params == nullptr)
2310     {
2311         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kPLSParamsNULL);
2312         return false;
2313     }
2314     return true;
2315 }
2316 }  // namespace
2317 
ValidateFramebufferMemorylessPixelLocalStorageANGLE(const Context * context,angle::EntryPoint entryPoint,GLint plane,GLenum internalformat)2318 bool ValidateFramebufferMemorylessPixelLocalStorageANGLE(const Context *context,
2319                                                          angle::EntryPoint entryPoint,
2320                                                          GLint plane,
2321                                                          GLenum internalformat)
2322 {
2323     if (!ValidatePLSCommon(context, entryPoint, plane, PLSExpectedStatus::Any))
2324     {
2325         return false;
2326     }
2327 
2328     // INVALID_ENUM is generated if <internalformat> is not one of the acceptable values in Table
2329     // X.2, or NONE.
2330     if (internalformat != GL_NONE)
2331     {
2332         if (!ValidatePLSInternalformat(context, entryPoint, internalformat))
2333         {
2334             return false;
2335         }
2336     }
2337 
2338     return true;
2339 }
2340 
ValidateFramebufferTexturePixelLocalStorageANGLE(const Context * context,angle::EntryPoint entryPoint,GLint plane,TextureID backingtexture,GLint level,GLint layer)2341 bool ValidateFramebufferTexturePixelLocalStorageANGLE(const Context *context,
2342                                                       angle::EntryPoint entryPoint,
2343                                                       GLint plane,
2344                                                       TextureID backingtexture,
2345                                                       GLint level,
2346                                                       GLint layer)
2347 {
2348     if (!ValidatePLSCommon(context, entryPoint, plane, PLSExpectedStatus::Any))
2349     {
2350         return false;
2351     }
2352 
2353     if (backingtexture.value != 0)
2354     {
2355         Texture *tex = context->getTexture(backingtexture);
2356 
2357         // INVALID_OPERATION is generated if <backingtexture> is not the name of an existing
2358         // immutable texture object, or zero.
2359         if (!tex)
2360         {
2361             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidTextureName);
2362             return false;
2363         }
2364         if (!tex->getImmutableFormat())
2365         {
2366             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kTextureIsNotImmutable);
2367             return false;
2368         }
2369 
2370         // INVALID_OPERATION is generated if <backingtexture> is nonzero
2371         // and not of type GL_TEXTURE_2D or GL_TEXTURE_2D_ARRAY.
2372         size_t textureDepth;
2373         if (!ValidatePLSTextureType(context, entryPoint, tex, &textureDepth))
2374         {
2375             return false;
2376         }
2377 
2378         // INVALID_VALUE is generated if <backingtexture> is nonzero and <level> < 0.
2379         if (level < 0)
2380         {
2381             ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeLevel);
2382             return false;
2383         }
2384 
2385         // INVALID_VALUE is generated if <backingtexture> is nonzero and <level> >= the
2386         // immutable number of mipmap levels in <backingtexture>.
2387         if (static_cast<GLuint>(level) >= tex->getImmutableLevels())
2388         {
2389             ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kTextureLevelOutOfRange);
2390             return false;
2391         }
2392 
2393         // INVALID_VALUE is generated if <backingtexture> is nonzero and <layer> < 0.
2394         if (layer < 0)
2395         {
2396             ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeLayer);
2397             return false;
2398         }
2399 
2400         // INVALID_VALUE is generated if <backingtexture> is nonzero and <layer> >= the immutable
2401         // number of texture layers in <backingtexture>.
2402         if ((size_t)layer >= textureDepth)
2403         {
2404             ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kTextureLayerOutOfRange);
2405             return false;
2406         }
2407 
2408         // INVALID_ENUM is generated if <backingtexture> is nonzero and its internalformat is not
2409         // one of the acceptable values in Table X.2.
2410         ASSERT(tex->getImmutableFormat());
2411         GLenum internalformat = tex->getState().getBaseLevelDesc().format.info->internalFormat;
2412         if (!ValidatePLSInternalformat(context, entryPoint, internalformat))
2413         {
2414             return false;
2415         }
2416     }
2417 
2418     return true;
2419 }
2420 
ValidateFramebufferPixelLocalClearValuefvANGLE(const Context * context,angle::EntryPoint entryPoint,GLint plane,const GLfloat[])2421 bool ValidateFramebufferPixelLocalClearValuefvANGLE(const Context *context,
2422                                                     angle::EntryPoint entryPoint,
2423                                                     GLint plane,
2424                                                     const GLfloat[])
2425 {
2426     return ValidatePLSCommon(context, entryPoint, plane, PLSExpectedStatus::Inactive);
2427 }
2428 
ValidateFramebufferPixelLocalClearValueivANGLE(const Context * context,angle::EntryPoint entryPoint,GLint plane,const GLint[])2429 bool ValidateFramebufferPixelLocalClearValueivANGLE(const Context *context,
2430                                                     angle::EntryPoint entryPoint,
2431                                                     GLint plane,
2432                                                     const GLint[])
2433 {
2434     return ValidatePLSCommon(context, entryPoint, plane, PLSExpectedStatus::Inactive);
2435 }
2436 
ValidateFramebufferPixelLocalClearValueuivANGLE(const Context * context,angle::EntryPoint entryPoint,GLint plane,const GLuint[])2437 bool ValidateFramebufferPixelLocalClearValueuivANGLE(const Context *context,
2438                                                      angle::EntryPoint entryPoint,
2439                                                      GLint plane,
2440                                                      const GLuint[])
2441 {
2442     return ValidatePLSCommon(context, entryPoint, plane, PLSExpectedStatus::Inactive);
2443 }
2444 
ValidateBeginPixelLocalStorageANGLE(const Context * context,angle::EntryPoint entryPoint,GLsizei n,const GLenum loadops[])2445 bool ValidateBeginPixelLocalStorageANGLE(const Context *context,
2446                                          angle::EntryPoint entryPoint,
2447                                          GLsizei n,
2448                                          const GLenum loadops[])
2449 {
2450     if (!ValidatePLSCommon(context, entryPoint, PLSExpectedStatus::Inactive))
2451     {
2452         return false;
2453     }
2454 
2455     const State &state             = context->getState();
2456     const Framebuffer *framebuffer = state.getDrawFramebuffer();
2457 
2458     // INVALID_OPERATION is generated if the value of SAMPLE_BUFFERS is 1 (i.e., if rendering to a
2459     // multisampled framebuffer).
2460     if (framebuffer->getSamples(context) != 0)
2461     {
2462         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPLSMultisamplingEnabled);
2463         return false;
2464     }
2465 
2466     // INVALID_OPERATION is generated if DITHER is enabled.
2467     if (state.isDitherEnabled())
2468     {
2469         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPLSDitherEnabled);
2470         return false;
2471     }
2472 
2473     // INVALID_OPERATION is generated if TRANSFORM_FEEDBACK_ACTIVE is true.
2474     if (state.isTransformFeedbackActive())
2475     {
2476         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPLSTransformFeedbackActive);
2477         return false;
2478     }
2479 
2480     // INVALID_OPERATION is generated if QCOM_tiled_rendering is active.
2481     if (context->getPrivateState().isTiledRendering())
2482     {
2483         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPLSTiledRenderingActive);
2484         return false;
2485     }
2486 
2487     // INVALID_OPERATION is generated if BLEND_DST_ALPHA, BLEND_DST_RGB, BLEND_SRC_ALPHA, or
2488     // BLEND_SRC_RGB, for any draw buffer, is a blend function requiring the secondary color input,
2489     // as specified in EXT_blend_func_extended.
2490     if (state.getExtensions().blendFuncExtendedEXT)
2491     {
2492         for (GLsizei i = 0; i < state.getCaps().maxDrawBuffers; ++i)
2493         {
2494             const BlendStateExt &blend = state.getBlendStateExt();
2495             if (!ValidatePLSActiveBlendFunc(context, entryPoint, blend.getDstAlphaIndexed(i)) ||
2496                 !ValidatePLSActiveBlendFunc(context, entryPoint, blend.getDstColorIndexed(i)) ||
2497                 !ValidatePLSActiveBlendFunc(context, entryPoint, blend.getSrcAlphaIndexed(i)) ||
2498                 !ValidatePLSActiveBlendFunc(context, entryPoint, blend.getSrcColorIndexed(i)))
2499             {
2500                 return false;
2501             }
2502         }
2503     }
2504 
2505     // INVALID_OPERATION is generated if BLEND_EQUATION_RGB and/or BLEND_EQUATION_ALPHA is an
2506     // advanced blend equation defined in KHR_blend_equation_advanced.
2507     if (state.getExtensions().blendEquationAdvancedKHR)
2508     {
2509         if (!ValidatePLSActiveBlendEquation(context, entryPoint,
2510                                             state.getBlendStateExt().getEquationColorIndexed(0)) ||
2511             !ValidatePLSActiveBlendEquation(context, entryPoint,
2512                                             state.getBlendStateExt().getEquationAlphaIndexed(0)))
2513         {
2514             return false;
2515         }
2516     }
2517     // INVALID_VALUE is generated if <n> < 1 or <n> > MAX_PIXEL_LOCAL_STORAGE_PLANES_ANGLE.
2518     if (n < 1)
2519     {
2520         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kPLSPlanesLessThanOne);
2521         return false;
2522     }
2523     if (n > static_cast<GLsizei>(context->getCaps().maxPixelLocalStoragePlanes))
2524     {
2525         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kPLSPlanesOutOfRange);
2526         return false;
2527     }
2528 
2529     // INVALID_FRAMEBUFFER_OPERATION is generated if the draw framebuffer has an image attached to
2530     // any color attachment point on or after:
2531     //
2532     //   COLOR_ATTACHMENT0 + MAX_COMBINED_DRAW_BUFFERS_AND_PIXEL_LOCAL_STORAGE_PLANES_ANGLE - <n>
2533     //
2534     const Caps &caps = context->getCaps();
2535     for (int i = caps.maxCombinedDrawBuffersAndPixelLocalStoragePlanes - n; i < caps.maxDrawBuffers;
2536          ++i)
2537     {
2538         if (framebuffer->getColorAttachment(i))
2539         {
2540             ANGLE_VALIDATION_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION,
2541                                    kPLSMaxCombinedDrawBuffersAndPlanesExceded);
2542             return false;
2543         }
2544     }
2545 
2546     // INVALID_VALUE is generated if <loadops> is NULL.
2547     if (loadops == nullptr)
2548     {
2549         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kPLSLoadOpsNULL);
2550         return false;
2551     }
2552 
2553     const PixelLocalStorage *pls   = framebuffer->peekPixelLocalStorage();
2554     bool hasTextureBackedPLSPlanes = false;
2555     Extents textureBackedPLSExtents{};
2556 
2557     for (GLsizei i = 0; i < n; ++i)
2558     {
2559         // INVALID_ENUM is generated if <loadops>[0..<n>-1] is not one of the Load Operations
2560         // enumerated in Table X.1.
2561         if (!ValidatePLSLoadOperation(context, entryPoint, loadops[i]))
2562         {
2563             return false;
2564         }
2565 
2566         // INVALID_OPERATION is generated if a pixel local storage plane at index [0..<n>-1] is in a
2567         // deinitialized state.
2568         if (pls == nullptr || pls->getPlane(i).isDeinitialized())
2569         {
2570             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPLSEnablingDeinitializedPlane);
2571             return false;
2572         }
2573 
2574         // [ANGLE_shader_pixel_local_storage] Section 4.4.2.X "Configuring Pixel Local Storage
2575         // on a Framebuffer": When a texture object is deleted, any pixel local storage plane to
2576         // which it was bound is automatically converted to a memoryless plane of matching
2577         // internalformat.
2578         const PixelLocalStoragePlane &plane = pls->getPlane(i);
2579 
2580         Extents textureExtents;
2581         if (plane.getTextureImageExtents(context, &textureExtents))
2582         {
2583             // INVALID_OPERATION is generated if all enabled, texture-backed pixel local storage
2584             // planes do not have the same width and height.
2585             if (!hasTextureBackedPLSPlanes)
2586             {
2587                 textureBackedPLSExtents   = textureExtents;
2588                 hasTextureBackedPLSPlanes = true;
2589             }
2590             else if (textureExtents != textureBackedPLSExtents)
2591             {
2592                 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPLSMismatchedBackingTextureSizes);
2593                 return false;
2594             }
2595         }
2596         else
2597         {
2598             // INVALID_OPERATION is generated if <loadops>[0..<n>-1] is LOAD_OP_LOAD_ANGLE and the
2599             // pixel local storage plane at that same index is memoryless.
2600             if (loadops[i] == GL_LOAD_OP_LOAD_ANGLE)
2601             {
2602                 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPLSKeepingMemorylessPlane);
2603                 return false;
2604             }
2605         }
2606 
2607         if (!plane.isMemoryless())
2608         {
2609             ASSERT(plane.getTextureID() != TextureID());
2610 
2611             const ImageIndex &planeImageIdx = plane.getTextureImageIndex();
2612             ASSERT(planeImageIdx.getLayerCount() == 1);
2613             ASSERT(planeImageIdx.getLevelIndex() >= 0);
2614 
2615             // INVALID_OPERATION is generated if a single texture slice is bound to more than one
2616             // active pixel local storage plane.
2617             for (GLsizei j = i + 1; j < n; ++j)
2618             {
2619                 const PixelLocalStoragePlane &otherPlane = pls->getPlane(j);
2620                 if (!otherPlane.isMemoryless() &&
2621                     plane.getTextureID() == otherPlane.getTextureID() &&
2622                     planeImageIdx == otherPlane.getTextureImageIndex())
2623                 {
2624                     ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPLSSingleTexImageMultiplePlanes);
2625                     return false;
2626                 }
2627             }
2628 
2629             // INVALID_OPERATION is generated if a single texture slice is simultaneously bound to
2630             // an active pixel local storage plane and attached to an enabled drawbuffer.
2631             const GLuint maxDrawBuffersWithPLSPlanes = std::min<GLuint>(
2632                 caps.maxCombinedDrawBuffersAndPixelLocalStoragePlanes - n, caps.maxDrawBuffers);
2633             for (GLuint j = 0; j < maxDrawBuffersWithPLSPlanes; ++j)
2634             {
2635                 if (framebuffer->getDrawBufferMask().test(j) &&
2636                     framebuffer->getColorAttachment(j)->isTextureWithId(plane.getTextureID()))
2637                 {
2638                     // Compare the ImageIndex values for the PLS plane and framebuffer attachment
2639                     // manually; the framebuffer uses a layer index of -1 for texture2d attachments,
2640                     // whereas PLS uses a layer index of 0.
2641                     const ImageIndex &attachmentImageIdx =
2642                         framebuffer->getColorAttachment(j)->getTextureImageIndex();
2643                     ASSERT(attachmentImageIdx.getLayerCount() == 1);
2644                     if (planeImageIdx.getType() == attachmentImageIdx.getType() &&
2645                         planeImageIdx.getLevelIndex() == attachmentImageIdx.getLevelIndex() &&
2646                         planeImageIdx.getLayerIndex() ==
2647                             std::max(attachmentImageIdx.getLayerIndex(), 0))
2648                     {
2649                         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION,
2650                                                kPLSSingleTexImagePLSAndAttachment);
2651                         return false;
2652                     }
2653                 }
2654             }
2655         }
2656     }
2657 
2658     const FramebufferAttachment *firstAttachment =
2659         framebuffer->getState().getFirstNonNullAttachment();
2660     if (firstAttachment)
2661     {
2662         // INVALID_OPERATION is generated if the draw framebuffer has other attachments, and its
2663         // enabled, texture-backed pixel local storage planes do not have identical dimensions
2664         // with the rendering area.
2665         if (hasTextureBackedPLSPlanes &&
2666             textureBackedPLSExtents != framebuffer->getState().getAttachmentExtentsIntersection())
2667         {
2668             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPLSDimensionsDontMatchRenderingArea);
2669             return false;
2670         }
2671     }
2672     else
2673     {
2674         // INVALID_OPERATION is generated if the draw framebuffer has no attachments and no
2675         // enabled, texture-backed pixel local storage planes.
2676         if (!hasTextureBackedPLSPlanes)
2677         {
2678             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPLSNoAttachmentsNoTextureBacked);
2679             return false;
2680         }
2681     }
2682 
2683     return true;
2684 }
2685 
ValidateEndPixelLocalStorageANGLE(const Context * context,angle::EntryPoint entryPoint,GLsizei n,const GLenum storeops[])2686 bool ValidateEndPixelLocalStorageANGLE(const Context *context,
2687                                        angle::EntryPoint entryPoint,
2688                                        GLsizei n,
2689                                        const GLenum storeops[])
2690 {
2691     if (!ValidatePLSCommon(context, entryPoint, PLSExpectedStatus::Active))
2692     {
2693         return false;
2694     }
2695 
2696     // INVALID_VALUE is generated if <n> != PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE.
2697     if (n != context->getState().getPixelLocalStorageActivePlanes())
2698     {
2699         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kPLSNNotEqualActivePlanes);
2700         return false;
2701     }
2702 
2703     // INVALID_ENUM is generated if <storeops>[0..PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE-1] is not
2704     // one of the Store Operations enumerated in Table X.2.
2705     for (GLsizei i = 0; i < n; ++i)
2706     {
2707         if (!ValidatePLSStoreOperation(context, entryPoint, storeops[i]))
2708         {
2709             return false;
2710         }
2711     }
2712 
2713     return true;
2714 }
2715 
ValidatePixelLocalStorageBarrierANGLE(const Context * context,angle::EntryPoint entryPoint)2716 bool ValidatePixelLocalStorageBarrierANGLE(const Context *context, angle::EntryPoint entryPoint)
2717 {
2718     return ValidatePLSCommon(context, entryPoint, PLSExpectedStatus::Active);
2719 }
2720 
ValidateFramebufferPixelLocalStorageInterruptANGLE(const Context * context,angle::EntryPoint entryPoint)2721 bool ValidateFramebufferPixelLocalStorageInterruptANGLE(const Context *context,
2722                                                         angle::EntryPoint entryPoint)
2723 {
2724     // Check that the pixel local storage extension is enabled at all.
2725     if (!context->getExtensions().shaderPixelLocalStorageANGLE)
2726     {
2727         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPLSExtensionNotEnabled);
2728         return false;
2729     }
2730 
2731     // INVALID_FRAMEBUFFER_OPERATION is generated if the current interrupt count on the draw
2732     // framebuffer is greater than or equal to 255.
2733     const PixelLocalStorage *pls =
2734         context->getState().getDrawFramebuffer()->peekPixelLocalStorage();
2735     if (pls != nullptr && pls->interruptCount() >= 255)
2736     {
2737         ANGLE_VALIDATION_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION, kPLSInterruptOverflow);
2738         return false;
2739     }
2740 
2741     return true;
2742 }
2743 
ValidateFramebufferPixelLocalStorageRestoreANGLE(const Context * context,angle::EntryPoint entryPoint)2744 bool ValidateFramebufferPixelLocalStorageRestoreANGLE(const Context *context,
2745                                                       angle::EntryPoint entryPoint)
2746 {
2747     // Check that the pixel local storage extension is enabled at all.
2748     if (!context->getExtensions().shaderPixelLocalStorageANGLE)
2749     {
2750         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPLSExtensionNotEnabled);
2751         return false;
2752     }
2753 
2754     // This command is ignored when the default framebuffer object name 0 is bound.
2755     const Framebuffer *framebuffer = context->getState().getDrawFramebuffer();
2756     if (context->getState().getDrawFramebuffer()->id().value == 0)
2757     {
2758         return true;
2759     }
2760 
2761     // INVALID_FRAMEBUFFER_OPERATION is generated if pixel local storage on the draw framebuffer is
2762     // not in an interrupted state.
2763     const PixelLocalStorage *pls = framebuffer->peekPixelLocalStorage();
2764     if (pls == nullptr || pls->interruptCount() == 0)
2765     {
2766         ANGLE_VALIDATION_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION, kPLSNotInterrupted);
2767         return false;
2768     }
2769 
2770     return true;
2771 }
2772 
ValidateGetFramebufferPixelLocalStorageParameterfvANGLE(const Context * context,angle::EntryPoint entryPoint,GLint plane,GLenum pname,const GLfloat * params)2773 bool ValidateGetFramebufferPixelLocalStorageParameterfvANGLE(const Context *context,
2774                                                              angle::EntryPoint entryPoint,
2775                                                              GLint plane,
2776                                                              GLenum pname,
2777                                                              const GLfloat *params)
2778 {
2779     return ValidateGetFramebufferPixelLocalStorageParameterfvRobustANGLE(
2780         context, entryPoint, plane, pname, std::numeric_limits<GLsizei>::max(), nullptr, params);
2781 }
2782 
ValidateGetFramebufferPixelLocalStorageParameterivANGLE(const Context * context,angle::EntryPoint entryPoint,GLint plane,GLenum pname,const GLint * params)2783 bool ValidateGetFramebufferPixelLocalStorageParameterivANGLE(const Context *context,
2784                                                              angle::EntryPoint entryPoint,
2785                                                              GLint plane,
2786                                                              GLenum pname,
2787                                                              const GLint *params)
2788 {
2789     return ValidateGetFramebufferPixelLocalStorageParameterivRobustANGLE(
2790         context, entryPoint, plane, pname, std::numeric_limits<GLsizei>::max(), nullptr, params);
2791 }
2792 
ValidateGetFramebufferPixelLocalStorageParameterfvRobustANGLE(const Context * context,angle::EntryPoint entryPoint,GLint plane,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLfloat * params)2793 bool ValidateGetFramebufferPixelLocalStorageParameterfvRobustANGLE(const Context *context,
2794                                                                    angle::EntryPoint entryPoint,
2795                                                                    GLint plane,
2796                                                                    GLenum pname,
2797                                                                    GLsizei bufSize,
2798                                                                    const GLsizei *length,
2799                                                                    const GLfloat *params)
2800 {
2801     if (!ValidatePLSCommon(context, entryPoint, plane, PLSExpectedStatus::Any))
2802     {
2803         return false;
2804     }
2805     GLsizei paramCount = 0;
2806     switch (pname)
2807     {
2808         case GL_PIXEL_LOCAL_CLEAR_VALUE_FLOAT_ANGLE:
2809             paramCount = 4;
2810             break;
2811         default:
2812             // INVALID_ENUM is generated if <pname> is not in Table 6.Y, or if the command issued is
2813             // not the associated "Get Command" for <pname> in Table 6.Y.
2814             ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
2815             return false;
2816     }
2817     return ValidatePLSQueryCommon(context, entryPoint, paramCount, bufSize, params);
2818 }
2819 
ValidateGetFramebufferPixelLocalStorageParameterivRobustANGLE(const Context * context,angle::EntryPoint entryPoint,GLint plane,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLint * params)2820 bool ValidateGetFramebufferPixelLocalStorageParameterivRobustANGLE(const Context *context,
2821                                                                    angle::EntryPoint entryPoint,
2822                                                                    GLint plane,
2823                                                                    GLenum pname,
2824                                                                    GLsizei bufSize,
2825                                                                    const GLsizei *length,
2826                                                                    const GLint *params)
2827 {
2828     if (!ValidatePLSCommon(context, entryPoint, plane, PLSExpectedStatus::Any))
2829     {
2830         return false;
2831     }
2832     GLsizei paramCount = 0;
2833     switch (pname)
2834     {
2835         case GL_PIXEL_LOCAL_FORMAT_ANGLE:
2836         case GL_PIXEL_LOCAL_TEXTURE_NAME_ANGLE:
2837         case GL_PIXEL_LOCAL_TEXTURE_LEVEL_ANGLE:
2838         case GL_PIXEL_LOCAL_TEXTURE_LAYER_ANGLE:
2839             paramCount = 1;
2840             break;
2841         case GL_PIXEL_LOCAL_CLEAR_VALUE_INT_ANGLE:
2842         case GL_PIXEL_LOCAL_CLEAR_VALUE_UNSIGNED_INT_ANGLE:
2843             paramCount = 4;
2844             break;
2845         default:
2846             // INVALID_ENUM is generated if <pname> is not in Table 6.Y, or if the command issued is
2847             // not the associated "Get Command" for <pname> in Table 6.Y.
2848             ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
2849             return false;
2850     }
2851     return ValidatePLSQueryCommon(context, entryPoint, paramCount, bufSize, params);
2852 }
2853 
ValidateFramebufferFetchBarrierEXT(const Context * context,angle::EntryPoint entryPoint)2854 bool ValidateFramebufferFetchBarrierEXT(const Context *context, angle::EntryPoint entryPoint)
2855 {
2856     if (!context->getExtensions().shaderFramebufferFetchNonCoherentEXT)
2857     {
2858         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION,
2859                                kFramebufferFetchNonCoherentExtensionNotEnabled);
2860         return false;
2861     }
2862     return true;
2863 }
2864 
ValidatePatchParameteriEXT(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLenum pname,GLint value)2865 bool ValidatePatchParameteriEXT(const PrivateState &state,
2866                                 ErrorSet *errors,
2867                                 angle::EntryPoint entryPoint,
2868                                 GLenum pname,
2869                                 GLint value)
2870 {
2871     if (!state.getExtensions().tessellationShaderEXT)
2872     {
2873         errors->validationError(entryPoint, GL_INVALID_OPERATION, kTessellationShaderEXTNotEnabled);
2874         return false;
2875     }
2876 
2877     return ValidatePatchParameteriBase(state, errors, entryPoint, pname, value);
2878 }
2879 
ValidatePatchParameteriOES(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLenum pname,GLint value)2880 bool ValidatePatchParameteriOES(const PrivateState &state,
2881                                 ErrorSet *errors,
2882                                 angle::EntryPoint entryPoint,
2883                                 GLenum pname,
2884                                 GLint value)
2885 {
2886     if (!state.getExtensions().tessellationShaderOES)
2887     {
2888         errors->validationError(entryPoint, GL_INVALID_OPERATION, kTessellationShaderOESNotEnabled);
2889         return false;
2890     }
2891 
2892     return ValidatePatchParameteriBase(state, errors, entryPoint, pname, value);
2893 }
2894 
ValidateTexStorageMemFlags2DANGLE(const Context * context,angle::EntryPoint entryPoint,TextureType targetPacked,GLsizei levels,GLenum internalFormat,GLsizei width,GLsizei height,MemoryObjectID memoryPacked,GLuint64 offset,GLbitfield createFlags,GLbitfield usageFlags,const void * imageCreateInfoPNext)2895 bool ValidateTexStorageMemFlags2DANGLE(const Context *context,
2896                                        angle::EntryPoint entryPoint,
2897                                        TextureType targetPacked,
2898                                        GLsizei levels,
2899                                        GLenum internalFormat,
2900                                        GLsizei width,
2901                                        GLsizei height,
2902                                        MemoryObjectID memoryPacked,
2903                                        GLuint64 offset,
2904                                        GLbitfield createFlags,
2905                                        GLbitfield usageFlags,
2906                                        const void *imageCreateInfoPNext)
2907 {
2908     if (!context->getExtensions().memoryObjectFlagsANGLE)
2909     {
2910         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
2911         return false;
2912     }
2913 
2914     if (!ValidateTexStorageMem2DEXT(context, entryPoint, targetPacked, levels, internalFormat,
2915                                     width, height, memoryPacked, offset))
2916     {
2917         return false;
2918     }
2919 
2920     // |createFlags| and |usageFlags| must only have bits specified by the extension.
2921     constexpr GLbitfield kAllCreateFlags =
2922         GL_CREATE_SPARSE_BINDING_BIT_ANGLE | GL_CREATE_SPARSE_RESIDENCY_BIT_ANGLE |
2923         GL_CREATE_SPARSE_ALIASED_BIT_ANGLE | GL_CREATE_MUTABLE_FORMAT_BIT_ANGLE |
2924         GL_CREATE_CUBE_COMPATIBLE_BIT_ANGLE | GL_CREATE_ALIAS_BIT_ANGLE |
2925         GL_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT_ANGLE | GL_CREATE_2D_ARRAY_COMPATIBLE_BIT_ANGLE |
2926         GL_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT_ANGLE | GL_CREATE_EXTENDED_USAGE_BIT_ANGLE |
2927         GL_CREATE_PROTECTED_BIT_ANGLE | GL_CREATE_DISJOINT_BIT_ANGLE |
2928         GL_CREATE_CORNER_SAMPLED_BIT_ANGLE | GL_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_ANGLE |
2929         GL_CREATE_SUBSAMPLED_BIT_ANGLE;
2930 
2931     if ((createFlags & ~kAllCreateFlags) != 0)
2932     {
2933         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidExternalCreateFlags);
2934         return false;
2935     }
2936 
2937     constexpr GLbitfield kAllUsageFlags =
2938         GL_USAGE_TRANSFER_SRC_BIT_ANGLE | GL_USAGE_TRANSFER_DST_BIT_ANGLE |
2939         GL_USAGE_SAMPLED_BIT_ANGLE | GL_USAGE_STORAGE_BIT_ANGLE |
2940         GL_USAGE_COLOR_ATTACHMENT_BIT_ANGLE | GL_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT_ANGLE |
2941         GL_USAGE_TRANSIENT_ATTACHMENT_BIT_ANGLE | GL_USAGE_INPUT_ATTACHMENT_BIT_ANGLE |
2942         GL_USAGE_SHADING_RATE_IMAGE_BIT_ANGLE | GL_USAGE_FRAGMENT_DENSITY_MAP_BIT_ANGLE;
2943 
2944     if ((usageFlags & ~kAllUsageFlags) != 0)
2945     {
2946         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidExternalUsageFlags);
2947         return false;
2948     }
2949 
2950     return true;
2951 }
2952 
ValidateTexStorageMemFlags2DMultisampleANGLE(const Context * context,angle::EntryPoint entryPoint,TextureType targetPacked,GLsizei samples,GLenum internalFormat,GLsizei width,GLsizei height,GLboolean fixedSampleLocations,MemoryObjectID memoryPacked,GLuint64 offset,GLbitfield createFlags,GLbitfield usageFlags,const void * imageCreateInfoPNext)2953 bool ValidateTexStorageMemFlags2DMultisampleANGLE(const Context *context,
2954                                                   angle::EntryPoint entryPoint,
2955                                                   TextureType targetPacked,
2956                                                   GLsizei samples,
2957                                                   GLenum internalFormat,
2958                                                   GLsizei width,
2959                                                   GLsizei height,
2960                                                   GLboolean fixedSampleLocations,
2961                                                   MemoryObjectID memoryPacked,
2962                                                   GLuint64 offset,
2963                                                   GLbitfield createFlags,
2964                                                   GLbitfield usageFlags,
2965                                                   const void *imageCreateInfoPNext)
2966 {
2967     UNIMPLEMENTED();
2968     return false;
2969 }
2970 
ValidateTexStorageMemFlags3DANGLE(const Context * context,angle::EntryPoint entryPoint,TextureType targetPacked,GLsizei levels,GLenum internalFormat,GLsizei width,GLsizei height,GLsizei depth,MemoryObjectID memoryPacked,GLuint64 offset,GLbitfield createFlags,GLbitfield usageFlags,const void * imageCreateInfoPNext)2971 bool ValidateTexStorageMemFlags3DANGLE(const Context *context,
2972                                        angle::EntryPoint entryPoint,
2973                                        TextureType targetPacked,
2974                                        GLsizei levels,
2975                                        GLenum internalFormat,
2976                                        GLsizei width,
2977                                        GLsizei height,
2978                                        GLsizei depth,
2979                                        MemoryObjectID memoryPacked,
2980                                        GLuint64 offset,
2981                                        GLbitfield createFlags,
2982                                        GLbitfield usageFlags,
2983                                        const void *imageCreateInfoPNext)
2984 {
2985     UNIMPLEMENTED();
2986     return false;
2987 }
2988 
ValidateTexStorageMemFlags3DMultisampleANGLE(const Context * context,angle::EntryPoint entryPoint,TextureType targetPacked,GLsizei samples,GLenum internalFormat,GLsizei width,GLsizei height,GLsizei depth,GLboolean fixedSampleLocations,MemoryObjectID memoryPacked,GLuint64 offset,GLbitfield createFlags,GLbitfield usageFlags,const void * imageCreateInfoPNext)2989 bool ValidateTexStorageMemFlags3DMultisampleANGLE(const Context *context,
2990                                                   angle::EntryPoint entryPoint,
2991                                                   TextureType targetPacked,
2992                                                   GLsizei samples,
2993                                                   GLenum internalFormat,
2994                                                   GLsizei width,
2995                                                   GLsizei height,
2996                                                   GLsizei depth,
2997                                                   GLboolean fixedSampleLocations,
2998                                                   MemoryObjectID memoryPacked,
2999                                                   GLuint64 offset,
3000                                                   GLbitfield createFlags,
3001                                                   GLbitfield usageFlags,
3002                                                   const void *imageCreateInfoPNext)
3003 {
3004     UNIMPLEMENTED();
3005     return false;
3006 }
3007 
3008 // GL_EXT_buffer_storage
ValidateBufferStorageEXT(const Context * context,angle::EntryPoint entryPoint,BufferBinding targetPacked,GLsizeiptr size,const void * data,GLbitfield flags)3009 bool ValidateBufferStorageEXT(const Context *context,
3010                               angle::EntryPoint entryPoint,
3011                               BufferBinding targetPacked,
3012                               GLsizeiptr size,
3013                               const void *data,
3014                               GLbitfield flags)
3015 {
3016     if (!context->isValidBufferBinding(targetPacked))
3017     {
3018         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidBufferTypes);
3019         return false;
3020     }
3021 
3022     if (size <= 0)
3023     {
3024         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNonPositiveSize);
3025         return false;
3026     }
3027 
3028     constexpr GLbitfield kAllUsageFlags =
3029         (GL_DYNAMIC_STORAGE_BIT_EXT | GL_MAP_READ_BIT | GL_MAP_WRITE_BIT |
3030          GL_MAP_PERSISTENT_BIT_EXT | GL_MAP_COHERENT_BIT_EXT | GL_CLIENT_STORAGE_BIT_EXT);
3031     if ((flags & ~kAllUsageFlags) != 0)
3032     {
3033         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidBufferUsageFlags);
3034         return false;
3035     }
3036 
3037     if (((flags & GL_MAP_PERSISTENT_BIT_EXT) != 0) &&
3038         ((flags & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)) == 0))
3039     {
3040         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidBufferUsageFlags);
3041         return false;
3042     }
3043 
3044     if (((flags & GL_MAP_COHERENT_BIT_EXT) != 0) && ((flags & GL_MAP_PERSISTENT_BIT_EXT) == 0))
3045     {
3046         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidBufferUsageFlags);
3047         return false;
3048     }
3049 
3050     Buffer *buffer = context->getState().getTargetBuffer(targetPacked);
3051 
3052     if (buffer == nullptr)
3053     {
3054         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBufferNotBound);
3055         return false;
3056     }
3057 
3058     if (buffer->isImmutable())
3059     {
3060         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBufferImmutable);
3061         return false;
3062     }
3063 
3064     return true;
3065 }
3066 
3067 // GL_EXT_clear_texture
ValidateClearTexImageEXT(const Context * context,angle::EntryPoint entryPoint,TextureID texturePacked,GLint level,GLenum format,GLenum type,const void * data)3068 bool ValidateClearTexImageEXT(const Context *context,
3069                               angle::EntryPoint entryPoint,
3070                               TextureID texturePacked,
3071                               GLint level,
3072                               GLenum format,
3073                               GLenum type,
3074                               const void *data)
3075 {
3076     return ValidateClearTexImageCommon(context, entryPoint, texturePacked, level, std::nullopt,
3077                                        format, type, data);
3078 }
3079 
ValidateClearTexSubImageEXT(const Context * context,angle::EntryPoint entryPoint,TextureID texturePacked,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLsizei depth,GLenum format,GLenum type,const void * data)3080 bool ValidateClearTexSubImageEXT(const Context *context,
3081                                  angle::EntryPoint entryPoint,
3082                                  TextureID texturePacked,
3083                                  GLint level,
3084                                  GLint xoffset,
3085                                  GLint yoffset,
3086                                  GLint zoffset,
3087                                  GLsizei width,
3088                                  GLsizei height,
3089                                  GLsizei depth,
3090                                  GLenum format,
3091                                  GLenum type,
3092                                  const void *data)
3093 {
3094     return ValidateClearTexImageCommon(context, entryPoint, texturePacked, level,
3095                                        Box(xoffset, yoffset, zoffset, width, height, depth), format,
3096                                        type, data);
3097 }
3098 
3099 // GL_EXT_clip_control
ValidateClipControlEXT(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,ClipOrigin originPacked,ClipDepthMode depthPacked)3100 bool ValidateClipControlEXT(const PrivateState &state,
3101                             ErrorSet *errors,
3102                             angle::EntryPoint entryPoint,
3103                             ClipOrigin originPacked,
3104                             ClipDepthMode depthPacked)
3105 {
3106     if (!state.getExtensions().clipControlEXT)
3107     {
3108         errors->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
3109         return false;
3110     }
3111 
3112     if (originPacked == ClipOrigin::InvalidEnum)
3113     {
3114         errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidOriginEnum);
3115         return false;
3116     }
3117 
3118     if (depthPacked == ClipDepthMode::InvalidEnum)
3119     {
3120         errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidDepthEnum);
3121         return false;
3122     }
3123 
3124     return true;
3125 }
3126 
3127 // GL_EXT_external_buffer
ValidateBufferStorageExternalEXT(const Context * context,angle::EntryPoint entryPoint,BufferBinding targetPacked,GLintptr offset,GLsizeiptr size,GLeglClientBufferEXT clientBuffer,GLbitfield flags)3128 bool ValidateBufferStorageExternalEXT(const Context *context,
3129                                       angle::EntryPoint entryPoint,
3130                                       BufferBinding targetPacked,
3131                                       GLintptr offset,
3132                                       GLsizeiptr size,
3133                                       GLeglClientBufferEXT clientBuffer,
3134                                       GLbitfield flags)
3135 {
3136     if (!ValidateBufferStorageEXT(context, entryPoint, targetPacked, size, nullptr, flags))
3137     {
3138         return false;
3139     }
3140 
3141     if (offset != 0)
3142     {
3143         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kExternalBufferInvalidOffset);
3144         return false;
3145     }
3146 
3147     if (clientBuffer == nullptr && size > 0)
3148     {
3149         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kClientBufferInvalid);
3150         return false;
3151     }
3152 
3153     return true;
3154 }
3155 
ValidateNamedBufferStorageExternalEXT(const Context * context,angle::EntryPoint entryPoint,GLuint buffer,GLintptr offset,GLsizeiptr size,GLeglClientBufferEXT clientBuffer,GLbitfield flags)3156 bool ValidateNamedBufferStorageExternalEXT(const Context *context,
3157                                            angle::EntryPoint entryPoint,
3158                                            GLuint buffer,
3159                                            GLintptr offset,
3160                                            GLsizeiptr size,
3161                                            GLeglClientBufferEXT clientBuffer,
3162                                            GLbitfield flags)
3163 {
3164     UNIMPLEMENTED();
3165     return false;
3166 }
3167 
3168 // GL_ANGLE_polygon_mode
ValidatePolygonModeANGLE(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLenum face,PolygonMode modePacked)3169 bool ValidatePolygonModeANGLE(const PrivateState &state,
3170                               ErrorSet *errors,
3171                               angle::EntryPoint entryPoint,
3172                               GLenum face,
3173                               PolygonMode modePacked)
3174 {
3175     if (!state.getExtensions().polygonModeANGLE)
3176     {
3177         errors->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
3178         return false;
3179     }
3180 
3181     if (face != GL_FRONT_AND_BACK)
3182     {
3183         errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidCullMode);
3184         return false;
3185     }
3186 
3187     if (modePacked == PolygonMode::Point || modePacked == PolygonMode::InvalidEnum)
3188     {
3189         errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPolygonMode);
3190         return false;
3191     }
3192 
3193     return true;
3194 }
3195 
3196 // GL_NV_polygon_mode
ValidatePolygonModeNV(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLenum face,PolygonMode modePacked)3197 bool ValidatePolygonModeNV(const PrivateState &state,
3198                            ErrorSet *errors,
3199                            angle::EntryPoint entryPoint,
3200                            GLenum face,
3201                            PolygonMode modePacked)
3202 {
3203     if (!state.getExtensions().polygonModeNV)
3204     {
3205         errors->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
3206         return false;
3207     }
3208 
3209     if (face != GL_FRONT_AND_BACK)
3210     {
3211         errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidCullMode);
3212         return false;
3213     }
3214 
3215     if (modePacked == PolygonMode::InvalidEnum)
3216     {
3217         errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPolygonMode);
3218         return false;
3219     }
3220 
3221     return true;
3222 }
3223 
3224 // GL_EXT_polygon_offset_clamp
ValidatePolygonOffsetClampEXT(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLfloat factor,GLfloat units,GLfloat clamp)3225 bool ValidatePolygonOffsetClampEXT(const PrivateState &state,
3226                                    ErrorSet *errors,
3227                                    angle::EntryPoint entryPoint,
3228                                    GLfloat factor,
3229                                    GLfloat units,
3230                                    GLfloat clamp)
3231 {
3232     if (!state.getExtensions().polygonOffsetClampEXT)
3233     {
3234         errors->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
3235         return false;
3236     }
3237 
3238     return true;
3239 }
3240 
3241 // GL_EXT_primitive_bounding_box
ValidatePrimitiveBoundingBoxEXT(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLfloat minX,GLfloat minY,GLfloat minZ,GLfloat minW,GLfloat maxX,GLfloat maxY,GLfloat maxZ,GLfloat maxW)3242 bool ValidatePrimitiveBoundingBoxEXT(const PrivateState &state,
3243                                      ErrorSet *errors,
3244                                      angle::EntryPoint entryPoint,
3245                                      GLfloat minX,
3246                                      GLfloat minY,
3247                                      GLfloat minZ,
3248                                      GLfloat minW,
3249                                      GLfloat maxX,
3250                                      GLfloat maxY,
3251                                      GLfloat maxZ,
3252                                      GLfloat maxW)
3253 {
3254     if (!state.getExtensions().primitiveBoundingBoxEXT)
3255     {
3256         errors->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
3257         return false;
3258     }
3259 
3260     return true;
3261 }
3262 
3263 // GL_OES_primitive_bounding_box
ValidatePrimitiveBoundingBoxOES(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLfloat minX,GLfloat minY,GLfloat minZ,GLfloat minW,GLfloat maxX,GLfloat maxY,GLfloat maxZ,GLfloat maxW)3264 bool ValidatePrimitiveBoundingBoxOES(const PrivateState &state,
3265                                      ErrorSet *errors,
3266                                      angle::EntryPoint entryPoint,
3267                                      GLfloat minX,
3268                                      GLfloat minY,
3269                                      GLfloat minZ,
3270                                      GLfloat minW,
3271                                      GLfloat maxX,
3272                                      GLfloat maxY,
3273                                      GLfloat maxZ,
3274                                      GLfloat maxW)
3275 {
3276     if (!state.getExtensions().primitiveBoundingBoxOES)
3277     {
3278         errors->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
3279         return false;
3280     }
3281 
3282     return true;
3283 }
3284 
3285 // GL_OES_texture_storage_multisample_2d_array
ValidateTexStorage3DMultisampleOES(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLsizei samples,GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth,GLboolean fixedsamplelocations)3286 bool ValidateTexStorage3DMultisampleOES(const Context *context,
3287                                         angle::EntryPoint entryPoint,
3288                                         TextureType target,
3289                                         GLsizei samples,
3290                                         GLenum internalformat,
3291                                         GLsizei width,
3292                                         GLsizei height,
3293                                         GLsizei depth,
3294                                         GLboolean fixedsamplelocations)
3295 {
3296     if (!context->getExtensions().textureStorageMultisample2dArrayOES)
3297     {
3298         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3299         return false;
3300     }
3301 
3302     return ValidateTexStorage3DMultisampleBase(context, entryPoint, target, samples, internalformat,
3303                                                width, height, depth);
3304 }
3305 
3306 // GL_EXT_separate_shader_objects
ValidateActiveShaderProgramEXT(const Context * context,angle::EntryPoint entryPoint,ProgramPipelineID pipelinePacked,ShaderProgramID programPacked)3307 bool ValidateActiveShaderProgramEXT(const Context *context,
3308                                     angle::EntryPoint entryPoint,
3309                                     ProgramPipelineID pipelinePacked,
3310                                     ShaderProgramID programPacked)
3311 {
3312     if (!context->getExtensions().separateShaderObjectsEXT)
3313     {
3314         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3315         return false;
3316     }
3317 
3318     return ValidateActiveShaderProgramBase(context, entryPoint, pipelinePacked, programPacked);
3319 }
3320 
ValidateBindProgramPipelineEXT(const Context * context,angle::EntryPoint entryPoint,ProgramPipelineID pipelinePacked)3321 bool ValidateBindProgramPipelineEXT(const Context *context,
3322                                     angle::EntryPoint entryPoint,
3323                                     ProgramPipelineID pipelinePacked)
3324 {
3325     if (!context->getExtensions().separateShaderObjectsEXT)
3326     {
3327         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3328         return false;
3329     }
3330 
3331     return ValidateBindProgramPipelineBase(context, entryPoint, pipelinePacked);
3332 }
3333 
ValidateCreateShaderProgramvEXT(const Context * context,angle::EntryPoint entryPoint,ShaderType typePacked,GLsizei count,const GLchar ** strings)3334 bool ValidateCreateShaderProgramvEXT(const Context *context,
3335                                      angle::EntryPoint entryPoint,
3336                                      ShaderType typePacked,
3337                                      GLsizei count,
3338                                      const GLchar **strings)
3339 {
3340     if (!context->getExtensions().separateShaderObjectsEXT)
3341     {
3342         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3343         return false;
3344     }
3345 
3346     return ValidateCreateShaderProgramvBase(context, entryPoint, typePacked, count, strings);
3347 }
3348 
ValidateDeleteProgramPipelinesEXT(const Context * context,angle::EntryPoint entryPoint,GLsizei n,const ProgramPipelineID * pipelinesPacked)3349 bool ValidateDeleteProgramPipelinesEXT(const Context *context,
3350                                        angle::EntryPoint entryPoint,
3351                                        GLsizei n,
3352                                        const ProgramPipelineID *pipelinesPacked)
3353 {
3354     if (!context->getExtensions().separateShaderObjectsEXT)
3355     {
3356         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3357         return false;
3358     }
3359 
3360     return ValidateDeleteProgramPipelinesBase(context, entryPoint, n, pipelinesPacked);
3361 }
3362 
ValidateGenProgramPipelinesEXT(const Context * context,angle::EntryPoint entryPoint,GLsizei n,const ProgramPipelineID * pipelinesPacked)3363 bool ValidateGenProgramPipelinesEXT(const Context *context,
3364                                     angle::EntryPoint entryPoint,
3365                                     GLsizei n,
3366                                     const ProgramPipelineID *pipelinesPacked)
3367 {
3368     if (!context->getExtensions().separateShaderObjectsEXT)
3369     {
3370         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3371         return false;
3372     }
3373 
3374     return ValidateGenProgramPipelinesBase(context, entryPoint, n, pipelinesPacked);
3375 }
3376 
ValidateGetProgramPipelineInfoLogEXT(const Context * context,angle::EntryPoint entryPoint,ProgramPipelineID pipelinePacked,GLsizei bufSize,const GLsizei * length,const GLchar * infoLog)3377 bool ValidateGetProgramPipelineInfoLogEXT(const Context *context,
3378                                           angle::EntryPoint entryPoint,
3379                                           ProgramPipelineID pipelinePacked,
3380                                           GLsizei bufSize,
3381                                           const GLsizei *length,
3382                                           const GLchar *infoLog)
3383 {
3384     if (!context->getExtensions().separateShaderObjectsEXT)
3385     {
3386         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3387         return false;
3388     }
3389 
3390     return ValidateGetProgramPipelineInfoLogBase(context, entryPoint, pipelinePacked, bufSize,
3391                                                  length, infoLog);
3392 }
3393 
ValidateGetProgramPipelineivEXT(const Context * context,angle::EntryPoint entryPoint,ProgramPipelineID pipelinePacked,GLenum pname,const GLint * params)3394 bool ValidateGetProgramPipelineivEXT(const Context *context,
3395                                      angle::EntryPoint entryPoint,
3396                                      ProgramPipelineID pipelinePacked,
3397                                      GLenum pname,
3398                                      const GLint *params)
3399 {
3400     if (!context->getExtensions().separateShaderObjectsEXT)
3401     {
3402         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3403         return false;
3404     }
3405 
3406     return ValidateGetProgramPipelineivBase(context, entryPoint, pipelinePacked, pname, params);
3407 }
3408 
ValidateIsProgramPipelineEXT(const Context * context,angle::EntryPoint entryPoint,ProgramPipelineID pipelinePacked)3409 bool ValidateIsProgramPipelineEXT(const Context *context,
3410                                   angle::EntryPoint entryPoint,
3411                                   ProgramPipelineID pipelinePacked)
3412 {
3413     if (!context->getExtensions().separateShaderObjectsEXT)
3414     {
3415         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3416         return false;
3417     }
3418 
3419     return ValidateIsProgramPipelineBase(context, entryPoint, pipelinePacked);
3420 }
3421 
ValidateProgramParameteriEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,GLenum pname,GLint value)3422 bool ValidateProgramParameteriEXT(const Context *context,
3423                                   angle::EntryPoint entryPoint,
3424                                   ShaderProgramID programPacked,
3425                                   GLenum pname,
3426                                   GLint value)
3427 {
3428     if (!context->getExtensions().separateShaderObjectsEXT)
3429     {
3430         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3431         return false;
3432     }
3433 
3434     return ValidateProgramParameteriBase(context, entryPoint, programPacked, pname, value);
3435 }
3436 
ValidateProgramUniform1fEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLfloat v0)3437 bool ValidateProgramUniform1fEXT(const Context *context,
3438                                  angle::EntryPoint entryPoint,
3439                                  ShaderProgramID programPacked,
3440                                  UniformLocation locationPacked,
3441                                  GLfloat v0)
3442 {
3443     if (!context->getExtensions().separateShaderObjectsEXT)
3444     {
3445         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3446         return false;
3447     }
3448 
3449     return ValidateProgramUniform1fBase(context, entryPoint, programPacked, locationPacked, v0);
3450 }
3451 
ValidateProgramUniform1fvEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLfloat * value)3452 bool ValidateProgramUniform1fvEXT(const Context *context,
3453                                   angle::EntryPoint entryPoint,
3454                                   ShaderProgramID programPacked,
3455                                   UniformLocation locationPacked,
3456                                   GLsizei count,
3457                                   const GLfloat *value)
3458 {
3459     if (!context->getExtensions().separateShaderObjectsEXT)
3460     {
3461         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3462         return false;
3463     }
3464 
3465     return ValidateProgramUniform1fvBase(context, entryPoint, programPacked, locationPacked, count,
3466                                          value);
3467 }
3468 
ValidateProgramUniform1iEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLint v0)3469 bool ValidateProgramUniform1iEXT(const Context *context,
3470                                  angle::EntryPoint entryPoint,
3471                                  ShaderProgramID programPacked,
3472                                  UniformLocation locationPacked,
3473                                  GLint v0)
3474 {
3475     if (!context->getExtensions().separateShaderObjectsEXT)
3476     {
3477         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3478         return false;
3479     }
3480 
3481     return ValidateProgramUniform1iBase(context, entryPoint, programPacked, locationPacked, v0);
3482 }
3483 
ValidateProgramUniform1ivEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLint * value)3484 bool ValidateProgramUniform1ivEXT(const Context *context,
3485                                   angle::EntryPoint entryPoint,
3486                                   ShaderProgramID programPacked,
3487                                   UniformLocation locationPacked,
3488                                   GLsizei count,
3489                                   const GLint *value)
3490 {
3491     if (!context->getExtensions().separateShaderObjectsEXT)
3492     {
3493         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3494         return false;
3495     }
3496 
3497     return ValidateProgramUniform1ivBase(context, entryPoint, programPacked, locationPacked, count,
3498                                          value);
3499 }
3500 
ValidateProgramUniform1uiEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLuint v0)3501 bool ValidateProgramUniform1uiEXT(const Context *context,
3502                                   angle::EntryPoint entryPoint,
3503                                   ShaderProgramID programPacked,
3504                                   UniformLocation locationPacked,
3505                                   GLuint v0)
3506 {
3507     if (!context->getExtensions().separateShaderObjectsEXT)
3508     {
3509         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3510         return false;
3511     }
3512 
3513     return ValidateProgramUniform1uiBase(context, entryPoint, programPacked, locationPacked, v0);
3514 }
3515 
ValidateProgramUniform1uivEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLuint * value)3516 bool ValidateProgramUniform1uivEXT(const Context *context,
3517                                    angle::EntryPoint entryPoint,
3518                                    ShaderProgramID programPacked,
3519                                    UniformLocation locationPacked,
3520                                    GLsizei count,
3521                                    const GLuint *value)
3522 {
3523     if (!context->getExtensions().separateShaderObjectsEXT)
3524     {
3525         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3526         return false;
3527     }
3528 
3529     return ValidateProgramUniform1uivBase(context, entryPoint, programPacked, locationPacked, count,
3530                                           value);
3531 }
3532 
ValidateProgramUniform2fEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLfloat v0,GLfloat v1)3533 bool ValidateProgramUniform2fEXT(const Context *context,
3534                                  angle::EntryPoint entryPoint,
3535                                  ShaderProgramID programPacked,
3536                                  UniformLocation locationPacked,
3537                                  GLfloat v0,
3538                                  GLfloat v1)
3539 {
3540     if (!context->getExtensions().separateShaderObjectsEXT)
3541     {
3542         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3543         return false;
3544     }
3545 
3546     return ValidateProgramUniform2fBase(context, entryPoint, programPacked, locationPacked, v0, v1);
3547 }
3548 
ValidateProgramUniform2fvEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLfloat * value)3549 bool ValidateProgramUniform2fvEXT(const Context *context,
3550                                   angle::EntryPoint entryPoint,
3551                                   ShaderProgramID programPacked,
3552                                   UniformLocation locationPacked,
3553                                   GLsizei count,
3554                                   const GLfloat *value)
3555 {
3556     if (!context->getExtensions().separateShaderObjectsEXT)
3557     {
3558         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3559         return false;
3560     }
3561 
3562     return ValidateProgramUniform2fvBase(context, entryPoint, programPacked, locationPacked, count,
3563                                          value);
3564 }
3565 
ValidateProgramUniform2iEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLint v0,GLint v1)3566 bool ValidateProgramUniform2iEXT(const Context *context,
3567                                  angle::EntryPoint entryPoint,
3568                                  ShaderProgramID programPacked,
3569                                  UniformLocation locationPacked,
3570                                  GLint v0,
3571                                  GLint v1)
3572 {
3573     if (!context->getExtensions().separateShaderObjectsEXT)
3574     {
3575         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3576         return false;
3577     }
3578 
3579     return ValidateProgramUniform2iBase(context, entryPoint, programPacked, locationPacked, v0, v1);
3580 }
3581 
ValidateProgramUniform2ivEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLint * value)3582 bool ValidateProgramUniform2ivEXT(const Context *context,
3583                                   angle::EntryPoint entryPoint,
3584                                   ShaderProgramID programPacked,
3585                                   UniformLocation locationPacked,
3586                                   GLsizei count,
3587                                   const GLint *value)
3588 {
3589     if (!context->getExtensions().separateShaderObjectsEXT)
3590     {
3591         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3592         return false;
3593     }
3594 
3595     return ValidateProgramUniform2ivBase(context, entryPoint, programPacked, locationPacked, count,
3596                                          value);
3597 }
3598 
ValidateProgramUniform2uiEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLuint v0,GLuint v1)3599 bool ValidateProgramUniform2uiEXT(const Context *context,
3600                                   angle::EntryPoint entryPoint,
3601                                   ShaderProgramID programPacked,
3602                                   UniformLocation locationPacked,
3603                                   GLuint v0,
3604                                   GLuint v1)
3605 {
3606     if (!context->getExtensions().separateShaderObjectsEXT)
3607     {
3608         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3609         return false;
3610     }
3611 
3612     return ValidateProgramUniform2uiBase(context, entryPoint, programPacked, locationPacked, v0,
3613                                          v1);
3614 }
3615 
ValidateProgramUniform2uivEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLuint * value)3616 bool ValidateProgramUniform2uivEXT(const Context *context,
3617                                    angle::EntryPoint entryPoint,
3618                                    ShaderProgramID programPacked,
3619                                    UniformLocation locationPacked,
3620                                    GLsizei count,
3621                                    const GLuint *value)
3622 {
3623     if (!context->getExtensions().separateShaderObjectsEXT)
3624     {
3625         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3626         return false;
3627     }
3628 
3629     return ValidateProgramUniform2uivBase(context, entryPoint, programPacked, locationPacked, count,
3630                                           value);
3631 }
3632 
ValidateProgramUniform3fEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLfloat v0,GLfloat v1,GLfloat v2)3633 bool ValidateProgramUniform3fEXT(const Context *context,
3634                                  angle::EntryPoint entryPoint,
3635                                  ShaderProgramID programPacked,
3636                                  UniformLocation locationPacked,
3637                                  GLfloat v0,
3638                                  GLfloat v1,
3639                                  GLfloat v2)
3640 {
3641     if (!context->getExtensions().separateShaderObjectsEXT)
3642     {
3643         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3644         return false;
3645     }
3646 
3647     return ValidateProgramUniform3fBase(context, entryPoint, programPacked, locationPacked, v0, v1,
3648                                         v2);
3649 }
3650 
ValidateProgramUniform3fvEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLfloat * value)3651 bool ValidateProgramUniform3fvEXT(const Context *context,
3652                                   angle::EntryPoint entryPoint,
3653                                   ShaderProgramID programPacked,
3654                                   UniformLocation locationPacked,
3655                                   GLsizei count,
3656                                   const GLfloat *value)
3657 {
3658     if (!context->getExtensions().separateShaderObjectsEXT)
3659     {
3660         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3661         return false;
3662     }
3663 
3664     return ValidateProgramUniform3fvBase(context, entryPoint, programPacked, locationPacked, count,
3665                                          value);
3666 }
3667 
ValidateProgramUniform3iEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLint v0,GLint v1,GLint v2)3668 bool ValidateProgramUniform3iEXT(const Context *context,
3669                                  angle::EntryPoint entryPoint,
3670                                  ShaderProgramID programPacked,
3671                                  UniformLocation locationPacked,
3672                                  GLint v0,
3673                                  GLint v1,
3674                                  GLint v2)
3675 {
3676     if (!context->getExtensions().separateShaderObjectsEXT)
3677     {
3678         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3679         return false;
3680     }
3681 
3682     return ValidateProgramUniform3iBase(context, entryPoint, programPacked, locationPacked, v0, v1,
3683                                         v2);
3684 }
3685 
ValidateProgramUniform3ivEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLint * value)3686 bool ValidateProgramUniform3ivEXT(const Context *context,
3687                                   angle::EntryPoint entryPoint,
3688                                   ShaderProgramID programPacked,
3689                                   UniformLocation locationPacked,
3690                                   GLsizei count,
3691                                   const GLint *value)
3692 {
3693     if (!context->getExtensions().separateShaderObjectsEXT)
3694     {
3695         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3696         return false;
3697     }
3698 
3699     return ValidateProgramUniform3ivBase(context, entryPoint, programPacked, locationPacked, count,
3700                                          value);
3701 }
3702 
ValidateProgramUniform3uiEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLuint v0,GLuint v1,GLuint v2)3703 bool ValidateProgramUniform3uiEXT(const Context *context,
3704                                   angle::EntryPoint entryPoint,
3705                                   ShaderProgramID programPacked,
3706                                   UniformLocation locationPacked,
3707                                   GLuint v0,
3708                                   GLuint v1,
3709                                   GLuint v2)
3710 {
3711     if (!context->getExtensions().separateShaderObjectsEXT)
3712     {
3713         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3714         return false;
3715     }
3716 
3717     return ValidateProgramUniform3uiBase(context, entryPoint, programPacked, locationPacked, v0, v1,
3718                                          v2);
3719 }
3720 
ValidateProgramUniform3uivEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLuint * value)3721 bool ValidateProgramUniform3uivEXT(const Context *context,
3722                                    angle::EntryPoint entryPoint,
3723                                    ShaderProgramID programPacked,
3724                                    UniformLocation locationPacked,
3725                                    GLsizei count,
3726                                    const GLuint *value)
3727 {
3728     if (!context->getExtensions().separateShaderObjectsEXT)
3729     {
3730         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3731         return false;
3732     }
3733 
3734     return ValidateProgramUniform3uivBase(context, entryPoint, programPacked, locationPacked, count,
3735                                           value);
3736 }
3737 
ValidateProgramUniform4fEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLfloat v0,GLfloat v1,GLfloat v2,GLfloat v3)3738 bool ValidateProgramUniform4fEXT(const Context *context,
3739                                  angle::EntryPoint entryPoint,
3740                                  ShaderProgramID programPacked,
3741                                  UniformLocation locationPacked,
3742                                  GLfloat v0,
3743                                  GLfloat v1,
3744                                  GLfloat v2,
3745                                  GLfloat v3)
3746 {
3747     if (!context->getExtensions().separateShaderObjectsEXT)
3748     {
3749         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3750         return false;
3751     }
3752 
3753     return ValidateProgramUniform4fBase(context, entryPoint, programPacked, locationPacked, v0, v1,
3754                                         v2, v3);
3755 }
3756 
ValidateProgramUniform4fvEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLfloat * value)3757 bool ValidateProgramUniform4fvEXT(const Context *context,
3758                                   angle::EntryPoint entryPoint,
3759                                   ShaderProgramID programPacked,
3760                                   UniformLocation locationPacked,
3761                                   GLsizei count,
3762                                   const GLfloat *value)
3763 {
3764     if (!context->getExtensions().separateShaderObjectsEXT)
3765     {
3766         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3767         return false;
3768     }
3769 
3770     return ValidateProgramUniform4fvBase(context, entryPoint, programPacked, locationPacked, count,
3771                                          value);
3772 }
3773 
ValidateProgramUniform4iEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLint v0,GLint v1,GLint v2,GLint v3)3774 bool ValidateProgramUniform4iEXT(const Context *context,
3775                                  angle::EntryPoint entryPoint,
3776                                  ShaderProgramID programPacked,
3777                                  UniformLocation locationPacked,
3778                                  GLint v0,
3779                                  GLint v1,
3780                                  GLint v2,
3781                                  GLint v3)
3782 {
3783     if (!context->getExtensions().separateShaderObjectsEXT)
3784     {
3785         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3786         return false;
3787     }
3788 
3789     return ValidateProgramUniform4iBase(context, entryPoint, programPacked, locationPacked, v0, v1,
3790                                         v2, v3);
3791 }
3792 
ValidateProgramUniform4ivEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLint * value)3793 bool ValidateProgramUniform4ivEXT(const Context *context,
3794                                   angle::EntryPoint entryPoint,
3795                                   ShaderProgramID programPacked,
3796                                   UniformLocation locationPacked,
3797                                   GLsizei count,
3798                                   const GLint *value)
3799 {
3800     return ValidateProgramUniform4ivBase(context, entryPoint, programPacked, locationPacked, count,
3801                                          value);
3802 }
3803 
ValidateProgramUniform4uiEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLuint v0,GLuint v1,GLuint v2,GLuint v3)3804 bool ValidateProgramUniform4uiEXT(const Context *context,
3805                                   angle::EntryPoint entryPoint,
3806                                   ShaderProgramID programPacked,
3807                                   UniformLocation locationPacked,
3808                                   GLuint v0,
3809                                   GLuint v1,
3810                                   GLuint v2,
3811                                   GLuint v3)
3812 {
3813     if (!context->getExtensions().separateShaderObjectsEXT)
3814     {
3815         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3816         return false;
3817     }
3818 
3819     return ValidateProgramUniform4uiBase(context, entryPoint, programPacked, locationPacked, v0, v1,
3820                                          v2, v3);
3821 }
3822 
ValidateProgramUniform4uivEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLuint * value)3823 bool ValidateProgramUniform4uivEXT(const Context *context,
3824                                    angle::EntryPoint entryPoint,
3825                                    ShaderProgramID programPacked,
3826                                    UniformLocation locationPacked,
3827                                    GLsizei count,
3828                                    const GLuint *value)
3829 {
3830     return ValidateProgramUniform4uivBase(context, entryPoint, programPacked, locationPacked, count,
3831                                           value);
3832 }
3833 
ValidateProgramUniformMatrix2fvEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,GLboolean transpose,const GLfloat * value)3834 bool ValidateProgramUniformMatrix2fvEXT(const Context *context,
3835                                         angle::EntryPoint entryPoint,
3836                                         ShaderProgramID programPacked,
3837                                         UniformLocation locationPacked,
3838                                         GLsizei count,
3839                                         GLboolean transpose,
3840                                         const GLfloat *value)
3841 {
3842     if (!context->getExtensions().separateShaderObjectsEXT)
3843     {
3844         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3845         return false;
3846     }
3847 
3848     return ValidateProgramUniformMatrix2fvBase(context, entryPoint, programPacked, locationPacked,
3849                                                count, transpose, value);
3850 }
3851 
ValidateProgramUniformMatrix2x3fvEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,GLboolean transpose,const GLfloat * value)3852 bool ValidateProgramUniformMatrix2x3fvEXT(const Context *context,
3853                                           angle::EntryPoint entryPoint,
3854                                           ShaderProgramID programPacked,
3855                                           UniformLocation locationPacked,
3856                                           GLsizei count,
3857                                           GLboolean transpose,
3858                                           const GLfloat *value)
3859 {
3860     if (!context->getExtensions().separateShaderObjectsEXT)
3861     {
3862         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3863         return false;
3864     }
3865 
3866     return ValidateProgramUniformMatrix2x3fvBase(context, entryPoint, programPacked, locationPacked,
3867                                                  count, transpose, value);
3868 }
3869 
ValidateProgramUniformMatrix2x4fvEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,GLboolean transpose,const GLfloat * value)3870 bool ValidateProgramUniformMatrix2x4fvEXT(const Context *context,
3871                                           angle::EntryPoint entryPoint,
3872                                           ShaderProgramID programPacked,
3873                                           UniformLocation locationPacked,
3874                                           GLsizei count,
3875                                           GLboolean transpose,
3876                                           const GLfloat *value)
3877 {
3878     if (!context->getExtensions().separateShaderObjectsEXT)
3879     {
3880         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3881         return false;
3882     }
3883 
3884     return ValidateProgramUniformMatrix2x4fvBase(context, entryPoint, programPacked, locationPacked,
3885                                                  count, transpose, value);
3886 }
3887 
ValidateProgramUniformMatrix3fvEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,GLboolean transpose,const GLfloat * value)3888 bool ValidateProgramUniformMatrix3fvEXT(const Context *context,
3889                                         angle::EntryPoint entryPoint,
3890                                         ShaderProgramID programPacked,
3891                                         UniformLocation locationPacked,
3892                                         GLsizei count,
3893                                         GLboolean transpose,
3894                                         const GLfloat *value)
3895 {
3896     if (!context->getExtensions().separateShaderObjectsEXT)
3897     {
3898         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3899         return false;
3900     }
3901 
3902     return ValidateProgramUniformMatrix3fvBase(context, entryPoint, programPacked, locationPacked,
3903                                                count, transpose, value);
3904 }
3905 
ValidateProgramUniformMatrix3x2fvEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,GLboolean transpose,const GLfloat * value)3906 bool ValidateProgramUniformMatrix3x2fvEXT(const Context *context,
3907                                           angle::EntryPoint entryPoint,
3908                                           ShaderProgramID programPacked,
3909                                           UniformLocation locationPacked,
3910                                           GLsizei count,
3911                                           GLboolean transpose,
3912                                           const GLfloat *value)
3913 {
3914     if (!context->getExtensions().separateShaderObjectsEXT)
3915     {
3916         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3917         return false;
3918     }
3919 
3920     return ValidateProgramUniformMatrix3x2fvBase(context, entryPoint, programPacked, locationPacked,
3921                                                  count, transpose, value);
3922 }
3923 
ValidateProgramUniformMatrix3x4fvEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,GLboolean transpose,const GLfloat * value)3924 bool ValidateProgramUniformMatrix3x4fvEXT(const Context *context,
3925                                           angle::EntryPoint entryPoint,
3926                                           ShaderProgramID programPacked,
3927                                           UniformLocation locationPacked,
3928                                           GLsizei count,
3929                                           GLboolean transpose,
3930                                           const GLfloat *value)
3931 {
3932     if (!context->getExtensions().separateShaderObjectsEXT)
3933     {
3934         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3935         return false;
3936     }
3937 
3938     return ValidateProgramUniformMatrix3x4fvBase(context, entryPoint, programPacked, locationPacked,
3939                                                  count, transpose, value);
3940 }
3941 
ValidateProgramUniformMatrix4fvEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,GLboolean transpose,const GLfloat * value)3942 bool ValidateProgramUniformMatrix4fvEXT(const Context *context,
3943                                         angle::EntryPoint entryPoint,
3944                                         ShaderProgramID programPacked,
3945                                         UniformLocation locationPacked,
3946                                         GLsizei count,
3947                                         GLboolean transpose,
3948                                         const GLfloat *value)
3949 {
3950     if (!context->getExtensions().separateShaderObjectsEXT)
3951     {
3952         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3953         return false;
3954     }
3955 
3956     return ValidateProgramUniformMatrix4fvBase(context, entryPoint, programPacked, locationPacked,
3957                                                count, transpose, value);
3958 }
3959 
ValidateProgramUniformMatrix4x2fvEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,GLboolean transpose,const GLfloat * value)3960 bool ValidateProgramUniformMatrix4x2fvEXT(const Context *context,
3961                                           angle::EntryPoint entryPoint,
3962                                           ShaderProgramID programPacked,
3963                                           UniformLocation locationPacked,
3964                                           GLsizei count,
3965                                           GLboolean transpose,
3966                                           const GLfloat *value)
3967 {
3968     if (!context->getExtensions().separateShaderObjectsEXT)
3969     {
3970         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3971         return false;
3972     }
3973 
3974     return ValidateProgramUniformMatrix4x2fvBase(context, entryPoint, programPacked, locationPacked,
3975                                                  count, transpose, value);
3976 }
3977 
ValidateProgramUniformMatrix4x3fvEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,GLboolean transpose,const GLfloat * value)3978 bool ValidateProgramUniformMatrix4x3fvEXT(const Context *context,
3979                                           angle::EntryPoint entryPoint,
3980                                           ShaderProgramID programPacked,
3981                                           UniformLocation locationPacked,
3982                                           GLsizei count,
3983                                           GLboolean transpose,
3984                                           const GLfloat *value)
3985 {
3986     if (!context->getExtensions().separateShaderObjectsEXT)
3987     {
3988         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3989         return false;
3990     }
3991 
3992     return ValidateProgramUniformMatrix4x3fvBase(context, entryPoint, programPacked, locationPacked,
3993                                                  count, transpose, value);
3994 }
3995 
ValidateUseProgramStagesEXT(const Context * context,angle::EntryPoint entryPoint,ProgramPipelineID pipelinePacked,GLbitfield stages,ShaderProgramID programPacked)3996 bool ValidateUseProgramStagesEXT(const Context *context,
3997                                  angle::EntryPoint entryPoint,
3998                                  ProgramPipelineID pipelinePacked,
3999                                  GLbitfield stages,
4000                                  ShaderProgramID programPacked)
4001 {
4002     if (!context->getExtensions().separateShaderObjectsEXT)
4003     {
4004         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
4005         return false;
4006     }
4007 
4008     return ValidateUseProgramStagesBase(context, entryPoint, pipelinePacked, stages, programPacked);
4009 }
4010 
ValidateValidateProgramPipelineEXT(const Context * context,angle::EntryPoint entryPoint,ProgramPipelineID pipelinePacked)4011 bool ValidateValidateProgramPipelineEXT(const Context *context,
4012                                         angle::EntryPoint entryPoint,
4013                                         ProgramPipelineID pipelinePacked)
4014 {
4015     if (!context->getExtensions().separateShaderObjectsEXT)
4016     {
4017         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
4018         return false;
4019     }
4020 
4021     return ValidateValidateProgramPipelineBase(context, entryPoint, pipelinePacked);
4022 }
4023 
4024 // GL_EXT_debug_label
ValidateGetObjectLabelEXT(const Context * context,angle::EntryPoint entryPoint,GLenum type,GLuint object,GLsizei bufSize,const GLsizei * length,const GLchar * label)4025 bool ValidateGetObjectLabelEXT(const Context *context,
4026                                angle::EntryPoint entryPoint,
4027                                GLenum type,
4028                                GLuint object,
4029                                GLsizei bufSize,
4030                                const GLsizei *length,
4031                                const GLchar *label)
4032 {
4033     if (!context->getExtensions().debugLabelEXT)
4034     {
4035         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
4036         return false;
4037     }
4038 
4039     if (bufSize < 0)
4040     {
4041         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeBufSize);
4042         return false;
4043     }
4044 
4045     return ValidateObjectIdentifierAndName(context, entryPoint, type, object);
4046 }
4047 
ValidateLabelObjectEXT(const Context * context,angle::EntryPoint entryPoint,GLenum type,GLuint object,GLsizei length,const GLchar * label)4048 bool ValidateLabelObjectEXT(const Context *context,
4049                             angle::EntryPoint entryPoint,
4050                             GLenum type,
4051                             GLuint object,
4052                             GLsizei length,
4053                             const GLchar *label)
4054 {
4055     if (!context->getExtensions().debugLabelEXT)
4056     {
4057         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
4058         return false;
4059     }
4060 
4061     if (length < 0)
4062     {
4063         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeLength);
4064         return false;
4065     }
4066 
4067     return ValidateObjectIdentifierAndName(context, entryPoint, type, object);
4068 }
4069 
ValidateEGLImageTargetTextureStorageEXT(const Context * context,angle::EntryPoint entryPoint,GLuint texture,egl::ImageID image,const GLint * attrib_list)4070 bool ValidateEGLImageTargetTextureStorageEXT(const Context *context,
4071                                              angle::EntryPoint entryPoint,
4072                                              GLuint texture,
4073                                              egl::ImageID image,
4074                                              const GLint *attrib_list)
4075 {
4076     UNREACHABLE();
4077     return false;
4078 }
4079 
ValidateEGLImageTargetTexStorageEXT(const Context * context,angle::EntryPoint entryPoint,GLenum target,egl::ImageID image,const GLint * attrib_list)4080 bool ValidateEGLImageTargetTexStorageEXT(const Context *context,
4081                                          angle::EntryPoint entryPoint,
4082                                          GLenum target,
4083                                          egl::ImageID image,
4084                                          const GLint *attrib_list)
4085 {
4086     if (!context->getExtensions().EGLImageStorageEXT)
4087     {
4088         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
4089         return false;
4090     }
4091 
4092     gl::TextureType targetType = FromGLenum<TextureType>(target);
4093     switch (targetType)
4094     {
4095         case TextureType::External:
4096             if (!context->getExtensions().EGLImageExternalOES)
4097             {
4098                 ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, ToGLenum(targetType));
4099             }
4100             break;
4101         case TextureType::CubeMapArray:
4102             if (!context->getExtensions().textureCubeMapArrayAny())
4103             {
4104                 ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, ToGLenum(targetType));
4105             }
4106             break;
4107         case TextureType::_2D:
4108         case TextureType::_2DArray:
4109         case TextureType::_3D:
4110         case TextureType::CubeMap:
4111             break;
4112         default:
4113             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidTextureTarget);
4114             return false;
4115     }
4116 
4117     // Validate egl source image is valid
4118     egl::Image *imageObject = context->getDisplay()->getImage(image);
4119     if (!ValidateEGLImageObject(context, entryPoint, targetType, image))
4120     {
4121         return false;
4122     }
4123 
4124     if (attrib_list != nullptr)
4125     {
4126         for (const GLint *attrib = attrib_list; attrib[0] != GL_NONE; attrib += 2)
4127         {
4128             switch (attrib[0])
4129             {
4130                 case GL_SURFACE_COMPRESSION_EXT:
4131                     switch (attrib[1])
4132                     {
4133                         case GL_SURFACE_COMPRESSION_FIXED_RATE_NONE_EXT:
4134                             if (imageObject->isFixedRatedCompression(context))
4135                             {
4136                                 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kAttributeNotMatch);
4137                                 return false;
4138                             }
4139                             break;
4140                         case GL_SURFACE_COMPRESSION_FIXED_RATE_DEFAULT_EXT:
4141                             break;
4142                         default:
4143                             ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kAttributeNotValid);
4144                             return false;
4145                     }
4146                     break;
4147                 default:
4148                     ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kAttributeNotValid);
4149                     return false;
4150             }
4151         }
4152     }
4153 
4154     GLsizei levelCount    = imageObject->getLevelCount();
4155     Extents size          = imageObject->getExtents();
4156     GLsizei width         = static_cast<GLsizei>(size.width);
4157     GLsizei height        = static_cast<GLsizei>(size.height);
4158     GLsizei depth         = static_cast<GLsizei>(size.depth);
4159     GLenum internalformat = imageObject->getFormat().info->sizedInternalFormat;
4160 
4161     if (width < 1 || height < 1 || depth < 1 || levelCount < 1)
4162     {
4163         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kTextureSizeTooSmall);
4164         return false;
4165     }
4166 
4167     if (!ValidateES3TexStorageParametersLevel(context, entryPoint, targetType, levelCount, width,
4168                                               height, depth))
4169     {
4170         // Error already generated.
4171         return false;
4172     }
4173 
4174     if (targetType == TextureType::External)
4175     {
4176         const Caps &caps = context->getCaps();
4177         if (width > caps.max2DTextureSize || height > caps.max2DTextureSize)
4178         {
4179             ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kResourceMaxTextureSize);
4180             return false;
4181         }
4182     }
4183     else if (!ValidateES3TexStorageParametersExtent(context, entryPoint, targetType, levelCount,
4184                                                     width, height, depth))
4185     {
4186         // Error already generated.
4187         return false;
4188     }
4189 
4190     if (!ValidateES3TexStorageParametersTexObject(context, entryPoint, targetType))
4191     {
4192         // Error already generated.
4193         return false;
4194     }
4195 
4196     if (!ValidateES3TexStorageParametersFormat(context, entryPoint, targetType, levelCount,
4197                                                internalformat, width, height, depth))
4198     {
4199         // Error already generated.
4200         return false;
4201     }
4202 
4203     return true;
4204 }
4205 
ValidateAcquireTexturesANGLE(const Context * context,angle::EntryPoint entryPoint,GLuint numTextures,const TextureID * textures,const GLenum * layouts)4206 bool ValidateAcquireTexturesANGLE(const Context *context,
4207                                   angle::EntryPoint entryPoint,
4208                                   GLuint numTextures,
4209                                   const TextureID *textures,
4210                                   const GLenum *layouts)
4211 {
4212     if (!context->getExtensions().vulkanImageANGLE)
4213     {
4214         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
4215         return false;
4216     }
4217 
4218     for (GLuint i = 0; i < numTextures; ++i)
4219     {
4220         if (!context->getTexture(textures[i]))
4221         {
4222             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidTextureName);
4223             return false;
4224         }
4225         if (!IsValidImageLayout(FromGLenum<ImageLayout>(layouts[i])))
4226         {
4227             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidImageLayout);
4228             return false;
4229         }
4230     }
4231 
4232     return true;
4233 }
4234 
ValidateReleaseTexturesANGLE(const Context * context,angle::EntryPoint entryPoint,GLuint numTextures,const TextureID * textures,const GLenum * layouts)4235 bool ValidateReleaseTexturesANGLE(const Context *context,
4236                                   angle::EntryPoint entryPoint,
4237                                   GLuint numTextures,
4238                                   const TextureID *textures,
4239                                   const GLenum *layouts)
4240 {
4241     if (!context->getExtensions().vulkanImageANGLE)
4242     {
4243         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
4244         return false;
4245     }
4246     for (GLuint i = 0; i < numTextures; ++i)
4247     {
4248         if (!context->getTexture(textures[i]))
4249         {
4250             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidTextureName);
4251             return false;
4252         }
4253     }
4254 
4255     return true;
4256 }
4257 
ValidateFramebufferParameteriMESA(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLenum pname,GLint param)4258 bool ValidateFramebufferParameteriMESA(const Context *context,
4259                                        angle::EntryPoint entryPoint,
4260                                        GLenum target,
4261                                        GLenum pname,
4262                                        GLint param)
4263 {
4264     if (pname != GL_FRAMEBUFFER_FLIP_Y_MESA)
4265     {
4266         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidPname);
4267         return false;
4268     }
4269     return ValidateFramebufferParameteriBase(context, entryPoint, target, pname, param);
4270 }
4271 
ValidateGetFramebufferParameterivMESA(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLenum pname,const GLint * params)4272 bool ValidateGetFramebufferParameterivMESA(const Context *context,
4273                                            angle::EntryPoint entryPoint,
4274                                            GLenum target,
4275                                            GLenum pname,
4276                                            const GLint *params)
4277 {
4278     if (pname != GL_FRAMEBUFFER_FLIP_Y_MESA)
4279     {
4280         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidPname);
4281         return false;
4282     }
4283     return ValidateGetFramebufferParameterivBase(context, entryPoint, target, pname, params);
4284 }
4285 
4286 // GL_AMD_performance_monitor
ValidateBeginPerfMonitorAMD(const Context * context,angle::EntryPoint entryPoint,GLuint monitor)4287 bool ValidateBeginPerfMonitorAMD(const Context *context,
4288                                  angle::EntryPoint entryPoint,
4289                                  GLuint monitor)
4290 {
4291     if (!context->getExtensions().performanceMonitorAMD)
4292     {
4293         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
4294         return false;
4295     }
4296 
4297     return true;
4298 }
4299 
ValidateDeletePerfMonitorsAMD(const Context * context,angle::EntryPoint entryPoint,GLsizei n,const GLuint * monitors)4300 bool ValidateDeletePerfMonitorsAMD(const Context *context,
4301                                    angle::EntryPoint entryPoint,
4302                                    GLsizei n,
4303                                    const GLuint *monitors)
4304 {
4305     if (!context->getExtensions().performanceMonitorAMD)
4306     {
4307         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
4308         return false;
4309     }
4310 
4311     // Note: ANGLE does not really create monitor objects or track ids.
4312     return true;
4313 }
4314 
ValidateEndPerfMonitorAMD(const Context * context,angle::EntryPoint entryPoint,GLuint monitor)4315 bool ValidateEndPerfMonitorAMD(const Context *context, angle::EntryPoint entryPoint, GLuint monitor)
4316 {
4317     if (!context->getExtensions().performanceMonitorAMD)
4318     {
4319         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
4320         return false;
4321     }
4322 
4323     if (!context->getState().isPerfMonitorActive())
4324     {
4325         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPerfMonitorNotActive);
4326         return false;
4327     }
4328 
4329     return true;
4330 }
4331 
ValidateGenPerfMonitorsAMD(const Context * context,angle::EntryPoint entryPoint,GLsizei n,const GLuint * monitors)4332 bool ValidateGenPerfMonitorsAMD(const Context *context,
4333                                 angle::EntryPoint entryPoint,
4334                                 GLsizei n,
4335                                 const GLuint *monitors)
4336 {
4337     if (!context->getExtensions().performanceMonitorAMD)
4338     {
4339         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
4340         return false;
4341     }
4342 
4343     return true;
4344 }
4345 
ValidateGetPerfMonitorCounterDataAMD(const Context * context,angle::EntryPoint entryPoint,GLuint monitor,GLenum pname,GLsizei dataSize,const GLuint * data,const GLint * bytesWritten)4346 bool ValidateGetPerfMonitorCounterDataAMD(const Context *context,
4347                                           angle::EntryPoint entryPoint,
4348                                           GLuint monitor,
4349                                           GLenum pname,
4350                                           GLsizei dataSize,
4351                                           const GLuint *data,
4352                                           const GLint *bytesWritten)
4353 {
4354     if (!context->getExtensions().performanceMonitorAMD)
4355     {
4356         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
4357         return false;
4358     }
4359 
4360     if (monitor != 0)
4361     {
4362         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidPerfMonitor);
4363         return false;
4364     }
4365 
4366     switch (pname)
4367     {
4368         case GL_PERFMON_RESULT_AVAILABLE_AMD:
4369         case GL_PERFMON_RESULT_SIZE_AMD:
4370         case GL_PERFMON_RESULT_AMD:
4371             break;
4372 
4373         default:
4374             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidPname);
4375             return false;
4376     }
4377 
4378     return true;
4379 }
4380 
ValidateGetPerfMonitorCounterInfoAMD(const Context * context,angle::EntryPoint entryPoint,GLuint group,GLuint counter,GLenum pname,const void * data)4381 bool ValidateGetPerfMonitorCounterInfoAMD(const Context *context,
4382                                           angle::EntryPoint entryPoint,
4383                                           GLuint group,
4384                                           GLuint counter,
4385                                           GLenum pname,
4386                                           const void *data)
4387 {
4388     if (!context->getExtensions().performanceMonitorAMD)
4389     {
4390         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
4391         return false;
4392     }
4393 
4394     const angle::PerfMonitorCounterGroups &groups = context->getPerfMonitorCounterGroups();
4395 
4396     if (group >= groups.size())
4397     {
4398         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidPerfMonitorGroup);
4399         return false;
4400     }
4401 
4402     if (counter >= groups[group].counters.size())
4403     {
4404         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidPerfMonitorCounter);
4405         return false;
4406     }
4407 
4408     switch (pname)
4409     {
4410         case GL_COUNTER_TYPE_AMD:
4411         case GL_COUNTER_RANGE_AMD:
4412             break;
4413 
4414         default:
4415             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidPname);
4416             return false;
4417     }
4418 
4419     return true;
4420 }
4421 
ValidateGetPerfMonitorCounterStringAMD(const Context * context,angle::EntryPoint entryPoint,GLuint group,GLuint counter,GLsizei bufSize,const GLsizei * length,const GLchar * counterString)4422 bool ValidateGetPerfMonitorCounterStringAMD(const Context *context,
4423                                             angle::EntryPoint entryPoint,
4424                                             GLuint group,
4425                                             GLuint counter,
4426                                             GLsizei bufSize,
4427                                             const GLsizei *length,
4428                                             const GLchar *counterString)
4429 {
4430     if (!context->getExtensions().performanceMonitorAMD)
4431     {
4432         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
4433         return false;
4434     }
4435 
4436     const angle::PerfMonitorCounterGroups &groups = context->getPerfMonitorCounterGroups();
4437 
4438     if (group >= groups.size())
4439     {
4440         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidPerfMonitorGroup);
4441         return false;
4442     }
4443 
4444     if (counter >= groups[group].counters.size())
4445     {
4446         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidPerfMonitorCounter);
4447         return false;
4448     }
4449 
4450     return true;
4451 }
4452 
ValidateGetPerfMonitorCountersAMD(const Context * context,angle::EntryPoint entryPoint,GLuint group,const GLint * numCounters,const GLint * maxActiveCounters,GLsizei counterSize,const GLuint * counters)4453 bool ValidateGetPerfMonitorCountersAMD(const Context *context,
4454                                        angle::EntryPoint entryPoint,
4455                                        GLuint group,
4456                                        const GLint *numCounters,
4457                                        const GLint *maxActiveCounters,
4458                                        GLsizei counterSize,
4459                                        const GLuint *counters)
4460 {
4461     if (!context->getExtensions().performanceMonitorAMD)
4462     {
4463         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
4464         return false;
4465     }
4466 
4467     const angle::PerfMonitorCounterGroups &groups = context->getPerfMonitorCounterGroups();
4468 
4469     if (group >= groups.size())
4470     {
4471         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidPerfMonitorGroup);
4472         return false;
4473     }
4474 
4475     return true;
4476 }
4477 
ValidateGetPerfMonitorGroupStringAMD(const Context * context,angle::EntryPoint entryPoint,GLuint group,GLsizei bufSize,const GLsizei * length,const GLchar * groupString)4478 bool ValidateGetPerfMonitorGroupStringAMD(const Context *context,
4479                                           angle::EntryPoint entryPoint,
4480                                           GLuint group,
4481                                           GLsizei bufSize,
4482                                           const GLsizei *length,
4483                                           const GLchar *groupString)
4484 {
4485     if (!context->getExtensions().performanceMonitorAMD)
4486     {
4487         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
4488         return false;
4489     }
4490 
4491     const angle::PerfMonitorCounterGroups &groups = context->getPerfMonitorCounterGroups();
4492 
4493     if (group >= groups.size())
4494     {
4495         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidPerfMonitorGroup);
4496         return false;
4497     }
4498 
4499     return true;
4500 }
4501 
ValidateGetPerfMonitorGroupsAMD(const Context * context,angle::EntryPoint entryPoint,const GLint * numGroups,GLsizei groupsSize,const GLuint * groups)4502 bool ValidateGetPerfMonitorGroupsAMD(const Context *context,
4503                                      angle::EntryPoint entryPoint,
4504                                      const GLint *numGroups,
4505                                      GLsizei groupsSize,
4506                                      const GLuint *groups)
4507 {
4508     if (!context->getExtensions().performanceMonitorAMD)
4509     {
4510         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
4511         return false;
4512     }
4513 
4514     return true;
4515 }
4516 
ValidateSelectPerfMonitorCountersAMD(const Context * context,angle::EntryPoint entryPoint,GLuint monitor,GLboolean enable,GLuint group,GLint numCounters,const GLuint * counterList)4517 bool ValidateSelectPerfMonitorCountersAMD(const Context *context,
4518                                           angle::EntryPoint entryPoint,
4519                                           GLuint monitor,
4520                                           GLboolean enable,
4521                                           GLuint group,
4522                                           GLint numCounters,
4523                                           const GLuint *counterList)
4524 {
4525     if (!context->getExtensions().performanceMonitorAMD)
4526     {
4527         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
4528         return false;
4529     }
4530 
4531     UNIMPLEMENTED();
4532     return false;
4533 }
4534 
ValidateShadingRateQCOM(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLenum rate)4535 bool ValidateShadingRateQCOM(const PrivateState &state,
4536                              ErrorSet *errors,
4537                              angle::EntryPoint entryPoint,
4538                              GLenum rate)
4539 {
4540     if (!state.getExtensions().shadingRateQCOM)
4541     {
4542         errors->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
4543         return false;
4544     }
4545 
4546     gl::ShadingRate shadingRate = gl::FromGLenum<gl::ShadingRate>(rate);
4547     if (shadingRate == gl::ShadingRate::Undefined || shadingRate == gl::ShadingRate::InvalidEnum)
4548     {
4549         errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidShadingRate);
4550         return false;
4551     }
4552 
4553     return true;
4554 }
4555 
ValidateLogicOpANGLE(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,LogicalOperation opcodePacked)4556 bool ValidateLogicOpANGLE(const PrivateState &state,
4557                           ErrorSet *errors,
4558                           angle::EntryPoint entryPoint,
4559                           LogicalOperation opcodePacked)
4560 {
4561     if (!state.getExtensions().logicOpANGLE)
4562     {
4563         errors->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
4564         return false;
4565     }
4566 
4567     return ValidateLogicOpCommon(state, errors, entryPoint, opcodePacked);
4568 }
4569 
ValidateFramebufferFoveationConfigQCOM(const Context * context,angle::EntryPoint entryPoint,FramebufferID framebufferPacked,GLuint numLayers,GLuint focalPointsPerLayer,GLuint requestedFeatures,const GLuint * providedFeatures)4570 bool ValidateFramebufferFoveationConfigQCOM(const Context *context,
4571                                             angle::EntryPoint entryPoint,
4572                                             FramebufferID framebufferPacked,
4573                                             GLuint numLayers,
4574                                             GLuint focalPointsPerLayer,
4575                                             GLuint requestedFeatures,
4576                                             const GLuint *providedFeatures)
4577 {
4578     Framebuffer *framebuffer = context->getFramebuffer(framebufferPacked);
4579 
4580     // INVALID_VALUE is generated by FramebufferFoveationConfigQCOM if 'fbo' is not a valid
4581     // framebuffer.
4582     if (framebuffer == nullptr)
4583     {
4584         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidFramebufferName);
4585         return false;
4586     }
4587 
4588     // INVALID_VALUE is generated by FramebufferFoveationConfigQCOM if 'numLayers' is greater than
4589     // GL_MAX_ARRAY_TEXTURE_LAYERS - 1.
4590     if (numLayers > static_cast<GLuint>(context->getState().getCaps().maxArrayTextureLayers) - 1)
4591     {
4592         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kFramebufferFoveationLayersExceedMaxArrayLayers);
4593         return false;
4594     }
4595 
4596     // INVALID_VALUE is generated by FramebufferFoveationConfigQCOM if 'numFocalPoints' is greater
4597     // than implementation can support.
4598     if (focalPointsPerLayer > gl::IMPLEMENTATION_MAX_FOCAL_POINTS)
4599     {
4600         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kFocalPointsExceedMaxFocalPoints);
4601         return false;
4602     }
4603 
4604     // INVALID_OPERATION is generated by FramebufferFoveationConfigQCOM if it is called for a fbo
4605     // that has already been cofigured for foveated rendering.
4606     if (framebuffer->isFoveationConfigured())
4607     {
4608         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kFramebufferFoveationAlreadyConfigured);
4609         return false;
4610     }
4611 
4612     return true;
4613 }
4614 
ValidateFramebufferFoveationParametersQCOM(const Context * context,angle::EntryPoint entryPoint,FramebufferID framebufferPacked,GLuint layer,GLuint focalPoint,GLfloat focalX,GLfloat focalY,GLfloat gainX,GLfloat gainY,GLfloat foveaArea)4615 bool ValidateFramebufferFoveationParametersQCOM(const Context *context,
4616                                                 angle::EntryPoint entryPoint,
4617                                                 FramebufferID framebufferPacked,
4618                                                 GLuint layer,
4619                                                 GLuint focalPoint,
4620                                                 GLfloat focalX,
4621                                                 GLfloat focalY,
4622                                                 GLfloat gainX,
4623                                                 GLfloat gainY,
4624                                                 GLfloat foveaArea)
4625 {
4626     Framebuffer *framebuffer = context->getFramebuffer(framebufferPacked);
4627 
4628     // INVALID_VALUE is generated by FramebufferFoveationParametersQCOM if 'fbo' is not a valid
4629     // framebuffer.
4630     if (framebuffer == nullptr)
4631     {
4632         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidFramebufferName);
4633         return false;
4634     }
4635 
4636     // INVALID_OPERATION is generated by FramebufferFoveationParametersQCOM if 'fbo' has not been
4637     // configured for foveated rendering.
4638     if (!framebuffer->isFoveationConfigured())
4639     {
4640         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kFramebufferFoveationNotConfigured);
4641         return false;
4642     }
4643 
4644     // INVALID_VALUE is generated by FramebufferFoveationParametersQCOM if 'layer' is greater than
4645     // or equal to the numLayers that the fbo was previously configured for in
4646     // FramebufferFoveationConfigQCOM.
4647     if (layer >= gl::IMPLEMENTATION_MAX_NUM_LAYERS)
4648     {
4649         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kFramebufferFoveationLayersExceedMaxArrayLayers);
4650         return false;
4651     }
4652 
4653     // INVALID_VALUE is generated by FramebufferFoveationParametersQCOM if 'numFocalPoints' is
4654     // greater than implementation can support. INVALID_OPERATION is generated by
4655     if (focalPoint >= gl::IMPLEMENTATION_MAX_FOCAL_POINTS)
4656     {
4657         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kFocalPointsExceedMaxFocalPoints);
4658         return false;
4659     }
4660     return true;
4661 }
4662 
ValidateTextureFoveationParametersQCOM(const Context * context,angle::EntryPoint entryPoint,TextureID texturePacked,GLuint layer,GLuint focalPoint,GLfloat focalX,GLfloat focalY,GLfloat gainX,GLfloat gainY,GLfloat foveaArea)4663 bool ValidateTextureFoveationParametersQCOM(const Context *context,
4664                                             angle::EntryPoint entryPoint,
4665                                             TextureID texturePacked,
4666                                             GLuint layer,
4667                                             GLuint focalPoint,
4668                                             GLfloat focalX,
4669                                             GLfloat focalY,
4670                                             GLfloat gainX,
4671                                             GLfloat gainY,
4672                                             GLfloat foveaArea)
4673 {
4674     Texture *texture = context->getTexture(texturePacked);
4675 
4676     // INVALID_VALUE is generated by TextureFoveationParametersQCOM if 'texture' is not a valid
4677     // texture object.
4678     if (texture == nullptr)
4679     {
4680         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidTextureName);
4681         return false;
4682     }
4683 
4684     // INVALID_OPERATION is generated by TextureFoveationParametersQCOM if 'texture' has not been
4685     // set as foveated. i.e. 'texture's parameter TEXTURE_FOVEATED_FEATURE_BITS_QCOM does not
4686     // contain FOVEATION_ENABLE_BIT_QCOM.
4687     if (!texture->isFoveationEnabled())
4688     {
4689         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kTextureFoveationNotEnabled);
4690         return false;
4691     }
4692 
4693     // INVALID_VALUE is generated by TextureFoveationParametersQCOM if 'focalPoint' is larger than
4694     // TEXTURE_FOVEATED_NUM_FOCAL_POINTS_QUERY_QCOM minus one.
4695     if (focalPoint > texture->getNumFocalPoints() - 1)
4696     {
4697         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kFocalPointsExceedMaxFocalPoints);
4698         return false;
4699     }
4700 
4701     return true;
4702 }
4703 
ValidateEndTilingQCOM(const Context * context,angle::EntryPoint entryPoint,GLbitfield preserveMask)4704 bool ValidateEndTilingQCOM(const Context *context,
4705                            angle::EntryPoint entryPoint,
4706                            GLbitfield preserveMask)
4707 {
4708     if (!context->getExtensions().tiledRenderingQCOM)
4709     {
4710         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
4711         return false;
4712     }
4713 
4714     const gl::PrivateState &privateState = context->getPrivateState();
4715     if (!privateState.isTiledRendering())
4716     {
4717         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kTilingEndCalledWithoutStart);
4718         return false;
4719     }
4720 
4721     // preserveMask does not need to be validated. The bitfield covers the entire 32 bits of
4722     // GLbitfield and unbound attachments are siliently ignored like in glClear
4723 
4724     return true;
4725 }
4726 
ValidateStartTilingQCOM(const Context * context,angle::EntryPoint entryPoint,GLuint x,GLuint y,GLuint width,GLuint height,GLbitfield preserveMask)4727 bool ValidateStartTilingQCOM(const Context *context,
4728                              angle::EntryPoint entryPoint,
4729                              GLuint x,
4730                              GLuint y,
4731                              GLuint width,
4732                              GLuint height,
4733                              GLbitfield preserveMask)
4734 {
4735     if (!context->getExtensions().tiledRenderingQCOM)
4736     {
4737         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
4738         return false;
4739     }
4740 
4741     const gl::PrivateState &privateState = context->getPrivateState();
4742     if (privateState.isTiledRendering())
4743     {
4744         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kTilingStartCalledWithoutEnd);
4745         return false;
4746     }
4747 
4748     Framebuffer *framebuffer                   = context->getState().getDrawFramebuffer();
4749     const FramebufferStatus &framebufferStatus = framebuffer->checkStatus(context);
4750     if (!framebufferStatus.isComplete())
4751     {
4752         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, framebufferStatus.reason);
4753         return false;
4754     }
4755 
4756     // preserveMask does not need to be validated. The bitfield covers the entire 32 bits of
4757     // GLbitfield and unbound attachments are siliently ignored like in glClear
4758 
4759     return true;
4760 }
4761 
ValidateTexStorageAttribs(const GLint * attrib_list)4762 bool ValidateTexStorageAttribs(const GLint *attrib_list)
4763 {
4764     if (nullptr != attrib_list && GL_NONE != *attrib_list)
4765     {
4766         attrib_list++;
4767         if (nullptr == attrib_list)
4768         {
4769             return false;
4770         }
4771 
4772         if (*attrib_list == GL_SURFACE_COMPRESSION_FIXED_RATE_NONE_EXT ||
4773             *attrib_list == GL_SURFACE_COMPRESSION_FIXED_RATE_DEFAULT_EXT)
4774         {
4775             return true;
4776         }
4777         else if (*attrib_list >= GL_SURFACE_COMPRESSION_FIXED_RATE_1BPC_EXT &&
4778                  *attrib_list <= GL_SURFACE_COMPRESSION_FIXED_RATE_12BPC_EXT)
4779         {
4780             return true;
4781         }
4782         else
4783         {
4784             return false;
4785         }
4786     }
4787 
4788     return true;
4789 }
4790 
ValidateTexStorageAttribs2DEXT(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLsizei levels,GLenum internalformat,GLsizei width,GLsizei height,const GLint * attrib_list)4791 bool ValidateTexStorageAttribs2DEXT(const Context *context,
4792                                     angle::EntryPoint entryPoint,
4793                                     GLenum target,
4794                                     GLsizei levels,
4795                                     GLenum internalformat,
4796                                     GLsizei width,
4797                                     GLsizei height,
4798                                     const GLint *attrib_list)
4799 {
4800     gl::TextureType targetType = FromGLenum<TextureType>(target);
4801     if (!context->getExtensions().textureStorageCompressionEXT)
4802     {
4803         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
4804         return false;
4805     }
4806 
4807     if (ValidateTexStorageAttribs(attrib_list) == false)
4808     {
4809         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidAttribList);
4810     }
4811 
4812     if (context->getClientMajorVersion() < 3)
4813     {
4814         return ValidateES2TexStorageParametersBase(context, entryPoint, targetType, levels,
4815                                                    internalformat, width, height);
4816     }
4817 
4818     if (context->getClientMajorVersion() >= 3)
4819     {
4820         return ValidateES3TexStorage2DParameters(context, entryPoint, targetType, levels,
4821                                                  internalformat, width, height, 1);
4822     }
4823 
4824     return true;
4825 }
4826 
ValidateTexStorageAttribs3DEXT(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLsizei levels,GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth,const GLint * attrib_list)4827 bool ValidateTexStorageAttribs3DEXT(const Context *context,
4828                                     angle::EntryPoint entryPoint,
4829                                     GLenum target,
4830                                     GLsizei levels,
4831                                     GLenum internalformat,
4832                                     GLsizei width,
4833                                     GLsizei height,
4834                                     GLsizei depth,
4835                                     const GLint *attrib_list)
4836 {
4837     gl::TextureType targetType = FromGLenum<TextureType>(target);
4838     if (!context->getExtensions().textureStorageCompressionEXT)
4839     {
4840         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
4841         return false;
4842     }
4843 
4844     if (ValidateTexStorageAttribs(attrib_list) == false)
4845     {
4846         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidAttribList);
4847     }
4848 
4849     if (context->getClientMajorVersion() < 3)
4850     {
4851         return ValidateES2TexStorageParametersBase(context, entryPoint, targetType, levels,
4852                                                    internalformat, width, height);
4853     }
4854 
4855     if (context->getClientMajorVersion() >= 3)
4856     {
4857         return ValidateES3TexStorage3DParameters(context, entryPoint, targetType, levels,
4858                                                  internalformat, width, height, depth);
4859     }
4860 
4861     return true;
4862 }
4863 
4864 }  // namespace gl
4865