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