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