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