1 //
2 // Copyright 2016 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 
7 // validationES31.cpp: Validation functions for OpenGL ES 3.1 entry point parameters
8 
9 #include "libANGLE/validationES31_autogen.h"
10 
11 #include "libANGLE/Context.h"
12 #include "libANGLE/ErrorStrings.h"
13 #include "libANGLE/Framebuffer.h"
14 #include "libANGLE/ProgramExecutable.h"
15 #include "libANGLE/VertexArray.h"
16 #include "libANGLE/validationES.h"
17 #include "libANGLE/validationES2_autogen.h"
18 #include "libANGLE/validationES31.h"
19 #include "libANGLE/validationES3_autogen.h"
20 
21 #include "common/utilities.h"
22 
23 using namespace angle;
24 
25 namespace gl
26 {
27 using namespace err;
28 
29 namespace
30 {
31 
ValidateNamedProgramInterface(GLenum programInterface)32 bool ValidateNamedProgramInterface(GLenum programInterface)
33 {
34     switch (programInterface)
35     {
36         case GL_UNIFORM:
37         case GL_UNIFORM_BLOCK:
38         case GL_PROGRAM_INPUT:
39         case GL_PROGRAM_OUTPUT:
40         case GL_TRANSFORM_FEEDBACK_VARYING:
41         case GL_BUFFER_VARIABLE:
42         case GL_SHADER_STORAGE_BLOCK:
43             return true;
44         default:
45             return false;
46     }
47 }
48 
ValidateLocationProgramInterface(GLenum programInterface)49 bool ValidateLocationProgramInterface(GLenum programInterface)
50 {
51     switch (programInterface)
52     {
53         case GL_UNIFORM:
54         case GL_PROGRAM_INPUT:
55         case GL_PROGRAM_OUTPUT:
56             return true;
57         default:
58             return false;
59     }
60 }
61 
ValidateProgramInterface(GLenum programInterface)62 bool ValidateProgramInterface(GLenum programInterface)
63 {
64     return (programInterface == GL_ATOMIC_COUNTER_BUFFER ||
65             ValidateNamedProgramInterface(programInterface));
66 }
67 
ValidateProgramResourceProperty(const Context * context,GLenum prop)68 bool ValidateProgramResourceProperty(const Context *context, GLenum prop)
69 {
70     ASSERT(context);
71     switch (prop)
72     {
73         case GL_ACTIVE_VARIABLES:
74         case GL_BUFFER_BINDING:
75         case GL_NUM_ACTIVE_VARIABLES:
76 
77         case GL_ARRAY_SIZE:
78 
79         case GL_ARRAY_STRIDE:
80         case GL_BLOCK_INDEX:
81         case GL_IS_ROW_MAJOR:
82         case GL_MATRIX_STRIDE:
83 
84         case GL_ATOMIC_COUNTER_BUFFER_INDEX:
85 
86         case GL_BUFFER_DATA_SIZE:
87 
88         case GL_LOCATION:
89 
90         case GL_NAME_LENGTH:
91 
92         case GL_OFFSET:
93 
94         case GL_REFERENCED_BY_VERTEX_SHADER:
95         case GL_REFERENCED_BY_FRAGMENT_SHADER:
96         case GL_REFERENCED_BY_COMPUTE_SHADER:
97 
98         case GL_TOP_LEVEL_ARRAY_SIZE:
99         case GL_TOP_LEVEL_ARRAY_STRIDE:
100 
101         case GL_TYPE:
102             return true;
103 
104         case GL_REFERENCED_BY_GEOMETRY_SHADER_EXT:
105             return context->getExtensions().geometryShaderAny() ||
106                    context->getClientVersion() >= ES_3_2;
107 
108         case GL_REFERENCED_BY_TESS_CONTROL_SHADER_EXT:
109         case GL_REFERENCED_BY_TESS_EVALUATION_SHADER_EXT:
110         case GL_IS_PER_PATCH_EXT:
111             return context->getExtensions().tessellationShaderEXT ||
112                    context->getClientVersion() >= ES_3_2;
113 
114         case GL_LOCATION_INDEX_EXT:
115             return context->getExtensions().blendFuncExtended;
116 
117         default:
118             return false;
119     }
120 }
121 
122 // GLES 3.10 spec: Page 82 -- Table 7.2
ValidateProgramResourcePropertyByInterface(GLenum prop,GLenum programInterface)123 bool ValidateProgramResourcePropertyByInterface(GLenum prop, GLenum programInterface)
124 {
125     switch (prop)
126     {
127         case GL_ACTIVE_VARIABLES:
128         case GL_BUFFER_BINDING:
129         case GL_NUM_ACTIVE_VARIABLES:
130         {
131             switch (programInterface)
132             {
133                 case GL_ATOMIC_COUNTER_BUFFER:
134                 case GL_SHADER_STORAGE_BLOCK:
135                 case GL_UNIFORM_BLOCK:
136                     return true;
137                 default:
138                     return false;
139             }
140         }
141 
142         case GL_ARRAY_SIZE:
143         {
144             switch (programInterface)
145             {
146                 case GL_BUFFER_VARIABLE:
147                 case GL_PROGRAM_INPUT:
148                 case GL_PROGRAM_OUTPUT:
149                 case GL_TRANSFORM_FEEDBACK_VARYING:
150                 case GL_UNIFORM:
151                     return true;
152                 default:
153                     return false;
154             }
155         }
156 
157         case GL_ARRAY_STRIDE:
158         case GL_BLOCK_INDEX:
159         case GL_IS_ROW_MAJOR:
160         case GL_MATRIX_STRIDE:
161         {
162             switch (programInterface)
163             {
164                 case GL_BUFFER_VARIABLE:
165                 case GL_UNIFORM:
166                     return true;
167                 default:
168                     return false;
169             }
170         }
171 
172         case GL_ATOMIC_COUNTER_BUFFER_INDEX:
173         {
174             if (programInterface == GL_UNIFORM)
175             {
176                 return true;
177             }
178             return false;
179         }
180 
181         case GL_BUFFER_DATA_SIZE:
182         {
183             switch (programInterface)
184             {
185                 case GL_ATOMIC_COUNTER_BUFFER:
186                 case GL_SHADER_STORAGE_BLOCK:
187                 case GL_UNIFORM_BLOCK:
188                     return true;
189                 default:
190                     return false;
191             }
192         }
193 
194         case GL_LOCATION:
195         {
196             return ValidateLocationProgramInterface(programInterface);
197         }
198 
199         case GL_LOCATION_INDEX_EXT:
200         {
201             // EXT_blend_func_extended
202             return (programInterface == GL_PROGRAM_OUTPUT);
203         }
204 
205         case GL_NAME_LENGTH:
206         {
207             return ValidateNamedProgramInterface(programInterface);
208         }
209 
210         case GL_OFFSET:
211         {
212             switch (programInterface)
213             {
214                 case GL_BUFFER_VARIABLE:
215                 case GL_UNIFORM:
216                     return true;
217                 default:
218                     return false;
219             }
220         }
221 
222         case GL_REFERENCED_BY_VERTEX_SHADER:
223         case GL_REFERENCED_BY_FRAGMENT_SHADER:
224         case GL_REFERENCED_BY_COMPUTE_SHADER:
225         case GL_REFERENCED_BY_GEOMETRY_SHADER_EXT:
226         case GL_REFERENCED_BY_TESS_CONTROL_SHADER_EXT:
227         case GL_REFERENCED_BY_TESS_EVALUATION_SHADER_EXT:
228         {
229             switch (programInterface)
230             {
231                 case GL_ATOMIC_COUNTER_BUFFER:
232                 case GL_BUFFER_VARIABLE:
233                 case GL_PROGRAM_INPUT:
234                 case GL_PROGRAM_OUTPUT:
235                 case GL_SHADER_STORAGE_BLOCK:
236                 case GL_UNIFORM:
237                 case GL_UNIFORM_BLOCK:
238                     return true;
239                 default:
240                     return false;
241             }
242         }
243 
244         case GL_TOP_LEVEL_ARRAY_SIZE:
245         case GL_TOP_LEVEL_ARRAY_STRIDE:
246         {
247             if (programInterface == GL_BUFFER_VARIABLE)
248             {
249                 return true;
250             }
251             return false;
252         }
253 
254         case GL_TYPE:
255         {
256             switch (programInterface)
257             {
258                 case GL_BUFFER_VARIABLE:
259                 case GL_PROGRAM_INPUT:
260                 case GL_PROGRAM_OUTPUT:
261                 case GL_TRANSFORM_FEEDBACK_VARYING:
262                 case GL_UNIFORM:
263                     return true;
264                 default:
265                     return false;
266             }
267         }
268         case GL_IS_PER_PATCH_EXT:
269             switch (programInterface)
270             {
271                 case GL_PROGRAM_INPUT:
272                 case GL_PROGRAM_OUTPUT:
273                     return true;
274             }
275             return false;
276 
277         default:
278             return false;
279     }
280 }
281 
ValidateProgramResourceIndex(const Program * programObject,GLenum programInterface,GLuint index)282 bool ValidateProgramResourceIndex(const Program *programObject,
283                                   GLenum programInterface,
284                                   GLuint index)
285 {
286     switch (programInterface)
287     {
288         case GL_PROGRAM_INPUT:
289             return (index <
290                     static_cast<GLuint>(programObject->getState().getProgramInputs().size()));
291 
292         case GL_PROGRAM_OUTPUT:
293             return (index < static_cast<GLuint>(programObject->getOutputResourceCount()));
294 
295         case GL_UNIFORM:
296             return (index < static_cast<GLuint>(programObject->getActiveUniformCount()));
297 
298         case GL_BUFFER_VARIABLE:
299             return (index < static_cast<GLuint>(programObject->getActiveBufferVariableCount()));
300 
301         case GL_SHADER_STORAGE_BLOCK:
302             return (index < static_cast<GLuint>(programObject->getActiveShaderStorageBlockCount()));
303 
304         case GL_UNIFORM_BLOCK:
305             return (index < programObject->getActiveUniformBlockCount());
306 
307         case GL_ATOMIC_COUNTER_BUFFER:
308             return (index < programObject->getActiveAtomicCounterBufferCount());
309 
310         case GL_TRANSFORM_FEEDBACK_VARYING:
311             return (index < static_cast<GLuint>(programObject->getTransformFeedbackVaryingCount()));
312 
313         default:
314             UNREACHABLE();
315             return false;
316     }
317 }
318 
ValidateProgramUniformBase(const Context * context,GLenum valueType,ShaderProgramID program,UniformLocation location,GLsizei count)319 bool ValidateProgramUniformBase(const Context *context,
320                                 GLenum valueType,
321                                 ShaderProgramID program,
322                                 UniformLocation location,
323                                 GLsizei count)
324 {
325     const LinkedUniform *uniform = nullptr;
326     Program *programObject       = GetValidProgram(context, program);
327     return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
328            ValidateUniformValue(context, valueType, uniform->type);
329 }
330 
ValidateProgramUniformMatrixBase(const Context * context,GLenum valueType,ShaderProgramID program,UniformLocation location,GLsizei count,GLboolean transpose)331 bool ValidateProgramUniformMatrixBase(const Context *context,
332                                       GLenum valueType,
333                                       ShaderProgramID program,
334                                       UniformLocation location,
335                                       GLsizei count,
336                                       GLboolean transpose)
337 {
338     const LinkedUniform *uniform = nullptr;
339     Program *programObject       = GetValidProgram(context, program);
340     return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
341            ValidateUniformMatrixValue(context, valueType, uniform->type);
342 }
343 
ValidateVertexAttribFormatCommon(const Context * context,GLuint relativeOffset)344 bool ValidateVertexAttribFormatCommon(const Context *context, GLuint relativeOffset)
345 {
346     if (context->getClientVersion() < ES_3_1)
347     {
348         context->validationError(GL_INVALID_OPERATION, kES31Required);
349         return false;
350     }
351 
352     const Caps &caps = context->getCaps();
353     if (relativeOffset > static_cast<GLuint>(caps.maxVertexAttribRelativeOffset))
354     {
355         context->validationError(GL_INVALID_VALUE, kRelativeOffsetTooLarge);
356         return false;
357     }
358 
359     // [OpenGL ES 3.1] Section 10.3.1 page 243:
360     // An INVALID_OPERATION error is generated if the default vertex array object is bound.
361     if (context->getState().getVertexArrayId().value == 0)
362     {
363         context->validationError(GL_INVALID_OPERATION, kDefaultVertexArray);
364         return false;
365     }
366 
367     return true;
368 }
369 
370 }  // anonymous namespace
371 
ValidateGetBooleani_v(const Context * context,GLenum target,GLuint index,const GLboolean * data)372 bool ValidateGetBooleani_v(const Context *context,
373                            GLenum target,
374                            GLuint index,
375                            const GLboolean *data)
376 {
377     if (context->getClientVersion() < ES_3_1 && !context->getExtensions().drawBuffersIndexedAny())
378     {
379         context->validationError(GL_INVALID_OPERATION,
380                                  kES31OrDrawBuffersIndexedExtensionNotAvailable);
381         return false;
382     }
383 
384     if (!ValidateIndexedStateQuery(context, target, index, nullptr))
385     {
386         return false;
387     }
388 
389     return true;
390 }
391 
ValidateGetBooleani_vRobustANGLE(const Context * context,GLenum target,GLuint index,GLsizei bufSize,const GLsizei * length,const GLboolean * data)392 bool ValidateGetBooleani_vRobustANGLE(const Context *context,
393                                       GLenum target,
394                                       GLuint index,
395                                       GLsizei bufSize,
396                                       const GLsizei *length,
397                                       const GLboolean *data)
398 {
399     if (context->getClientVersion() < ES_3_1 && !context->getExtensions().drawBuffersIndexedAny())
400     {
401         context->validationError(GL_INVALID_OPERATION,
402                                  kES31OrDrawBuffersIndexedExtensionNotAvailable);
403         return false;
404     }
405 
406     if (!ValidateRobustEntryPoint(context, bufSize))
407     {
408         return false;
409     }
410 
411     GLsizei numParams = 0;
412 
413     if (!ValidateIndexedStateQuery(context, target, index, &numParams))
414     {
415         return false;
416     }
417 
418     if (!ValidateRobustBufferSize(context, bufSize, numParams))
419     {
420         return false;
421     }
422 
423     SetRobustLengthParam(length, numParams);
424     return true;
425 }
426 
ValidateDrawIndirectBase(const Context * context,PrimitiveMode mode,const void * indirect)427 bool ValidateDrawIndirectBase(const Context *context, PrimitiveMode mode, const void *indirect)
428 {
429     if (context->getClientVersion() < ES_3_1)
430     {
431         context->validationError(GL_INVALID_OPERATION, kES31Required);
432         return false;
433     }
434 
435     // Here the third parameter 1 is only to pass the count validation.
436     if (!ValidateDrawBase(context, mode))
437     {
438         return false;
439     }
440 
441     const State &state = context->getState();
442 
443     // An INVALID_OPERATION error is generated if zero is bound to VERTEX_ARRAY_BINDING,
444     // DRAW_INDIRECT_BUFFER or to any enabled vertex array.
445     if (state.getVertexArrayId().value == 0)
446     {
447         context->validationError(GL_INVALID_OPERATION, kDefaultVertexArray);
448         return false;
449     }
450 
451     if (context->getStateCache().hasAnyActiveClientAttrib())
452     {
453         context->validationError(GL_INVALID_OPERATION, kClientDataInVertexArray);
454         return false;
455     }
456 
457     Buffer *drawIndirectBuffer = state.getTargetBuffer(BufferBinding::DrawIndirect);
458     if (!drawIndirectBuffer)
459     {
460         context->validationError(GL_INVALID_OPERATION, kDrawIndirectBufferNotBound);
461         return false;
462     }
463 
464     // An INVALID_VALUE error is generated if indirect is not a multiple of the size, in basic
465     // machine units, of uint.
466     GLint64 offset = reinterpret_cast<GLint64>(indirect);
467     if ((static_cast<GLuint>(offset) % sizeof(GLuint)) != 0)
468     {
469         context->validationError(GL_INVALID_VALUE, kInvalidIndirectOffset);
470         return false;
471     }
472 
473     return true;
474 }
475 
ValidateDrawArraysIndirect(const Context * context,PrimitiveMode mode,const void * indirect)476 bool ValidateDrawArraysIndirect(const Context *context, PrimitiveMode mode, const void *indirect)
477 {
478     const State &state                      = context->getState();
479     TransformFeedback *curTransformFeedback = state.getCurrentTransformFeedback();
480     if (curTransformFeedback && curTransformFeedback->isActive() &&
481         !curTransformFeedback->isPaused())
482     {
483         // EXT_geometry_shader allows transform feedback to work with all draw commands.
484         // [EXT_geometry_shader] Section 12.1, "Transform Feedback"
485         if (context->getExtensions().geometryShaderAny() || context->getClientVersion() >= ES_3_2)
486         {
487             if (!ValidateTransformFeedbackPrimitiveMode(
488                     context, curTransformFeedback->getPrimitiveMode(), mode))
489             {
490                 context->validationError(GL_INVALID_OPERATION, kInvalidDrawModeTransformFeedback);
491                 return false;
492             }
493         }
494         else
495         {
496             // An INVALID_OPERATION error is generated if transform feedback is active and not
497             // paused.
498             context->validationError(GL_INVALID_OPERATION,
499                                      kUnsupportedDrawModeForTransformFeedback);
500             return false;
501         }
502     }
503 
504     if (!ValidateDrawIndirectBase(context, mode, indirect))
505         return false;
506 
507     Buffer *drawIndirectBuffer = state.getTargetBuffer(BufferBinding::DrawIndirect);
508     CheckedNumeric<size_t> checkedOffset(reinterpret_cast<size_t>(indirect));
509     // In OpenGL ES3.1 spec, session 10.5, it defines the struct of DrawArraysIndirectCommand
510     // which's size is 4 * sizeof(uint).
511     auto checkedSum = checkedOffset + 4 * sizeof(GLuint);
512     if (!checkedSum.IsValid() ||
513         checkedSum.ValueOrDie() > static_cast<size_t>(drawIndirectBuffer->getSize()))
514     {
515         context->validationError(GL_INVALID_OPERATION, kParamOverflow);
516         return false;
517     }
518 
519     return true;
520 }
521 
ValidateDrawElementsIndirect(const Context * context,PrimitiveMode mode,DrawElementsType type,const void * indirect)522 bool ValidateDrawElementsIndirect(const Context *context,
523                                   PrimitiveMode mode,
524                                   DrawElementsType type,
525                                   const void *indirect)
526 {
527     if (!ValidateDrawElementsBase(context, mode, type))
528     {
529         return false;
530     }
531 
532     const State &state         = context->getState();
533     const VertexArray *vao     = state.getVertexArray();
534     Buffer *elementArrayBuffer = vao->getElementArrayBuffer();
535     if (!elementArrayBuffer)
536     {
537         context->validationError(GL_INVALID_OPERATION, kMustHaveElementArrayBinding);
538         return false;
539     }
540 
541     if (!ValidateDrawIndirectBase(context, mode, indirect))
542         return false;
543 
544     Buffer *drawIndirectBuffer = state.getTargetBuffer(BufferBinding::DrawIndirect);
545     CheckedNumeric<size_t> checkedOffset(reinterpret_cast<size_t>(indirect));
546     // In OpenGL ES3.1 spec, session 10.5, it defines the struct of DrawElementsIndirectCommand
547     // which's size is 5 * sizeof(uint).
548     auto checkedSum = checkedOffset + 5 * sizeof(GLuint);
549     if (!checkedSum.IsValid() ||
550         checkedSum.ValueOrDie() > static_cast<size_t>(drawIndirectBuffer->getSize()))
551     {
552         context->validationError(GL_INVALID_OPERATION, kParamOverflow);
553         return false;
554     }
555 
556     return true;
557 }
558 
ValidateProgramUniform1iBase(const Context * context,ShaderProgramID program,UniformLocation location,GLint v0)559 bool ValidateProgramUniform1iBase(const Context *context,
560                                   ShaderProgramID program,
561                                   UniformLocation location,
562                                   GLint v0)
563 {
564     return ValidateProgramUniform1ivBase(context, program, location, 1, &v0);
565 }
566 
ValidateProgramUniform2iBase(const Context * context,ShaderProgramID program,UniformLocation location,GLint v0,GLint v1)567 bool ValidateProgramUniform2iBase(const Context *context,
568                                   ShaderProgramID program,
569                                   UniformLocation location,
570                                   GLint v0,
571                                   GLint v1)
572 {
573     GLint xy[2] = {v0, v1};
574     return ValidateProgramUniform2ivBase(context, program, location, 1, xy);
575 }
576 
ValidateProgramUniform3iBase(const Context * context,ShaderProgramID program,UniformLocation location,GLint v0,GLint v1,GLint v2)577 bool ValidateProgramUniform3iBase(const Context *context,
578                                   ShaderProgramID program,
579                                   UniformLocation location,
580                                   GLint v0,
581                                   GLint v1,
582                                   GLint v2)
583 {
584     GLint xyz[3] = {v0, v1, v2};
585     return ValidateProgramUniform3ivBase(context, program, location, 1, xyz);
586 }
587 
ValidateProgramUniform4iBase(const Context * context,ShaderProgramID program,UniformLocation location,GLint v0,GLint v1,GLint v2,GLint v3)588 bool ValidateProgramUniform4iBase(const Context *context,
589                                   ShaderProgramID program,
590                                   UniformLocation location,
591                                   GLint v0,
592                                   GLint v1,
593                                   GLint v2,
594                                   GLint v3)
595 {
596     GLint xyzw[4] = {v0, v1, v2, v3};
597     return ValidateProgramUniform4ivBase(context, program, location, 1, xyzw);
598 }
599 
ValidateProgramUniform1uiBase(const Context * context,ShaderProgramID program,UniformLocation location,GLuint v0)600 bool ValidateProgramUniform1uiBase(const Context *context,
601                                    ShaderProgramID program,
602                                    UniformLocation location,
603                                    GLuint v0)
604 {
605     return ValidateProgramUniform1uivBase(context, program, location, 1, &v0);
606 }
607 
ValidateProgramUniform2uiBase(const Context * context,ShaderProgramID program,UniformLocation location,GLuint v0,GLuint v1)608 bool ValidateProgramUniform2uiBase(const Context *context,
609                                    ShaderProgramID program,
610                                    UniformLocation location,
611                                    GLuint v0,
612                                    GLuint v1)
613 {
614     GLuint xy[2] = {v0, v1};
615     return ValidateProgramUniform2uivBase(context, program, location, 1, xy);
616 }
617 
ValidateProgramUniform3uiBase(const Context * context,ShaderProgramID program,UniformLocation location,GLuint v0,GLuint v1,GLuint v2)618 bool ValidateProgramUniform3uiBase(const Context *context,
619                                    ShaderProgramID program,
620                                    UniformLocation location,
621                                    GLuint v0,
622                                    GLuint v1,
623                                    GLuint v2)
624 {
625     GLuint xyz[3] = {v0, v1, v2};
626     return ValidateProgramUniform3uivBase(context, program, location, 1, xyz);
627 }
628 
ValidateProgramUniform4uiBase(const Context * context,ShaderProgramID program,UniformLocation location,GLuint v0,GLuint v1,GLuint v2,GLuint v3)629 bool ValidateProgramUniform4uiBase(const Context *context,
630                                    ShaderProgramID program,
631                                    UniformLocation location,
632                                    GLuint v0,
633                                    GLuint v1,
634                                    GLuint v2,
635                                    GLuint v3)
636 {
637     GLuint xyzw[4] = {v0, v1, v2, v3};
638     return ValidateProgramUniform4uivBase(context, program, location, 1, xyzw);
639 }
640 
ValidateProgramUniform1fBase(const Context * context,ShaderProgramID program,UniformLocation location,GLfloat v0)641 bool ValidateProgramUniform1fBase(const Context *context,
642                                   ShaderProgramID program,
643                                   UniformLocation location,
644                                   GLfloat v0)
645 {
646     return ValidateProgramUniform1fvBase(context, program, location, 1, &v0);
647 }
648 
ValidateProgramUniform2fBase(const Context * context,ShaderProgramID program,UniformLocation location,GLfloat v0,GLfloat v1)649 bool ValidateProgramUniform2fBase(const Context *context,
650                                   ShaderProgramID program,
651                                   UniformLocation location,
652                                   GLfloat v0,
653                                   GLfloat v1)
654 {
655     GLfloat xy[2] = {v0, v1};
656     return ValidateProgramUniform2fvBase(context, program, location, 1, xy);
657 }
658 
ValidateProgramUniform3fBase(const Context * context,ShaderProgramID program,UniformLocation location,GLfloat v0,GLfloat v1,GLfloat v2)659 bool ValidateProgramUniform3fBase(const Context *context,
660                                   ShaderProgramID program,
661                                   UniformLocation location,
662                                   GLfloat v0,
663                                   GLfloat v1,
664                                   GLfloat v2)
665 {
666     GLfloat xyz[3] = {v0, v1, v2};
667     return ValidateProgramUniform3fvBase(context, program, location, 1, xyz);
668 }
669 
ValidateProgramUniform4fBase(const Context * context,ShaderProgramID program,UniformLocation location,GLfloat v0,GLfloat v1,GLfloat v2,GLfloat v3)670 bool ValidateProgramUniform4fBase(const Context *context,
671                                   ShaderProgramID program,
672                                   UniformLocation location,
673                                   GLfloat v0,
674                                   GLfloat v1,
675                                   GLfloat v2,
676                                   GLfloat v3)
677 {
678     GLfloat xyzw[4] = {v0, v1, v2, v3};
679     return ValidateProgramUniform4fvBase(context, program, location, 1, xyzw);
680 }
681 
ValidateProgramUniform1ivBase(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,const GLint * value)682 bool ValidateProgramUniform1ivBase(const Context *context,
683                                    ShaderProgramID program,
684                                    UniformLocation location,
685                                    GLsizei count,
686                                    const GLint *value)
687 {
688     const LinkedUniform *uniform = nullptr;
689     Program *programObject       = GetValidProgram(context, program);
690     return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
691            ValidateUniform1ivValue(context, uniform->type, count, value);
692 }
693 
ValidateProgramUniform2ivBase(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,const GLint * value)694 bool ValidateProgramUniform2ivBase(const Context *context,
695                                    ShaderProgramID program,
696                                    UniformLocation location,
697                                    GLsizei count,
698                                    const GLint *value)
699 {
700     return ValidateProgramUniformBase(context, GL_INT_VEC2, program, location, count);
701 }
702 
ValidateProgramUniform3ivBase(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,const GLint * value)703 bool ValidateProgramUniform3ivBase(const Context *context,
704                                    ShaderProgramID program,
705                                    UniformLocation location,
706                                    GLsizei count,
707                                    const GLint *value)
708 {
709     return ValidateProgramUniformBase(context, GL_INT_VEC3, program, location, count);
710 }
711 
ValidateProgramUniform4ivBase(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,const GLint * value)712 bool ValidateProgramUniform4ivBase(const Context *context,
713                                    ShaderProgramID program,
714                                    UniformLocation location,
715                                    GLsizei count,
716                                    const GLint *value)
717 {
718     return ValidateProgramUniformBase(context, GL_INT_VEC4, program, location, count);
719 }
720 
ValidateProgramUniform1uivBase(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,const GLuint * value)721 bool ValidateProgramUniform1uivBase(const Context *context,
722                                     ShaderProgramID program,
723                                     UniformLocation location,
724                                     GLsizei count,
725                                     const GLuint *value)
726 {
727     return ValidateProgramUniformBase(context, GL_UNSIGNED_INT, program, location, count);
728 }
729 
ValidateProgramUniform2uivBase(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,const GLuint * value)730 bool ValidateProgramUniform2uivBase(const Context *context,
731                                     ShaderProgramID program,
732                                     UniformLocation location,
733                                     GLsizei count,
734                                     const GLuint *value)
735 {
736     return ValidateProgramUniformBase(context, GL_UNSIGNED_INT_VEC2, program, location, count);
737 }
738 
ValidateProgramUniform3uivBase(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,const GLuint * value)739 bool ValidateProgramUniform3uivBase(const Context *context,
740                                     ShaderProgramID program,
741                                     UniformLocation location,
742                                     GLsizei count,
743                                     const GLuint *value)
744 {
745     return ValidateProgramUniformBase(context, GL_UNSIGNED_INT_VEC3, program, location, count);
746 }
747 
ValidateProgramUniform4uivBase(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,const GLuint * value)748 bool ValidateProgramUniform4uivBase(const Context *context,
749                                     ShaderProgramID program,
750                                     UniformLocation location,
751                                     GLsizei count,
752                                     const GLuint *value)
753 {
754     return ValidateProgramUniformBase(context, GL_UNSIGNED_INT_VEC4, program, location, count);
755 }
756 
ValidateProgramUniform1fvBase(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,const GLfloat * value)757 bool ValidateProgramUniform1fvBase(const Context *context,
758                                    ShaderProgramID program,
759                                    UniformLocation location,
760                                    GLsizei count,
761                                    const GLfloat *value)
762 {
763     return ValidateProgramUniformBase(context, GL_FLOAT, program, location, count);
764 }
765 
ValidateProgramUniform2fvBase(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,const GLfloat * value)766 bool ValidateProgramUniform2fvBase(const Context *context,
767                                    ShaderProgramID program,
768                                    UniformLocation location,
769                                    GLsizei count,
770                                    const GLfloat *value)
771 {
772     return ValidateProgramUniformBase(context, GL_FLOAT_VEC2, program, location, count);
773 }
774 
ValidateProgramUniform3fvBase(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,const GLfloat * value)775 bool ValidateProgramUniform3fvBase(const Context *context,
776                                    ShaderProgramID program,
777                                    UniformLocation location,
778                                    GLsizei count,
779                                    const GLfloat *value)
780 {
781     return ValidateProgramUniformBase(context, GL_FLOAT_VEC3, program, location, count);
782 }
783 
ValidateProgramUniform4fvBase(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,const GLfloat * value)784 bool ValidateProgramUniform4fvBase(const Context *context,
785                                    ShaderProgramID program,
786                                    UniformLocation location,
787                                    GLsizei count,
788                                    const GLfloat *value)
789 {
790     return ValidateProgramUniformBase(context, GL_FLOAT_VEC4, program, location, count);
791 }
792 
ValidateProgramUniformMatrix2fvBase(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)793 bool ValidateProgramUniformMatrix2fvBase(const Context *context,
794                                          ShaderProgramID program,
795                                          UniformLocation location,
796                                          GLsizei count,
797                                          GLboolean transpose,
798                                          const GLfloat *value)
799 {
800     return ValidateProgramUniformMatrixBase(context, GL_FLOAT_MAT2, program, location, count,
801                                             transpose);
802 }
803 
ValidateProgramUniformMatrix3fvBase(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)804 bool ValidateProgramUniformMatrix3fvBase(const Context *context,
805                                          ShaderProgramID program,
806                                          UniformLocation location,
807                                          GLsizei count,
808                                          GLboolean transpose,
809                                          const GLfloat *value)
810 {
811     return ValidateProgramUniformMatrixBase(context, GL_FLOAT_MAT3, program, location, count,
812                                             transpose);
813 }
814 
ValidateProgramUniformMatrix4fvBase(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)815 bool ValidateProgramUniformMatrix4fvBase(const Context *context,
816                                          ShaderProgramID program,
817                                          UniformLocation location,
818                                          GLsizei count,
819                                          GLboolean transpose,
820                                          const GLfloat *value)
821 {
822     return ValidateProgramUniformMatrixBase(context, GL_FLOAT_MAT4, program, location, count,
823                                             transpose);
824 }
825 
ValidateProgramUniformMatrix2x3fvBase(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)826 bool ValidateProgramUniformMatrix2x3fvBase(const Context *context,
827                                            ShaderProgramID program,
828                                            UniformLocation location,
829                                            GLsizei count,
830                                            GLboolean transpose,
831                                            const GLfloat *value)
832 {
833     return ValidateProgramUniformMatrixBase(context, GL_FLOAT_MAT2x3, program, location, count,
834                                             transpose);
835 }
836 
ValidateProgramUniformMatrix3x2fvBase(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)837 bool ValidateProgramUniformMatrix3x2fvBase(const Context *context,
838                                            ShaderProgramID program,
839                                            UniformLocation location,
840                                            GLsizei count,
841                                            GLboolean transpose,
842                                            const GLfloat *value)
843 {
844     return ValidateProgramUniformMatrixBase(context, GL_FLOAT_MAT3x2, program, location, count,
845                                             transpose);
846 }
847 
ValidateProgramUniformMatrix2x4fvBase(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)848 bool ValidateProgramUniformMatrix2x4fvBase(const Context *context,
849                                            ShaderProgramID program,
850                                            UniformLocation location,
851                                            GLsizei count,
852                                            GLboolean transpose,
853                                            const GLfloat *value)
854 {
855     return ValidateProgramUniformMatrixBase(context, GL_FLOAT_MAT2x4, program, location, count,
856                                             transpose);
857 }
858 
ValidateProgramUniformMatrix4x2fvBase(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)859 bool ValidateProgramUniformMatrix4x2fvBase(const Context *context,
860                                            ShaderProgramID program,
861                                            UniformLocation location,
862                                            GLsizei count,
863                                            GLboolean transpose,
864                                            const GLfloat *value)
865 {
866     return ValidateProgramUniformMatrixBase(context, GL_FLOAT_MAT4x2, program, location, count,
867                                             transpose);
868 }
869 
ValidateProgramUniformMatrix3x4fvBase(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)870 bool ValidateProgramUniformMatrix3x4fvBase(const Context *context,
871                                            ShaderProgramID program,
872                                            UniformLocation location,
873                                            GLsizei count,
874                                            GLboolean transpose,
875                                            const GLfloat *value)
876 {
877     return ValidateProgramUniformMatrixBase(context, GL_FLOAT_MAT3x4, program, location, count,
878                                             transpose);
879 }
880 
ValidateProgramUniformMatrix4x3fvBase(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)881 bool ValidateProgramUniformMatrix4x3fvBase(const Context *context,
882                                            ShaderProgramID program,
883                                            UniformLocation location,
884                                            GLsizei count,
885                                            GLboolean transpose,
886                                            const GLfloat *value)
887 {
888     return ValidateProgramUniformMatrixBase(context, GL_FLOAT_MAT4x3, program, location, count,
889                                             transpose);
890 }
891 
ValidateGetTexLevelParameterfv(const Context * context,TextureTarget target,GLint level,GLenum pname,const GLfloat * params)892 bool ValidateGetTexLevelParameterfv(const Context *context,
893                                     TextureTarget target,
894                                     GLint level,
895                                     GLenum pname,
896                                     const GLfloat *params)
897 {
898     if (context->getClientVersion() < ES_3_1)
899     {
900         context->validationError(GL_INVALID_OPERATION, kES31Required);
901         return false;
902     }
903 
904     return ValidateGetTexLevelParameterBase(context, target, level, pname, nullptr);
905 }
906 
ValidateGetTexLevelParameterfvRobustANGLE(const Context * context,TextureTarget target,GLint level,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLfloat * params)907 bool ValidateGetTexLevelParameterfvRobustANGLE(const Context *context,
908                                                TextureTarget target,
909                                                GLint level,
910                                                GLenum pname,
911                                                GLsizei bufSize,
912                                                const GLsizei *length,
913                                                const GLfloat *params)
914 {
915     UNIMPLEMENTED();
916     return false;
917 }
918 
ValidateGetTexLevelParameteriv(const Context * context,TextureTarget target,GLint level,GLenum pname,const GLint * params)919 bool ValidateGetTexLevelParameteriv(const Context *context,
920                                     TextureTarget target,
921                                     GLint level,
922                                     GLenum pname,
923                                     const GLint *params)
924 {
925     if (context->getClientVersion() < ES_3_1)
926     {
927         context->validationError(GL_INVALID_OPERATION, kES31Required);
928         return false;
929     }
930 
931     return ValidateGetTexLevelParameterBase(context, target, level, pname, nullptr);
932 }
933 
ValidateGetTexLevelParameterivRobustANGLE(const Context * context,TextureTarget target,GLint level,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLint * params)934 bool ValidateGetTexLevelParameterivRobustANGLE(const Context *context,
935                                                TextureTarget target,
936                                                GLint level,
937                                                GLenum pname,
938                                                GLsizei bufSize,
939                                                const GLsizei *length,
940                                                const GLint *params)
941 {
942     UNIMPLEMENTED();
943     return false;
944 }
945 
ValidateTexStorage2DMultisample(const Context * context,TextureType target,GLsizei samples,GLenum internalFormat,GLsizei width,GLsizei height,GLboolean fixedSampleLocations)946 bool ValidateTexStorage2DMultisample(const Context *context,
947                                      TextureType target,
948                                      GLsizei samples,
949                                      GLenum internalFormat,
950                                      GLsizei width,
951                                      GLsizei height,
952                                      GLboolean fixedSampleLocations)
953 {
954     if (context->getClientVersion() < ES_3_1)
955     {
956         context->validationError(GL_INVALID_OPERATION, kES31Required);
957         return false;
958     }
959 
960     return ValidateTexStorage2DMultisampleBase(context, target, samples, internalFormat, width,
961                                                height);
962 }
963 
ValidateTexStorageMem2DMultisampleEXT(const Context * context,TextureType target,GLsizei samples,GLenum internalFormat,GLsizei width,GLsizei height,GLboolean fixedSampleLocations,MemoryObjectID memory,GLuint64 offset)964 bool ValidateTexStorageMem2DMultisampleEXT(const Context *context,
965                                            TextureType target,
966                                            GLsizei samples,
967                                            GLenum internalFormat,
968                                            GLsizei width,
969                                            GLsizei height,
970                                            GLboolean fixedSampleLocations,
971                                            MemoryObjectID memory,
972                                            GLuint64 offset)
973 {
974     if (!context->getExtensions().memoryObject)
975     {
976         context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
977         return false;
978     }
979 
980     UNIMPLEMENTED();
981     return false;
982 }
983 
ValidateGetMultisamplefv(const Context * context,GLenum pname,GLuint index,const GLfloat * val)984 bool ValidateGetMultisamplefv(const Context *context,
985                               GLenum pname,
986                               GLuint index,
987                               const GLfloat *val)
988 {
989     if (context->getClientVersion() < ES_3_1)
990     {
991         context->validationError(GL_INVALID_OPERATION, kES31Required);
992         return false;
993     }
994 
995     return ValidateGetMultisamplefvBase(context, pname, index, val);
996 }
997 
ValidateGetMultisamplefvRobustANGLE(const Context * context,GLenum pname,GLuint index,GLsizei bufSize,const GLsizei * length,const GLfloat * val)998 bool ValidateGetMultisamplefvRobustANGLE(const Context *context,
999                                          GLenum pname,
1000                                          GLuint index,
1001                                          GLsizei bufSize,
1002                                          const GLsizei *length,
1003                                          const GLfloat *val)
1004 {
1005     UNIMPLEMENTED();
1006     return false;
1007 }
1008 
ValidateFramebufferParameteri(const Context * context,GLenum target,GLenum pname,GLint param)1009 bool ValidateFramebufferParameteri(const Context *context, GLenum target, GLenum pname, GLint param)
1010 {
1011     if (context->getClientVersion() < ES_3_1)
1012     {
1013         context->validationError(GL_INVALID_OPERATION, kES31Required);
1014         return false;
1015     }
1016 
1017     if (!ValidFramebufferTarget(context, target))
1018     {
1019         context->validationError(GL_INVALID_ENUM, kInvalidFramebufferTarget);
1020         return false;
1021     }
1022 
1023     switch (pname)
1024     {
1025         case GL_FRAMEBUFFER_DEFAULT_WIDTH:
1026         {
1027             GLint maxWidth = context->getCaps().maxFramebufferWidth;
1028             if (param < 0 || param > maxWidth)
1029             {
1030                 context->validationError(GL_INVALID_VALUE, kExceedsFramebufferWidth);
1031                 return false;
1032             }
1033             break;
1034         }
1035         case GL_FRAMEBUFFER_DEFAULT_HEIGHT:
1036         {
1037             GLint maxHeight = context->getCaps().maxFramebufferHeight;
1038             if (param < 0 || param > maxHeight)
1039             {
1040                 context->validationError(GL_INVALID_VALUE, kExceedsFramebufferHeight);
1041                 return false;
1042             }
1043             break;
1044         }
1045         case GL_FRAMEBUFFER_DEFAULT_SAMPLES:
1046         {
1047             GLint maxSamples = context->getCaps().maxFramebufferSamples;
1048             if (param < 0 || param > maxSamples)
1049             {
1050                 context->validationError(GL_INVALID_VALUE, kExceedsFramebufferSamples);
1051                 return false;
1052             }
1053             break;
1054         }
1055         case GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS:
1056         {
1057             break;
1058         }
1059         case GL_FRAMEBUFFER_DEFAULT_LAYERS_EXT:
1060         {
1061             if (!context->getExtensions().geometryShaderAny() &&
1062                 context->getClientVersion() < ES_3_2)
1063             {
1064                 context->validationError(GL_INVALID_ENUM, kGeometryShaderExtensionNotEnabled);
1065                 return false;
1066             }
1067             GLint maxLayers = context->getCaps().maxFramebufferLayers;
1068             if (param < 0 || param > maxLayers)
1069             {
1070                 context->validationError(GL_INVALID_VALUE, kInvalidFramebufferLayer);
1071                 return false;
1072             }
1073             break;
1074         }
1075         default:
1076         {
1077             context->validationError(GL_INVALID_ENUM, kInvalidPname);
1078             return false;
1079         }
1080     }
1081 
1082     const Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
1083     ASSERT(framebuffer);
1084     if (framebuffer->isDefault())
1085     {
1086         context->validationError(GL_INVALID_OPERATION, kDefaultFramebuffer);
1087         return false;
1088     }
1089     return true;
1090 }
1091 
ValidateGetFramebufferParameteriv(const Context * context,GLenum target,GLenum pname,const GLint * params)1092 bool ValidateGetFramebufferParameteriv(const Context *context,
1093                                        GLenum target,
1094                                        GLenum pname,
1095                                        const GLint *params)
1096 {
1097     if (context->getClientVersion() < ES_3_1)
1098     {
1099         context->validationError(GL_INVALID_OPERATION, kES31Required);
1100         return false;
1101     }
1102 
1103     if (!ValidFramebufferTarget(context, target))
1104     {
1105         context->validationError(GL_INVALID_ENUM, kInvalidFramebufferTarget);
1106         return false;
1107     }
1108 
1109     switch (pname)
1110     {
1111         case GL_FRAMEBUFFER_DEFAULT_WIDTH:
1112         case GL_FRAMEBUFFER_DEFAULT_HEIGHT:
1113         case GL_FRAMEBUFFER_DEFAULT_SAMPLES:
1114         case GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS:
1115             break;
1116         case GL_FRAMEBUFFER_DEFAULT_LAYERS_EXT:
1117             if (!context->getExtensions().geometryShaderAny() &&
1118                 context->getClientVersion() < ES_3_2)
1119             {
1120                 context->validationError(GL_INVALID_ENUM, kGeometryShaderExtensionNotEnabled);
1121                 return false;
1122             }
1123             break;
1124         default:
1125             context->validationError(GL_INVALID_ENUM, kInvalidPname);
1126             return false;
1127     }
1128 
1129     const Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
1130     ASSERT(framebuffer);
1131 
1132     if (framebuffer->isDefault())
1133     {
1134         context->validationError(GL_INVALID_OPERATION, kDefaultFramebuffer);
1135         return false;
1136     }
1137     return true;
1138 }
1139 
ValidateGetFramebufferParameterivRobustANGLE(const Context * context,GLenum target,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLint * params)1140 bool ValidateGetFramebufferParameterivRobustANGLE(const Context *context,
1141                                                   GLenum target,
1142                                                   GLenum pname,
1143                                                   GLsizei bufSize,
1144                                                   const GLsizei *length,
1145                                                   const GLint *params)
1146 {
1147     UNIMPLEMENTED();
1148     return false;
1149 }
1150 
ValidateGetProgramResourceIndex(const Context * context,ShaderProgramID program,GLenum programInterface,const GLchar * name)1151 bool ValidateGetProgramResourceIndex(const Context *context,
1152                                      ShaderProgramID program,
1153                                      GLenum programInterface,
1154                                      const GLchar *name)
1155 {
1156     if (context->getClientVersion() < ES_3_1)
1157     {
1158         context->validationError(GL_INVALID_OPERATION, kES31Required);
1159         return false;
1160     }
1161 
1162     Program *programObject = GetValidProgram(context, program);
1163     if (programObject == nullptr)
1164     {
1165         return false;
1166     }
1167 
1168     if (!ValidateNamedProgramInterface(programInterface))
1169     {
1170         context->validationError(GL_INVALID_ENUM, kInvalidProgramInterface);
1171         return false;
1172     }
1173 
1174     return true;
1175 }
1176 
ValidateBindVertexBuffer(const Context * context,GLuint bindingIndex,BufferID buffer,GLintptr offset,GLsizei stride)1177 bool ValidateBindVertexBuffer(const Context *context,
1178                               GLuint bindingIndex,
1179                               BufferID buffer,
1180                               GLintptr offset,
1181                               GLsizei stride)
1182 {
1183     if (context->getClientVersion() < ES_3_1)
1184     {
1185         context->validationError(GL_INVALID_OPERATION, kES31Required);
1186         return false;
1187     }
1188 
1189     if (!context->isBufferGenerated(buffer))
1190     {
1191         context->validationError(GL_INVALID_OPERATION, kObjectNotGenerated);
1192         return false;
1193     }
1194 
1195     const Caps &caps = context->getCaps();
1196     if (bindingIndex >= static_cast<GLuint>(caps.maxVertexAttribBindings))
1197     {
1198         context->validationError(GL_INVALID_VALUE, kExceedsMaxVertexAttribBindings);
1199         return false;
1200     }
1201 
1202     if (offset < 0)
1203     {
1204         context->validationError(GL_INVALID_VALUE, kNegativeOffset);
1205         return false;
1206     }
1207 
1208     if (stride < 0 || stride > caps.maxVertexAttribStride)
1209     {
1210         context->validationError(GL_INVALID_VALUE, kExceedsMaxVertexAttribStride);
1211         return false;
1212     }
1213 
1214     // [OpenGL ES 3.1] Section 10.3.1 page 244:
1215     // An INVALID_OPERATION error is generated if the default vertex array object is bound.
1216     if (context->getState().getVertexArrayId().value == 0)
1217     {
1218         context->validationError(GL_INVALID_OPERATION, kDefaultVertexArray);
1219         return false;
1220     }
1221 
1222     return true;
1223 }
1224 
ValidateVertexBindingDivisor(const Context * context,GLuint bindingIndex,GLuint divisor)1225 bool ValidateVertexBindingDivisor(const Context *context, GLuint bindingIndex, GLuint divisor)
1226 {
1227     if (context->getClientVersion() < ES_3_1)
1228     {
1229         context->validationError(GL_INVALID_OPERATION, kES31Required);
1230         return false;
1231     }
1232 
1233     const Caps &caps = context->getCaps();
1234     if (bindingIndex >= static_cast<GLuint>(caps.maxVertexAttribBindings))
1235     {
1236         context->validationError(GL_INVALID_VALUE, kExceedsMaxVertexAttribBindings);
1237         return false;
1238     }
1239 
1240     // [OpenGL ES 3.1] Section 10.3.1 page 243:
1241     // An INVALID_OPERATION error is generated if the default vertex array object is bound.
1242     if (context->getState().getVertexArrayId().value == 0)
1243     {
1244         context->validationError(GL_INVALID_OPERATION, kDefaultVertexArray);
1245         return false;
1246     }
1247 
1248     return true;
1249 }
1250 
ValidateVertexAttribFormat(const Context * context,GLuint attribindex,GLint size,VertexAttribType type,GLboolean normalized,GLuint relativeoffset)1251 bool ValidateVertexAttribFormat(const Context *context,
1252                                 GLuint attribindex,
1253                                 GLint size,
1254                                 VertexAttribType type,
1255                                 GLboolean normalized,
1256                                 GLuint relativeoffset)
1257 {
1258     if (!ValidateVertexAttribFormatCommon(context, relativeoffset))
1259     {
1260         return false;
1261     }
1262 
1263     return ValidateFloatVertexFormat(context, attribindex, size, type);
1264 }
1265 
ValidateVertexAttribIFormat(const Context * context,GLuint attribindex,GLint size,VertexAttribType type,GLuint relativeoffset)1266 bool ValidateVertexAttribIFormat(const Context *context,
1267                                  GLuint attribindex,
1268                                  GLint size,
1269                                  VertexAttribType type,
1270                                  GLuint relativeoffset)
1271 {
1272     if (!ValidateVertexAttribFormatCommon(context, relativeoffset))
1273     {
1274         return false;
1275     }
1276 
1277     return ValidateIntegerVertexFormat(context, attribindex, size, type);
1278 }
1279 
ValidateVertexAttribBinding(const Context * context,GLuint attribIndex,GLuint bindingIndex)1280 bool ValidateVertexAttribBinding(const Context *context, GLuint attribIndex, GLuint bindingIndex)
1281 {
1282     if (context->getClientVersion() < ES_3_1)
1283     {
1284         context->validationError(GL_INVALID_OPERATION, kES31Required);
1285         return false;
1286     }
1287 
1288     // [OpenGL ES 3.1] Section 10.3.1 page 243:
1289     // An INVALID_OPERATION error is generated if the default vertex array object is bound.
1290     if (context->getState().getVertexArrayId().value == 0)
1291     {
1292         context->validationError(GL_INVALID_OPERATION, kDefaultVertexArray);
1293         return false;
1294     }
1295 
1296     const Caps &caps = context->getCaps();
1297     if (attribIndex >= static_cast<GLuint>(caps.maxVertexAttributes))
1298     {
1299         context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
1300         return false;
1301     }
1302 
1303     if (bindingIndex >= static_cast<GLuint>(caps.maxVertexAttribBindings))
1304     {
1305         context->validationError(GL_INVALID_VALUE, kExceedsMaxVertexAttribBindings);
1306         return false;
1307     }
1308 
1309     return true;
1310 }
1311 
ValidateGetProgramResourceName(const Context * context,ShaderProgramID program,GLenum programInterface,GLuint index,GLsizei bufSize,const GLsizei * length,const GLchar * name)1312 bool ValidateGetProgramResourceName(const Context *context,
1313                                     ShaderProgramID program,
1314                                     GLenum programInterface,
1315                                     GLuint index,
1316                                     GLsizei bufSize,
1317                                     const GLsizei *length,
1318                                     const GLchar *name)
1319 {
1320     if (context->getClientVersion() < ES_3_1)
1321     {
1322         context->validationError(GL_INVALID_OPERATION, kES31Required);
1323         return false;
1324     }
1325 
1326     Program *programObject = GetValidProgram(context, program);
1327     if (programObject == nullptr)
1328     {
1329         return false;
1330     }
1331 
1332     if (!ValidateNamedProgramInterface(programInterface))
1333     {
1334         context->validationError(GL_INVALID_ENUM, kInvalidProgramInterface);
1335         return false;
1336     }
1337 
1338     if (!ValidateProgramResourceIndex(programObject, programInterface, index))
1339     {
1340         context->validationError(GL_INVALID_VALUE, kInvalidProgramResourceIndex);
1341         return false;
1342     }
1343 
1344     if (bufSize < 0)
1345     {
1346         context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
1347         return false;
1348     }
1349 
1350     return true;
1351 }
1352 
ValidateDispatchCompute(const Context * context,GLuint numGroupsX,GLuint numGroupsY,GLuint numGroupsZ)1353 bool ValidateDispatchCompute(const Context *context,
1354                              GLuint numGroupsX,
1355                              GLuint numGroupsY,
1356                              GLuint numGroupsZ)
1357 {
1358     if (context->getClientVersion() < ES_3_1)
1359     {
1360         context->validationError(GL_INVALID_OPERATION, kES31Required);
1361         return false;
1362     }
1363 
1364     const State &state                  = context->getState();
1365     const ProgramExecutable *executable = state.getProgramExecutable();
1366 
1367     if (executable == nullptr || !executable->hasLinkedShaderStage(ShaderType::Compute))
1368     {
1369         context->validationError(GL_INVALID_OPERATION, kNoActiveProgramWithComputeShader);
1370         return false;
1371     }
1372 
1373     const Caps &caps = context->getCaps();
1374     if (numGroupsX > static_cast<GLuint>(caps.maxComputeWorkGroupCount[0]))
1375     {
1376         context->validationError(GL_INVALID_VALUE, kExceedsComputeWorkGroupCountX);
1377         return false;
1378     }
1379     if (numGroupsY > static_cast<GLuint>(caps.maxComputeWorkGroupCount[1]))
1380     {
1381         context->validationError(GL_INVALID_VALUE, kExceedsComputeWorkGroupCountY);
1382         return false;
1383     }
1384     if (numGroupsZ > static_cast<GLuint>(caps.maxComputeWorkGroupCount[2]))
1385     {
1386         context->validationError(GL_INVALID_VALUE, kExceedsComputeWorkGroupCountZ);
1387         return false;
1388     }
1389 
1390     return true;
1391 }
1392 
ValidateDispatchComputeIndirect(const Context * context,GLintptr indirect)1393 bool ValidateDispatchComputeIndirect(const Context *context, GLintptr indirect)
1394 {
1395     if (context->getClientVersion() < ES_3_1)
1396     {
1397         context->validationError(GL_INVALID_OPERATION, kES31Required);
1398         return false;
1399     }
1400 
1401     const State &state                  = context->getState();
1402     const ProgramExecutable *executable = state.getProgramExecutable();
1403 
1404     if (executable == nullptr || !executable->hasLinkedShaderStage(ShaderType::Compute))
1405     {
1406         context->validationError(GL_INVALID_OPERATION, kNoActiveProgramWithComputeShader);
1407         return false;
1408     }
1409 
1410     if (indirect < 0)
1411     {
1412         context->validationError(GL_INVALID_VALUE, kNegativeOffset);
1413         return false;
1414     }
1415 
1416     if ((indirect & (sizeof(GLuint) - 1)) != 0)
1417     {
1418         context->validationError(GL_INVALID_VALUE, kOffsetMustBeMultipleOfUint);
1419         return false;
1420     }
1421 
1422     Buffer *dispatchIndirectBuffer = state.getTargetBuffer(BufferBinding::DispatchIndirect);
1423     if (!dispatchIndirectBuffer)
1424     {
1425         context->validationError(GL_INVALID_OPERATION, kDispatchIndirectBufferNotBound);
1426         return false;
1427     }
1428 
1429     CheckedNumeric<GLuint64> checkedOffset(static_cast<GLuint64>(indirect));
1430     auto checkedSum = checkedOffset + static_cast<GLuint64>(3 * sizeof(GLuint));
1431     if (!checkedSum.IsValid() ||
1432         checkedSum.ValueOrDie() > static_cast<GLuint64>(dispatchIndirectBuffer->getSize()))
1433     {
1434         context->validationError(GL_INVALID_OPERATION, kInsufficientBufferSize);
1435         return false;
1436     }
1437 
1438     return true;
1439 }
1440 
ValidateBindImageTexture(const Context * context,GLuint unit,TextureID texture,GLint level,GLboolean layered,GLint layer,GLenum access,GLenum format)1441 bool ValidateBindImageTexture(const Context *context,
1442                               GLuint unit,
1443                               TextureID texture,
1444                               GLint level,
1445                               GLboolean layered,
1446                               GLint layer,
1447                               GLenum access,
1448                               GLenum format)
1449 {
1450     if (context->getClientVersion() < ES_3_1)
1451     {
1452         context->validationError(GL_INVALID_OPERATION, kES31Required);
1453         return false;
1454     }
1455 
1456     GLuint maxImageUnits = static_cast<GLuint>(context->getCaps().maxImageUnits);
1457     if (unit >= maxImageUnits)
1458     {
1459         context->validationError(GL_INVALID_VALUE, kExceedsMaxImageUnits);
1460         return false;
1461     }
1462 
1463     if (level < 0)
1464     {
1465         context->validationError(GL_INVALID_VALUE, kNegativeLevel);
1466         return false;
1467     }
1468 
1469     if (layer < 0)
1470     {
1471         context->validationError(GL_INVALID_VALUE, kNegativeLayer);
1472         return false;
1473     }
1474 
1475     if (access != GL_READ_ONLY && access != GL_WRITE_ONLY && access != GL_READ_WRITE)
1476     {
1477         context->validationError(GL_INVALID_ENUM, kInvalidImageAccess);
1478         return false;
1479     }
1480 
1481     switch (format)
1482     {
1483         case GL_RGBA32F:
1484         case GL_RGBA16F:
1485         case GL_R32F:
1486         case GL_RGBA32UI:
1487         case GL_RGBA16UI:
1488         case GL_RGBA8UI:
1489         case GL_R32UI:
1490         case GL_RGBA32I:
1491         case GL_RGBA16I:
1492         case GL_RGBA8I:
1493         case GL_R32I:
1494         case GL_RGBA8:
1495         case GL_RGBA8_SNORM:
1496             break;
1497         default:
1498             context->validationError(GL_INVALID_VALUE, kInvalidImageFormat);
1499             return false;
1500     }
1501 
1502     if (texture.value != 0)
1503     {
1504         Texture *tex = context->getTexture(texture);
1505 
1506         if (tex == nullptr)
1507         {
1508             context->validationError(GL_INVALID_VALUE, kMissingTextureName);
1509             return false;
1510         }
1511 
1512         if (!tex->getImmutableFormat())
1513         {
1514             context->validationError(GL_INVALID_OPERATION, kTextureIsNotImmutable);
1515             return false;
1516         }
1517     }
1518 
1519     return true;
1520 }
1521 
ValidateGetProgramResourceLocation(const Context * context,ShaderProgramID program,GLenum programInterface,const GLchar * name)1522 bool ValidateGetProgramResourceLocation(const Context *context,
1523                                         ShaderProgramID program,
1524                                         GLenum programInterface,
1525                                         const GLchar *name)
1526 {
1527     if (context->getClientVersion() < ES_3_1)
1528     {
1529         context->validationError(GL_INVALID_OPERATION, kES31Required);
1530         return false;
1531     }
1532 
1533     Program *programObject = GetValidProgram(context, program);
1534     if (programObject == nullptr)
1535     {
1536         return false;
1537     }
1538 
1539     if (!programObject->isLinked())
1540     {
1541         context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
1542         return false;
1543     }
1544 
1545     if (!ValidateLocationProgramInterface(programInterface))
1546     {
1547         context->validationError(GL_INVALID_ENUM, kInvalidProgramInterface);
1548         return false;
1549     }
1550     return true;
1551 }
1552 
ValidateGetProgramResourceiv(const Context * context,ShaderProgramID program,GLenum programInterface,GLuint index,GLsizei propCount,const GLenum * props,GLsizei bufSize,const GLsizei * length,const GLint * params)1553 bool ValidateGetProgramResourceiv(const Context *context,
1554                                   ShaderProgramID program,
1555                                   GLenum programInterface,
1556                                   GLuint index,
1557                                   GLsizei propCount,
1558                                   const GLenum *props,
1559                                   GLsizei bufSize,
1560                                   const GLsizei *length,
1561                                   const GLint *params)
1562 {
1563     if (context->getClientVersion() < ES_3_1)
1564     {
1565         context->validationError(GL_INVALID_OPERATION, kES31Required);
1566         return false;
1567     }
1568 
1569     Program *programObject = GetValidProgram(context, program);
1570     if (programObject == nullptr)
1571     {
1572         return false;
1573     }
1574     if (!ValidateProgramInterface(programInterface))
1575     {
1576         context->validationError(GL_INVALID_ENUM, kInvalidProgramInterface);
1577         return false;
1578     }
1579     if (propCount <= 0)
1580     {
1581         context->validationError(GL_INVALID_VALUE, kInvalidPropCount);
1582         return false;
1583     }
1584     if (bufSize < 0)
1585     {
1586         context->validationError(GL_INVALID_VALUE, kNegativeBufSize);
1587         return false;
1588     }
1589     if (!ValidateProgramResourceIndex(programObject, programInterface, index))
1590     {
1591         context->validationError(GL_INVALID_VALUE, kInvalidProgramResourceIndex);
1592         return false;
1593     }
1594     for (GLsizei i = 0; i < propCount; i++)
1595     {
1596         if (!ValidateProgramResourceProperty(context, props[i]))
1597         {
1598             context->validationError(GL_INVALID_ENUM, kInvalidProgramResourceProperty);
1599             return false;
1600         }
1601         if (!ValidateProgramResourcePropertyByInterface(props[i], programInterface))
1602         {
1603             context->validationError(GL_INVALID_OPERATION, kInvalidPropertyForProgramInterface);
1604             return false;
1605         }
1606     }
1607     return true;
1608 }
1609 
ValidateGetProgramInterfaceiv(const Context * context,ShaderProgramID program,GLenum programInterface,GLenum pname,const GLint * params)1610 bool ValidateGetProgramInterfaceiv(const Context *context,
1611                                    ShaderProgramID program,
1612                                    GLenum programInterface,
1613                                    GLenum pname,
1614                                    const GLint *params)
1615 {
1616     if (context->getClientVersion() < ES_3_1)
1617     {
1618         context->validationError(GL_INVALID_OPERATION, kES31Required);
1619         return false;
1620     }
1621 
1622     Program *programObject = GetValidProgram(context, program);
1623     if (programObject == nullptr)
1624     {
1625         return false;
1626     }
1627 
1628     if (!ValidateProgramInterface(programInterface))
1629     {
1630         context->validationError(GL_INVALID_ENUM, kInvalidProgramInterface);
1631         return false;
1632     }
1633 
1634     switch (pname)
1635     {
1636         case GL_ACTIVE_RESOURCES:
1637         case GL_MAX_NAME_LENGTH:
1638         case GL_MAX_NUM_ACTIVE_VARIABLES:
1639             break;
1640 
1641         default:
1642             context->validationError(GL_INVALID_ENUM, kInvalidPname);
1643             return false;
1644     }
1645 
1646     if (pname == GL_MAX_NAME_LENGTH && programInterface == GL_ATOMIC_COUNTER_BUFFER)
1647     {
1648         context->validationError(GL_INVALID_OPERATION, kAtomicCounterResourceName);
1649         return false;
1650     }
1651 
1652     if (pname == GL_MAX_NUM_ACTIVE_VARIABLES)
1653     {
1654         switch (programInterface)
1655         {
1656             case GL_ATOMIC_COUNTER_BUFFER:
1657             case GL_SHADER_STORAGE_BLOCK:
1658             case GL_UNIFORM_BLOCK:
1659                 break;
1660 
1661             default:
1662                 context->validationError(GL_INVALID_OPERATION, kMaxActiveVariablesInterface);
1663                 return false;
1664         }
1665     }
1666 
1667     return true;
1668 }
1669 
ValidateGetProgramInterfaceivRobustANGLE(const Context * context,ShaderProgramID program,GLenum programInterface,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLint * params)1670 bool ValidateGetProgramInterfaceivRobustANGLE(const Context *context,
1671                                               ShaderProgramID program,
1672                                               GLenum programInterface,
1673                                               GLenum pname,
1674                                               GLsizei bufSize,
1675                                               const GLsizei *length,
1676                                               const GLint *params)
1677 {
1678     UNIMPLEMENTED();
1679     return false;
1680 }
1681 
ValidateGenProgramPipelinesBase(const Context * context,GLsizei n,const ProgramPipelineID * pipelines)1682 bool ValidateGenProgramPipelinesBase(const Context *context,
1683                                      GLsizei n,
1684                                      const ProgramPipelineID *pipelines)
1685 {
1686     return ValidateGenOrDelete(context, n);
1687 }
1688 
ValidateDeleteProgramPipelinesBase(const Context * context,GLsizei n,const ProgramPipelineID * pipelines)1689 bool ValidateDeleteProgramPipelinesBase(const Context *context,
1690                                         GLsizei n,
1691                                         const ProgramPipelineID *pipelines)
1692 {
1693     return ValidateGenOrDelete(context, n);
1694 }
1695 
ValidateBindProgramPipelineBase(const Context * context,ProgramPipelineID pipeline)1696 bool ValidateBindProgramPipelineBase(const Context *context, ProgramPipelineID pipeline)
1697 {
1698     if (!context->isProgramPipelineGenerated({pipeline}))
1699     {
1700         context->validationError(GL_INVALID_OPERATION, kObjectNotGenerated);
1701         return false;
1702     }
1703 
1704     return true;
1705 }
1706 
ValidateIsProgramPipelineBase(const Context * context,ProgramPipelineID pipeline)1707 bool ValidateIsProgramPipelineBase(const Context *context, ProgramPipelineID pipeline)
1708 {
1709     return true;
1710 }
1711 
ValidateUseProgramStagesBase(const Context * context,ProgramPipelineID pipeline,GLbitfield stages,ShaderProgramID programId)1712 bool ValidateUseProgramStagesBase(const Context *context,
1713                                   ProgramPipelineID pipeline,
1714                                   GLbitfield stages,
1715                                   ShaderProgramID programId)
1716 {
1717     // GL_INVALID_VALUE is generated if shaders contains set bits that are not recognized, and is
1718     // not the reserved value GL_ALL_SHADER_BITS.
1719     GLbitfield knownShaderBits =
1720         GL_VERTEX_SHADER_BIT | GL_FRAGMENT_SHADER_BIT | GL_COMPUTE_SHADER_BIT;
1721 
1722     if (context->getClientVersion() >= ES_3_2 || context->getExtensions().geometryShaderAny())
1723     {
1724         knownShaderBits |= GL_GEOMETRY_SHADER_BIT;
1725     }
1726 
1727     if (context->getClientVersion() >= ES_3_2 || context->getExtensions().tessellationShaderEXT)
1728     {
1729         knownShaderBits |= GL_TESS_CONTROL_SHADER_BIT;
1730         knownShaderBits |= GL_TESS_EVALUATION_SHADER_BIT;
1731     }
1732 
1733     if ((stages & ~knownShaderBits) && (stages != GL_ALL_SHADER_BITS))
1734     {
1735         context->validationError(GL_INVALID_VALUE, kUnrecognizedShaderStageBit);
1736         return false;
1737     }
1738 
1739     // GL_INVALID_OPERATION is generated if pipeline is not a name previously returned from a call
1740     // to glGenProgramPipelines or if such a name has been deleted by a call to
1741     // glDeleteProgramPipelines.
1742     if (!context->isProgramPipelineGenerated({pipeline}))
1743     {
1744         context->validationError(GL_INVALID_OPERATION, kObjectNotGenerated);
1745         return false;
1746     }
1747 
1748     // If program is zero, or refers to a program object with no valid shader executable for a given
1749     // stage, it is as if the pipeline object has no programmable stage configured for the indicated
1750     // shader stages.
1751     if (programId.value == 0)
1752     {
1753         return true;
1754     }
1755 
1756     Program *program = context->getProgramNoResolveLink(programId);
1757     if (!program)
1758     {
1759         context->validationError(GL_INVALID_VALUE, kProgramDoesNotExist);
1760         return false;
1761     }
1762 
1763     // GL_INVALID_OPERATION is generated if program refers to a program object that was not linked
1764     // with its GL_PROGRAM_SEPARABLE status set.
1765     // resolveLink() may not have been called if glCreateShaderProgramv() was not used and
1766     // glDetachShader() was not called.
1767     program->resolveLink(context);
1768     if (!program->isSeparable())
1769     {
1770         context->validationError(GL_INVALID_OPERATION, kProgramNotSeparable);
1771         return false;
1772     }
1773 
1774     // GL_INVALID_OPERATION is generated if program refers to a program object that has not been
1775     // successfully linked.
1776     if (!program->isLinked())
1777     {
1778         context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
1779         return false;
1780     }
1781 
1782     return true;
1783 }
1784 
ValidateActiveShaderProgramBase(const Context * context,ProgramPipelineID pipeline,ShaderProgramID programId)1785 bool ValidateActiveShaderProgramBase(const Context *context,
1786                                      ProgramPipelineID pipeline,
1787                                      ShaderProgramID programId)
1788 {
1789     // An INVALID_OPERATION error is generated if pipeline is not a name returned from a previous
1790     // call to GenProgramPipelines or if such a name has since been deleted by
1791     // DeleteProgramPipelines.
1792     if (!context->isProgramPipelineGenerated({pipeline}))
1793     {
1794         context->validationError(GL_INVALID_OPERATION, kObjectNotGenerated);
1795         return false;
1796     }
1797 
1798     // An INVALID_VALUE error is generated if program is not zero and is not the name of either a
1799     // program or shader object.
1800     if ((programId.value != 0) && !context->isProgram(programId) && !context->isShader(programId))
1801     {
1802         context->validationError(GL_INVALID_VALUE, kProgramDoesNotExist);
1803         return false;
1804     }
1805 
1806     // An INVALID_OPERATION error is generated if program is the name of a shader object.
1807     if (context->isShader(programId))
1808     {
1809         context->validationError(GL_INVALID_OPERATION, kExpectedProgramName);
1810         return false;
1811     }
1812 
1813     // An INVALID_OPERATION error is generated if program is not zero and has not been linked, or
1814     // was last linked unsuccessfully. The active program is not modified.
1815     Program *program = context->getProgramNoResolveLink(programId);
1816     if ((programId.value != 0) && !program->isLinked())
1817     {
1818         context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
1819         return false;
1820     }
1821 
1822     return true;
1823 }
1824 
ValidateCreateShaderProgramvBase(const Context * context,ShaderType type,GLsizei count,const GLchar * const * strings)1825 bool ValidateCreateShaderProgramvBase(const Context *context,
1826                                       ShaderType type,
1827                                       GLsizei count,
1828                                       const GLchar *const *strings)
1829 {
1830     switch (type)
1831     {
1832         case ShaderType::InvalidEnum:
1833             context->validationError(GL_INVALID_ENUM, kInvalidShaderType);
1834             return false;
1835         case ShaderType::Vertex:
1836         case ShaderType::Fragment:
1837         case ShaderType::Compute:
1838             break;
1839         case ShaderType::Geometry:
1840             if (!context->getExtensions().geometryShaderAny() &&
1841                 context->getClientVersion() < ES_3_2)
1842             {
1843                 context->validationError(GL_INVALID_ENUM, kInvalidShaderType);
1844                 return false;
1845             }
1846             break;
1847         case ShaderType::TessControl:
1848         case ShaderType::TessEvaluation:
1849             if (!context->getExtensions().tessellationShaderEXT &&
1850                 context->getClientVersion() < ES_3_2)
1851             {
1852                 context->validationError(GL_INVALID_ENUM, kInvalidShaderType);
1853                 return false;
1854             }
1855             break;
1856         default:
1857             UNREACHABLE();
1858     }
1859 
1860     // GL_INVALID_VALUE is generated if count is negative.
1861     if (count < 0)
1862     {
1863         context->validationError(GL_INVALID_VALUE, kNegativeCount);
1864         return false;
1865     }
1866 
1867     return true;
1868 }
1869 
ValidateCreateShaderProgramvBase(const Context * context,ShaderType type,GLsizei count,const GLchar ** strings)1870 bool ValidateCreateShaderProgramvBase(const Context *context,
1871                                       ShaderType type,
1872                                       GLsizei count,
1873                                       const GLchar **strings)
1874 {
1875     const GLchar *const *tmpStrings = strings;
1876     return ValidateCreateShaderProgramvBase(context, type, count, tmpStrings);
1877 }
1878 
ValidateGetProgramPipelineivBase(const Context * context,ProgramPipelineID pipeline,GLenum pname,const GLint * params)1879 bool ValidateGetProgramPipelineivBase(const Context *context,
1880                                       ProgramPipelineID pipeline,
1881                                       GLenum pname,
1882                                       const GLint *params)
1883 {
1884     // An INVALID_OPERATION error is generated if pipeline is not a name returned from a previous
1885     // call to GenProgramPipelines or if such a name has since been deleted by
1886     // DeleteProgramPipelines.
1887     if ((pipeline.value == 0) || (!context->isProgramPipelineGenerated(pipeline)))
1888     {
1889         context->validationError(GL_INVALID_OPERATION, kProgramPipelineDoesNotExist);
1890         return false;
1891     }
1892 
1893     // An INVALID_ENUM error is generated if pname is not ACTIVE_PROGRAM,
1894     // INFO_LOG_LENGTH, VALIDATE_STATUS, or one of the type arguments in
1895     // table 7.1.
1896     switch (pname)
1897     {
1898         case GL_ACTIVE_PROGRAM:
1899         case GL_INFO_LOG_LENGTH:
1900         case GL_VALIDATE_STATUS:
1901         case GL_VERTEX_SHADER:
1902         case GL_FRAGMENT_SHADER:
1903         case GL_COMPUTE_SHADER:
1904             break;
1905         case GL_GEOMETRY_SHADER:
1906             return context->getExtensions().geometryShaderAny() ||
1907                    context->getClientVersion() >= ES_3_2;
1908         case GL_TESS_CONTROL_SHADER:
1909         case GL_TESS_EVALUATION_SHADER:
1910             return context->getExtensions().tessellationShaderEXT ||
1911                    context->getClientVersion() >= ES_3_2;
1912 
1913         default:
1914             context->validationError(GL_INVALID_ENUM, kInvalidPname);
1915             return false;
1916     }
1917 
1918     return true;
1919 }
1920 
ValidateValidateProgramPipelineBase(const Context * context,ProgramPipelineID pipeline)1921 bool ValidateValidateProgramPipelineBase(const Context *context, ProgramPipelineID pipeline)
1922 {
1923     if (pipeline.value == 0)
1924     {
1925         return false;
1926     }
1927 
1928     if (!context->isProgramPipelineGenerated(pipeline))
1929     {
1930         context->validationError(GL_INVALID_OPERATION, kProgramPipelineDoesNotExist);
1931         return false;
1932     }
1933 
1934     return true;
1935 }
1936 
ValidateGetProgramPipelineInfoLogBase(const Context * context,ProgramPipelineID pipeline,GLsizei bufSize,const GLsizei * length,const GLchar * infoLog)1937 bool ValidateGetProgramPipelineInfoLogBase(const Context *context,
1938                                            ProgramPipelineID pipeline,
1939                                            GLsizei bufSize,
1940                                            const GLsizei *length,
1941                                            const GLchar *infoLog)
1942 {
1943     if (bufSize < 0)
1944     {
1945         context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
1946         return false;
1947     }
1948 
1949     if (!context->isProgramPipelineGenerated(pipeline))
1950     {
1951         context->validationError(GL_INVALID_VALUE, kProgramPipelineDoesNotExist);
1952         return false;
1953     }
1954 
1955     return true;
1956 }
1957 
ValidateActiveShaderProgram(const Context * context,ProgramPipelineID pipelinePacked,ShaderProgramID programPacked)1958 bool ValidateActiveShaderProgram(const Context *context,
1959                                  ProgramPipelineID pipelinePacked,
1960                                  ShaderProgramID programPacked)
1961 {
1962     if (context->getClientVersion() < ES_3_1)
1963     {
1964         context->validationError(GL_INVALID_OPERATION, kES31Required);
1965         return false;
1966     }
1967 
1968     return ValidateActiveShaderProgramBase(context, pipelinePacked, programPacked);
1969 }
1970 
ValidateBindProgramPipeline(const Context * context,ProgramPipelineID pipelinePacked)1971 bool ValidateBindProgramPipeline(const Context *context, ProgramPipelineID pipelinePacked)
1972 {
1973     if (context->getClientVersion() < ES_3_1)
1974     {
1975         context->validationError(GL_INVALID_OPERATION, kES31Required);
1976         return false;
1977     }
1978 
1979     return ValidateBindProgramPipelineBase(context, pipelinePacked);
1980 }
1981 
ValidateCreateShaderProgramv(const Context * context,ShaderType typePacked,GLsizei count,const GLchar * const * strings)1982 bool ValidateCreateShaderProgramv(const Context *context,
1983                                   ShaderType typePacked,
1984                                   GLsizei count,
1985                                   const GLchar *const *strings)
1986 {
1987     if (context->getClientVersion() < ES_3_1)
1988     {
1989         context->validationError(GL_INVALID_OPERATION, kES31Required);
1990         return false;
1991     }
1992 
1993     return ValidateCreateShaderProgramvBase(context, typePacked, count, strings);
1994 }
1995 
ValidateDeleteProgramPipelines(const Context * context,GLsizei n,const ProgramPipelineID * pipelinesPacked)1996 bool ValidateDeleteProgramPipelines(const Context *context,
1997                                     GLsizei n,
1998                                     const ProgramPipelineID *pipelinesPacked)
1999 {
2000     if (context->getClientVersion() < ES_3_1)
2001     {
2002         context->validationError(GL_INVALID_OPERATION, kES31Required);
2003         return false;
2004     }
2005 
2006     return ValidateDeleteProgramPipelinesBase(context, n, pipelinesPacked);
2007 }
2008 
ValidateGenProgramPipelines(const Context * context,GLsizei n,const ProgramPipelineID * pipelinesPacked)2009 bool ValidateGenProgramPipelines(const Context *context,
2010                                  GLsizei n,
2011                                  const ProgramPipelineID *pipelinesPacked)
2012 {
2013     if (context->getClientVersion() < ES_3_1)
2014     {
2015         context->validationError(GL_INVALID_OPERATION, kES31Required);
2016         return false;
2017     }
2018 
2019     return ValidateGenProgramPipelinesBase(context, n, pipelinesPacked);
2020 }
2021 
ValidateGetProgramPipelineInfoLog(const Context * context,ProgramPipelineID pipelinePacked,GLsizei bufSize,const GLsizei * length,const GLchar * infoLog)2022 bool ValidateGetProgramPipelineInfoLog(const Context *context,
2023                                        ProgramPipelineID pipelinePacked,
2024                                        GLsizei bufSize,
2025                                        const GLsizei *length,
2026                                        const GLchar *infoLog)
2027 {
2028     if (context->getClientVersion() < ES_3_1)
2029     {
2030         context->validationError(GL_INVALID_OPERATION, kES31Required);
2031         return false;
2032     }
2033 
2034     return ValidateGetProgramPipelineInfoLogBase(context, pipelinePacked, bufSize, length, infoLog);
2035 }
2036 
ValidateGetProgramPipelineiv(const Context * context,ProgramPipelineID pipelinePacked,GLenum pname,const GLint * params)2037 bool ValidateGetProgramPipelineiv(const Context *context,
2038                                   ProgramPipelineID pipelinePacked,
2039                                   GLenum pname,
2040                                   const GLint *params)
2041 {
2042     if (context->getClientVersion() < ES_3_1)
2043     {
2044         context->validationError(GL_INVALID_OPERATION, kES31Required);
2045         return false;
2046     }
2047 
2048     return ValidateGetProgramPipelineivBase(context, pipelinePacked, pname, params);
2049 }
2050 
ValidateIsProgramPipeline(const Context * context,ProgramPipelineID pipelinePacked)2051 bool ValidateIsProgramPipeline(const Context *context, ProgramPipelineID pipelinePacked)
2052 {
2053     if (context->getClientVersion() < ES_3_1)
2054     {
2055         context->validationError(GL_INVALID_OPERATION, kES31Required);
2056         return false;
2057     }
2058 
2059     return ValidateIsProgramPipelineBase(context, pipelinePacked);
2060 }
2061 
ValidateProgramUniform1f(const Context * context,ShaderProgramID programPacked,UniformLocation locationPacked,GLfloat v0)2062 bool ValidateProgramUniform1f(const Context *context,
2063                               ShaderProgramID programPacked,
2064                               UniformLocation locationPacked,
2065                               GLfloat v0)
2066 {
2067     if (context->getClientVersion() < ES_3_1)
2068     {
2069         context->validationError(GL_INVALID_OPERATION, kES31Required);
2070         return false;
2071     }
2072 
2073     return ValidateProgramUniform1fBase(context, programPacked, locationPacked, v0);
2074 }
2075 
ValidateProgramUniform1fv(const Context * context,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLfloat * value)2076 bool ValidateProgramUniform1fv(const Context *context,
2077                                ShaderProgramID programPacked,
2078                                UniformLocation locationPacked,
2079                                GLsizei count,
2080                                const GLfloat *value)
2081 {
2082     if (context->getClientVersion() < ES_3_1)
2083     {
2084         context->validationError(GL_INVALID_OPERATION, kES31Required);
2085         return false;
2086     }
2087 
2088     return ValidateProgramUniform1fvBase(context, programPacked, locationPacked, count, value);
2089 }
2090 
ValidateProgramUniform1i(const Context * context,ShaderProgramID programPacked,UniformLocation locationPacked,GLint v0)2091 bool ValidateProgramUniform1i(const Context *context,
2092                               ShaderProgramID programPacked,
2093                               UniformLocation locationPacked,
2094                               GLint v0)
2095 {
2096     if (context->getClientVersion() < ES_3_1)
2097     {
2098         context->validationError(GL_INVALID_OPERATION, kES31Required);
2099         return false;
2100     }
2101 
2102     return ValidateProgramUniform1iBase(context, programPacked, locationPacked, v0);
2103 }
2104 
ValidateProgramUniform1iv(const Context * context,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLint * value)2105 bool ValidateProgramUniform1iv(const Context *context,
2106                                ShaderProgramID programPacked,
2107                                UniformLocation locationPacked,
2108                                GLsizei count,
2109                                const GLint *value)
2110 {
2111     if (context->getClientVersion() < ES_3_1)
2112     {
2113         context->validationError(GL_INVALID_OPERATION, kES31Required);
2114         return false;
2115     }
2116 
2117     return ValidateProgramUniform1ivBase(context, programPacked, locationPacked, count, value);
2118 }
2119 
ValidateProgramUniform1ui(const Context * context,ShaderProgramID programPacked,UniformLocation locationPacked,GLuint v0)2120 bool ValidateProgramUniform1ui(const Context *context,
2121                                ShaderProgramID programPacked,
2122                                UniformLocation locationPacked,
2123                                GLuint v0)
2124 {
2125     if (context->getClientVersion() < ES_3_1)
2126     {
2127         context->validationError(GL_INVALID_OPERATION, kES31Required);
2128         return false;
2129     }
2130 
2131     return ValidateProgramUniform1uiBase(context, programPacked, locationPacked, v0);
2132 }
2133 
ValidateProgramUniform1uiv(const Context * context,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLuint * value)2134 bool ValidateProgramUniform1uiv(const Context *context,
2135                                 ShaderProgramID programPacked,
2136                                 UniformLocation locationPacked,
2137                                 GLsizei count,
2138                                 const GLuint *value)
2139 {
2140     if (context->getClientVersion() < ES_3_1)
2141     {
2142         context->validationError(GL_INVALID_OPERATION, kES31Required);
2143         return false;
2144     }
2145 
2146     return ValidateProgramUniform1uivBase(context, programPacked, locationPacked, count, value);
2147 }
2148 
ValidateProgramUniform2f(const Context * context,ShaderProgramID programPacked,UniformLocation locationPacked,GLfloat v0,GLfloat v1)2149 bool ValidateProgramUniform2f(const Context *context,
2150                               ShaderProgramID programPacked,
2151                               UniformLocation locationPacked,
2152                               GLfloat v0,
2153                               GLfloat v1)
2154 {
2155     if (context->getClientVersion() < ES_3_1)
2156     {
2157         context->validationError(GL_INVALID_OPERATION, kES31Required);
2158         return false;
2159     }
2160 
2161     return ValidateProgramUniform2fBase(context, programPacked, locationPacked, v0, v1);
2162 }
2163 
ValidateProgramUniform2fv(const Context * context,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLfloat * value)2164 bool ValidateProgramUniform2fv(const Context *context,
2165                                ShaderProgramID programPacked,
2166                                UniformLocation locationPacked,
2167                                GLsizei count,
2168                                const GLfloat *value)
2169 {
2170     if (context->getClientVersion() < ES_3_1)
2171     {
2172         context->validationError(GL_INVALID_OPERATION, kES31Required);
2173         return false;
2174     }
2175 
2176     return ValidateProgramUniform2fvBase(context, programPacked, locationPacked, count, value);
2177 }
2178 
ValidateProgramUniform2i(const Context * context,ShaderProgramID programPacked,UniformLocation locationPacked,GLint v0,GLint v1)2179 bool ValidateProgramUniform2i(const Context *context,
2180                               ShaderProgramID programPacked,
2181                               UniformLocation locationPacked,
2182                               GLint v0,
2183                               GLint v1)
2184 {
2185     if (context->getClientVersion() < ES_3_1)
2186     {
2187         context->validationError(GL_INVALID_OPERATION, kES31Required);
2188         return false;
2189     }
2190 
2191     return ValidateProgramUniform2iBase(context, programPacked, locationPacked, v0, v1);
2192 }
2193 
ValidateProgramUniform2iv(const Context * context,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLint * value)2194 bool ValidateProgramUniform2iv(const Context *context,
2195                                ShaderProgramID programPacked,
2196                                UniformLocation locationPacked,
2197                                GLsizei count,
2198                                const GLint *value)
2199 {
2200     if (context->getClientVersion() < ES_3_1)
2201     {
2202         context->validationError(GL_INVALID_OPERATION, kES31Required);
2203         return false;
2204     }
2205 
2206     return ValidateProgramUniform2ivBase(context, programPacked, locationPacked, count, value);
2207 }
2208 
ValidateProgramUniform2ui(const Context * context,ShaderProgramID programPacked,UniformLocation locationPacked,GLuint v0,GLuint v1)2209 bool ValidateProgramUniform2ui(const Context *context,
2210                                ShaderProgramID programPacked,
2211                                UniformLocation locationPacked,
2212                                GLuint v0,
2213                                GLuint v1)
2214 {
2215     if (context->getClientVersion() < ES_3_1)
2216     {
2217         context->validationError(GL_INVALID_OPERATION, kES31Required);
2218         return false;
2219     }
2220 
2221     return ValidateProgramUniform2uiBase(context, programPacked, locationPacked, v0, v1);
2222 }
2223 
ValidateProgramUniform2uiv(const Context * context,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLuint * value)2224 bool ValidateProgramUniform2uiv(const Context *context,
2225                                 ShaderProgramID programPacked,
2226                                 UniformLocation locationPacked,
2227                                 GLsizei count,
2228                                 const GLuint *value)
2229 {
2230     if (context->getClientVersion() < ES_3_1)
2231     {
2232         context->validationError(GL_INVALID_OPERATION, kES31Required);
2233         return false;
2234     }
2235 
2236     return ValidateProgramUniform2uivBase(context, programPacked, locationPacked, count, value);
2237 }
2238 
ValidateProgramUniform3f(const Context * context,ShaderProgramID programPacked,UniformLocation locationPacked,GLfloat v0,GLfloat v1,GLfloat v2)2239 bool ValidateProgramUniform3f(const Context *context,
2240                               ShaderProgramID programPacked,
2241                               UniformLocation locationPacked,
2242                               GLfloat v0,
2243                               GLfloat v1,
2244                               GLfloat v2)
2245 {
2246     if (context->getClientVersion() < ES_3_1)
2247     {
2248         context->validationError(GL_INVALID_OPERATION, kES31Required);
2249         return false;
2250     }
2251 
2252     return ValidateProgramUniform3fBase(context, programPacked, locationPacked, v0, v1, v2);
2253 }
2254 
ValidateProgramUniform3fv(const Context * context,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLfloat * value)2255 bool ValidateProgramUniform3fv(const Context *context,
2256                                ShaderProgramID programPacked,
2257                                UniformLocation locationPacked,
2258                                GLsizei count,
2259                                const GLfloat *value)
2260 {
2261     if (context->getClientVersion() < ES_3_1)
2262     {
2263         context->validationError(GL_INVALID_OPERATION, kES31Required);
2264         return false;
2265     }
2266 
2267     return ValidateProgramUniform3fvBase(context, programPacked, locationPacked, count, value);
2268 }
2269 
ValidateProgramUniform3i(const Context * context,ShaderProgramID programPacked,UniformLocation locationPacked,GLint v0,GLint v1,GLint v2)2270 bool ValidateProgramUniform3i(const Context *context,
2271                               ShaderProgramID programPacked,
2272                               UniformLocation locationPacked,
2273                               GLint v0,
2274                               GLint v1,
2275                               GLint v2)
2276 {
2277     if (context->getClientVersion() < ES_3_1)
2278     {
2279         context->validationError(GL_INVALID_OPERATION, kES31Required);
2280         return false;
2281     }
2282 
2283     return ValidateProgramUniform3iBase(context, programPacked, locationPacked, v0, v1, v2);
2284 }
2285 
ValidateProgramUniform3iv(const Context * context,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLint * value)2286 bool ValidateProgramUniform3iv(const Context *context,
2287                                ShaderProgramID programPacked,
2288                                UniformLocation locationPacked,
2289                                GLsizei count,
2290                                const GLint *value)
2291 {
2292     if (context->getClientVersion() < ES_3_1)
2293     {
2294         context->validationError(GL_INVALID_OPERATION, kES31Required);
2295         return false;
2296     }
2297 
2298     return ValidateProgramUniform3ivBase(context, programPacked, locationPacked, count, value);
2299 }
2300 
ValidateProgramUniform3ui(const Context * context,ShaderProgramID programPacked,UniformLocation locationPacked,GLuint v0,GLuint v1,GLuint v2)2301 bool ValidateProgramUniform3ui(const Context *context,
2302                                ShaderProgramID programPacked,
2303                                UniformLocation locationPacked,
2304                                GLuint v0,
2305                                GLuint v1,
2306                                GLuint v2)
2307 {
2308     if (context->getClientVersion() < ES_3_1)
2309     {
2310         context->validationError(GL_INVALID_OPERATION, kES31Required);
2311         return false;
2312     }
2313 
2314     return ValidateProgramUniform3uiBase(context, programPacked, locationPacked, v0, v1, v2);
2315 }
2316 
ValidateProgramUniform3uiv(const Context * context,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLuint * value)2317 bool ValidateProgramUniform3uiv(const Context *context,
2318                                 ShaderProgramID programPacked,
2319                                 UniformLocation locationPacked,
2320                                 GLsizei count,
2321                                 const GLuint *value)
2322 {
2323     if (context->getClientVersion() < ES_3_1)
2324     {
2325         context->validationError(GL_INVALID_OPERATION, kES31Required);
2326         return false;
2327     }
2328 
2329     return ValidateProgramUniform3uivBase(context, programPacked, locationPacked, count, value);
2330 }
2331 
ValidateProgramUniform4f(const Context * context,ShaderProgramID programPacked,UniformLocation locationPacked,GLfloat v0,GLfloat v1,GLfloat v2,GLfloat v3)2332 bool ValidateProgramUniform4f(const Context *context,
2333                               ShaderProgramID programPacked,
2334                               UniformLocation locationPacked,
2335                               GLfloat v0,
2336                               GLfloat v1,
2337                               GLfloat v2,
2338                               GLfloat v3)
2339 {
2340     if (context->getClientVersion() < ES_3_1)
2341     {
2342         context->validationError(GL_INVALID_OPERATION, kES31Required);
2343         return false;
2344     }
2345 
2346     return ValidateProgramUniform4fBase(context, programPacked, locationPacked, v0, v1, v2, v3);
2347 }
2348 
ValidateProgramUniform4fv(const Context * context,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLfloat * value)2349 bool ValidateProgramUniform4fv(const Context *context,
2350                                ShaderProgramID programPacked,
2351                                UniformLocation locationPacked,
2352                                GLsizei count,
2353                                const GLfloat *value)
2354 {
2355     if (context->getClientVersion() < ES_3_1)
2356     {
2357         context->validationError(GL_INVALID_OPERATION, kES31Required);
2358         return false;
2359     }
2360 
2361     return ValidateProgramUniform4fvBase(context, programPacked, locationPacked, count, value);
2362 }
2363 
ValidateProgramUniform4i(const Context * context,ShaderProgramID programPacked,UniformLocation locationPacked,GLint v0,GLint v1,GLint v2,GLint v3)2364 bool ValidateProgramUniform4i(const Context *context,
2365                               ShaderProgramID programPacked,
2366                               UniformLocation locationPacked,
2367                               GLint v0,
2368                               GLint v1,
2369                               GLint v2,
2370                               GLint v3)
2371 {
2372     if (context->getClientVersion() < ES_3_1)
2373     {
2374         context->validationError(GL_INVALID_OPERATION, kES31Required);
2375         return false;
2376     }
2377 
2378     return ValidateProgramUniform4iBase(context, programPacked, locationPacked, v0, v1, v2, v3);
2379 }
2380 
ValidateProgramUniform4iv(const Context * context,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLint * value)2381 bool ValidateProgramUniform4iv(const Context *context,
2382                                ShaderProgramID programPacked,
2383                                UniformLocation locationPacked,
2384                                GLsizei count,
2385                                const GLint *value)
2386 {
2387     if (context->getClientVersion() < ES_3_1)
2388     {
2389         context->validationError(GL_INVALID_OPERATION, kES31Required);
2390         return false;
2391     }
2392 
2393     return ValidateProgramUniform4ivBase(context, programPacked, locationPacked, count, value);
2394 }
2395 
ValidateProgramUniform4ui(const Context * context,ShaderProgramID programPacked,UniformLocation locationPacked,GLuint v0,GLuint v1,GLuint v2,GLuint v3)2396 bool ValidateProgramUniform4ui(const Context *context,
2397                                ShaderProgramID programPacked,
2398                                UniformLocation locationPacked,
2399                                GLuint v0,
2400                                GLuint v1,
2401                                GLuint v2,
2402                                GLuint v3)
2403 {
2404     if (context->getClientVersion() < ES_3_1)
2405     {
2406         context->validationError(GL_INVALID_OPERATION, kES31Required);
2407         return false;
2408     }
2409 
2410     return ValidateProgramUniform4uiBase(context, programPacked, locationPacked, v0, v1, v2, v3);
2411 }
2412 
ValidateProgramUniform4uiv(const Context * context,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLuint * value)2413 bool ValidateProgramUniform4uiv(const Context *context,
2414                                 ShaderProgramID programPacked,
2415                                 UniformLocation locationPacked,
2416                                 GLsizei count,
2417                                 const GLuint *value)
2418 {
2419     if (context->getClientVersion() < ES_3_1)
2420     {
2421         context->validationError(GL_INVALID_OPERATION, kES31Required);
2422         return false;
2423     }
2424 
2425     return ValidateProgramUniform4uivBase(context, programPacked, locationPacked, count, value);
2426 }
2427 
ValidateProgramUniformMatrix2fv(const Context * context,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,GLboolean transpose,const GLfloat * value)2428 bool ValidateProgramUniformMatrix2fv(const Context *context,
2429                                      ShaderProgramID programPacked,
2430                                      UniformLocation locationPacked,
2431                                      GLsizei count,
2432                                      GLboolean transpose,
2433                                      const GLfloat *value)
2434 {
2435     if (context->getClientVersion() < ES_3_1)
2436     {
2437         context->validationError(GL_INVALID_OPERATION, kES31Required);
2438         return false;
2439     }
2440 
2441     return ValidateProgramUniformMatrix2fvBase(context, programPacked, locationPacked, count,
2442                                                transpose, value);
2443 }
2444 
ValidateProgramUniformMatrix2x3fv(const Context * context,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,GLboolean transpose,const GLfloat * value)2445 bool ValidateProgramUniformMatrix2x3fv(const Context *context,
2446                                        ShaderProgramID programPacked,
2447                                        UniformLocation locationPacked,
2448                                        GLsizei count,
2449                                        GLboolean transpose,
2450                                        const GLfloat *value)
2451 {
2452     if (context->getClientVersion() < ES_3_1)
2453     {
2454         context->validationError(GL_INVALID_OPERATION, kES31Required);
2455         return false;
2456     }
2457 
2458     return ValidateProgramUniformMatrix2x3fvBase(context, programPacked, locationPacked, count,
2459                                                  transpose, value);
2460 }
2461 
ValidateProgramUniformMatrix2x4fv(const Context * context,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,GLboolean transpose,const GLfloat * value)2462 bool ValidateProgramUniformMatrix2x4fv(const Context *context,
2463                                        ShaderProgramID programPacked,
2464                                        UniformLocation locationPacked,
2465                                        GLsizei count,
2466                                        GLboolean transpose,
2467                                        const GLfloat *value)
2468 {
2469     if (context->getClientVersion() < ES_3_1)
2470     {
2471         context->validationError(GL_INVALID_OPERATION, kES31Required);
2472         return false;
2473     }
2474 
2475     return ValidateProgramUniformMatrix2x4fvBase(context, programPacked, locationPacked, count,
2476                                                  transpose, value);
2477 }
2478 
ValidateProgramUniformMatrix3fv(const Context * context,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,GLboolean transpose,const GLfloat * value)2479 bool ValidateProgramUniformMatrix3fv(const Context *context,
2480                                      ShaderProgramID programPacked,
2481                                      UniformLocation locationPacked,
2482                                      GLsizei count,
2483                                      GLboolean transpose,
2484                                      const GLfloat *value)
2485 {
2486     if (context->getClientVersion() < ES_3_1)
2487     {
2488         context->validationError(GL_INVALID_OPERATION, kES31Required);
2489         return false;
2490     }
2491 
2492     return ValidateProgramUniformMatrix3fvBase(context, programPacked, locationPacked, count,
2493                                                transpose, value);
2494 }
2495 
ValidateProgramUniformMatrix3x2fv(const Context * context,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,GLboolean transpose,const GLfloat * value)2496 bool ValidateProgramUniformMatrix3x2fv(const Context *context,
2497                                        ShaderProgramID programPacked,
2498                                        UniformLocation locationPacked,
2499                                        GLsizei count,
2500                                        GLboolean transpose,
2501                                        const GLfloat *value)
2502 {
2503     if (context->getClientVersion() < ES_3_1)
2504     {
2505         context->validationError(GL_INVALID_OPERATION, kES31Required);
2506         return false;
2507     }
2508 
2509     return ValidateProgramUniformMatrix3x2fvBase(context, programPacked, locationPacked, count,
2510                                                  transpose, value);
2511 }
2512 
ValidateProgramUniformMatrix3x4fv(const Context * context,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,GLboolean transpose,const GLfloat * value)2513 bool ValidateProgramUniformMatrix3x4fv(const Context *context,
2514                                        ShaderProgramID programPacked,
2515                                        UniformLocation locationPacked,
2516                                        GLsizei count,
2517                                        GLboolean transpose,
2518                                        const GLfloat *value)
2519 {
2520     if (context->getClientVersion() < ES_3_1)
2521     {
2522         context->validationError(GL_INVALID_OPERATION, kES31Required);
2523         return false;
2524     }
2525 
2526     return ValidateProgramUniformMatrix3x4fvBase(context, programPacked, locationPacked, count,
2527                                                  transpose, value);
2528 }
2529 
ValidateProgramUniformMatrix4fv(const Context * context,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,GLboolean transpose,const GLfloat * value)2530 bool ValidateProgramUniformMatrix4fv(const Context *context,
2531                                      ShaderProgramID programPacked,
2532                                      UniformLocation locationPacked,
2533                                      GLsizei count,
2534                                      GLboolean transpose,
2535                                      const GLfloat *value)
2536 {
2537     if (context->getClientVersion() < ES_3_1)
2538     {
2539         context->validationError(GL_INVALID_OPERATION, kES31Required);
2540         return false;
2541     }
2542 
2543     return ValidateProgramUniformMatrix4fvBase(context, programPacked, locationPacked, count,
2544                                                transpose, value);
2545 }
2546 
ValidateProgramUniformMatrix4x2fv(const Context * context,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,GLboolean transpose,const GLfloat * value)2547 bool ValidateProgramUniformMatrix4x2fv(const Context *context,
2548                                        ShaderProgramID programPacked,
2549                                        UniformLocation locationPacked,
2550                                        GLsizei count,
2551                                        GLboolean transpose,
2552                                        const GLfloat *value)
2553 {
2554     if (context->getClientVersion() < ES_3_1)
2555     {
2556         context->validationError(GL_INVALID_OPERATION, kES31Required);
2557         return false;
2558     }
2559 
2560     return ValidateProgramUniformMatrix4x2fvBase(context, programPacked, locationPacked, count,
2561                                                  transpose, value);
2562 }
2563 
ValidateProgramUniformMatrix4x3fv(const Context * context,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,GLboolean transpose,const GLfloat * value)2564 bool ValidateProgramUniformMatrix4x3fv(const Context *context,
2565                                        ShaderProgramID programPacked,
2566                                        UniformLocation locationPacked,
2567                                        GLsizei count,
2568                                        GLboolean transpose,
2569                                        const GLfloat *value)
2570 {
2571     if (context->getClientVersion() < ES_3_1)
2572     {
2573         context->validationError(GL_INVALID_OPERATION, kES31Required);
2574         return false;
2575     }
2576 
2577     return ValidateProgramUniformMatrix4x3fvBase(context, programPacked, locationPacked, count,
2578                                                  transpose, value);
2579 }
2580 
ValidateUseProgramStages(const Context * context,ProgramPipelineID pipelinePacked,GLbitfield stages,ShaderProgramID programPacked)2581 bool ValidateUseProgramStages(const Context *context,
2582                               ProgramPipelineID pipelinePacked,
2583                               GLbitfield stages,
2584                               ShaderProgramID programPacked)
2585 {
2586     if (context->getClientVersion() < ES_3_1)
2587     {
2588         context->validationError(GL_INVALID_OPERATION, kES31Required);
2589         return false;
2590     }
2591 
2592     return ValidateUseProgramStagesBase(context, pipelinePacked, stages, programPacked);
2593 }
2594 
ValidateValidateProgramPipeline(const Context * context,ProgramPipelineID pipelinePacked)2595 bool ValidateValidateProgramPipeline(const Context *context, ProgramPipelineID pipelinePacked)
2596 {
2597     if (context->getClientVersion() < ES_3_1)
2598     {
2599         context->validationError(GL_INVALID_OPERATION, kES31Required);
2600         return false;
2601     }
2602 
2603     return ValidateValidateProgramPipelineBase(context, pipelinePacked);
2604 }
2605 
ValidateMemoryBarrier(const Context * context,GLbitfield barriers)2606 bool ValidateMemoryBarrier(const Context *context, GLbitfield barriers)
2607 {
2608     if (context->getClientVersion() < ES_3_1)
2609     {
2610         context->validationError(GL_INVALID_OPERATION, kES31Required);
2611         return false;
2612     }
2613 
2614     if (barriers == GL_ALL_BARRIER_BITS)
2615     {
2616         return true;
2617     }
2618 
2619     GLbitfield supported_barrier_bits =
2620         GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT | GL_ELEMENT_ARRAY_BARRIER_BIT | GL_UNIFORM_BARRIER_BIT |
2621         GL_TEXTURE_FETCH_BARRIER_BIT | GL_SHADER_IMAGE_ACCESS_BARRIER_BIT | GL_COMMAND_BARRIER_BIT |
2622         GL_PIXEL_BUFFER_BARRIER_BIT | GL_TEXTURE_UPDATE_BARRIER_BIT | GL_BUFFER_UPDATE_BARRIER_BIT |
2623         GL_FRAMEBUFFER_BARRIER_BIT | GL_TRANSFORM_FEEDBACK_BARRIER_BIT |
2624         GL_ATOMIC_COUNTER_BARRIER_BIT | GL_SHADER_STORAGE_BARRIER_BIT;
2625 
2626     if (context->getExtensions().bufferStorageEXT)
2627     {
2628         supported_barrier_bits |= GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT_EXT;
2629     }
2630 
2631     if (barriers == 0 || (barriers & ~supported_barrier_bits) != 0)
2632     {
2633         context->validationError(GL_INVALID_VALUE, kInvalidMemoryBarrierBit);
2634         return false;
2635     }
2636 
2637     return true;
2638 }
2639 
ValidateMemoryBarrierByRegion(const Context * context,GLbitfield barriers)2640 bool ValidateMemoryBarrierByRegion(const Context *context, GLbitfield barriers)
2641 {
2642     if (context->getClientVersion() < ES_3_1)
2643     {
2644         context->validationError(GL_INVALID_OPERATION, kES31Required);
2645         return false;
2646     }
2647 
2648     if (barriers == GL_ALL_BARRIER_BITS)
2649     {
2650         return true;
2651     }
2652 
2653     GLbitfield supported_barrier_bits = GL_ATOMIC_COUNTER_BARRIER_BIT | GL_FRAMEBUFFER_BARRIER_BIT |
2654                                         GL_SHADER_IMAGE_ACCESS_BARRIER_BIT |
2655                                         GL_SHADER_STORAGE_BARRIER_BIT |
2656                                         GL_TEXTURE_FETCH_BARRIER_BIT | GL_UNIFORM_BARRIER_BIT;
2657     if (barriers == 0 || (barriers & ~supported_barrier_bits) != 0)
2658     {
2659         context->validationError(GL_INVALID_VALUE, kInvalidMemoryBarrierBit);
2660         return false;
2661     }
2662 
2663     return true;
2664 }
2665 
ValidateSampleMaski(const Context * context,GLuint maskNumber,GLbitfield mask)2666 bool ValidateSampleMaski(const Context *context, GLuint maskNumber, GLbitfield mask)
2667 {
2668     if (context->getClientVersion() < ES_3_1)
2669     {
2670         context->validationError(GL_INVALID_OPERATION, kES31Required);
2671         return false;
2672     }
2673 
2674     return ValidateSampleMaskiBase(context, maskNumber, mask);
2675 }
2676 
ValidateMinSampleShadingOES(const Context * context,GLfloat value)2677 bool ValidateMinSampleShadingOES(const Context *context, GLfloat value)
2678 {
2679     if (!context->getExtensions().sampleShadingOES)
2680     {
2681         context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
2682         return false;
2683     }
2684 
2685     return true;
2686 }
2687 
ValidateFramebufferTextureCommon(const Context * context,GLenum target,GLenum attachment,TextureID texture,GLint level)2688 bool ValidateFramebufferTextureCommon(const Context *context,
2689                                       GLenum target,
2690                                       GLenum attachment,
2691                                       TextureID texture,
2692                                       GLint level)
2693 {
2694     if (texture.value != 0)
2695     {
2696         Texture *tex = context->getTexture(texture);
2697 
2698         // [EXT_geometry_shader] Section 9.2.8 "Attaching Texture Images to a Framebuffer"
2699         // An INVALID_VALUE error is generated if <texture> is not the name of a texture object.
2700         // We put this validation before ValidateFramebufferTextureBase because it is an
2701         // INVALID_OPERATION error for both FramebufferTexture2D and FramebufferTextureLayer:
2702         // [OpenGL ES 3.1] Chapter 9.2.8 (FramebufferTexture2D)
2703         // An INVALID_OPERATION error is generated if texture is not zero, and does not name an
2704         // existing texture object of type matching textarget.
2705         // [OpenGL ES 3.1 Chapter 9.2.8 (FramebufferTextureLayer)
2706         // An INVALID_OPERATION error is generated if texture is non-zero and is not the name of a
2707         // three-dimensional or two-dimensional array texture.
2708         if (tex == nullptr)
2709         {
2710             context->validationError(GL_INVALID_VALUE, kInvalidTextureName);
2711             return false;
2712         }
2713 
2714         if (!ValidMipLevel(context, tex->getType(), level))
2715         {
2716             context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
2717             return false;
2718         }
2719     }
2720 
2721     if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
2722     {
2723         return false;
2724     }
2725 
2726     return true;
2727 }
2728 
ValidateFramebufferTextureEXT(const Context * context,GLenum target,GLenum attachment,TextureID texture,GLint level)2729 bool ValidateFramebufferTextureEXT(const Context *context,
2730                                    GLenum target,
2731                                    GLenum attachment,
2732                                    TextureID texture,
2733                                    GLint level)
2734 {
2735     if (!context->getExtensions().geometryShaderEXT)
2736     {
2737         context->validationError(GL_INVALID_OPERATION, kGeometryShaderExtensionNotEnabled);
2738         return false;
2739     }
2740 
2741     return ValidateFramebufferTextureCommon(context, target, attachment, texture, level);
2742 }
2743 
ValidateFramebufferTextureOES(const Context * context,GLenum target,GLenum attachment,TextureID texture,GLint level)2744 bool ValidateFramebufferTextureOES(const Context *context,
2745                                    GLenum target,
2746                                    GLenum attachment,
2747                                    TextureID texture,
2748                                    GLint level)
2749 {
2750     if (!context->getExtensions().geometryShaderOES)
2751     {
2752         context->validationError(GL_INVALID_OPERATION, kGeometryShaderExtensionNotEnabled);
2753         return false;
2754     }
2755 
2756     return ValidateFramebufferTextureCommon(context, target, attachment, texture, level);
2757 }
2758 
2759 // GL_OES_texture_storage_multisample_2d_array
ValidateTexStorage3DMultisampleOES(const Context * context,TextureType target,GLsizei samples,GLenum sizedinternalformat,GLsizei width,GLsizei height,GLsizei depth,GLboolean fixedsamplelocations)2760 bool ValidateTexStorage3DMultisampleOES(const Context *context,
2761                                         TextureType target,
2762                                         GLsizei samples,
2763                                         GLenum sizedinternalformat,
2764                                         GLsizei width,
2765                                         GLsizei height,
2766                                         GLsizei depth,
2767                                         GLboolean fixedsamplelocations)
2768 {
2769     if (!context->getExtensions().textureStorageMultisample2DArrayOES)
2770     {
2771         context->validationError(GL_INVALID_ENUM, kMultisampleArrayExtensionRequired);
2772         return false;
2773     }
2774 
2775     if (target != TextureType::_2DMultisampleArray)
2776     {
2777         context->validationError(GL_INVALID_ENUM, kTargetMustBeTexture2DMultisampleArrayOES);
2778         return false;
2779     }
2780 
2781     if (width < 1 || height < 1 || depth < 1)
2782     {
2783         context->validationError(GL_INVALID_VALUE, kNegativeSize);
2784         return false;
2785     }
2786 
2787     if (depth > context->getCaps().maxArrayTextureLayers)
2788     {
2789         context->validationError(GL_INVALID_VALUE, kTextureDepthOutOfRange);
2790         return false;
2791     }
2792 
2793     return ValidateTexStorageMultisample(context, target, samples, sizedinternalformat, width,
2794                                          height);
2795 }
2796 
ValidateTexStorageMem3DMultisampleEXT(const Context * context,TextureType target,GLsizei samples,GLenum internalFormat,GLsizei width,GLsizei height,GLsizei depth,GLboolean fixedSampleLocations,MemoryObjectID memory,GLuint64 offset)2797 bool ValidateTexStorageMem3DMultisampleEXT(const Context *context,
2798                                            TextureType target,
2799                                            GLsizei samples,
2800                                            GLenum internalFormat,
2801                                            GLsizei width,
2802                                            GLsizei height,
2803                                            GLsizei depth,
2804                                            GLboolean fixedSampleLocations,
2805                                            MemoryObjectID memory,
2806                                            GLuint64 offset)
2807 {
2808     if (!context->getExtensions().memoryObject)
2809     {
2810         context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
2811         return false;
2812     }
2813 
2814     UNIMPLEMENTED();
2815     return false;
2816 }
2817 
ValidateGetProgramResourceLocationIndexEXT(const Context * context,ShaderProgramID program,GLenum programInterface,const char * name)2818 bool ValidateGetProgramResourceLocationIndexEXT(const Context *context,
2819                                                 ShaderProgramID program,
2820                                                 GLenum programInterface,
2821                                                 const char *name)
2822 {
2823     if (!context->getExtensions().blendFuncExtended)
2824     {
2825         context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
2826         return false;
2827     }
2828     if (context->getClientVersion() < ES_3_1)
2829     {
2830         context->validationError(GL_INVALID_OPERATION, kES31Required);
2831         return false;
2832     }
2833     if (programInterface != GL_PROGRAM_OUTPUT)
2834     {
2835         context->validationError(GL_INVALID_ENUM, kProgramInterfaceMustBeProgramOutput);
2836         return false;
2837     }
2838     Program *programObject = GetValidProgram(context, program);
2839     if (!programObject)
2840     {
2841         return false;
2842     }
2843     if (!programObject->isLinked())
2844     {
2845         context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
2846         return false;
2847     }
2848     return true;
2849 }
2850 
2851 // GL_OES_texture_buffer
ValidateTexBufferOES(const Context * context,TextureType target,GLenum internalformat,BufferID bufferPacked)2852 bool ValidateTexBufferOES(const Context *context,
2853                           TextureType target,
2854                           GLenum internalformat,
2855                           BufferID bufferPacked)
2856 {
2857     if (!context->getExtensions().textureBufferOES)
2858     {
2859         context->validationError(GL_INVALID_OPERATION, kTextureBufferExtensionNotAvailable);
2860         return false;
2861     }
2862 
2863     return ValidateTexBufferBase(context, target, internalformat, bufferPacked);
2864 }
2865 
ValidateTexBufferRangeOES(const Context * context,TextureType target,GLenum internalformat,BufferID bufferPacked,GLintptr offset,GLsizeiptr size)2866 bool ValidateTexBufferRangeOES(const Context *context,
2867                                TextureType target,
2868                                GLenum internalformat,
2869                                BufferID bufferPacked,
2870                                GLintptr offset,
2871                                GLsizeiptr size)
2872 {
2873     if (!context->getExtensions().textureBufferOES)
2874     {
2875         context->validationError(GL_INVALID_OPERATION, kTextureBufferExtensionNotAvailable);
2876         return false;
2877     }
2878 
2879     return ValidateTexBufferRangeBase(context, target, internalformat, bufferPacked, offset, size);
2880 }
2881 
2882 // GL_EXT_texture_buffer
ValidateTexBufferEXT(const Context * context,TextureType target,GLenum internalformat,BufferID bufferPacked)2883 bool ValidateTexBufferEXT(const Context *context,
2884                           TextureType target,
2885                           GLenum internalformat,
2886                           BufferID bufferPacked)
2887 {
2888     if (!context->getExtensions().textureBufferEXT)
2889     {
2890         context->validationError(GL_INVALID_OPERATION, kTextureBufferExtensionNotAvailable);
2891         return false;
2892     }
2893 
2894     return ValidateTexBufferBase(context, target, internalformat, bufferPacked);
2895 }
2896 
ValidateTexBufferRangeEXT(const Context * context,TextureType target,GLenum internalformat,BufferID bufferPacked,GLintptr offset,GLsizeiptr size)2897 bool ValidateTexBufferRangeEXT(const Context *context,
2898                                TextureType target,
2899                                GLenum internalformat,
2900                                BufferID bufferPacked,
2901                                GLintptr offset,
2902                                GLsizeiptr size)
2903 {
2904     if (!context->getExtensions().textureBufferEXT)
2905     {
2906         context->validationError(GL_INVALID_OPERATION, kTextureBufferExtensionNotAvailable);
2907         return false;
2908     }
2909 
2910     return ValidateTexBufferRangeBase(context, target, internalformat, bufferPacked, offset, size);
2911 }
2912 
ValidateTexBufferBase(const Context * context,TextureType target,GLenum internalformat,BufferID bufferPacked)2913 bool ValidateTexBufferBase(const Context *context,
2914                            TextureType target,
2915                            GLenum internalformat,
2916                            BufferID bufferPacked)
2917 {
2918     if (target != TextureType::Buffer)
2919     {
2920         context->validationError(GL_INVALID_ENUM, kTextureBufferTarget);
2921         return false;
2922     }
2923 
2924     switch (internalformat)
2925     {
2926         case GL_R8:
2927         case GL_R16F:
2928         case GL_R32F:
2929         case GL_R8I:
2930         case GL_R16I:
2931         case GL_R32I:
2932         case GL_R8UI:
2933         case GL_R16UI:
2934         case GL_R32UI:
2935         case GL_RG8:
2936         case GL_RG16F:
2937         case GL_RG32F:
2938         case GL_RG8I:
2939         case GL_RG16I:
2940         case GL_RG32I:
2941         case GL_RG8UI:
2942         case GL_RG16UI:
2943         case GL_RG32UI:
2944         case GL_RGB32F:
2945         case GL_RGB32I:
2946         case GL_RGB32UI:
2947         case GL_RGBA8:
2948         case GL_RGBA16F:
2949         case GL_RGBA32F:
2950         case GL_RGBA8I:
2951         case GL_RGBA16I:
2952         case GL_RGBA32I:
2953         case GL_RGBA8UI:
2954         case GL_RGBA16UI:
2955         case GL_RGBA32UI:
2956             break;
2957 
2958         default:
2959             context->validationError(GL_INVALID_ENUM, kTextureBufferInternalFormat);
2960             return false;
2961     }
2962 
2963     if (bufferPacked.value != 0)
2964     {
2965         if (!context->isBufferGenerated(bufferPacked))
2966         {
2967             context->validationError(GL_INVALID_OPERATION, kTextureBufferInvalidBuffer);
2968             return false;
2969         }
2970     }
2971 
2972     return true;
2973 }
2974 
ValidateTexBufferRangeBase(const Context * context,TextureType target,GLenum internalformat,BufferID bufferPacked,GLintptr offset,GLsizeiptr size)2975 bool ValidateTexBufferRangeBase(const Context *context,
2976                                 TextureType target,
2977                                 GLenum internalformat,
2978                                 BufferID bufferPacked,
2979                                 GLintptr offset,
2980                                 GLsizeiptr size)
2981 {
2982     const Caps &caps = context->getCaps();
2983 
2984     if (offset < 0 || (offset % caps.textureBufferOffsetAlignment) != 0)
2985     {
2986         context->validationError(GL_INVALID_VALUE, kTextureBufferOffsetAlignment);
2987         return false;
2988     }
2989     if (size <= 0)
2990     {
2991         context->validationError(GL_INVALID_VALUE, kTextureBufferSize);
2992         return false;
2993     }
2994     const Buffer *buffer = context->getBuffer(bufferPacked);
2995 
2996     if (!buffer)
2997     {
2998         context->validationError(GL_INVALID_OPERATION, kBufferNotBound);
2999         return false;
3000     }
3001 
3002     if (offset + size > buffer->getSize())
3003     {
3004         context->validationError(GL_INVALID_VALUE, kTextureBufferSizeOffset);
3005         return false;
3006     }
3007 
3008     return ValidateTexBufferBase(context, target, internalformat, bufferPacked);
3009 }
3010 
3011 }  // namespace gl
3012