• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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().tessellationShaderEXT ||
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     switch (programInterface)
289     {
290         case GL_PROGRAM_INPUT:
291             return (index <
292                     static_cast<GLuint>(programObject->getState().getProgramInputs().size()));
293 
294         case GL_PROGRAM_OUTPUT:
295             return (index < static_cast<GLuint>(programObject->getOutputResourceCount()));
296 
297         case GL_UNIFORM:
298             return (index < static_cast<GLuint>(programObject->getActiveUniformCount()));
299 
300         case GL_BUFFER_VARIABLE:
301             return (index < static_cast<GLuint>(programObject->getActiveBufferVariableCount()));
302 
303         case GL_SHADER_STORAGE_BLOCK:
304             return (index < static_cast<GLuint>(programObject->getActiveShaderStorageBlockCount()));
305 
306         case GL_UNIFORM_BLOCK:
307             return (index < programObject->getActiveUniformBlockCount());
308 
309         case GL_ATOMIC_COUNTER_BUFFER:
310             return (index < programObject->getActiveAtomicCounterBufferCount());
311 
312         case GL_TRANSFORM_FEEDBACK_VARYING:
313             return (index < static_cast<GLuint>(programObject->getTransformFeedbackVaryingCount()));
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.getProgramExecutable();
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 
1525     return true;
1526 }
1527 
ValidateGetProgramResourceLocation(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,GLenum programInterface,const GLchar * name)1528 bool ValidateGetProgramResourceLocation(const Context *context,
1529                                         angle::EntryPoint entryPoint,
1530                                         ShaderProgramID program,
1531                                         GLenum programInterface,
1532                                         const GLchar *name)
1533 {
1534     if (context->getClientVersion() < ES_3_1)
1535     {
1536         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
1537         return false;
1538     }
1539 
1540     Program *programObject = GetValidProgram(context, entryPoint, program);
1541     if (programObject == nullptr)
1542     {
1543         return false;
1544     }
1545 
1546     if (!programObject->isLinked())
1547     {
1548         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kProgramNotLinked);
1549         return false;
1550     }
1551 
1552     if (!ValidateLocationProgramInterface(programInterface))
1553     {
1554         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidProgramInterface);
1555         return false;
1556     }
1557     return true;
1558 }
1559 
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)1560 bool ValidateGetProgramResourceiv(const Context *context,
1561                                   angle::EntryPoint entryPoint,
1562                                   ShaderProgramID program,
1563                                   GLenum programInterface,
1564                                   GLuint index,
1565                                   GLsizei propCount,
1566                                   const GLenum *props,
1567                                   GLsizei bufSize,
1568                                   const GLsizei *length,
1569                                   const GLint *params)
1570 {
1571     if (context->getClientVersion() < ES_3_1)
1572     {
1573         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
1574         return false;
1575     }
1576 
1577     Program *programObject = GetValidProgram(context, entryPoint, program);
1578     if (programObject == nullptr)
1579     {
1580         return false;
1581     }
1582     if (!ValidateProgramInterface(programInterface))
1583     {
1584         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidProgramInterface);
1585         return false;
1586     }
1587     if (propCount <= 0)
1588     {
1589         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidPropCount);
1590         return false;
1591     }
1592     if (bufSize < 0)
1593     {
1594         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeBufSize);
1595         return false;
1596     }
1597     if (!ValidateProgramResourceIndex(programObject, programInterface, index))
1598     {
1599         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidProgramResourceIndex);
1600         return false;
1601     }
1602     for (GLsizei i = 0; i < propCount; i++)
1603     {
1604         if (!ValidateProgramResourceProperty(context, entryPoint, props[i]))
1605         {
1606             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidProgramResourceProperty);
1607             return false;
1608         }
1609         if (!ValidateProgramResourcePropertyByInterface(props[i], programInterface))
1610         {
1611             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidPropertyForProgramInterface);
1612             return false;
1613         }
1614     }
1615     return true;
1616 }
1617 
ValidateGetProgramInterfaceiv(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,GLenum programInterface,GLenum pname,const GLint * params)1618 bool ValidateGetProgramInterfaceiv(const Context *context,
1619                                    angle::EntryPoint entryPoint,
1620                                    ShaderProgramID program,
1621                                    GLenum programInterface,
1622                                    GLenum pname,
1623                                    const GLint *params)
1624 {
1625     if (context->getClientVersion() < ES_3_1)
1626     {
1627         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
1628         return false;
1629     }
1630 
1631     Program *programObject = GetValidProgram(context, entryPoint, program);
1632     if (programObject == nullptr)
1633     {
1634         return false;
1635     }
1636 
1637     if (!ValidateProgramInterface(programInterface))
1638     {
1639         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidProgramInterface);
1640         return false;
1641     }
1642 
1643     switch (pname)
1644     {
1645         case GL_ACTIVE_RESOURCES:
1646         case GL_MAX_NAME_LENGTH:
1647         case GL_MAX_NUM_ACTIVE_VARIABLES:
1648             break;
1649 
1650         default:
1651             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidPname);
1652             return false;
1653     }
1654 
1655     if (pname == GL_MAX_NAME_LENGTH && programInterface == GL_ATOMIC_COUNTER_BUFFER)
1656     {
1657         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kAtomicCounterResourceName);
1658         return false;
1659     }
1660 
1661     if (pname == GL_MAX_NUM_ACTIVE_VARIABLES)
1662     {
1663         switch (programInterface)
1664         {
1665             case GL_ATOMIC_COUNTER_BUFFER:
1666             case GL_SHADER_STORAGE_BLOCK:
1667             case GL_UNIFORM_BLOCK:
1668                 break;
1669 
1670             default:
1671                 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kMaxActiveVariablesInterface);
1672                 return false;
1673         }
1674     }
1675 
1676     return true;
1677 }
1678 
ValidateGetProgramInterfaceivRobustANGLE(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,GLenum programInterface,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLint * params)1679 bool ValidateGetProgramInterfaceivRobustANGLE(const Context *context,
1680                                               angle::EntryPoint entryPoint,
1681                                               ShaderProgramID program,
1682                                               GLenum programInterface,
1683                                               GLenum pname,
1684                                               GLsizei bufSize,
1685                                               const GLsizei *length,
1686                                               const GLint *params)
1687 {
1688     UNIMPLEMENTED();
1689     return false;
1690 }
1691 
ValidateGenProgramPipelinesBase(const Context * context,angle::EntryPoint entryPoint,GLsizei n,const ProgramPipelineID * pipelines)1692 bool ValidateGenProgramPipelinesBase(const Context *context,
1693                                      angle::EntryPoint entryPoint,
1694                                      GLsizei n,
1695                                      const ProgramPipelineID *pipelines)
1696 {
1697     return ValidateGenOrDelete(context, entryPoint, n);
1698 }
1699 
ValidateDeleteProgramPipelinesBase(const Context * context,angle::EntryPoint entryPoint,GLsizei n,const ProgramPipelineID * pipelines)1700 bool ValidateDeleteProgramPipelinesBase(const Context *context,
1701                                         angle::EntryPoint entryPoint,
1702                                         GLsizei n,
1703                                         const ProgramPipelineID *pipelines)
1704 {
1705     return ValidateGenOrDelete(context, entryPoint, n);
1706 }
1707 
ValidateBindProgramPipelineBase(const Context * context,angle::EntryPoint entryPoint,ProgramPipelineID pipeline)1708 bool ValidateBindProgramPipelineBase(const Context *context,
1709                                      angle::EntryPoint entryPoint,
1710                                      ProgramPipelineID pipeline)
1711 {
1712     if (!context->isProgramPipelineGenerated({pipeline}))
1713     {
1714         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kObjectNotGenerated);
1715         return false;
1716     }
1717 
1718     return true;
1719 }
1720 
ValidateIsProgramPipelineBase(const Context * context,angle::EntryPoint entryPoint,ProgramPipelineID pipeline)1721 bool ValidateIsProgramPipelineBase(const Context *context,
1722                                    angle::EntryPoint entryPoint,
1723                                    ProgramPipelineID pipeline)
1724 {
1725     return true;
1726 }
1727 
ValidateUseProgramStagesBase(const Context * context,angle::EntryPoint entryPoint,ProgramPipelineID pipeline,GLbitfield stages,ShaderProgramID programId)1728 bool ValidateUseProgramStagesBase(const Context *context,
1729                                   angle::EntryPoint entryPoint,
1730                                   ProgramPipelineID pipeline,
1731                                   GLbitfield stages,
1732                                   ShaderProgramID programId)
1733 {
1734     // GL_INVALID_VALUE is generated if shaders contains set bits that are not recognized, and is
1735     // not the reserved value GL_ALL_SHADER_BITS.
1736     GLbitfield knownShaderBits =
1737         GL_VERTEX_SHADER_BIT | GL_FRAGMENT_SHADER_BIT | GL_COMPUTE_SHADER_BIT;
1738 
1739     if (context->getClientVersion() >= ES_3_2 || context->getExtensions().geometryShaderAny())
1740     {
1741         knownShaderBits |= GL_GEOMETRY_SHADER_BIT;
1742     }
1743 
1744     if (context->getClientVersion() >= ES_3_2 || context->getExtensions().tessellationShaderEXT)
1745     {
1746         knownShaderBits |= GL_TESS_CONTROL_SHADER_BIT;
1747         knownShaderBits |= GL_TESS_EVALUATION_SHADER_BIT;
1748     }
1749 
1750     if ((stages & ~knownShaderBits) && (stages != GL_ALL_SHADER_BITS))
1751     {
1752         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kUnrecognizedShaderStageBit);
1753         return false;
1754     }
1755 
1756     // GL_INVALID_OPERATION is generated if pipeline is not a name previously returned from a call
1757     // to glGenProgramPipelines or if such a name has been deleted by a call to
1758     // glDeleteProgramPipelines.
1759     if (!context->isProgramPipelineGenerated({pipeline}))
1760     {
1761         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kObjectNotGenerated);
1762         return false;
1763     }
1764 
1765     // If program is zero, or refers to a program object with no valid shader executable for a given
1766     // stage, it is as if the pipeline object has no programmable stage configured for the indicated
1767     // shader stages.
1768     if (programId.value == 0)
1769     {
1770         return true;
1771     }
1772 
1773     Program *program = context->getProgramNoResolveLink(programId);
1774     if (!program)
1775     {
1776         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kProgramDoesNotExist);
1777         return false;
1778     }
1779 
1780     // GL_INVALID_OPERATION is generated if program refers to a program object that was not linked
1781     // with its GL_PROGRAM_SEPARABLE status set.
1782     // resolveLink() may not have been called if glCreateShaderProgramv() was not used and
1783     // glDetachShader() was not called.
1784     program->resolveLink(context);
1785     if (!program->isSeparable())
1786     {
1787         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kProgramNotSeparable);
1788         return false;
1789     }
1790 
1791     // GL_INVALID_OPERATION is generated if program refers to a program object that has not been
1792     // successfully linked.
1793     if (!program->isLinked())
1794     {
1795         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kProgramNotLinked);
1796         return false;
1797     }
1798 
1799     return true;
1800 }
1801 
ValidateActiveShaderProgramBase(const Context * context,angle::EntryPoint entryPoint,ProgramPipelineID pipeline,ShaderProgramID programId)1802 bool ValidateActiveShaderProgramBase(const Context *context,
1803                                      angle::EntryPoint entryPoint,
1804                                      ProgramPipelineID pipeline,
1805                                      ShaderProgramID programId)
1806 {
1807     // An INVALID_OPERATION error is generated if pipeline is not a name returned from a previous
1808     // call to GenProgramPipelines or if such a name has since been deleted by
1809     // DeleteProgramPipelines.
1810     if (!context->isProgramPipelineGenerated({pipeline}))
1811     {
1812         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kObjectNotGenerated);
1813         return false;
1814     }
1815 
1816     // An INVALID_VALUE error is generated if program is not zero and is not the name of either a
1817     // program or shader object.
1818     if ((programId.value != 0) && !context->isProgram(programId) && !context->isShader(programId))
1819     {
1820         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kProgramDoesNotExist);
1821         return false;
1822     }
1823 
1824     // An INVALID_OPERATION error is generated if program is the name of a shader object.
1825     if (context->isShader(programId))
1826     {
1827         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExpectedProgramName);
1828         return false;
1829     }
1830 
1831     // An INVALID_OPERATION error is generated if program is not zero and has not been linked, or
1832     // was last linked unsuccessfully. The active program is not modified.
1833     Program *program = context->getProgramNoResolveLink(programId);
1834     if ((programId.value != 0) && !program->isLinked())
1835     {
1836         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kProgramNotLinked);
1837         return false;
1838     }
1839 
1840     return true;
1841 }
1842 
ValidateCreateShaderProgramvBase(const Context * context,angle::EntryPoint entryPoint,ShaderType type,GLsizei count,const GLchar * const * strings)1843 bool ValidateCreateShaderProgramvBase(const Context *context,
1844                                       angle::EntryPoint entryPoint,
1845                                       ShaderType type,
1846                                       GLsizei count,
1847                                       const GLchar *const *strings)
1848 {
1849     switch (type)
1850     {
1851         case ShaderType::InvalidEnum:
1852             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidShaderType);
1853             return false;
1854         case ShaderType::Vertex:
1855         case ShaderType::Fragment:
1856         case ShaderType::Compute:
1857             break;
1858         case ShaderType::Geometry:
1859             if (!context->getExtensions().geometryShaderAny() &&
1860                 context->getClientVersion() < ES_3_2)
1861             {
1862                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidShaderType);
1863                 return false;
1864             }
1865             break;
1866         case ShaderType::TessControl:
1867         case ShaderType::TessEvaluation:
1868             if (!context->getExtensions().tessellationShaderEXT &&
1869                 context->getClientVersion() < ES_3_2)
1870             {
1871                 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidShaderType);
1872                 return false;
1873             }
1874             break;
1875         default:
1876             UNREACHABLE();
1877     }
1878 
1879     // GL_INVALID_VALUE is generated if count is negative.
1880     if (count < 0)
1881     {
1882         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeCount);
1883         return false;
1884     }
1885 
1886     return true;
1887 }
1888 
ValidateCreateShaderProgramvBase(const Context * context,angle::EntryPoint entryPoint,ShaderType type,GLsizei count,const GLchar ** strings)1889 bool ValidateCreateShaderProgramvBase(const Context *context,
1890                                       angle::EntryPoint entryPoint,
1891                                       ShaderType type,
1892                                       GLsizei count,
1893                                       const GLchar **strings)
1894 {
1895     const GLchar *const *tmpStrings = strings;
1896     return ValidateCreateShaderProgramvBase(context, entryPoint, type, count, tmpStrings);
1897 }
1898 
ValidateGetProgramPipelineivBase(const Context * context,angle::EntryPoint entryPoint,ProgramPipelineID pipeline,GLenum pname,const GLint * params)1899 bool ValidateGetProgramPipelineivBase(const Context *context,
1900                                       angle::EntryPoint entryPoint,
1901                                       ProgramPipelineID pipeline,
1902                                       GLenum pname,
1903                                       const GLint *params)
1904 {
1905     // An INVALID_OPERATION error is generated if pipeline is not a name returned from a previous
1906     // call to GenProgramPipelines or if such a name has since been deleted by
1907     // DeleteProgramPipelines.
1908     if ((pipeline.value == 0) || (!context->isProgramPipelineGenerated(pipeline)))
1909     {
1910         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kProgramPipelineDoesNotExist);
1911         return false;
1912     }
1913 
1914     // An INVALID_ENUM error is generated if pname is not ACTIVE_PROGRAM,
1915     // INFO_LOG_LENGTH, VALIDATE_STATUS, or one of the type arguments in
1916     // table 7.1.
1917     switch (pname)
1918     {
1919         case GL_ACTIVE_PROGRAM:
1920         case GL_INFO_LOG_LENGTH:
1921         case GL_VALIDATE_STATUS:
1922         case GL_VERTEX_SHADER:
1923         case GL_FRAGMENT_SHADER:
1924         case GL_COMPUTE_SHADER:
1925             break;
1926         case GL_GEOMETRY_SHADER:
1927             return context->getExtensions().geometryShaderAny() ||
1928                    context->getClientVersion() >= ES_3_2;
1929         case GL_TESS_CONTROL_SHADER:
1930         case GL_TESS_EVALUATION_SHADER:
1931             return context->getExtensions().tessellationShaderEXT ||
1932                    context->getClientVersion() >= ES_3_2;
1933 
1934         default:
1935             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidPname);
1936             return false;
1937     }
1938 
1939     return true;
1940 }
1941 
ValidateValidateProgramPipelineBase(const Context * context,angle::EntryPoint entryPoint,ProgramPipelineID pipeline)1942 bool ValidateValidateProgramPipelineBase(const Context *context,
1943                                          angle::EntryPoint entryPoint,
1944                                          ProgramPipelineID pipeline)
1945 {
1946     if (pipeline.value == 0)
1947     {
1948         return false;
1949     }
1950 
1951     if (!context->isProgramPipelineGenerated(pipeline))
1952     {
1953         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kProgramPipelineDoesNotExist);
1954         return false;
1955     }
1956 
1957     return true;
1958 }
1959 
ValidateGetProgramPipelineInfoLogBase(const Context * context,angle::EntryPoint entryPoint,ProgramPipelineID pipeline,GLsizei bufSize,const GLsizei * length,const GLchar * infoLog)1960 bool ValidateGetProgramPipelineInfoLogBase(const Context *context,
1961                                            angle::EntryPoint entryPoint,
1962                                            ProgramPipelineID pipeline,
1963                                            GLsizei bufSize,
1964                                            const GLsizei *length,
1965                                            const GLchar *infoLog)
1966 {
1967     if (bufSize < 0)
1968     {
1969         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeBufferSize);
1970         return false;
1971     }
1972 
1973     if (!context->isProgramPipelineGenerated(pipeline))
1974     {
1975         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kProgramPipelineDoesNotExist);
1976         return false;
1977     }
1978 
1979     return true;
1980 }
1981 
ValidateActiveShaderProgram(const Context * context,angle::EntryPoint entryPoint,ProgramPipelineID pipelinePacked,ShaderProgramID programPacked)1982 bool ValidateActiveShaderProgram(const Context *context,
1983                                  angle::EntryPoint entryPoint,
1984                                  ProgramPipelineID pipelinePacked,
1985                                  ShaderProgramID programPacked)
1986 {
1987     if (context->getClientVersion() < ES_3_1)
1988     {
1989         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
1990         return false;
1991     }
1992 
1993     return ValidateActiveShaderProgramBase(context, entryPoint, pipelinePacked, programPacked);
1994 }
1995 
ValidateBindProgramPipeline(const Context * context,angle::EntryPoint entryPoint,ProgramPipelineID pipelinePacked)1996 bool ValidateBindProgramPipeline(const Context *context,
1997                                  angle::EntryPoint entryPoint,
1998                                  ProgramPipelineID pipelinePacked)
1999 {
2000     if (context->getClientVersion() < ES_3_1)
2001     {
2002         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2003         return false;
2004     }
2005 
2006     return ValidateBindProgramPipelineBase(context, entryPoint, pipelinePacked);
2007 }
2008 
ValidateCreateShaderProgramv(const Context * context,angle::EntryPoint entryPoint,ShaderType typePacked,GLsizei count,const GLchar * const * strings)2009 bool ValidateCreateShaderProgramv(const Context *context,
2010                                   angle::EntryPoint entryPoint,
2011                                   ShaderType typePacked,
2012                                   GLsizei count,
2013                                   const GLchar *const *strings)
2014 {
2015     if (context->getClientVersion() < ES_3_1)
2016     {
2017         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2018         return false;
2019     }
2020 
2021     return ValidateCreateShaderProgramvBase(context, entryPoint, typePacked, count, strings);
2022 }
2023 
ValidateDeleteProgramPipelines(const Context * context,angle::EntryPoint entryPoint,GLsizei n,const ProgramPipelineID * pipelinesPacked)2024 bool ValidateDeleteProgramPipelines(const Context *context,
2025                                     angle::EntryPoint entryPoint,
2026                                     GLsizei n,
2027                                     const ProgramPipelineID *pipelinesPacked)
2028 {
2029     if (context->getClientVersion() < ES_3_1)
2030     {
2031         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2032         return false;
2033     }
2034 
2035     return ValidateDeleteProgramPipelinesBase(context, entryPoint, n, pipelinesPacked);
2036 }
2037 
ValidateGenProgramPipelines(const Context * context,angle::EntryPoint entryPoint,GLsizei n,const ProgramPipelineID * pipelinesPacked)2038 bool ValidateGenProgramPipelines(const Context *context,
2039                                  angle::EntryPoint entryPoint,
2040                                  GLsizei n,
2041                                  const ProgramPipelineID *pipelinesPacked)
2042 {
2043     if (context->getClientVersion() < ES_3_1)
2044     {
2045         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2046         return false;
2047     }
2048 
2049     return ValidateGenProgramPipelinesBase(context, entryPoint, n, pipelinesPacked);
2050 }
2051 
ValidateGetProgramPipelineInfoLog(const Context * context,angle::EntryPoint entryPoint,ProgramPipelineID pipelinePacked,GLsizei bufSize,const GLsizei * length,const GLchar * infoLog)2052 bool ValidateGetProgramPipelineInfoLog(const Context *context,
2053                                        angle::EntryPoint entryPoint,
2054                                        ProgramPipelineID pipelinePacked,
2055                                        GLsizei bufSize,
2056                                        const GLsizei *length,
2057                                        const GLchar *infoLog)
2058 {
2059     if (context->getClientVersion() < ES_3_1)
2060     {
2061         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2062         return false;
2063     }
2064 
2065     return ValidateGetProgramPipelineInfoLogBase(context, entryPoint, pipelinePacked, bufSize,
2066                                                  length, infoLog);
2067 }
2068 
ValidateGetProgramPipelineiv(const Context * context,angle::EntryPoint entryPoint,ProgramPipelineID pipelinePacked,GLenum pname,const GLint * params)2069 bool ValidateGetProgramPipelineiv(const Context *context,
2070                                   angle::EntryPoint entryPoint,
2071                                   ProgramPipelineID pipelinePacked,
2072                                   GLenum pname,
2073                                   const GLint *params)
2074 {
2075     if (context->getClientVersion() < ES_3_1)
2076     {
2077         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2078         return false;
2079     }
2080 
2081     return ValidateGetProgramPipelineivBase(context, entryPoint, pipelinePacked, pname, params);
2082 }
2083 
ValidateIsProgramPipeline(const Context * context,angle::EntryPoint entryPoint,ProgramPipelineID pipelinePacked)2084 bool ValidateIsProgramPipeline(const Context *context,
2085                                angle::EntryPoint entryPoint,
2086                                ProgramPipelineID pipelinePacked)
2087 {
2088     if (context->getClientVersion() < ES_3_1)
2089     {
2090         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2091         return false;
2092     }
2093 
2094     return ValidateIsProgramPipelineBase(context, entryPoint, pipelinePacked);
2095 }
2096 
ValidateProgramUniform1f(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLfloat v0)2097 bool ValidateProgramUniform1f(const Context *context,
2098                               angle::EntryPoint entryPoint,
2099                               ShaderProgramID programPacked,
2100                               UniformLocation locationPacked,
2101                               GLfloat v0)
2102 {
2103     if (context->getClientVersion() < ES_3_1)
2104     {
2105         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2106         return false;
2107     }
2108 
2109     return ValidateProgramUniform1fBase(context, entryPoint, programPacked, locationPacked, v0);
2110 }
2111 
ValidateProgramUniform1fv(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLfloat * value)2112 bool ValidateProgramUniform1fv(const Context *context,
2113                                angle::EntryPoint entryPoint,
2114                                ShaderProgramID programPacked,
2115                                UniformLocation locationPacked,
2116                                GLsizei count,
2117                                const GLfloat *value)
2118 {
2119     if (context->getClientVersion() < ES_3_1)
2120     {
2121         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2122         return false;
2123     }
2124 
2125     return ValidateProgramUniform1fvBase(context, entryPoint, programPacked, locationPacked, count,
2126                                          value);
2127 }
2128 
ValidateProgramUniform1i(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLint v0)2129 bool ValidateProgramUniform1i(const Context *context,
2130                               angle::EntryPoint entryPoint,
2131                               ShaderProgramID programPacked,
2132                               UniformLocation locationPacked,
2133                               GLint v0)
2134 {
2135     if (context->getClientVersion() < ES_3_1)
2136     {
2137         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2138         return false;
2139     }
2140 
2141     return ValidateProgramUniform1iBase(context, entryPoint, programPacked, locationPacked, v0);
2142 }
2143 
ValidateProgramUniform1iv(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLint * value)2144 bool ValidateProgramUniform1iv(const Context *context,
2145                                angle::EntryPoint entryPoint,
2146                                ShaderProgramID programPacked,
2147                                UniformLocation locationPacked,
2148                                GLsizei count,
2149                                const GLint *value)
2150 {
2151     if (context->getClientVersion() < ES_3_1)
2152     {
2153         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2154         return false;
2155     }
2156 
2157     return ValidateProgramUniform1ivBase(context, entryPoint, programPacked, locationPacked, count,
2158                                          value);
2159 }
2160 
ValidateProgramUniform1ui(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLuint v0)2161 bool ValidateProgramUniform1ui(const Context *context,
2162                                angle::EntryPoint entryPoint,
2163                                ShaderProgramID programPacked,
2164                                UniformLocation locationPacked,
2165                                GLuint v0)
2166 {
2167     if (context->getClientVersion() < ES_3_1)
2168     {
2169         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2170         return false;
2171     }
2172 
2173     return ValidateProgramUniform1uiBase(context, entryPoint, programPacked, locationPacked, v0);
2174 }
2175 
ValidateProgramUniform1uiv(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLuint * value)2176 bool ValidateProgramUniform1uiv(const Context *context,
2177                                 angle::EntryPoint entryPoint,
2178                                 ShaderProgramID programPacked,
2179                                 UniformLocation locationPacked,
2180                                 GLsizei count,
2181                                 const GLuint *value)
2182 {
2183     if (context->getClientVersion() < ES_3_1)
2184     {
2185         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2186         return false;
2187     }
2188 
2189     return ValidateProgramUniform1uivBase(context, entryPoint, programPacked, locationPacked, count,
2190                                           value);
2191 }
2192 
ValidateProgramUniform2f(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLfloat v0,GLfloat v1)2193 bool ValidateProgramUniform2f(const Context *context,
2194                               angle::EntryPoint entryPoint,
2195                               ShaderProgramID programPacked,
2196                               UniformLocation locationPacked,
2197                               GLfloat v0,
2198                               GLfloat v1)
2199 {
2200     if (context->getClientVersion() < ES_3_1)
2201     {
2202         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2203         return false;
2204     }
2205 
2206     return ValidateProgramUniform2fBase(context, entryPoint, programPacked, locationPacked, v0, v1);
2207 }
2208 
ValidateProgramUniform2fv(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLfloat * value)2209 bool ValidateProgramUniform2fv(const Context *context,
2210                                angle::EntryPoint entryPoint,
2211                                ShaderProgramID programPacked,
2212                                UniformLocation locationPacked,
2213                                GLsizei count,
2214                                const GLfloat *value)
2215 {
2216     if (context->getClientVersion() < ES_3_1)
2217     {
2218         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2219         return false;
2220     }
2221 
2222     return ValidateProgramUniform2fvBase(context, entryPoint, programPacked, locationPacked, count,
2223                                          value);
2224 }
2225 
ValidateProgramUniform2i(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLint v0,GLint v1)2226 bool ValidateProgramUniform2i(const Context *context,
2227                               angle::EntryPoint entryPoint,
2228                               ShaderProgramID programPacked,
2229                               UniformLocation locationPacked,
2230                               GLint v0,
2231                               GLint v1)
2232 {
2233     if (context->getClientVersion() < ES_3_1)
2234     {
2235         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2236         return false;
2237     }
2238 
2239     return ValidateProgramUniform2iBase(context, entryPoint, programPacked, locationPacked, v0, v1);
2240 }
2241 
ValidateProgramUniform2iv(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLint * value)2242 bool ValidateProgramUniform2iv(const Context *context,
2243                                angle::EntryPoint entryPoint,
2244                                ShaderProgramID programPacked,
2245                                UniformLocation locationPacked,
2246                                GLsizei count,
2247                                const GLint *value)
2248 {
2249     if (context->getClientVersion() < ES_3_1)
2250     {
2251         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2252         return false;
2253     }
2254 
2255     return ValidateProgramUniform2ivBase(context, entryPoint, programPacked, locationPacked, count,
2256                                          value);
2257 }
2258 
ValidateProgramUniform2ui(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLuint v0,GLuint v1)2259 bool ValidateProgramUniform2ui(const Context *context,
2260                                angle::EntryPoint entryPoint,
2261                                ShaderProgramID programPacked,
2262                                UniformLocation locationPacked,
2263                                GLuint v0,
2264                                GLuint v1)
2265 {
2266     if (context->getClientVersion() < ES_3_1)
2267     {
2268         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2269         return false;
2270     }
2271 
2272     return ValidateProgramUniform2uiBase(context, entryPoint, programPacked, locationPacked, v0,
2273                                          v1);
2274 }
2275 
ValidateProgramUniform2uiv(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLuint * value)2276 bool ValidateProgramUniform2uiv(const Context *context,
2277                                 angle::EntryPoint entryPoint,
2278                                 ShaderProgramID programPacked,
2279                                 UniformLocation locationPacked,
2280                                 GLsizei count,
2281                                 const GLuint *value)
2282 {
2283     if (context->getClientVersion() < ES_3_1)
2284     {
2285         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2286         return false;
2287     }
2288 
2289     return ValidateProgramUniform2uivBase(context, entryPoint, programPacked, locationPacked, count,
2290                                           value);
2291 }
2292 
ValidateProgramUniform3f(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLfloat v0,GLfloat v1,GLfloat v2)2293 bool ValidateProgramUniform3f(const Context *context,
2294                               angle::EntryPoint entryPoint,
2295                               ShaderProgramID programPacked,
2296                               UniformLocation locationPacked,
2297                               GLfloat v0,
2298                               GLfloat v1,
2299                               GLfloat v2)
2300 {
2301     if (context->getClientVersion() < ES_3_1)
2302     {
2303         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2304         return false;
2305     }
2306 
2307     return ValidateProgramUniform3fBase(context, entryPoint, programPacked, locationPacked, v0, v1,
2308                                         v2);
2309 }
2310 
ValidateProgramUniform3fv(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLfloat * value)2311 bool ValidateProgramUniform3fv(const Context *context,
2312                                angle::EntryPoint entryPoint,
2313                                ShaderProgramID programPacked,
2314                                UniformLocation locationPacked,
2315                                GLsizei count,
2316                                const GLfloat *value)
2317 {
2318     if (context->getClientVersion() < ES_3_1)
2319     {
2320         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2321         return false;
2322     }
2323 
2324     return ValidateProgramUniform3fvBase(context, entryPoint, programPacked, locationPacked, count,
2325                                          value);
2326 }
2327 
ValidateProgramUniform3i(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLint v0,GLint v1,GLint v2)2328 bool ValidateProgramUniform3i(const Context *context,
2329                               angle::EntryPoint entryPoint,
2330                               ShaderProgramID programPacked,
2331                               UniformLocation locationPacked,
2332                               GLint v0,
2333                               GLint v1,
2334                               GLint v2)
2335 {
2336     if (context->getClientVersion() < ES_3_1)
2337     {
2338         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2339         return false;
2340     }
2341 
2342     return ValidateProgramUniform3iBase(context, entryPoint, programPacked, locationPacked, v0, v1,
2343                                         v2);
2344 }
2345 
ValidateProgramUniform3iv(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLint * value)2346 bool ValidateProgramUniform3iv(const Context *context,
2347                                angle::EntryPoint entryPoint,
2348                                ShaderProgramID programPacked,
2349                                UniformLocation locationPacked,
2350                                GLsizei count,
2351                                const GLint *value)
2352 {
2353     if (context->getClientVersion() < ES_3_1)
2354     {
2355         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2356         return false;
2357     }
2358 
2359     return ValidateProgramUniform3ivBase(context, entryPoint, programPacked, locationPacked, count,
2360                                          value);
2361 }
2362 
ValidateProgramUniform3ui(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLuint v0,GLuint v1,GLuint v2)2363 bool ValidateProgramUniform3ui(const Context *context,
2364                                angle::EntryPoint entryPoint,
2365                                ShaderProgramID programPacked,
2366                                UniformLocation locationPacked,
2367                                GLuint v0,
2368                                GLuint v1,
2369                                GLuint v2)
2370 {
2371     if (context->getClientVersion() < ES_3_1)
2372     {
2373         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2374         return false;
2375     }
2376 
2377     return ValidateProgramUniform3uiBase(context, entryPoint, programPacked, locationPacked, v0, v1,
2378                                          v2);
2379 }
2380 
ValidateProgramUniform3uiv(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLuint * value)2381 bool ValidateProgramUniform3uiv(const Context *context,
2382                                 angle::EntryPoint entryPoint,
2383                                 ShaderProgramID programPacked,
2384                                 UniformLocation locationPacked,
2385                                 GLsizei count,
2386                                 const GLuint *value)
2387 {
2388     if (context->getClientVersion() < ES_3_1)
2389     {
2390         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2391         return false;
2392     }
2393 
2394     return ValidateProgramUniform3uivBase(context, entryPoint, programPacked, locationPacked, count,
2395                                           value);
2396 }
2397 
ValidateProgramUniform4f(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLfloat v0,GLfloat v1,GLfloat v2,GLfloat v3)2398 bool ValidateProgramUniform4f(const Context *context,
2399                               angle::EntryPoint entryPoint,
2400                               ShaderProgramID programPacked,
2401                               UniformLocation locationPacked,
2402                               GLfloat v0,
2403                               GLfloat v1,
2404                               GLfloat v2,
2405                               GLfloat v3)
2406 {
2407     if (context->getClientVersion() < ES_3_1)
2408     {
2409         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2410         return false;
2411     }
2412 
2413     return ValidateProgramUniform4fBase(context, entryPoint, programPacked, locationPacked, v0, v1,
2414                                         v2, v3);
2415 }
2416 
ValidateProgramUniform4fv(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLfloat * value)2417 bool ValidateProgramUniform4fv(const Context *context,
2418                                angle::EntryPoint entryPoint,
2419                                ShaderProgramID programPacked,
2420                                UniformLocation locationPacked,
2421                                GLsizei count,
2422                                const GLfloat *value)
2423 {
2424     if (context->getClientVersion() < ES_3_1)
2425     {
2426         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2427         return false;
2428     }
2429 
2430     return ValidateProgramUniform4fvBase(context, entryPoint, programPacked, locationPacked, count,
2431                                          value);
2432 }
2433 
ValidateProgramUniform4i(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLint v0,GLint v1,GLint v2,GLint v3)2434 bool ValidateProgramUniform4i(const Context *context,
2435                               angle::EntryPoint entryPoint,
2436                               ShaderProgramID programPacked,
2437                               UniformLocation locationPacked,
2438                               GLint v0,
2439                               GLint v1,
2440                               GLint v2,
2441                               GLint v3)
2442 {
2443     if (context->getClientVersion() < ES_3_1)
2444     {
2445         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2446         return false;
2447     }
2448 
2449     return ValidateProgramUniform4iBase(context, entryPoint, programPacked, locationPacked, v0, v1,
2450                                         v2, v3);
2451 }
2452 
ValidateProgramUniform4iv(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLint * value)2453 bool ValidateProgramUniform4iv(const Context *context,
2454                                angle::EntryPoint entryPoint,
2455                                ShaderProgramID programPacked,
2456                                UniformLocation locationPacked,
2457                                GLsizei count,
2458                                const GLint *value)
2459 {
2460     if (context->getClientVersion() < ES_3_1)
2461     {
2462         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2463         return false;
2464     }
2465 
2466     return ValidateProgramUniform4ivBase(context, entryPoint, programPacked, locationPacked, count,
2467                                          value);
2468 }
2469 
ValidateProgramUniform4ui(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLuint v0,GLuint v1,GLuint v2,GLuint v3)2470 bool ValidateProgramUniform4ui(const Context *context,
2471                                angle::EntryPoint entryPoint,
2472                                ShaderProgramID programPacked,
2473                                UniformLocation locationPacked,
2474                                GLuint v0,
2475                                GLuint v1,
2476                                GLuint v2,
2477                                GLuint v3)
2478 {
2479     if (context->getClientVersion() < ES_3_1)
2480     {
2481         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2482         return false;
2483     }
2484 
2485     return ValidateProgramUniform4uiBase(context, entryPoint, programPacked, locationPacked, v0, v1,
2486                                          v2, v3);
2487 }
2488 
ValidateProgramUniform4uiv(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLuint * value)2489 bool ValidateProgramUniform4uiv(const Context *context,
2490                                 angle::EntryPoint entryPoint,
2491                                 ShaderProgramID programPacked,
2492                                 UniformLocation locationPacked,
2493                                 GLsizei count,
2494                                 const GLuint *value)
2495 {
2496     if (context->getClientVersion() < ES_3_1)
2497     {
2498         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2499         return false;
2500     }
2501 
2502     return ValidateProgramUniform4uivBase(context, entryPoint, programPacked, locationPacked, count,
2503                                           value);
2504 }
2505 
ValidateProgramUniformMatrix2fv(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,GLboolean transpose,const GLfloat * value)2506 bool ValidateProgramUniformMatrix2fv(const Context *context,
2507                                      angle::EntryPoint entryPoint,
2508                                      ShaderProgramID programPacked,
2509                                      UniformLocation locationPacked,
2510                                      GLsizei count,
2511                                      GLboolean transpose,
2512                                      const GLfloat *value)
2513 {
2514     if (context->getClientVersion() < ES_3_1)
2515     {
2516         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2517         return false;
2518     }
2519 
2520     return ValidateProgramUniformMatrix2fvBase(context, entryPoint, programPacked, locationPacked,
2521                                                count, transpose, value);
2522 }
2523 
ValidateProgramUniformMatrix2x3fv(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,GLboolean transpose,const GLfloat * value)2524 bool ValidateProgramUniformMatrix2x3fv(const Context *context,
2525                                        angle::EntryPoint entryPoint,
2526                                        ShaderProgramID programPacked,
2527                                        UniformLocation locationPacked,
2528                                        GLsizei count,
2529                                        GLboolean transpose,
2530                                        const GLfloat *value)
2531 {
2532     if (context->getClientVersion() < ES_3_1)
2533     {
2534         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2535         return false;
2536     }
2537 
2538     return ValidateProgramUniformMatrix2x3fvBase(context, entryPoint, programPacked, locationPacked,
2539                                                  count, transpose, value);
2540 }
2541 
ValidateProgramUniformMatrix2x4fv(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,GLboolean transpose,const GLfloat * value)2542 bool ValidateProgramUniformMatrix2x4fv(const Context *context,
2543                                        angle::EntryPoint entryPoint,
2544                                        ShaderProgramID programPacked,
2545                                        UniformLocation locationPacked,
2546                                        GLsizei count,
2547                                        GLboolean transpose,
2548                                        const GLfloat *value)
2549 {
2550     if (context->getClientVersion() < ES_3_1)
2551     {
2552         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2553         return false;
2554     }
2555 
2556     return ValidateProgramUniformMatrix2x4fvBase(context, entryPoint, programPacked, locationPacked,
2557                                                  count, transpose, value);
2558 }
2559 
ValidateProgramUniformMatrix3fv(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,GLboolean transpose,const GLfloat * value)2560 bool ValidateProgramUniformMatrix3fv(const Context *context,
2561                                      angle::EntryPoint entryPoint,
2562                                      ShaderProgramID programPacked,
2563                                      UniformLocation locationPacked,
2564                                      GLsizei count,
2565                                      GLboolean transpose,
2566                                      const GLfloat *value)
2567 {
2568     if (context->getClientVersion() < ES_3_1)
2569     {
2570         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2571         return false;
2572     }
2573 
2574     return ValidateProgramUniformMatrix3fvBase(context, entryPoint, programPacked, locationPacked,
2575                                                count, transpose, value);
2576 }
2577 
ValidateProgramUniformMatrix3x2fv(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,GLboolean transpose,const GLfloat * value)2578 bool ValidateProgramUniformMatrix3x2fv(const Context *context,
2579                                        angle::EntryPoint entryPoint,
2580                                        ShaderProgramID programPacked,
2581                                        UniformLocation locationPacked,
2582                                        GLsizei count,
2583                                        GLboolean transpose,
2584                                        const GLfloat *value)
2585 {
2586     if (context->getClientVersion() < ES_3_1)
2587     {
2588         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2589         return false;
2590     }
2591 
2592     return ValidateProgramUniformMatrix3x2fvBase(context, entryPoint, programPacked, locationPacked,
2593                                                  count, transpose, value);
2594 }
2595 
ValidateProgramUniformMatrix3x4fv(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,GLboolean transpose,const GLfloat * value)2596 bool ValidateProgramUniformMatrix3x4fv(const Context *context,
2597                                        angle::EntryPoint entryPoint,
2598                                        ShaderProgramID programPacked,
2599                                        UniformLocation locationPacked,
2600                                        GLsizei count,
2601                                        GLboolean transpose,
2602                                        const GLfloat *value)
2603 {
2604     if (context->getClientVersion() < ES_3_1)
2605     {
2606         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2607         return false;
2608     }
2609 
2610     return ValidateProgramUniformMatrix3x4fvBase(context, entryPoint, programPacked, locationPacked,
2611                                                  count, transpose, value);
2612 }
2613 
ValidateProgramUniformMatrix4fv(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,GLboolean transpose,const GLfloat * value)2614 bool ValidateProgramUniformMatrix4fv(const Context *context,
2615                                      angle::EntryPoint entryPoint,
2616                                      ShaderProgramID programPacked,
2617                                      UniformLocation locationPacked,
2618                                      GLsizei count,
2619                                      GLboolean transpose,
2620                                      const GLfloat *value)
2621 {
2622     if (context->getClientVersion() < ES_3_1)
2623     {
2624         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2625         return false;
2626     }
2627 
2628     return ValidateProgramUniformMatrix4fvBase(context, entryPoint, programPacked, locationPacked,
2629                                                count, transpose, value);
2630 }
2631 
ValidateProgramUniformMatrix4x2fv(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,GLboolean transpose,const GLfloat * value)2632 bool ValidateProgramUniformMatrix4x2fv(const Context *context,
2633                                        angle::EntryPoint entryPoint,
2634                                        ShaderProgramID programPacked,
2635                                        UniformLocation locationPacked,
2636                                        GLsizei count,
2637                                        GLboolean transpose,
2638                                        const GLfloat *value)
2639 {
2640     if (context->getClientVersion() < ES_3_1)
2641     {
2642         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2643         return false;
2644     }
2645 
2646     return ValidateProgramUniformMatrix4x2fvBase(context, entryPoint, programPacked, locationPacked,
2647                                                  count, transpose, value);
2648 }
2649 
ValidateProgramUniformMatrix4x3fv(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,GLboolean transpose,const GLfloat * value)2650 bool ValidateProgramUniformMatrix4x3fv(const Context *context,
2651                                        angle::EntryPoint entryPoint,
2652                                        ShaderProgramID programPacked,
2653                                        UniformLocation locationPacked,
2654                                        GLsizei count,
2655                                        GLboolean transpose,
2656                                        const GLfloat *value)
2657 {
2658     if (context->getClientVersion() < ES_3_1)
2659     {
2660         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2661         return false;
2662     }
2663 
2664     return ValidateProgramUniformMatrix4x3fvBase(context, entryPoint, programPacked, locationPacked,
2665                                                  count, transpose, value);
2666 }
2667 
ValidateUseProgramStages(const Context * context,angle::EntryPoint entryPoint,ProgramPipelineID pipelinePacked,GLbitfield stages,ShaderProgramID programPacked)2668 bool ValidateUseProgramStages(const Context *context,
2669                               angle::EntryPoint entryPoint,
2670                               ProgramPipelineID pipelinePacked,
2671                               GLbitfield stages,
2672                               ShaderProgramID programPacked)
2673 {
2674     if (context->getClientVersion() < ES_3_1)
2675     {
2676         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2677         return false;
2678     }
2679 
2680     return ValidateUseProgramStagesBase(context, entryPoint, pipelinePacked, stages, programPacked);
2681 }
2682 
ValidateValidateProgramPipeline(const Context * context,angle::EntryPoint entryPoint,ProgramPipelineID pipelinePacked)2683 bool ValidateValidateProgramPipeline(const Context *context,
2684                                      angle::EntryPoint entryPoint,
2685                                      ProgramPipelineID pipelinePacked)
2686 {
2687     if (context->getClientVersion() < ES_3_1)
2688     {
2689         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2690         return false;
2691     }
2692 
2693     return ValidateValidateProgramPipelineBase(context, entryPoint, pipelinePacked);
2694 }
2695 
ValidateMemoryBarrier(const Context * context,angle::EntryPoint entryPoint,GLbitfield barriers)2696 bool ValidateMemoryBarrier(const Context *context,
2697                            angle::EntryPoint entryPoint,
2698                            GLbitfield barriers)
2699 {
2700     if (context->getClientVersion() < ES_3_1)
2701     {
2702         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2703         return false;
2704     }
2705 
2706     if (barriers == GL_ALL_BARRIER_BITS)
2707     {
2708         return true;
2709     }
2710 
2711     GLbitfield supported_barrier_bits =
2712         GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT | GL_ELEMENT_ARRAY_BARRIER_BIT | GL_UNIFORM_BARRIER_BIT |
2713         GL_TEXTURE_FETCH_BARRIER_BIT | GL_SHADER_IMAGE_ACCESS_BARRIER_BIT | GL_COMMAND_BARRIER_BIT |
2714         GL_PIXEL_BUFFER_BARRIER_BIT | GL_TEXTURE_UPDATE_BARRIER_BIT | GL_BUFFER_UPDATE_BARRIER_BIT |
2715         GL_FRAMEBUFFER_BARRIER_BIT | GL_TRANSFORM_FEEDBACK_BARRIER_BIT |
2716         GL_ATOMIC_COUNTER_BARRIER_BIT | GL_SHADER_STORAGE_BARRIER_BIT;
2717 
2718     if (context->getExtensions().bufferStorageEXT)
2719     {
2720         supported_barrier_bits |= GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT_EXT;
2721     }
2722 
2723     if (barriers == 0 || (barriers & ~supported_barrier_bits) != 0)
2724     {
2725         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidMemoryBarrierBit);
2726         return false;
2727     }
2728 
2729     return true;
2730 }
2731 
ValidateMemoryBarrierByRegion(const Context * context,angle::EntryPoint entryPoint,GLbitfield barriers)2732 bool ValidateMemoryBarrierByRegion(const Context *context,
2733                                    angle::EntryPoint entryPoint,
2734                                    GLbitfield barriers)
2735 {
2736     if (context->getClientVersion() < ES_3_1)
2737     {
2738         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2739         return false;
2740     }
2741 
2742     if (barriers == GL_ALL_BARRIER_BITS)
2743     {
2744         return true;
2745     }
2746 
2747     GLbitfield supported_barrier_bits = GL_ATOMIC_COUNTER_BARRIER_BIT | GL_FRAMEBUFFER_BARRIER_BIT |
2748                                         GL_SHADER_IMAGE_ACCESS_BARRIER_BIT |
2749                                         GL_SHADER_STORAGE_BARRIER_BIT |
2750                                         GL_TEXTURE_FETCH_BARRIER_BIT | GL_UNIFORM_BARRIER_BIT;
2751     if (barriers == 0 || (barriers & ~supported_barrier_bits) != 0)
2752     {
2753         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidMemoryBarrierBit);
2754         return false;
2755     }
2756 
2757     return true;
2758 }
2759 
ValidateSampleMaski(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLuint maskNumber,GLbitfield mask)2760 bool ValidateSampleMaski(const PrivateState &state,
2761                          ErrorSet *errors,
2762                          angle::EntryPoint entryPoint,
2763                          GLuint maskNumber,
2764                          GLbitfield mask)
2765 {
2766     if (state.getClientVersion() < ES_3_1)
2767     {
2768         errors->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required);
2769         return false;
2770     }
2771 
2772     return ValidateSampleMaskiBase(state, errors, entryPoint, maskNumber, mask);
2773 }
2774 
ValidateMinSampleShadingOES(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLfloat value)2775 bool ValidateMinSampleShadingOES(const PrivateState &state,
2776                                  ErrorSet *errors,
2777                                  angle::EntryPoint entryPoint,
2778                                  GLfloat value)
2779 {
2780     if (!state.getExtensions().sampleShadingOES)
2781     {
2782         errors->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
2783         return false;
2784     }
2785 
2786     return true;
2787 }
2788 
ValidateFramebufferTextureCommon(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLenum attachment,TextureID texture,GLint level)2789 bool ValidateFramebufferTextureCommon(const Context *context,
2790                                       angle::EntryPoint entryPoint,
2791                                       GLenum target,
2792                                       GLenum attachment,
2793                                       TextureID texture,
2794                                       GLint level)
2795 {
2796     if (texture.value != 0)
2797     {
2798         Texture *tex = context->getTexture(texture);
2799 
2800         // [EXT_geometry_shader] Section 9.2.8 "Attaching Texture Images to a Framebuffer"
2801         // An INVALID_VALUE error is generated if <texture> is not the name of a texture object.
2802         // We put this validation before ValidateFramebufferTextureBase because it is an
2803         // INVALID_OPERATION error for both FramebufferTexture2D and FramebufferTextureLayer:
2804         // [OpenGL ES 3.1] Chapter 9.2.8 (FramebufferTexture2D)
2805         // An INVALID_OPERATION error is generated if texture is not zero, and does not name an
2806         // existing texture object of type matching textarget.
2807         // [OpenGL ES 3.1 Chapter 9.2.8 (FramebufferTextureLayer)
2808         // An INVALID_OPERATION error is generated if texture is non-zero and is not the name of a
2809         // three-dimensional or two-dimensional array texture.
2810         if (tex == nullptr)
2811         {
2812             ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidTextureName);
2813             return false;
2814         }
2815 
2816         if (!ValidMipLevel(context, tex->getType(), level))
2817         {
2818             ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidMipLevel);
2819             return false;
2820         }
2821 
2822         // GLES spec 3.1, Section 9.2.8 "Attaching Texture Images to a Framebuffer"
2823         // If textarget is TEXTURE_2D_MULTISAMPLE, then level must be zero.
2824         if (tex->getType() == TextureType::_2DMultisample && level != 0)
2825         {
2826             ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kLevelNotZero);
2827             return false;
2828         }
2829 
2830         // [OES_texture_storage_multisample_2d_array] Section 9.2.2 "Attaching Images to Framebuffer
2831         // Objects"
2832         // If texture is a two-dimensional multisample array texture, then level must be zero.
2833         if (context->getExtensions().textureStorageMultisample2dArrayOES &&
2834             tex->getType() == TextureType::_2DMultisampleArray && level != 0)
2835         {
2836             ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kLevelNotZero);
2837             return false;
2838         }
2839     }
2840 
2841     if (!ValidateFramebufferTextureBase(context, entryPoint, target, attachment, texture, level))
2842     {
2843         return false;
2844     }
2845 
2846     return true;
2847 }
2848 
ValidateFramebufferTextureEXT(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLenum attachment,TextureID texture,GLint level)2849 bool ValidateFramebufferTextureEXT(const Context *context,
2850                                    angle::EntryPoint entryPoint,
2851                                    GLenum target,
2852                                    GLenum attachment,
2853                                    TextureID texture,
2854                                    GLint level)
2855 {
2856     if (!context->getExtensions().geometryShaderEXT)
2857     {
2858         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kGeometryShaderExtensionNotEnabled);
2859         return false;
2860     }
2861 
2862     return ValidateFramebufferTextureCommon(context, entryPoint, target, attachment, texture,
2863                                             level);
2864 }
2865 
ValidateFramebufferTextureOES(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLenum attachment,TextureID texture,GLint level)2866 bool ValidateFramebufferTextureOES(const Context *context,
2867                                    angle::EntryPoint entryPoint,
2868                                    GLenum target,
2869                                    GLenum attachment,
2870                                    TextureID texture,
2871                                    GLint level)
2872 {
2873     if (!context->getExtensions().geometryShaderOES)
2874     {
2875         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kGeometryShaderExtensionNotEnabled);
2876         return false;
2877     }
2878 
2879     return ValidateFramebufferTextureCommon(context, entryPoint, target, attachment, texture,
2880                                             level);
2881 }
2882 
2883 // GL_OES_texture_storage_multisample_2d_array
ValidateTexStorage3DMultisampleOES(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLsizei samples,GLenum sizedinternalformat,GLsizei width,GLsizei height,GLsizei depth,GLboolean fixedsamplelocations)2884 bool ValidateTexStorage3DMultisampleOES(const Context *context,
2885                                         angle::EntryPoint entryPoint,
2886                                         TextureType target,
2887                                         GLsizei samples,
2888                                         GLenum sizedinternalformat,
2889                                         GLsizei width,
2890                                         GLsizei height,
2891                                         GLsizei depth,
2892                                         GLboolean fixedsamplelocations)
2893 {
2894     if (!context->getExtensions().textureStorageMultisample2dArrayOES)
2895     {
2896         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kMultisampleArrayExtensionRequired);
2897         return false;
2898     }
2899 
2900     if (target != TextureType::_2DMultisampleArray)
2901     {
2902         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kTargetMustBeTexture2DMultisampleArrayOES);
2903         return false;
2904     }
2905 
2906     if (width < 1 || height < 1 || depth < 1)
2907     {
2908         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeSize);
2909         return false;
2910     }
2911 
2912     if (depth > context->getCaps().maxArrayTextureLayers)
2913     {
2914         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kTextureDepthOutOfRange);
2915         return false;
2916     }
2917 
2918     return ValidateTexStorageMultisample(context, entryPoint, target, samples, sizedinternalformat,
2919                                          width, height);
2920 }
2921 
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)2922 bool ValidateTexStorageMem3DMultisampleEXT(const Context *context,
2923                                            angle::EntryPoint entryPoint,
2924                                            TextureType target,
2925                                            GLsizei samples,
2926                                            GLenum internalFormat,
2927                                            GLsizei width,
2928                                            GLsizei height,
2929                                            GLsizei depth,
2930                                            GLboolean fixedSampleLocations,
2931                                            MemoryObjectID memory,
2932                                            GLuint64 offset)
2933 {
2934     if (!context->getExtensions().memoryObjectEXT)
2935     {
2936         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
2937         return false;
2938     }
2939 
2940     UNIMPLEMENTED();
2941     return false;
2942 }
2943 
ValidateGetProgramResourceLocationIndexEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID program,GLenum programInterface,const char * name)2944 bool ValidateGetProgramResourceLocationIndexEXT(const Context *context,
2945                                                 angle::EntryPoint entryPoint,
2946                                                 ShaderProgramID program,
2947                                                 GLenum programInterface,
2948                                                 const char *name)
2949 {
2950     if (!context->getExtensions().blendFuncExtendedEXT)
2951     {
2952         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
2953         return false;
2954     }
2955     if (context->getClientVersion() < ES_3_1)
2956     {
2957         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES31Required);
2958         return false;
2959     }
2960     if (programInterface != GL_PROGRAM_OUTPUT)
2961     {
2962         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kProgramInterfaceMustBeProgramOutput);
2963         return false;
2964     }
2965     Program *programObject = GetValidProgram(context, entryPoint, program);
2966     if (!programObject)
2967     {
2968         return false;
2969     }
2970     if (!programObject->isLinked())
2971     {
2972         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kProgramNotLinked);
2973         return false;
2974     }
2975     return true;
2976 }
2977 
2978 // GL_OES_texture_buffer
ValidateTexBufferOES(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLenum internalformat,BufferID bufferPacked)2979 bool ValidateTexBufferOES(const Context *context,
2980                           angle::EntryPoint entryPoint,
2981                           TextureType target,
2982                           GLenum internalformat,
2983                           BufferID bufferPacked)
2984 {
2985     if (!context->getExtensions().textureBufferOES)
2986     {
2987         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kTextureBufferExtensionNotAvailable);
2988         return false;
2989     }
2990 
2991     return ValidateTexBufferBase(context, entryPoint, target, internalformat, bufferPacked);
2992 }
2993 
ValidateTexBufferRangeOES(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLenum internalformat,BufferID bufferPacked,GLintptr offset,GLsizeiptr size)2994 bool ValidateTexBufferRangeOES(const Context *context,
2995                                angle::EntryPoint entryPoint,
2996                                TextureType target,
2997                                GLenum internalformat,
2998                                BufferID bufferPacked,
2999                                GLintptr offset,
3000                                GLsizeiptr size)
3001 {
3002     if (!context->getExtensions().textureBufferOES)
3003     {
3004         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kTextureBufferExtensionNotAvailable);
3005         return false;
3006     }
3007 
3008     return ValidateTexBufferRangeBase(context, entryPoint, target, internalformat, bufferPacked,
3009                                       offset, size);
3010 }
3011 
3012 // GL_EXT_texture_buffer
ValidateTexBufferEXT(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLenum internalformat,BufferID bufferPacked)3013 bool ValidateTexBufferEXT(const Context *context,
3014                           angle::EntryPoint entryPoint,
3015                           TextureType target,
3016                           GLenum internalformat,
3017                           BufferID bufferPacked)
3018 {
3019     if (!context->getExtensions().textureBufferEXT)
3020     {
3021         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kTextureBufferExtensionNotAvailable);
3022         return false;
3023     }
3024 
3025     return ValidateTexBufferBase(context, entryPoint, target, internalformat, bufferPacked);
3026 }
3027 
ValidateTexBufferRangeEXT(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLenum internalformat,BufferID bufferPacked,GLintptr offset,GLsizeiptr size)3028 bool ValidateTexBufferRangeEXT(const Context *context,
3029                                angle::EntryPoint entryPoint,
3030                                TextureType target,
3031                                GLenum internalformat,
3032                                BufferID bufferPacked,
3033                                GLintptr offset,
3034                                GLsizeiptr size)
3035 {
3036     if (!context->getExtensions().textureBufferEXT)
3037     {
3038         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kTextureBufferExtensionNotAvailable);
3039         return false;
3040     }
3041 
3042     return ValidateTexBufferRangeBase(context, entryPoint, target, internalformat, bufferPacked,
3043                                       offset, size);
3044 }
3045 
ValidateTexBufferBase(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLenum internalformat,BufferID bufferPacked)3046 bool ValidateTexBufferBase(const Context *context,
3047                            angle::EntryPoint entryPoint,
3048                            TextureType target,
3049                            GLenum internalformat,
3050                            BufferID bufferPacked)
3051 {
3052     if (target != TextureType::Buffer)
3053     {
3054         ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kTextureBufferTarget);
3055         return false;
3056     }
3057 
3058     switch (internalformat)
3059     {
3060         case GL_R8:
3061         case GL_R16F:
3062         case GL_R32F:
3063         case GL_R8I:
3064         case GL_R16I:
3065         case GL_R32I:
3066         case GL_R8UI:
3067         case GL_R16UI:
3068         case GL_R32UI:
3069         case GL_RG8:
3070         case GL_RG16F:
3071         case GL_RG32F:
3072         case GL_RG8I:
3073         case GL_RG16I:
3074         case GL_RG32I:
3075         case GL_RG8UI:
3076         case GL_RG16UI:
3077         case GL_RG32UI:
3078         case GL_RGB32F:
3079         case GL_RGB32I:
3080         case GL_RGB32UI:
3081         case GL_RGBA8:
3082         case GL_RGBA16F:
3083         case GL_RGBA32F:
3084         case GL_RGBA8I:
3085         case GL_RGBA16I:
3086         case GL_RGBA32I:
3087         case GL_RGBA8UI:
3088         case GL_RGBA16UI:
3089         case GL_RGBA32UI:
3090             break;
3091 
3092         default:
3093             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kTextureBufferInternalFormat);
3094             return false;
3095     }
3096 
3097     if (bufferPacked.value != 0)
3098     {
3099         if (!context->isBufferGenerated(bufferPacked))
3100         {
3101             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kTextureBufferInvalidBuffer);
3102             return false;
3103         }
3104     }
3105 
3106     return true;
3107 }
3108 
ValidateTexBufferRangeBase(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLenum internalformat,BufferID bufferPacked,GLintptr offset,GLsizeiptr size)3109 bool ValidateTexBufferRangeBase(const Context *context,
3110                                 angle::EntryPoint entryPoint,
3111                                 TextureType target,
3112                                 GLenum internalformat,
3113                                 BufferID bufferPacked,
3114                                 GLintptr offset,
3115                                 GLsizeiptr size)
3116 {
3117     const Caps &caps = context->getCaps();
3118 
3119     if (offset < 0 || (offset % caps.textureBufferOffsetAlignment) != 0)
3120     {
3121         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kTextureBufferOffsetAlignment);
3122         return false;
3123     }
3124     if (size <= 0)
3125     {
3126         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kTextureBufferSize);
3127         return false;
3128     }
3129     const Buffer *buffer = context->getBuffer(bufferPacked);
3130 
3131     if (!buffer)
3132     {
3133         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBufferNotBound);
3134         return false;
3135     }
3136 
3137     if (offset + size > buffer->getSize())
3138     {
3139         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kTextureBufferSizeOffset);
3140         return false;
3141     }
3142 
3143     return ValidateTexBufferBase(context, entryPoint, target, internalformat, bufferPacked);
3144 }
3145 
3146 }  // namespace gl
3147