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