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