• 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/validationES3_autogen.h"
19 
20 #include "common/utilities.h"
21 
22 using namespace angle;
23 
24 namespace gl
25 {
26 using namespace err;
27 
28 namespace
29 {
30 
ValidateNamedProgramInterface(GLenum programInterface)31 bool ValidateNamedProgramInterface(GLenum programInterface)
32 {
33     switch (programInterface)
34     {
35         case GL_UNIFORM:
36         case GL_UNIFORM_BLOCK:
37         case GL_PROGRAM_INPUT:
38         case GL_PROGRAM_OUTPUT:
39         case GL_TRANSFORM_FEEDBACK_VARYING:
40         case GL_BUFFER_VARIABLE:
41         case GL_SHADER_STORAGE_BLOCK:
42             return true;
43         default:
44             return false;
45     }
46 }
47 
ValidateLocationProgramInterface(GLenum programInterface)48 bool ValidateLocationProgramInterface(GLenum programInterface)
49 {
50     switch (programInterface)
51     {
52         case GL_UNIFORM:
53         case GL_PROGRAM_INPUT:
54         case GL_PROGRAM_OUTPUT:
55             return true;
56         default:
57             return false;
58     }
59 }
60 
ValidateProgramInterface(GLenum programInterface)61 bool ValidateProgramInterface(GLenum programInterface)
62 {
63     return (programInterface == GL_ATOMIC_COUNTER_BUFFER ||
64             ValidateNamedProgramInterface(programInterface));
65 }
66 
ValidateProgramResourceProperty(const Context * context,GLenum prop)67 bool ValidateProgramResourceProperty(const Context *context, GLenum prop)
68 {
69     ASSERT(context);
70     switch (prop)
71     {
72         case GL_ACTIVE_VARIABLES:
73         case GL_BUFFER_BINDING:
74         case GL_NUM_ACTIVE_VARIABLES:
75 
76         case GL_ARRAY_SIZE:
77 
78         case GL_ARRAY_STRIDE:
79         case GL_BLOCK_INDEX:
80         case GL_IS_ROW_MAJOR:
81         case GL_MATRIX_STRIDE:
82 
83         case GL_ATOMIC_COUNTER_BUFFER_INDEX:
84 
85         case GL_BUFFER_DATA_SIZE:
86 
87         case GL_LOCATION:
88 
89         case GL_NAME_LENGTH:
90 
91         case GL_OFFSET:
92 
93         case GL_REFERENCED_BY_VERTEX_SHADER:
94         case GL_REFERENCED_BY_FRAGMENT_SHADER:
95         case GL_REFERENCED_BY_COMPUTE_SHADER:
96 
97         case GL_TOP_LEVEL_ARRAY_SIZE:
98         case GL_TOP_LEVEL_ARRAY_STRIDE:
99 
100         case GL_TYPE:
101             return true;
102 
103         case GL_REFERENCED_BY_GEOMETRY_SHADER_EXT:
104             return context->getExtensions().geometryShader;
105 
106         case GL_LOCATION_INDEX_EXT:
107             return context->getExtensions().blendFuncExtended;
108 
109         default:
110             return false;
111     }
112 }
113 
114 // GLES 3.10 spec: Page 82 -- Table 7.2
ValidateProgramResourcePropertyByInterface(GLenum prop,GLenum programInterface)115 bool ValidateProgramResourcePropertyByInterface(GLenum prop, GLenum programInterface)
116 {
117     switch (prop)
118     {
119         case GL_ACTIVE_VARIABLES:
120         case GL_BUFFER_BINDING:
121         case GL_NUM_ACTIVE_VARIABLES:
122         {
123             switch (programInterface)
124             {
125                 case GL_ATOMIC_COUNTER_BUFFER:
126                 case GL_SHADER_STORAGE_BLOCK:
127                 case GL_UNIFORM_BLOCK:
128                     return true;
129                 default:
130                     return false;
131             }
132         }
133 
134         case GL_ARRAY_SIZE:
135         {
136             switch (programInterface)
137             {
138                 case GL_BUFFER_VARIABLE:
139                 case GL_PROGRAM_INPUT:
140                 case GL_PROGRAM_OUTPUT:
141                 case GL_TRANSFORM_FEEDBACK_VARYING:
142                 case GL_UNIFORM:
143                     return true;
144                 default:
145                     return false;
146             }
147         }
148 
149         case GL_ARRAY_STRIDE:
150         case GL_BLOCK_INDEX:
151         case GL_IS_ROW_MAJOR:
152         case GL_MATRIX_STRIDE:
153         {
154             switch (programInterface)
155             {
156                 case GL_BUFFER_VARIABLE:
157                 case GL_UNIFORM:
158                     return true;
159                 default:
160                     return false;
161             }
162         }
163 
164         case GL_ATOMIC_COUNTER_BUFFER_INDEX:
165         {
166             if (programInterface == GL_UNIFORM)
167             {
168                 return true;
169             }
170             return false;
171         }
172 
173         case GL_BUFFER_DATA_SIZE:
174         {
175             switch (programInterface)
176             {
177                 case GL_ATOMIC_COUNTER_BUFFER:
178                 case GL_SHADER_STORAGE_BLOCK:
179                 case GL_UNIFORM_BLOCK:
180                     return true;
181                 default:
182                     return false;
183             }
184         }
185 
186         case GL_LOCATION:
187         {
188             return ValidateLocationProgramInterface(programInterface);
189         }
190 
191         case GL_LOCATION_INDEX_EXT:
192         {
193             // EXT_blend_func_extended
194             return (programInterface == GL_PROGRAM_OUTPUT);
195         }
196 
197         case GL_NAME_LENGTH:
198         {
199             return ValidateNamedProgramInterface(programInterface);
200         }
201 
202         case GL_OFFSET:
203         {
204             switch (programInterface)
205             {
206                 case GL_BUFFER_VARIABLE:
207                 case GL_UNIFORM:
208                     return true;
209                 default:
210                     return false;
211             }
212         }
213 
214         case GL_REFERENCED_BY_VERTEX_SHADER:
215         case GL_REFERENCED_BY_FRAGMENT_SHADER:
216         case GL_REFERENCED_BY_COMPUTE_SHADER:
217         case GL_REFERENCED_BY_GEOMETRY_SHADER_EXT:
218         {
219             switch (programInterface)
220             {
221                 case GL_ATOMIC_COUNTER_BUFFER:
222                 case GL_BUFFER_VARIABLE:
223                 case GL_PROGRAM_INPUT:
224                 case GL_PROGRAM_OUTPUT:
225                 case GL_SHADER_STORAGE_BLOCK:
226                 case GL_UNIFORM:
227                 case GL_UNIFORM_BLOCK:
228                     return true;
229                 default:
230                     return false;
231             }
232         }
233 
234         case GL_TOP_LEVEL_ARRAY_SIZE:
235         case GL_TOP_LEVEL_ARRAY_STRIDE:
236         {
237             if (programInterface == GL_BUFFER_VARIABLE)
238             {
239                 return true;
240             }
241             return false;
242         }
243 
244         case GL_TYPE:
245         {
246             switch (programInterface)
247             {
248                 case GL_BUFFER_VARIABLE:
249                 case GL_PROGRAM_INPUT:
250                 case GL_PROGRAM_OUTPUT:
251                 case GL_TRANSFORM_FEEDBACK_VARYING:
252                 case GL_UNIFORM:
253                     return true;
254                 default:
255                     return false;
256             }
257         }
258 
259         default:
260             return false;
261     }
262 }
263 
ValidateProgramResourceIndex(const Program * programObject,GLenum programInterface,GLuint index)264 bool ValidateProgramResourceIndex(const Program *programObject,
265                                   GLenum programInterface,
266                                   GLuint index)
267 {
268     switch (programInterface)
269     {
270         case GL_PROGRAM_INPUT:
271             return (index <
272                     static_cast<GLuint>(programObject->getState().getProgramInputs().size()));
273 
274         case GL_PROGRAM_OUTPUT:
275             return (index < static_cast<GLuint>(programObject->getOutputResourceCount()));
276 
277         case GL_UNIFORM:
278             return (index < static_cast<GLuint>(programObject->getActiveUniformCount()));
279 
280         case GL_BUFFER_VARIABLE:
281             return (index < static_cast<GLuint>(programObject->getActiveBufferVariableCount()));
282 
283         case GL_SHADER_STORAGE_BLOCK:
284             return (index < static_cast<GLuint>(programObject->getActiveShaderStorageBlockCount()));
285 
286         case GL_UNIFORM_BLOCK:
287             return (index < programObject->getActiveUniformBlockCount());
288 
289         case GL_ATOMIC_COUNTER_BUFFER:
290             return (index < programObject->getActiveAtomicCounterBufferCount());
291 
292         case GL_TRANSFORM_FEEDBACK_VARYING:
293             return (index < static_cast<GLuint>(programObject->getTransformFeedbackVaryingCount()));
294 
295         default:
296             UNREACHABLE();
297             return false;
298     }
299 }
300 
ValidateProgramUniform(const Context * context,GLenum valueType,ShaderProgramID program,UniformLocation location,GLsizei count)301 bool ValidateProgramUniform(const Context *context,
302                             GLenum valueType,
303                             ShaderProgramID program,
304                             UniformLocation location,
305                             GLsizei count)
306 {
307     // Check for ES31 program uniform entry points
308     if (context->getClientVersion() < Version(3, 1))
309     {
310         context->validationError(GL_INVALID_OPERATION, kES31Required);
311         return false;
312     }
313 
314     const LinkedUniform *uniform = nullptr;
315     Program *programObject       = GetValidProgram(context, program);
316     return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
317            ValidateUniformValue(context, valueType, uniform->type);
318 }
319 
ValidateProgramUniformMatrix(const Context * context,GLenum valueType,ShaderProgramID program,UniformLocation location,GLsizei count,GLboolean transpose)320 bool ValidateProgramUniformMatrix(const Context *context,
321                                   GLenum valueType,
322                                   ShaderProgramID program,
323                                   UniformLocation location,
324                                   GLsizei count,
325                                   GLboolean transpose)
326 {
327     // Check for ES31 program uniform entry points
328     if (context->getClientVersion() < Version(3, 1))
329     {
330         context->validationError(GL_INVALID_OPERATION, kES31Required);
331         return false;
332     }
333 
334     const LinkedUniform *uniform = nullptr;
335     Program *programObject       = GetValidProgram(context, program);
336     return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
337            ValidateUniformMatrixValue(context, valueType, uniform->type);
338 }
339 
ValidateVertexAttribFormatCommon(const Context * context,GLuint relativeOffset)340 bool ValidateVertexAttribFormatCommon(const Context *context, GLuint relativeOffset)
341 {
342     if (context->getClientVersion() < ES_3_1)
343     {
344         context->validationError(GL_INVALID_OPERATION, kES31Required);
345         return false;
346     }
347 
348     const Caps &caps = context->getCaps();
349     if (relativeOffset > static_cast<GLuint>(caps.maxVertexAttribRelativeOffset))
350     {
351         context->validationError(GL_INVALID_VALUE, kRelativeOffsetTooLarge);
352         return false;
353     }
354 
355     // [OpenGL ES 3.1] Section 10.3.1 page 243:
356     // An INVALID_OPERATION error is generated if the default vertex array object is bound.
357     if (context->getState().getVertexArrayId().value == 0)
358     {
359         context->validationError(GL_INVALID_OPERATION, kDefaultVertexArray);
360         return false;
361     }
362 
363     return true;
364 }
365 
366 }  // anonymous namespace
367 
ValidateGetBooleani_v(const Context * context,GLenum target,GLuint index,const GLboolean * data)368 bool ValidateGetBooleani_v(const Context *context,
369                            GLenum target,
370                            GLuint index,
371                            const GLboolean *data)
372 {
373     if (context->getClientVersion() < ES_3_1)
374     {
375         context->validationError(GL_INVALID_OPERATION, kES31Required);
376         return false;
377     }
378 
379     if (!ValidateIndexedStateQuery(context, target, index, nullptr))
380     {
381         return false;
382     }
383 
384     return true;
385 }
386 
ValidateGetBooleani_vRobustANGLE(const Context * context,GLenum target,GLuint index,GLsizei bufSize,const GLsizei * length,const GLboolean * data)387 bool ValidateGetBooleani_vRobustANGLE(const Context *context,
388                                       GLenum target,
389                                       GLuint index,
390                                       GLsizei bufSize,
391                                       const GLsizei *length,
392                                       const GLboolean *data)
393 {
394     if (context->getClientVersion() < ES_3_1)
395     {
396         context->validationError(GL_INVALID_OPERATION, kES31Required);
397         return false;
398     }
399 
400     if (!ValidateRobustEntryPoint(context, bufSize))
401     {
402         return false;
403     }
404 
405     GLsizei numParams = 0;
406 
407     if (!ValidateIndexedStateQuery(context, target, index, &numParams))
408     {
409         return false;
410     }
411 
412     if (!ValidateRobustBufferSize(context, bufSize, numParams))
413     {
414         return false;
415     }
416 
417     SetRobustLengthParam(length, numParams);
418     return true;
419 }
420 
ValidateDrawIndirectBase(const Context * context,PrimitiveMode mode,const void * indirect)421 bool ValidateDrawIndirectBase(const Context *context, PrimitiveMode mode, const void *indirect)
422 {
423     if (context->getClientVersion() < ES_3_1)
424     {
425         context->validationError(GL_INVALID_OPERATION, kES31Required);
426         return false;
427     }
428 
429     // Here the third parameter 1 is only to pass the count validation.
430     if (!ValidateDrawBase(context, mode))
431     {
432         return false;
433     }
434 
435     const State &state = context->getState();
436 
437     // An INVALID_OPERATION error is generated if zero is bound to VERTEX_ARRAY_BINDING,
438     // DRAW_INDIRECT_BUFFER or to any enabled vertex array.
439     if (state.getVertexArrayId().value == 0)
440     {
441         context->validationError(GL_INVALID_OPERATION, kDefaultVertexArray);
442         return false;
443     }
444 
445     if (context->getStateCache().hasAnyActiveClientAttrib())
446     {
447         context->validationError(GL_INVALID_OPERATION, kClientDataInVertexArray);
448         return false;
449     }
450 
451     Buffer *drawIndirectBuffer = state.getTargetBuffer(BufferBinding::DrawIndirect);
452     if (!drawIndirectBuffer)
453     {
454         context->validationError(GL_INVALID_OPERATION, kDrawIndirectBufferNotBound);
455         return false;
456     }
457 
458     // An INVALID_VALUE error is generated if indirect is not a multiple of the size, in basic
459     // machine units, of uint.
460     GLint64 offset = reinterpret_cast<GLint64>(indirect);
461     if ((static_cast<GLuint>(offset) % sizeof(GLuint)) != 0)
462     {
463         context->validationError(GL_INVALID_VALUE, kInvalidIndirectOffset);
464         return false;
465     }
466 
467     return true;
468 }
469 
ValidateDrawArraysIndirect(const Context * context,PrimitiveMode mode,const void * indirect)470 bool ValidateDrawArraysIndirect(const Context *context, PrimitiveMode mode, const void *indirect)
471 {
472     const State &state                      = context->getState();
473     TransformFeedback *curTransformFeedback = state.getCurrentTransformFeedback();
474     if (curTransformFeedback && curTransformFeedback->isActive() &&
475         !curTransformFeedback->isPaused())
476     {
477         // EXT_geometry_shader allows transform feedback to work with all draw commands.
478         // [EXT_geometry_shader] Section 12.1, "Transform Feedback"
479         if (context->getExtensions().geometryShader)
480         {
481             if (!ValidateTransformFeedbackPrimitiveMode(
482                     context, curTransformFeedback->getPrimitiveMode(), mode))
483             {
484                 context->validationError(GL_INVALID_OPERATION, kInvalidDrawModeTransformFeedback);
485                 return false;
486             }
487         }
488         else
489         {
490             // An INVALID_OPERATION error is generated if transform feedback is active and not
491             // paused.
492             context->validationError(GL_INVALID_OPERATION,
493                                      kUnsupportedDrawModeForTransformFeedback);
494             return false;
495         }
496     }
497 
498     if (!ValidateDrawIndirectBase(context, mode, indirect))
499         return false;
500 
501     Buffer *drawIndirectBuffer = state.getTargetBuffer(BufferBinding::DrawIndirect);
502     CheckedNumeric<size_t> checkedOffset(reinterpret_cast<size_t>(indirect));
503     // In OpenGL ES3.1 spec, session 10.5, it defines the struct of DrawArraysIndirectCommand
504     // which's size is 4 * sizeof(uint).
505     auto checkedSum = checkedOffset + 4 * sizeof(GLuint);
506     if (!checkedSum.IsValid() ||
507         checkedSum.ValueOrDie() > static_cast<size_t>(drawIndirectBuffer->getSize()))
508     {
509         context->validationError(GL_INVALID_OPERATION, kParamOverflow);
510         return false;
511     }
512 
513     return true;
514 }
515 
ValidateDrawElementsIndirect(const Context * context,PrimitiveMode mode,DrawElementsType type,const void * indirect)516 bool ValidateDrawElementsIndirect(const Context *context,
517                                   PrimitiveMode mode,
518                                   DrawElementsType type,
519                                   const void *indirect)
520 {
521     if (!ValidateDrawElementsBase(context, mode, type))
522     {
523         return false;
524     }
525 
526     const State &state         = context->getState();
527     const VertexArray *vao     = state.getVertexArray();
528     Buffer *elementArrayBuffer = vao->getElementArrayBuffer();
529     if (!elementArrayBuffer)
530     {
531         context->validationError(GL_INVALID_OPERATION, kMustHaveElementArrayBinding);
532         return false;
533     }
534 
535     if (!ValidateDrawIndirectBase(context, mode, indirect))
536         return false;
537 
538     Buffer *drawIndirectBuffer = state.getTargetBuffer(BufferBinding::DrawIndirect);
539     CheckedNumeric<size_t> checkedOffset(reinterpret_cast<size_t>(indirect));
540     // In OpenGL ES3.1 spec, session 10.5, it defines the struct of DrawElementsIndirectCommand
541     // which's size is 5 * sizeof(uint).
542     auto checkedSum = checkedOffset + 5 * sizeof(GLuint);
543     if (!checkedSum.IsValid() ||
544         checkedSum.ValueOrDie() > static_cast<size_t>(drawIndirectBuffer->getSize()))
545     {
546         context->validationError(GL_INVALID_OPERATION, kParamOverflow);
547         return false;
548     }
549 
550     return true;
551 }
552 
ValidateProgramUniform1i(const Context * context,ShaderProgramID program,UniformLocation location,GLint v0)553 bool ValidateProgramUniform1i(const Context *context,
554                               ShaderProgramID program,
555                               UniformLocation location,
556                               GLint v0)
557 {
558     return ValidateProgramUniform1iv(context, program, location, 1, &v0);
559 }
560 
ValidateProgramUniform2i(const Context * context,ShaderProgramID program,UniformLocation location,GLint v0,GLint v1)561 bool ValidateProgramUniform2i(const Context *context,
562                               ShaderProgramID program,
563                               UniformLocation location,
564                               GLint v0,
565                               GLint v1)
566 {
567     GLint xy[2] = {v0, v1};
568     return ValidateProgramUniform2iv(context, program, location, 1, xy);
569 }
570 
ValidateProgramUniform3i(const Context * context,ShaderProgramID program,UniformLocation location,GLint v0,GLint v1,GLint v2)571 bool ValidateProgramUniform3i(const Context *context,
572                               ShaderProgramID program,
573                               UniformLocation location,
574                               GLint v0,
575                               GLint v1,
576                               GLint v2)
577 {
578     GLint xyz[3] = {v0, v1, v2};
579     return ValidateProgramUniform3iv(context, program, location, 1, xyz);
580 }
581 
ValidateProgramUniform4i(const Context * context,ShaderProgramID program,UniformLocation location,GLint v0,GLint v1,GLint v2,GLint v3)582 bool ValidateProgramUniform4i(const Context *context,
583                               ShaderProgramID program,
584                               UniformLocation location,
585                               GLint v0,
586                               GLint v1,
587                               GLint v2,
588                               GLint v3)
589 {
590     GLint xyzw[4] = {v0, v1, v2, v3};
591     return ValidateProgramUniform4iv(context, program, location, 1, xyzw);
592 }
593 
ValidateProgramUniform1ui(const Context * context,ShaderProgramID program,UniformLocation location,GLuint v0)594 bool ValidateProgramUniform1ui(const Context *context,
595                                ShaderProgramID program,
596                                UniformLocation location,
597                                GLuint v0)
598 {
599     return ValidateProgramUniform1uiv(context, program, location, 1, &v0);
600 }
601 
ValidateProgramUniform2ui(const Context * context,ShaderProgramID program,UniformLocation location,GLuint v0,GLuint v1)602 bool ValidateProgramUniform2ui(const Context *context,
603                                ShaderProgramID program,
604                                UniformLocation location,
605                                GLuint v0,
606                                GLuint v1)
607 {
608     GLuint xy[2] = {v0, v1};
609     return ValidateProgramUniform2uiv(context, program, location, 1, xy);
610 }
611 
ValidateProgramUniform3ui(const Context * context,ShaderProgramID program,UniformLocation location,GLuint v0,GLuint v1,GLuint v2)612 bool ValidateProgramUniform3ui(const Context *context,
613                                ShaderProgramID program,
614                                UniformLocation location,
615                                GLuint v0,
616                                GLuint v1,
617                                GLuint v2)
618 {
619     GLuint xyz[3] = {v0, v1, v2};
620     return ValidateProgramUniform3uiv(context, program, location, 1, xyz);
621 }
622 
ValidateProgramUniform4ui(const Context * context,ShaderProgramID program,UniformLocation location,GLuint v0,GLuint v1,GLuint v2,GLuint v3)623 bool ValidateProgramUniform4ui(const Context *context,
624                                ShaderProgramID program,
625                                UniformLocation location,
626                                GLuint v0,
627                                GLuint v1,
628                                GLuint v2,
629                                GLuint v3)
630 {
631     GLuint xyzw[4] = {v0, v1, v2, v3};
632     return ValidateProgramUniform4uiv(context, program, location, 1, xyzw);
633 }
634 
ValidateProgramUniform1f(const Context * context,ShaderProgramID program,UniformLocation location,GLfloat v0)635 bool ValidateProgramUniform1f(const Context *context,
636                               ShaderProgramID program,
637                               UniformLocation location,
638                               GLfloat v0)
639 {
640     return ValidateProgramUniform1fv(context, program, location, 1, &v0);
641 }
642 
ValidateProgramUniform2f(const Context * context,ShaderProgramID program,UniformLocation location,GLfloat v0,GLfloat v1)643 bool ValidateProgramUniform2f(const Context *context,
644                               ShaderProgramID program,
645                               UniformLocation location,
646                               GLfloat v0,
647                               GLfloat v1)
648 {
649     GLfloat xy[2] = {v0, v1};
650     return ValidateProgramUniform2fv(context, program, location, 1, xy);
651 }
652 
ValidateProgramUniform3f(const Context * context,ShaderProgramID program,UniformLocation location,GLfloat v0,GLfloat v1,GLfloat v2)653 bool ValidateProgramUniform3f(const Context *context,
654                               ShaderProgramID program,
655                               UniformLocation location,
656                               GLfloat v0,
657                               GLfloat v1,
658                               GLfloat v2)
659 {
660     GLfloat xyz[3] = {v0, v1, v2};
661     return ValidateProgramUniform3fv(context, program, location, 1, xyz);
662 }
663 
ValidateProgramUniform4f(const Context * context,ShaderProgramID program,UniformLocation location,GLfloat v0,GLfloat v1,GLfloat v2,GLfloat v3)664 bool ValidateProgramUniform4f(const Context *context,
665                               ShaderProgramID program,
666                               UniformLocation location,
667                               GLfloat v0,
668                               GLfloat v1,
669                               GLfloat v2,
670                               GLfloat v3)
671 {
672     GLfloat xyzw[4] = {v0, v1, v2, v3};
673     return ValidateProgramUniform4fv(context, program, location, 1, xyzw);
674 }
675 
ValidateProgramUniform1iv(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,const GLint * value)676 bool ValidateProgramUniform1iv(const Context *context,
677                                ShaderProgramID program,
678                                UniformLocation location,
679                                GLsizei count,
680                                const GLint *value)
681 {
682     // Check for ES31 program uniform entry points
683     if (context->getClientVersion() < Version(3, 1))
684     {
685         context->validationError(GL_INVALID_OPERATION, kES31Required);
686         return false;
687     }
688 
689     const LinkedUniform *uniform = nullptr;
690     Program *programObject       = GetValidProgram(context, program);
691     return ValidateUniformCommonBase(context, programObject, location, count, &uniform) &&
692            ValidateUniform1ivValue(context, uniform->type, count, value);
693 }
694 
ValidateProgramUniform2iv(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,const GLint * value)695 bool ValidateProgramUniform2iv(const Context *context,
696                                ShaderProgramID program,
697                                UniformLocation location,
698                                GLsizei count,
699                                const GLint *value)
700 {
701     return ValidateProgramUniform(context, GL_INT_VEC2, program, location, count);
702 }
703 
ValidateProgramUniform3iv(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,const GLint * value)704 bool ValidateProgramUniform3iv(const Context *context,
705                                ShaderProgramID program,
706                                UniformLocation location,
707                                GLsizei count,
708                                const GLint *value)
709 {
710     return ValidateProgramUniform(context, GL_INT_VEC3, program, location, count);
711 }
712 
ValidateProgramUniform4iv(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,const GLint * value)713 bool ValidateProgramUniform4iv(const Context *context,
714                                ShaderProgramID program,
715                                UniformLocation location,
716                                GLsizei count,
717                                const GLint *value)
718 {
719     return ValidateProgramUniform(context, GL_INT_VEC4, program, location, count);
720 }
721 
ValidateProgramUniform1uiv(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,const GLuint * value)722 bool ValidateProgramUniform1uiv(const Context *context,
723                                 ShaderProgramID program,
724                                 UniformLocation location,
725                                 GLsizei count,
726                                 const GLuint *value)
727 {
728     return ValidateProgramUniform(context, GL_UNSIGNED_INT, program, location, count);
729 }
730 
ValidateProgramUniform2uiv(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,const GLuint * value)731 bool ValidateProgramUniform2uiv(const Context *context,
732                                 ShaderProgramID program,
733                                 UniformLocation location,
734                                 GLsizei count,
735                                 const GLuint *value)
736 {
737     return ValidateProgramUniform(context, GL_UNSIGNED_INT_VEC2, program, location, count);
738 }
739 
ValidateProgramUniform3uiv(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,const GLuint * value)740 bool ValidateProgramUniform3uiv(const Context *context,
741                                 ShaderProgramID program,
742                                 UniformLocation location,
743                                 GLsizei count,
744                                 const GLuint *value)
745 {
746     return ValidateProgramUniform(context, GL_UNSIGNED_INT_VEC3, program, location, count);
747 }
748 
ValidateProgramUniform4uiv(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,const GLuint * value)749 bool ValidateProgramUniform4uiv(const Context *context,
750                                 ShaderProgramID program,
751                                 UniformLocation location,
752                                 GLsizei count,
753                                 const GLuint *value)
754 {
755     return ValidateProgramUniform(context, GL_UNSIGNED_INT_VEC4, program, location, count);
756 }
757 
ValidateProgramUniform1fv(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,const GLfloat * value)758 bool ValidateProgramUniform1fv(const Context *context,
759                                ShaderProgramID program,
760                                UniformLocation location,
761                                GLsizei count,
762                                const GLfloat *value)
763 {
764     return ValidateProgramUniform(context, GL_FLOAT, program, location, count);
765 }
766 
ValidateProgramUniform2fv(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,const GLfloat * value)767 bool ValidateProgramUniform2fv(const Context *context,
768                                ShaderProgramID program,
769                                UniformLocation location,
770                                GLsizei count,
771                                const GLfloat *value)
772 {
773     return ValidateProgramUniform(context, GL_FLOAT_VEC2, program, location, count);
774 }
775 
ValidateProgramUniform3fv(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,const GLfloat * value)776 bool ValidateProgramUniform3fv(const Context *context,
777                                ShaderProgramID program,
778                                UniformLocation location,
779                                GLsizei count,
780                                const GLfloat *value)
781 {
782     return ValidateProgramUniform(context, GL_FLOAT_VEC3, program, location, count);
783 }
784 
ValidateProgramUniform4fv(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,const GLfloat * value)785 bool ValidateProgramUniform4fv(const Context *context,
786                                ShaderProgramID program,
787                                UniformLocation location,
788                                GLsizei count,
789                                const GLfloat *value)
790 {
791     return ValidateProgramUniform(context, GL_FLOAT_VEC4, program, location, count);
792 }
793 
ValidateProgramUniformMatrix2fv(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)794 bool ValidateProgramUniformMatrix2fv(const Context *context,
795                                      ShaderProgramID program,
796                                      UniformLocation location,
797                                      GLsizei count,
798                                      GLboolean transpose,
799                                      const GLfloat *value)
800 {
801     return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT2, program, location, count,
802                                         transpose);
803 }
804 
ValidateProgramUniformMatrix3fv(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)805 bool ValidateProgramUniformMatrix3fv(const Context *context,
806                                      ShaderProgramID program,
807                                      UniformLocation location,
808                                      GLsizei count,
809                                      GLboolean transpose,
810                                      const GLfloat *value)
811 {
812     return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT3, program, location, count,
813                                         transpose);
814 }
815 
ValidateProgramUniformMatrix4fv(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)816 bool ValidateProgramUniformMatrix4fv(const Context *context,
817                                      ShaderProgramID program,
818                                      UniformLocation location,
819                                      GLsizei count,
820                                      GLboolean transpose,
821                                      const GLfloat *value)
822 {
823     return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT4, program, location, count,
824                                         transpose);
825 }
826 
ValidateProgramUniformMatrix2x3fv(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)827 bool ValidateProgramUniformMatrix2x3fv(const Context *context,
828                                        ShaderProgramID program,
829                                        UniformLocation location,
830                                        GLsizei count,
831                                        GLboolean transpose,
832                                        const GLfloat *value)
833 {
834     return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT2x3, program, location, count,
835                                         transpose);
836 }
837 
ValidateProgramUniformMatrix3x2fv(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)838 bool ValidateProgramUniformMatrix3x2fv(const Context *context,
839                                        ShaderProgramID program,
840                                        UniformLocation location,
841                                        GLsizei count,
842                                        GLboolean transpose,
843                                        const GLfloat *value)
844 {
845     return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT3x2, program, location, count,
846                                         transpose);
847 }
848 
ValidateProgramUniformMatrix2x4fv(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)849 bool ValidateProgramUniformMatrix2x4fv(const Context *context,
850                                        ShaderProgramID program,
851                                        UniformLocation location,
852                                        GLsizei count,
853                                        GLboolean transpose,
854                                        const GLfloat *value)
855 {
856     return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT2x4, program, location, count,
857                                         transpose);
858 }
859 
ValidateProgramUniformMatrix4x2fv(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)860 bool ValidateProgramUniformMatrix4x2fv(const Context *context,
861                                        ShaderProgramID program,
862                                        UniformLocation location,
863                                        GLsizei count,
864                                        GLboolean transpose,
865                                        const GLfloat *value)
866 {
867     return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT4x2, program, location, count,
868                                         transpose);
869 }
870 
ValidateProgramUniformMatrix3x4fv(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)871 bool ValidateProgramUniformMatrix3x4fv(const Context *context,
872                                        ShaderProgramID program,
873                                        UniformLocation location,
874                                        GLsizei count,
875                                        GLboolean transpose,
876                                        const GLfloat *value)
877 {
878     return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT3x4, program, location, count,
879                                         transpose);
880 }
881 
ValidateProgramUniformMatrix4x3fv(const Context * context,ShaderProgramID program,UniformLocation location,GLsizei count,GLboolean transpose,const GLfloat * value)882 bool ValidateProgramUniformMatrix4x3fv(const Context *context,
883                                        ShaderProgramID program,
884                                        UniformLocation location,
885                                        GLsizei count,
886                                        GLboolean transpose,
887                                        const GLfloat *value)
888 {
889     return ValidateProgramUniformMatrix(context, GL_FLOAT_MAT4x3, program, location, count,
890                                         transpose);
891 }
892 
ValidateGetTexLevelParameterfv(const Context * context,TextureTarget target,GLint level,GLenum pname,const GLfloat * params)893 bool ValidateGetTexLevelParameterfv(const Context *context,
894                                     TextureTarget target,
895                                     GLint level,
896                                     GLenum pname,
897                                     const GLfloat *params)
898 {
899     if (context->getClientVersion() < ES_3_1)
900     {
901         context->validationError(GL_INVALID_OPERATION, kES31Required);
902         return false;
903     }
904 
905     return ValidateGetTexLevelParameterBase(context, target, level, pname, nullptr);
906 }
907 
ValidateGetTexLevelParameterfvRobustANGLE(const Context * context,TextureTarget target,GLint level,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLfloat * params)908 bool ValidateGetTexLevelParameterfvRobustANGLE(const Context *context,
909                                                TextureTarget target,
910                                                GLint level,
911                                                GLenum pname,
912                                                GLsizei bufSize,
913                                                const GLsizei *length,
914                                                const GLfloat *params)
915 {
916     UNIMPLEMENTED();
917     return false;
918 }
919 
ValidateGetTexLevelParameteriv(const Context * context,TextureTarget target,GLint level,GLenum pname,const GLint * params)920 bool ValidateGetTexLevelParameteriv(const Context *context,
921                                     TextureTarget target,
922                                     GLint level,
923                                     GLenum pname,
924                                     const GLint *params)
925 {
926     if (context->getClientVersion() < ES_3_1)
927     {
928         context->validationError(GL_INVALID_OPERATION, kES31Required);
929         return false;
930     }
931 
932     return ValidateGetTexLevelParameterBase(context, target, level, pname, nullptr);
933 }
934 
ValidateGetTexLevelParameterivRobustANGLE(const Context * context,TextureTarget target,GLint level,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLint * params)935 bool ValidateGetTexLevelParameterivRobustANGLE(const Context *context,
936                                                TextureTarget target,
937                                                GLint level,
938                                                GLenum pname,
939                                                GLsizei bufSize,
940                                                const GLsizei *length,
941                                                const GLint *params)
942 {
943     UNIMPLEMENTED();
944     return false;
945 }
946 
ValidateTexStorage2DMultisample(const Context * context,TextureType target,GLsizei samples,GLenum internalFormat,GLsizei width,GLsizei height,GLboolean fixedSampleLocations)947 bool ValidateTexStorage2DMultisample(const Context *context,
948                                      TextureType target,
949                                      GLsizei samples,
950                                      GLenum internalFormat,
951                                      GLsizei width,
952                                      GLsizei height,
953                                      GLboolean fixedSampleLocations)
954 {
955     if (context->getClientVersion() < ES_3_1)
956     {
957         context->validationError(GL_INVALID_OPERATION, kES31Required);
958         return false;
959     }
960 
961     return ValidateTexStorage2DMultisampleBase(context, target, samples, internalFormat, width,
962                                                height);
963 }
964 
ValidateTexStorageMem2DMultisampleEXT(const Context * context,TextureType target,GLsizei samples,GLenum internalFormat,GLsizei width,GLsizei height,GLboolean fixedSampleLocations,MemoryObjectID memory,GLuint64 offset)965 bool ValidateTexStorageMem2DMultisampleEXT(const Context *context,
966                                            TextureType target,
967                                            GLsizei samples,
968                                            GLenum internalFormat,
969                                            GLsizei width,
970                                            GLsizei height,
971                                            GLboolean fixedSampleLocations,
972                                            MemoryObjectID memory,
973                                            GLuint64 offset)
974 {
975     if (!context->getExtensions().memoryObject)
976     {
977         context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
978         return false;
979     }
980 
981     UNIMPLEMENTED();
982     return false;
983 }
984 
ValidateGetMultisamplefv(const Context * context,GLenum pname,GLuint index,const GLfloat * val)985 bool ValidateGetMultisamplefv(const Context *context,
986                               GLenum pname,
987                               GLuint index,
988                               const GLfloat *val)
989 {
990     if (context->getClientVersion() < ES_3_1)
991     {
992         context->validationError(GL_INVALID_OPERATION, kES31Required);
993         return false;
994     }
995 
996     return ValidateGetMultisamplefvBase(context, pname, index, val);
997 }
998 
ValidateGetMultisamplefvRobustANGLE(const Context * context,GLenum pname,GLuint index,GLsizei bufSize,const GLsizei * length,const GLfloat * val)999 bool ValidateGetMultisamplefvRobustANGLE(const Context *context,
1000                                          GLenum pname,
1001                                          GLuint index,
1002                                          GLsizei bufSize,
1003                                          const GLsizei *length,
1004                                          const GLfloat *val)
1005 {
1006     UNIMPLEMENTED();
1007     return false;
1008 }
1009 
ValidateFramebufferParameteri(const Context * context,GLenum target,GLenum pname,GLint param)1010 bool ValidateFramebufferParameteri(const Context *context, GLenum target, GLenum pname, GLint param)
1011 {
1012     if (context->getClientVersion() < ES_3_1)
1013     {
1014         context->validationError(GL_INVALID_OPERATION, kES31Required);
1015         return false;
1016     }
1017 
1018     if (!ValidFramebufferTarget(context, target))
1019     {
1020         context->validationError(GL_INVALID_ENUM, kInvalidFramebufferTarget);
1021         return false;
1022     }
1023 
1024     switch (pname)
1025     {
1026         case GL_FRAMEBUFFER_DEFAULT_WIDTH:
1027         {
1028             GLint maxWidth = context->getCaps().maxFramebufferWidth;
1029             if (param < 0 || param > maxWidth)
1030             {
1031                 context->validationError(GL_INVALID_VALUE, kExceedsFramebufferWidth);
1032                 return false;
1033             }
1034             break;
1035         }
1036         case GL_FRAMEBUFFER_DEFAULT_HEIGHT:
1037         {
1038             GLint maxHeight = context->getCaps().maxFramebufferHeight;
1039             if (param < 0 || param > maxHeight)
1040             {
1041                 context->validationError(GL_INVALID_VALUE, kExceedsFramebufferHeight);
1042                 return false;
1043             }
1044             break;
1045         }
1046         case GL_FRAMEBUFFER_DEFAULT_SAMPLES:
1047         {
1048             GLint maxSamples = context->getCaps().maxFramebufferSamples;
1049             if (param < 0 || param > maxSamples)
1050             {
1051                 context->validationError(GL_INVALID_VALUE, kExceedsFramebufferSamples);
1052                 return false;
1053             }
1054             break;
1055         }
1056         case GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS:
1057         {
1058             break;
1059         }
1060         case GL_FRAMEBUFFER_DEFAULT_LAYERS_EXT:
1061         {
1062             if (!context->getExtensions().geometryShader)
1063             {
1064                 context->validationError(GL_INVALID_ENUM, kGeometryShaderExtensionNotEnabled);
1065                 return false;
1066             }
1067             GLint maxLayers = context->getCaps().maxFramebufferLayers;
1068             if (param < 0 || param > maxLayers)
1069             {
1070                 context->validationError(GL_INVALID_VALUE, kInvalidFramebufferLayer);
1071                 return false;
1072             }
1073             break;
1074         }
1075         default:
1076         {
1077             context->validationError(GL_INVALID_ENUM, kInvalidPname);
1078             return false;
1079         }
1080     }
1081 
1082     const Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
1083     ASSERT(framebuffer);
1084     if (framebuffer->isDefault())
1085     {
1086         context->validationError(GL_INVALID_OPERATION, kDefaultFramebuffer);
1087         return false;
1088     }
1089     return true;
1090 }
1091 
ValidateGetFramebufferParameteriv(const Context * context,GLenum target,GLenum pname,const GLint * params)1092 bool ValidateGetFramebufferParameteriv(const Context *context,
1093                                        GLenum target,
1094                                        GLenum pname,
1095                                        const GLint *params)
1096 {
1097     if (context->getClientVersion() < ES_3_1)
1098     {
1099         context->validationError(GL_INVALID_OPERATION, kES31Required);
1100         return false;
1101     }
1102 
1103     if (!ValidFramebufferTarget(context, target))
1104     {
1105         context->validationError(GL_INVALID_ENUM, kInvalidFramebufferTarget);
1106         return false;
1107     }
1108 
1109     switch (pname)
1110     {
1111         case GL_FRAMEBUFFER_DEFAULT_WIDTH:
1112         case GL_FRAMEBUFFER_DEFAULT_HEIGHT:
1113         case GL_FRAMEBUFFER_DEFAULT_SAMPLES:
1114         case GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS:
1115             break;
1116         case GL_FRAMEBUFFER_DEFAULT_LAYERS_EXT:
1117             if (!context->getExtensions().geometryShader)
1118             {
1119                 context->validationError(GL_INVALID_ENUM, kGeometryShaderExtensionNotEnabled);
1120                 return false;
1121             }
1122             break;
1123         default:
1124             context->validationError(GL_INVALID_ENUM, kInvalidPname);
1125             return false;
1126     }
1127 
1128     const Framebuffer *framebuffer = context->getState().getTargetFramebuffer(target);
1129     ASSERT(framebuffer);
1130 
1131     if (framebuffer->isDefault())
1132     {
1133         context->validationError(GL_INVALID_OPERATION, kDefaultFramebuffer);
1134         return false;
1135     }
1136     return true;
1137 }
1138 
ValidateGetFramebufferParameterivRobustANGLE(const Context * context,GLenum target,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLint * params)1139 bool ValidateGetFramebufferParameterivRobustANGLE(const Context *context,
1140                                                   GLenum target,
1141                                                   GLenum pname,
1142                                                   GLsizei bufSize,
1143                                                   const GLsizei *length,
1144                                                   const GLint *params)
1145 {
1146     UNIMPLEMENTED();
1147     return false;
1148 }
1149 
ValidateGetProgramResourceIndex(const Context * context,ShaderProgramID program,GLenum programInterface,const GLchar * name)1150 bool ValidateGetProgramResourceIndex(const Context *context,
1151                                      ShaderProgramID program,
1152                                      GLenum programInterface,
1153                                      const GLchar *name)
1154 {
1155     if (context->getClientVersion() < ES_3_1)
1156     {
1157         context->validationError(GL_INVALID_OPERATION, kES31Required);
1158         return false;
1159     }
1160 
1161     Program *programObject = GetValidProgram(context, program);
1162     if (programObject == nullptr)
1163     {
1164         return false;
1165     }
1166 
1167     if (!ValidateNamedProgramInterface(programInterface))
1168     {
1169         context->validationError(GL_INVALID_ENUM, kInvalidProgramInterface);
1170         return false;
1171     }
1172 
1173     return true;
1174 }
1175 
ValidateBindVertexBuffer(const Context * context,GLuint bindingIndex,BufferID buffer,GLintptr offset,GLsizei stride)1176 bool ValidateBindVertexBuffer(const Context *context,
1177                               GLuint bindingIndex,
1178                               BufferID buffer,
1179                               GLintptr offset,
1180                               GLsizei stride)
1181 {
1182     if (context->getClientVersion() < ES_3_1)
1183     {
1184         context->validationError(GL_INVALID_OPERATION, kES31Required);
1185         return false;
1186     }
1187 
1188     if (!context->isBufferGenerated(buffer))
1189     {
1190         context->validationError(GL_INVALID_OPERATION, kObjectNotGenerated);
1191         return false;
1192     }
1193 
1194     const Caps &caps = context->getCaps();
1195     if (bindingIndex >= static_cast<GLuint>(caps.maxVertexAttribBindings))
1196     {
1197         context->validationError(GL_INVALID_VALUE, kExceedsMaxVertexAttribBindings);
1198         return false;
1199     }
1200 
1201     if (offset < 0)
1202     {
1203         context->validationError(GL_INVALID_VALUE, kNegativeOffset);
1204         return false;
1205     }
1206 
1207     if (stride < 0 || stride > caps.maxVertexAttribStride)
1208     {
1209         context->validationError(GL_INVALID_VALUE, kExceedsMaxVertexAttribStride);
1210         return false;
1211     }
1212 
1213     // [OpenGL ES 3.1] Section 10.3.1 page 244:
1214     // An INVALID_OPERATION error is generated if the default vertex array object is bound.
1215     if (context->getState().getVertexArrayId().value == 0)
1216     {
1217         context->validationError(GL_INVALID_OPERATION, kDefaultVertexArray);
1218         return false;
1219     }
1220 
1221     return true;
1222 }
1223 
ValidateVertexBindingDivisor(const Context * context,GLuint bindingIndex,GLuint divisor)1224 bool ValidateVertexBindingDivisor(const Context *context, GLuint bindingIndex, GLuint divisor)
1225 {
1226     if (context->getClientVersion() < ES_3_1)
1227     {
1228         context->validationError(GL_INVALID_OPERATION, kES31Required);
1229         return false;
1230     }
1231 
1232     const Caps &caps = context->getCaps();
1233     if (bindingIndex >= static_cast<GLuint>(caps.maxVertexAttribBindings))
1234     {
1235         context->validationError(GL_INVALID_VALUE, kExceedsMaxVertexAttribBindings);
1236         return false;
1237     }
1238 
1239     // [OpenGL ES 3.1] Section 10.3.1 page 243:
1240     // An INVALID_OPERATION error is generated if the default vertex array object is bound.
1241     if (context->getState().getVertexArrayId().value == 0)
1242     {
1243         context->validationError(GL_INVALID_OPERATION, kDefaultVertexArray);
1244         return false;
1245     }
1246 
1247     return true;
1248 }
1249 
ValidateVertexAttribFormat(const Context * context,GLuint attribindex,GLint size,VertexAttribType type,GLboolean normalized,GLuint relativeoffset)1250 bool ValidateVertexAttribFormat(const Context *context,
1251                                 GLuint attribindex,
1252                                 GLint size,
1253                                 VertexAttribType type,
1254                                 GLboolean normalized,
1255                                 GLuint relativeoffset)
1256 {
1257     if (!ValidateVertexAttribFormatCommon(context, relativeoffset))
1258     {
1259         return false;
1260     }
1261 
1262     return ValidateFloatVertexFormat(context, attribindex, size, type);
1263 }
1264 
ValidateVertexAttribIFormat(const Context * context,GLuint attribindex,GLint size,VertexAttribType type,GLuint relativeoffset)1265 bool ValidateVertexAttribIFormat(const Context *context,
1266                                  GLuint attribindex,
1267                                  GLint size,
1268                                  VertexAttribType type,
1269                                  GLuint relativeoffset)
1270 {
1271     if (!ValidateVertexAttribFormatCommon(context, relativeoffset))
1272     {
1273         return false;
1274     }
1275 
1276     return ValidateIntegerVertexFormat(context, attribindex, size, type);
1277 }
1278 
ValidateVertexAttribBinding(const Context * context,GLuint attribIndex,GLuint bindingIndex)1279 bool ValidateVertexAttribBinding(const Context *context, GLuint attribIndex, GLuint bindingIndex)
1280 {
1281     if (context->getClientVersion() < ES_3_1)
1282     {
1283         context->validationError(GL_INVALID_OPERATION, kES31Required);
1284         return false;
1285     }
1286 
1287     // [OpenGL ES 3.1] Section 10.3.1 page 243:
1288     // An INVALID_OPERATION error is generated if the default vertex array object is bound.
1289     if (context->getState().getVertexArrayId().value == 0)
1290     {
1291         context->validationError(GL_INVALID_OPERATION, kDefaultVertexArray);
1292         return false;
1293     }
1294 
1295     const Caps &caps = context->getCaps();
1296     if (attribIndex >= static_cast<GLuint>(caps.maxVertexAttributes))
1297     {
1298         context->validationError(GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute);
1299         return false;
1300     }
1301 
1302     if (bindingIndex >= static_cast<GLuint>(caps.maxVertexAttribBindings))
1303     {
1304         context->validationError(GL_INVALID_VALUE, kExceedsMaxVertexAttribBindings);
1305         return false;
1306     }
1307 
1308     return true;
1309 }
1310 
ValidateGetProgramResourceName(const Context * context,ShaderProgramID program,GLenum programInterface,GLuint index,GLsizei bufSize,const GLsizei * length,const GLchar * name)1311 bool ValidateGetProgramResourceName(const Context *context,
1312                                     ShaderProgramID program,
1313                                     GLenum programInterface,
1314                                     GLuint index,
1315                                     GLsizei bufSize,
1316                                     const GLsizei *length,
1317                                     const GLchar *name)
1318 {
1319     if (context->getClientVersion() < ES_3_1)
1320     {
1321         context->validationError(GL_INVALID_OPERATION, kES31Required);
1322         return false;
1323     }
1324 
1325     Program *programObject = GetValidProgram(context, program);
1326     if (programObject == nullptr)
1327     {
1328         return false;
1329     }
1330 
1331     if (!ValidateNamedProgramInterface(programInterface))
1332     {
1333         context->validationError(GL_INVALID_ENUM, kInvalidProgramInterface);
1334         return false;
1335     }
1336 
1337     if (!ValidateProgramResourceIndex(programObject, programInterface, index))
1338     {
1339         context->validationError(GL_INVALID_VALUE, kInvalidProgramResourceIndex);
1340         return false;
1341     }
1342 
1343     if (bufSize < 0)
1344     {
1345         context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
1346         return false;
1347     }
1348 
1349     return true;
1350 }
1351 
ValidateDispatchCompute(const Context * context,GLuint numGroupsX,GLuint numGroupsY,GLuint numGroupsZ)1352 bool ValidateDispatchCompute(const Context *context,
1353                              GLuint numGroupsX,
1354                              GLuint numGroupsY,
1355                              GLuint numGroupsZ)
1356 {
1357     if (context->getClientVersion() < ES_3_1)
1358     {
1359         context->validationError(GL_INVALID_OPERATION, kES31Required);
1360         return false;
1361     }
1362 
1363     const State &state                  = context->getState();
1364     const ProgramExecutable *executable = state.getProgramExecutable();
1365 
1366     if (executable == nullptr || !executable->hasLinkedShaderStage(ShaderType::Compute))
1367     {
1368         context->validationError(GL_INVALID_OPERATION, kNoActiveProgramWithComputeShader);
1369         return false;
1370     }
1371 
1372     const Caps &caps = context->getCaps();
1373     if (numGroupsX > static_cast<GLuint>(caps.maxComputeWorkGroupCount[0]))
1374     {
1375         context->validationError(GL_INVALID_VALUE, kExceedsComputeWorkGroupCountX);
1376         return false;
1377     }
1378     if (numGroupsY > static_cast<GLuint>(caps.maxComputeWorkGroupCount[1]))
1379     {
1380         context->validationError(GL_INVALID_VALUE, kExceedsComputeWorkGroupCountY);
1381         return false;
1382     }
1383     if (numGroupsZ > static_cast<GLuint>(caps.maxComputeWorkGroupCount[2]))
1384     {
1385         context->validationError(GL_INVALID_VALUE, kExceedsComputeWorkGroupCountZ);
1386         return false;
1387     }
1388 
1389     return true;
1390 }
1391 
ValidateDispatchComputeIndirect(const Context * context,GLintptr indirect)1392 bool ValidateDispatchComputeIndirect(const Context *context, GLintptr indirect)
1393 {
1394     if (context->getClientVersion() < ES_3_1)
1395     {
1396         context->validationError(GL_INVALID_OPERATION, kES31Required);
1397         return false;
1398     }
1399 
1400     const State &state                  = context->getState();
1401     const ProgramExecutable *executable = state.getProgramExecutable();
1402 
1403     if (executable == nullptr || !executable->hasLinkedShaderStage(ShaderType::Compute))
1404     {
1405         context->validationError(GL_INVALID_OPERATION, kNoActiveProgramWithComputeShader);
1406         return false;
1407     }
1408 
1409     if (indirect < 0)
1410     {
1411         context->validationError(GL_INVALID_VALUE, kNegativeOffset);
1412         return false;
1413     }
1414 
1415     if ((indirect & (sizeof(GLuint) - 1)) != 0)
1416     {
1417         context->validationError(GL_INVALID_VALUE, kOffsetMustBeMultipleOfUint);
1418         return false;
1419     }
1420 
1421     Buffer *dispatchIndirectBuffer = state.getTargetBuffer(BufferBinding::DispatchIndirect);
1422     if (!dispatchIndirectBuffer)
1423     {
1424         context->validationError(GL_INVALID_OPERATION, kDispatchIndirectBufferNotBound);
1425         return false;
1426     }
1427 
1428     CheckedNumeric<GLuint64> checkedOffset(static_cast<GLuint64>(indirect));
1429     auto checkedSum = checkedOffset + static_cast<GLuint64>(3 * sizeof(GLuint));
1430     if (!checkedSum.IsValid() ||
1431         checkedSum.ValueOrDie() > static_cast<GLuint64>(dispatchIndirectBuffer->getSize()))
1432     {
1433         context->validationError(GL_INVALID_OPERATION, kInsufficientBufferSize);
1434         return false;
1435     }
1436 
1437     return true;
1438 }
1439 
ValidateBindImageTexture(const Context * context,GLuint unit,TextureID texture,GLint level,GLboolean layered,GLint layer,GLenum access,GLenum format)1440 bool ValidateBindImageTexture(const Context *context,
1441                               GLuint unit,
1442                               TextureID texture,
1443                               GLint level,
1444                               GLboolean layered,
1445                               GLint layer,
1446                               GLenum access,
1447                               GLenum format)
1448 {
1449     GLuint maxImageUnits = static_cast<GLuint>(context->getCaps().maxImageUnits);
1450     if (unit >= maxImageUnits)
1451     {
1452         context->validationError(GL_INVALID_VALUE, kExceedsMaxImageUnits);
1453         return false;
1454     }
1455 
1456     if (level < 0)
1457     {
1458         context->validationError(GL_INVALID_VALUE, kNegativeLevel);
1459         return false;
1460     }
1461 
1462     if (layer < 0)
1463     {
1464         context->validationError(GL_INVALID_VALUE, kNegativeLayer);
1465         return false;
1466     }
1467 
1468     if (access != GL_READ_ONLY && access != GL_WRITE_ONLY && access != GL_READ_WRITE)
1469     {
1470         context->validationError(GL_INVALID_ENUM, kInvalidImageAccess);
1471         return false;
1472     }
1473 
1474     switch (format)
1475     {
1476         case GL_RGBA32F:
1477         case GL_RGBA16F:
1478         case GL_R32F:
1479         case GL_RGBA32UI:
1480         case GL_RGBA16UI:
1481         case GL_RGBA8UI:
1482         case GL_R32UI:
1483         case GL_RGBA32I:
1484         case GL_RGBA16I:
1485         case GL_RGBA8I:
1486         case GL_R32I:
1487         case GL_RGBA8:
1488         case GL_RGBA8_SNORM:
1489             break;
1490         default:
1491             context->validationError(GL_INVALID_VALUE, kInvalidImageFormat);
1492             return false;
1493     }
1494 
1495     if (texture.value != 0)
1496     {
1497         Texture *tex = context->getTexture(texture);
1498 
1499         if (tex == nullptr)
1500         {
1501             context->validationError(GL_INVALID_VALUE, kMissingTextureName);
1502             return false;
1503         }
1504 
1505         if (!tex->getImmutableFormat())
1506         {
1507             context->validationError(GL_INVALID_OPERATION, kTextureIsNotImmutable);
1508             return false;
1509         }
1510     }
1511 
1512     return true;
1513 }
1514 
ValidateGetProgramResourceLocation(const Context * context,ShaderProgramID program,GLenum programInterface,const GLchar * name)1515 bool ValidateGetProgramResourceLocation(const Context *context,
1516                                         ShaderProgramID program,
1517                                         GLenum programInterface,
1518                                         const GLchar *name)
1519 {
1520     if (context->getClientVersion() < ES_3_1)
1521     {
1522         context->validationError(GL_INVALID_OPERATION, kES31Required);
1523         return false;
1524     }
1525 
1526     Program *programObject = GetValidProgram(context, program);
1527     if (programObject == nullptr)
1528     {
1529         return false;
1530     }
1531 
1532     if (!programObject->isLinked())
1533     {
1534         context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
1535         return false;
1536     }
1537 
1538     if (!ValidateLocationProgramInterface(programInterface))
1539     {
1540         context->validationError(GL_INVALID_ENUM, kInvalidProgramInterface);
1541         return false;
1542     }
1543     return true;
1544 }
1545 
ValidateGetProgramResourceiv(const Context * context,ShaderProgramID program,GLenum programInterface,GLuint index,GLsizei propCount,const GLenum * props,GLsizei bufSize,const GLsizei * length,const GLint * params)1546 bool ValidateGetProgramResourceiv(const Context *context,
1547                                   ShaderProgramID program,
1548                                   GLenum programInterface,
1549                                   GLuint index,
1550                                   GLsizei propCount,
1551                                   const GLenum *props,
1552                                   GLsizei bufSize,
1553                                   const GLsizei *length,
1554                                   const GLint *params)
1555 {
1556     if (context->getClientVersion() < ES_3_1)
1557     {
1558         context->validationError(GL_INVALID_OPERATION, kES31Required);
1559         return false;
1560     }
1561 
1562     Program *programObject = GetValidProgram(context, program);
1563     if (programObject == nullptr)
1564     {
1565         return false;
1566     }
1567     if (!ValidateProgramInterface(programInterface))
1568     {
1569         context->validationError(GL_INVALID_ENUM, kInvalidProgramInterface);
1570         return false;
1571     }
1572     if (propCount <= 0)
1573     {
1574         context->validationError(GL_INVALID_VALUE, kInvalidPropCount);
1575         return false;
1576     }
1577     if (bufSize < 0)
1578     {
1579         context->validationError(GL_INVALID_VALUE, kNegativeBufSize);
1580         return false;
1581     }
1582     if (!ValidateProgramResourceIndex(programObject, programInterface, index))
1583     {
1584         context->validationError(GL_INVALID_VALUE, kInvalidProgramResourceIndex);
1585         return false;
1586     }
1587     for (GLsizei i = 0; i < propCount; i++)
1588     {
1589         if (!ValidateProgramResourceProperty(context, props[i]))
1590         {
1591             context->validationError(GL_INVALID_ENUM, kInvalidProgramResourceProperty);
1592             return false;
1593         }
1594         if (!ValidateProgramResourcePropertyByInterface(props[i], programInterface))
1595         {
1596             context->validationError(GL_INVALID_OPERATION, kInvalidPropertyForProgramInterface);
1597             return false;
1598         }
1599     }
1600     return true;
1601 }
1602 
ValidateGetProgramInterfaceiv(const Context * context,ShaderProgramID program,GLenum programInterface,GLenum pname,const GLint * params)1603 bool ValidateGetProgramInterfaceiv(const Context *context,
1604                                    ShaderProgramID program,
1605                                    GLenum programInterface,
1606                                    GLenum pname,
1607                                    const GLint *params)
1608 {
1609     if (context->getClientVersion() < ES_3_1)
1610     {
1611         context->validationError(GL_INVALID_OPERATION, kES31Required);
1612         return false;
1613     }
1614 
1615     Program *programObject = GetValidProgram(context, program);
1616     if (programObject == nullptr)
1617     {
1618         return false;
1619     }
1620 
1621     if (!ValidateProgramInterface(programInterface))
1622     {
1623         context->validationError(GL_INVALID_ENUM, kInvalidProgramInterface);
1624         return false;
1625     }
1626 
1627     switch (pname)
1628     {
1629         case GL_ACTIVE_RESOURCES:
1630         case GL_MAX_NAME_LENGTH:
1631         case GL_MAX_NUM_ACTIVE_VARIABLES:
1632             break;
1633 
1634         default:
1635             context->validationError(GL_INVALID_ENUM, kInvalidPname);
1636             return false;
1637     }
1638 
1639     if (pname == GL_MAX_NAME_LENGTH && programInterface == GL_ATOMIC_COUNTER_BUFFER)
1640     {
1641         context->validationError(GL_INVALID_OPERATION, kAtomicCounterResourceName);
1642         return false;
1643     }
1644 
1645     if (pname == GL_MAX_NUM_ACTIVE_VARIABLES)
1646     {
1647         switch (programInterface)
1648         {
1649             case GL_ATOMIC_COUNTER_BUFFER:
1650             case GL_SHADER_STORAGE_BLOCK:
1651             case GL_UNIFORM_BLOCK:
1652                 break;
1653 
1654             default:
1655                 context->validationError(GL_INVALID_OPERATION, kMaxActiveVariablesInterface);
1656                 return false;
1657         }
1658     }
1659 
1660     return true;
1661 }
1662 
ValidateGetProgramInterfaceivRobustANGLE(const Context * context,ShaderProgramID program,GLenum programInterface,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLint * params)1663 bool ValidateGetProgramInterfaceivRobustANGLE(const Context *context,
1664                                               ShaderProgramID program,
1665                                               GLenum programInterface,
1666                                               GLenum pname,
1667                                               GLsizei bufSize,
1668                                               const GLsizei *length,
1669                                               const GLint *params)
1670 {
1671     UNIMPLEMENTED();
1672     return false;
1673 }
1674 
ValidateGenOrDeleteES31(const Context * context,GLint n)1675 static bool ValidateGenOrDeleteES31(const Context *context, GLint n)
1676 {
1677     if (context->getClientVersion() < ES_3_1)
1678     {
1679         context->validationError(GL_INVALID_OPERATION, kES31Required);
1680         return false;
1681     }
1682 
1683     return ValidateGenOrDelete(context, n);
1684 }
1685 
ValidateGenProgramPipelines(const Context * context,GLint n,const ProgramPipelineID * pipelines)1686 bool ValidateGenProgramPipelines(const Context *context,
1687                                  GLint n,
1688                                  const ProgramPipelineID *pipelines)
1689 {
1690     return ValidateGenOrDeleteES31(context, n);
1691 }
1692 
ValidateDeleteProgramPipelines(const Context * context,GLint n,const ProgramPipelineID * pipelines)1693 bool ValidateDeleteProgramPipelines(const Context *context,
1694                                     GLint n,
1695                                     const ProgramPipelineID *pipelines)
1696 {
1697     return ValidateGenOrDeleteES31(context, n);
1698 }
1699 
ValidateBindProgramPipeline(const Context * context,ProgramPipelineID pipeline)1700 bool ValidateBindProgramPipeline(const Context *context, ProgramPipelineID pipeline)
1701 {
1702     if (context->getClientVersion() < ES_3_1)
1703     {
1704         context->validationError(GL_INVALID_OPERATION, kES31Required);
1705         return false;
1706     }
1707 
1708     if (!context->isProgramPipelineGenerated({pipeline}))
1709     {
1710         context->validationError(GL_INVALID_OPERATION, kObjectNotGenerated);
1711         return false;
1712     }
1713 
1714     return true;
1715 }
1716 
ValidateIsProgramPipeline(const Context * context,ProgramPipelineID pipeline)1717 bool ValidateIsProgramPipeline(const Context *context, ProgramPipelineID pipeline)
1718 {
1719     if (context->getClientVersion() < ES_3_1)
1720     {
1721         context->validationError(GL_INVALID_OPERATION, kES31Required);
1722         return false;
1723     }
1724 
1725     return true;
1726 }
1727 
ValidateUseProgramStages(const Context * context,ProgramPipelineID pipeline,GLbitfield stages,ShaderProgramID programId)1728 bool ValidateUseProgramStages(const Context *context,
1729                               ProgramPipelineID pipeline,
1730                               GLbitfield stages,
1731                               ShaderProgramID programId)
1732 {
1733     if (context->getClientVersion() < ES_3_1)
1734     {
1735         context->validationError(GL_INVALID_OPERATION, kES31Required);
1736         return false;
1737     }
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     const GLbitfield knownShaderBits =
1742         GL_VERTEX_SHADER_BIT | GL_FRAGMENT_SHADER_BIT | GL_COMPUTE_SHADER_BIT;
1743     if ((stages & ~knownShaderBits) && (stages != GL_ALL_SHADER_BITS))
1744     {
1745         context->validationError(GL_INVALID_VALUE, kUnrecognizedShaderStageBit);
1746         return false;
1747     }
1748 
1749     // GL_INVALID_OPERATION is generated if pipeline is not a name previously returned from a call
1750     // to glGenProgramPipelines or if such a name has been deleted by a call to
1751     // glDeleteProgramPipelines.
1752     if (!context->isProgramPipelineGenerated({pipeline}))
1753     {
1754         context->validationError(GL_INVALID_OPERATION, kObjectNotGenerated);
1755         return false;
1756     }
1757 
1758     // If program is zero, or refers to a program object with no valid shader executable for a given
1759     // stage, it is as if the pipeline object has no programmable stage configured for the indicated
1760     // shader stages.
1761     if (programId.value == 0)
1762     {
1763         return true;
1764     }
1765 
1766     Program *program = context->getProgramNoResolveLink(programId);
1767     if (!program)
1768     {
1769         context->validationError(GL_INVALID_VALUE, kProgramDoesNotExist);
1770         return false;
1771     }
1772 
1773     // GL_INVALID_OPERATION is generated if program refers to a program object that was not linked
1774     // with its GL_PROGRAM_SEPARABLE status set.
1775     // resolveLink() may not have been called if glCreateShaderProgramv() was not used and
1776     // glDetachShader() was not called.
1777     program->resolveLink(context);
1778     if (!program->isSeparable())
1779     {
1780         context->validationError(GL_INVALID_OPERATION, kProgramNotSeparable);
1781         return false;
1782     }
1783 
1784     // GL_INVALID_OPERATION is generated if program refers to a program object that has not been
1785     // successfully linked.
1786     if (!program->isLinked())
1787     {
1788         context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
1789         return false;
1790     }
1791 
1792     return true;
1793 }
1794 
ValidateActiveShaderProgram(const Context * context,ProgramPipelineID pipeline,ShaderProgramID programId)1795 bool ValidateActiveShaderProgram(const Context *context,
1796                                  ProgramPipelineID pipeline,
1797                                  ShaderProgramID programId)
1798 {
1799     // An INVALID_OPERATION error is generated if pipeline is not a name returned from a previous
1800     // call to GenProgramPipelines or if such a name has since been deleted by
1801     // DeleteProgramPipelines.
1802     if (!context->isProgramPipelineGenerated({pipeline}))
1803     {
1804         context->validationError(GL_INVALID_OPERATION, kObjectNotGenerated);
1805         return false;
1806     }
1807 
1808     // An INVALID_VALUE error is generated if program is not zero and is not the name of either a
1809     // program or shader object.
1810     if ((programId.value != 0) && !context->isProgram(programId) && !context->isShader(programId))
1811     {
1812         context->validationError(GL_INVALID_VALUE, kProgramDoesNotExist);
1813         return false;
1814     }
1815 
1816     // An INVALID_OPERATION error is generated if program is the name of a shader object.
1817     if (context->isShader(programId))
1818     {
1819         context->validationError(GL_INVALID_OPERATION, kExpectedProgramName);
1820         return false;
1821     }
1822 
1823     // An INVALID_OPERATION error is generated if program is not zero and has not been linked, or
1824     // was last linked unsuccessfully. The active program is not modified.
1825     Program *program = context->getProgramNoResolveLink(programId);
1826     if ((programId.value != 0) && !program->isLinked())
1827     {
1828         context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
1829         return false;
1830     }
1831 
1832     return true;
1833 }
1834 
ValidateCreateShaderProgramv(const Context * context,ShaderType type,GLsizei count,const GLchar * const * strings)1835 bool ValidateCreateShaderProgramv(const Context *context,
1836                                   ShaderType type,
1837                                   GLsizei count,
1838                                   const GLchar *const *strings)
1839 {
1840     if (context->getClientVersion() < ES_3_1)
1841     {
1842         context->validationError(GL_INVALID_OPERATION, kES31Required);
1843         return false;
1844     }
1845 
1846     // GL_INVALID_ENUM is generated if type is not an accepted shader type.
1847     if ((type != ShaderType::Vertex) && (type != ShaderType::Fragment) &&
1848         (type != ShaderType::Compute))
1849     {
1850         context->validationError(GL_INVALID_ENUM, kInvalidShaderType);
1851         return false;
1852     }
1853 
1854     // GL_INVALID_VALUE is generated if count is negative.
1855     if (count < 0)
1856     {
1857         context->validationError(GL_INVALID_VALUE, kNegativeCount);
1858         return false;
1859     }
1860 
1861     return true;
1862 }
1863 
ValidateGetProgramPipelineiv(const Context * context,ProgramPipelineID pipeline,GLenum pname,const GLint * params)1864 bool ValidateGetProgramPipelineiv(const Context *context,
1865                                   ProgramPipelineID pipeline,
1866                                   GLenum pname,
1867                                   const GLint *params)
1868 {
1869     // An INVALID_OPERATION error is generated if pipeline is not a name returned from a previous
1870     // call to GenProgramPipelines or if such a name has since been deleted by
1871     // DeleteProgramPipelines.
1872     if ((pipeline.value == 0) || (!context->isProgramPipelineGenerated(pipeline)))
1873     {
1874         context->validationError(GL_INVALID_OPERATION, kProgramPipelineDoesNotExist);
1875         return false;
1876     }
1877 
1878     // An INVALID_ENUM error is generated if pname is not ACTIVE_PROGRAM,
1879     // INFO_LOG_LENGTH, VALIDATE_STATUS, or one of the type arguments in
1880     // table 7.1.
1881     switch (pname)
1882     {
1883         case GL_ACTIVE_PROGRAM:
1884         case GL_INFO_LOG_LENGTH:
1885         case GL_VALIDATE_STATUS:
1886         case GL_VERTEX_SHADER:
1887         case GL_FRAGMENT_SHADER:
1888         case GL_COMPUTE_SHADER:
1889             break;
1890 
1891         default:
1892             context->validationError(GL_INVALID_ENUM, kInvalidPname);
1893             return false;
1894     }
1895 
1896     return true;
1897 }
1898 
ValidateValidateProgramPipeline(const Context * context,ProgramPipelineID pipeline)1899 bool ValidateValidateProgramPipeline(const Context *context, ProgramPipelineID pipeline)
1900 {
1901     if (pipeline.value == 0)
1902     {
1903         return false;
1904     }
1905 
1906     if (!context->isProgramPipelineGenerated(pipeline))
1907     {
1908         context->validationError(GL_INVALID_OPERATION, kProgramPipelineDoesNotExist);
1909         return false;
1910     }
1911 
1912     return true;
1913 }
1914 
ValidateGetProgramPipelineInfoLog(const Context * context,ProgramPipelineID pipeline,GLsizei bufSize,const GLsizei * length,const GLchar * infoLog)1915 bool ValidateGetProgramPipelineInfoLog(const Context *context,
1916                                        ProgramPipelineID pipeline,
1917                                        GLsizei bufSize,
1918                                        const GLsizei *length,
1919                                        const GLchar *infoLog)
1920 {
1921     if (bufSize < 0)
1922     {
1923         context->validationError(GL_INVALID_VALUE, kNegativeBufferSize);
1924         return false;
1925     }
1926 
1927     if (!context->isProgramPipelineGenerated(pipeline))
1928     {
1929         context->validationError(GL_INVALID_VALUE, kProgramPipelineDoesNotExist);
1930         return false;
1931     }
1932 
1933     return true;
1934 }
1935 
ValidateMemoryBarrier(const Context * context,GLbitfield barriers)1936 bool ValidateMemoryBarrier(const Context *context, GLbitfield barriers)
1937 {
1938     if (context->getClientVersion() < ES_3_1)
1939     {
1940         context->validationError(GL_INVALID_OPERATION, kES31Required);
1941         return false;
1942     }
1943 
1944     if (barriers == GL_ALL_BARRIER_BITS)
1945     {
1946         return true;
1947     }
1948 
1949     GLbitfield supported_barrier_bits =
1950         GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT | GL_ELEMENT_ARRAY_BARRIER_BIT | GL_UNIFORM_BARRIER_BIT |
1951         GL_TEXTURE_FETCH_BARRIER_BIT | GL_SHADER_IMAGE_ACCESS_BARRIER_BIT | GL_COMMAND_BARRIER_BIT |
1952         GL_PIXEL_BUFFER_BARRIER_BIT | GL_TEXTURE_UPDATE_BARRIER_BIT | GL_BUFFER_UPDATE_BARRIER_BIT |
1953         GL_FRAMEBUFFER_BARRIER_BIT | GL_TRANSFORM_FEEDBACK_BARRIER_BIT |
1954         GL_ATOMIC_COUNTER_BARRIER_BIT | GL_SHADER_STORAGE_BARRIER_BIT;
1955     if (barriers == 0 || (barriers & ~supported_barrier_bits) != 0)
1956     {
1957         context->validationError(GL_INVALID_VALUE, kInvalidMemoryBarrierBit);
1958         return false;
1959     }
1960 
1961     return true;
1962 }
1963 
ValidateMemoryBarrierByRegion(const Context * context,GLbitfield barriers)1964 bool ValidateMemoryBarrierByRegion(const Context *context, GLbitfield barriers)
1965 {
1966     if (context->getClientVersion() < ES_3_1)
1967     {
1968         context->validationError(GL_INVALID_OPERATION, kES31Required);
1969         return false;
1970     }
1971 
1972     if (barriers == GL_ALL_BARRIER_BITS)
1973     {
1974         return true;
1975     }
1976 
1977     GLbitfield supported_barrier_bits = GL_ATOMIC_COUNTER_BARRIER_BIT | GL_FRAMEBUFFER_BARRIER_BIT |
1978                                         GL_SHADER_IMAGE_ACCESS_BARRIER_BIT |
1979                                         GL_SHADER_STORAGE_BARRIER_BIT |
1980                                         GL_TEXTURE_FETCH_BARRIER_BIT | GL_UNIFORM_BARRIER_BIT;
1981     if (barriers == 0 || (barriers & ~supported_barrier_bits) != 0)
1982     {
1983         context->validationError(GL_INVALID_VALUE, kInvalidMemoryBarrierBit);
1984         return false;
1985     }
1986 
1987     return true;
1988 }
1989 
ValidateSampleMaski(const Context * context,GLuint maskNumber,GLbitfield mask)1990 bool ValidateSampleMaski(const Context *context, GLuint maskNumber, GLbitfield mask)
1991 {
1992     if (context->getClientVersion() < ES_3_1)
1993     {
1994         context->validationError(GL_INVALID_OPERATION, kES31Required);
1995         return false;
1996     }
1997 
1998     return ValidateSampleMaskiBase(context, maskNumber, mask);
1999 }
2000 
ValidateFramebufferTextureEXT(const Context * context,GLenum target,GLenum attachment,TextureID texture,GLint level)2001 bool ValidateFramebufferTextureEXT(const Context *context,
2002                                    GLenum target,
2003                                    GLenum attachment,
2004                                    TextureID texture,
2005                                    GLint level)
2006 {
2007     if (!context->getExtensions().geometryShader)
2008     {
2009         context->validationError(GL_INVALID_OPERATION, kGeometryShaderExtensionNotEnabled);
2010         return false;
2011     }
2012 
2013     if (texture.value != 0)
2014     {
2015         Texture *tex = context->getTexture(texture);
2016 
2017         // [EXT_geometry_shader] Section 9.2.8 "Attaching Texture Images to a Framebuffer"
2018         // An INVALID_VALUE error is generated if <texture> is not the name of a texture object.
2019         // We put this validation before ValidateFramebufferTextureBase because it is an
2020         // INVALID_OPERATION error for both FramebufferTexture2D and FramebufferTextureLayer:
2021         // [OpenGL ES 3.1] Chapter 9.2.8 (FramebufferTexture2D)
2022         // An INVALID_OPERATION error is generated if texture is not zero, and does not name an
2023         // existing texture object of type matching textarget.
2024         // [OpenGL ES 3.1 Chapter 9.2.8 (FramebufferTextureLayer)
2025         // An INVALID_OPERATION error is generated if texture is non-zero and is not the name of a
2026         // three-dimensional or two-dimensional array texture.
2027         if (tex == nullptr)
2028         {
2029             context->validationError(GL_INVALID_VALUE, kInvalidTextureName);
2030             return false;
2031         }
2032 
2033         if (!ValidMipLevel(context, tex->getType(), level))
2034         {
2035             context->validationError(GL_INVALID_VALUE, kInvalidMipLevel);
2036             return false;
2037         }
2038     }
2039 
2040     if (!ValidateFramebufferTextureBase(context, target, attachment, texture, level))
2041     {
2042         return false;
2043     }
2044 
2045     return true;
2046 }
2047 
2048 // GL_OES_texture_storage_multisample_2d_array
ValidateTexStorage3DMultisampleOES(const Context * context,TextureType target,GLsizei samples,GLenum sizedinternalformat,GLsizei width,GLsizei height,GLsizei depth,GLboolean fixedsamplelocations)2049 bool ValidateTexStorage3DMultisampleOES(const Context *context,
2050                                         TextureType target,
2051                                         GLsizei samples,
2052                                         GLenum sizedinternalformat,
2053                                         GLsizei width,
2054                                         GLsizei height,
2055                                         GLsizei depth,
2056                                         GLboolean fixedsamplelocations)
2057 {
2058     if (!context->getExtensions().textureStorageMultisample2DArrayOES)
2059     {
2060         context->validationError(GL_INVALID_ENUM, kMultisampleArrayExtensionRequired);
2061         return false;
2062     }
2063 
2064     if (target != TextureType::_2DMultisampleArray)
2065     {
2066         context->validationError(GL_INVALID_ENUM, kTargetMustBeTexture2DMultisampleArrayOES);
2067         return false;
2068     }
2069 
2070     if (width < 1 || height < 1 || depth < 1)
2071     {
2072         context->validationError(GL_INVALID_VALUE, kNegativeSize);
2073         return false;
2074     }
2075 
2076     return ValidateTexStorageMultisample(context, target, samples, sizedinternalformat, width,
2077                                          height);
2078 }
2079 
ValidateTexStorageMem3DMultisampleEXT(const Context * context,TextureType target,GLsizei samples,GLenum internalFormat,GLsizei width,GLsizei height,GLsizei depth,GLboolean fixedSampleLocations,MemoryObjectID memory,GLuint64 offset)2080 bool ValidateTexStorageMem3DMultisampleEXT(const Context *context,
2081                                            TextureType target,
2082                                            GLsizei samples,
2083                                            GLenum internalFormat,
2084                                            GLsizei width,
2085                                            GLsizei height,
2086                                            GLsizei depth,
2087                                            GLboolean fixedSampleLocations,
2088                                            MemoryObjectID memory,
2089                                            GLuint64 offset)
2090 {
2091     if (!context->getExtensions().memoryObject)
2092     {
2093         context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
2094         return false;
2095     }
2096 
2097     UNIMPLEMENTED();
2098     return false;
2099 }
2100 
ValidateGetProgramResourceLocationIndexEXT(const Context * context,ShaderProgramID program,GLenum programInterface,const char * name)2101 bool ValidateGetProgramResourceLocationIndexEXT(const Context *context,
2102                                                 ShaderProgramID program,
2103                                                 GLenum programInterface,
2104                                                 const char *name)
2105 {
2106     if (!context->getExtensions().blendFuncExtended)
2107     {
2108         context->validationError(GL_INVALID_OPERATION, kExtensionNotEnabled);
2109         return false;
2110     }
2111     if (context->getClientVersion() < ES_3_1)
2112     {
2113         context->validationError(GL_INVALID_OPERATION, kES31Required);
2114         return false;
2115     }
2116     if (programInterface != GL_PROGRAM_OUTPUT)
2117     {
2118         context->validationError(GL_INVALID_ENUM, kProgramInterfaceMustBeProgramOutput);
2119         return false;
2120     }
2121     Program *programObject = GetValidProgram(context, program);
2122     if (!programObject)
2123     {
2124         return false;
2125     }
2126     if (!programObject->isLinked())
2127     {
2128         context->validationError(GL_INVALID_OPERATION, kProgramNotLinked);
2129         return false;
2130     }
2131     return true;
2132 }
2133 
2134 }  // namespace gl
2135