• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2013 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 // validationES.h: Validation functions for generic OpenGL ES entry point parameters
8 
9 #ifndef LIBANGLE_VALIDATION_ES_H_
10 #define LIBANGLE_VALIDATION_ES_H_
11 
12 #include "common/PackedEnums.h"
13 #include "common/mathutil.h"
14 #include "common/utilities.h"
15 #include "libANGLE/Context.h"
16 #include "libANGLE/ErrorStrings.h"
17 #include "libANGLE/Framebuffer.h"
18 #include "libANGLE/VertexArray.h"
19 
20 #include <GLES2/gl2.h>
21 #include <GLES3/gl3.h>
22 #include <GLES3/gl31.h>
23 
24 namespace egl
25 {
26 class Display;
27 class Image;
28 }  // namespace egl
29 
30 namespace gl
31 {
32 class Context;
33 struct Format;
34 class Framebuffer;
35 struct LinkedUniform;
36 class Program;
37 class Shader;
38 
39 void SetRobustLengthParam(const GLsizei *length, GLsizei value);
40 bool ValidTextureTarget(const Context *context, TextureType type);
41 bool ValidTexture2DTarget(const Context *context, TextureType type);
42 bool ValidTexture3DTarget(const Context *context, TextureType target);
43 bool ValidTextureExternalTarget(const Context *context, TextureType target);
44 bool ValidTextureExternalTarget(const Context *context, TextureTarget target);
45 bool ValidTexture2DDestinationTarget(const Context *context, TextureTarget target);
46 bool ValidTexture3DDestinationTarget(const Context *context, TextureTarget target);
47 bool ValidTexLevelDestinationTarget(const Context *context, TextureType type);
48 bool ValidFramebufferTarget(const Context *context, GLenum target);
49 bool ValidMipLevel(const Context *context, TextureType type, GLint level);
50 bool ValidImageSizeParameters(const Context *context,
51                               angle::EntryPoint entryPoint,
52                               TextureType target,
53                               GLint level,
54                               GLsizei width,
55                               GLsizei height,
56                               GLsizei depth,
57                               bool isSubImage);
58 bool ValidCompressedImageSize(const Context *context,
59                               GLenum internalFormat,
60                               GLint level,
61                               GLsizei width,
62                               GLsizei height,
63                               GLsizei depth);
64 bool ValidCompressedSubImageSize(const Context *context,
65                                  GLenum internalFormat,
66                                  GLint xoffset,
67                                  GLint yoffset,
68                                  GLint zoffset,
69                                  GLsizei width,
70                                  GLsizei height,
71                                  GLsizei depth,
72                                  size_t textureWidth,
73                                  size_t textureHeight,
74                                  size_t textureDepth);
75 bool ValidImageDataSize(const Context *context,
76                         angle::EntryPoint entryPoint,
77                         TextureType texType,
78                         GLsizei width,
79                         GLsizei height,
80                         GLsizei depth,
81                         GLenum format,
82                         GLenum type,
83                         const void *pixels,
84                         GLsizei imageSize);
85 
86 bool ValidQueryType(const Context *context, QueryType queryType);
87 
88 bool ValidateWebGLVertexAttribPointer(const Context *context,
89                                       angle::EntryPoint entryPoint,
90                                       VertexAttribType type,
91                                       GLboolean normalized,
92                                       GLsizei stride,
93                                       const void *ptr,
94                                       bool pureInteger);
95 
96 // Returns valid program if id is a valid program name
97 // Errors INVALID_OPERATION if valid shader is given and returns NULL
98 // Errors INVALID_VALUE otherwise and returns NULL
99 Program *GetValidProgram(const Context *context, angle::EntryPoint entryPoint, ShaderProgramID id);
100 
101 // Returns valid shader if id is a valid shader name
102 // Errors INVALID_OPERATION if valid program is given and returns NULL
103 // Errors INVALID_VALUE otherwise and returns NULL
104 Shader *GetValidShader(const Context *context, angle::EntryPoint entryPoint, ShaderProgramID id);
105 
106 bool ValidateAttachmentTarget(const Context *context,
107                               angle::EntryPoint entryPoint,
108                               GLenum attachment);
109 
110 bool ValidateBlitFramebufferParameters(const Context *context,
111                                        angle::EntryPoint entryPoint,
112                                        GLint srcX0,
113                                        GLint srcY0,
114                                        GLint srcX1,
115                                        GLint srcY1,
116                                        GLint dstX0,
117                                        GLint dstY0,
118                                        GLint dstX1,
119                                        GLint dstY1,
120                                        GLbitfield mask,
121                                        GLenum filter);
122 
123 bool ValidateBindFramebufferBase(const Context *context,
124                                  angle::EntryPoint entryPoint,
125                                  GLenum target,
126                                  FramebufferID framebuffer);
127 bool ValidateBindRenderbufferBase(const Context *context,
128                                   angle::EntryPoint entryPoint,
129                                   GLenum target,
130                                   RenderbufferID renderbuffer);
131 bool ValidateFramebufferParameteriBase(const Context *context,
132                                        angle::EntryPoint entryPoint,
133                                        GLenum target,
134                                        GLenum pname,
135                                        GLint param);
136 bool ValidateFramebufferRenderbufferBase(const Context *context,
137                                          angle::EntryPoint entryPoint,
138                                          GLenum target,
139                                          GLenum attachment,
140                                          GLenum renderbuffertarget,
141                                          RenderbufferID renderbuffer);
142 bool ValidateFramebufferTextureBase(const Context *context,
143                                     angle::EntryPoint entryPoint,
144                                     GLenum target,
145                                     GLenum attachment,
146                                     TextureID texture,
147                                     GLint level);
148 bool ValidateGenerateMipmapBase(const Context *context,
149                                 angle::EntryPoint entryPoint,
150                                 TextureType target);
151 
152 bool ValidateRenderbufferStorageParametersBase(const Context *context,
153                                                angle::EntryPoint entryPoint,
154                                                GLenum target,
155                                                GLsizei samples,
156                                                GLenum internalformat,
157                                                GLsizei width,
158                                                GLsizei height);
159 
160 bool ValidatePixelPack(const Context *context,
161                        angle::EntryPoint entryPoint,
162                        GLenum format,
163                        GLenum type,
164                        GLint x,
165                        GLint y,
166                        GLsizei width,
167                        GLsizei height,
168                        GLsizei bufSize,
169                        GLsizei *length,
170                        const void *pixels);
171 
172 bool ValidateReadPixelsBase(const Context *context,
173                             angle::EntryPoint entryPoint,
174                             GLint x,
175                             GLint y,
176                             GLsizei width,
177                             GLsizei height,
178                             GLenum format,
179                             GLenum type,
180                             GLsizei bufSize,
181                             GLsizei *length,
182                             GLsizei *columns,
183                             GLsizei *rows,
184                             const void *pixels);
185 bool ValidateReadPixelsRobustANGLE(const Context *context,
186                                    angle::EntryPoint entryPoint,
187                                    GLint x,
188                                    GLint y,
189                                    GLsizei width,
190                                    GLsizei height,
191                                    GLenum format,
192                                    GLenum type,
193                                    GLsizei bufSize,
194                                    const GLsizei *length,
195                                    const GLsizei *columns,
196                                    const GLsizei *rows,
197                                    const void *pixels);
198 bool ValidateReadnPixelsEXT(const Context *context,
199                             angle::EntryPoint entryPoint,
200                             GLint x,
201                             GLint y,
202                             GLsizei width,
203                             GLsizei height,
204                             GLenum format,
205                             GLenum type,
206                             GLsizei bufSize,
207                             const void *pixels);
208 bool ValidateReadnPixelsRobustANGLE(const Context *context,
209                                     angle::EntryPoint entryPoint,
210                                     GLint x,
211                                     GLint y,
212                                     GLsizei width,
213                                     GLsizei height,
214                                     GLenum format,
215                                     GLenum type,
216                                     GLsizei bufSize,
217                                     const GLsizei *length,
218                                     const GLsizei *columns,
219                                     const GLsizei *rows,
220                                     const void *data);
221 
222 bool ValidateGenQueriesEXT(const Context *context,
223                            angle::EntryPoint entryPoint,
224                            GLsizei n,
225                            const QueryID *ids);
226 bool ValidateDeleteQueriesEXT(const Context *context,
227                               angle::EntryPoint entryPoint,
228                               GLsizei n,
229                               const QueryID *ids);
230 bool ValidateIsQueryEXT(const Context *context, angle::EntryPoint entryPoint, QueryID id);
231 bool ValidateBeginQueryBase(const Context *context,
232                             angle::EntryPoint entryPoint,
233                             QueryType target,
234                             QueryID id);
235 bool ValidateBeginQueryEXT(const Context *context,
236                            angle::EntryPoint entryPoint,
237                            QueryType target,
238                            QueryID id);
239 bool ValidateEndQueryBase(const Context *context, angle::EntryPoint entryPoint, QueryType target);
240 bool ValidateEndQueryEXT(const Context *context, angle::EntryPoint entryPoint, QueryType target);
241 bool ValidateQueryCounterEXT(const Context *context,
242                              angle::EntryPoint entryPoint,
243                              QueryID id,
244                              QueryType target);
245 bool ValidateGetQueryivBase(const Context *context,
246                             angle::EntryPoint entryPoint,
247                             QueryType target,
248                             GLenum pname,
249                             GLsizei *numParams);
250 bool ValidateGetQueryivEXT(const Context *context,
251                            angle::EntryPoint entryPoint,
252                            QueryType target,
253                            GLenum pname,
254                            const GLint *params);
255 bool ValidateGetQueryivRobustANGLE(const Context *context,
256                                    angle::EntryPoint entryPoint,
257                                    QueryType target,
258                                    GLenum pname,
259                                    GLsizei bufSize,
260                                    const GLsizei *length,
261                                    const GLint *params);
262 bool ValidateGetQueryObjectValueBase(const Context *context,
263                                      angle::EntryPoint entryPoint,
264                                      QueryID id,
265                                      GLenum pname,
266                                      GLsizei *numParams);
267 bool ValidateGetQueryObjectivEXT(const Context *context,
268                                  angle::EntryPoint entryPoint,
269                                  QueryID id,
270                                  GLenum pname,
271                                  const GLint *params);
272 bool ValidateGetQueryObjectivRobustANGLE(const Context *context,
273                                          angle::EntryPoint entryPoint,
274                                          QueryID id,
275                                          GLenum pname,
276                                          GLsizei bufSize,
277                                          const GLsizei *length,
278                                          const GLint *params);
279 bool ValidateGetQueryObjectuivEXT(const Context *context,
280                                   angle::EntryPoint entryPoint,
281                                   QueryID id,
282                                   GLenum pname,
283                                   const GLuint *params);
284 bool ValidateGetQueryObjectuivRobustANGLE(const Context *context,
285                                           angle::EntryPoint entryPoint,
286                                           QueryID id,
287                                           GLenum pname,
288                                           GLsizei bufSize,
289                                           const GLsizei *length,
290                                           const GLuint *params);
291 bool ValidateGetQueryObjecti64vEXT(const Context *context,
292                                    angle::EntryPoint entryPoint,
293                                    QueryID id,
294                                    GLenum pname,
295                                    GLint64 *params);
296 bool ValidateGetQueryObjecti64vRobustANGLE(const Context *context,
297                                            angle::EntryPoint entryPoint,
298                                            QueryID id,
299                                            GLenum pname,
300                                            GLsizei bufSize,
301                                            const GLsizei *length,
302                                            GLint64 *params);
303 bool ValidateGetQueryObjectui64vEXT(const Context *context,
304                                     angle::EntryPoint entryPoint,
305                                     QueryID id,
306                                     GLenum pname,
307                                     GLuint64 *params);
308 bool ValidateGetQueryObjectui64vRobustANGLE(const Context *context,
309                                             angle::EntryPoint entryPoint,
310                                             QueryID id,
311                                             GLenum pname,
312                                             GLsizei bufSize,
313                                             const GLsizei *length,
314                                             GLuint64 *params);
315 
316 bool ValidateUniformCommonBase(const Context *context,
317                                angle::EntryPoint entryPoint,
318                                const Program *program,
319                                UniformLocation location,
320                                GLsizei count,
321                                const LinkedUniform **uniformOut);
322 bool ValidateUniform1ivValue(const Context *context,
323                              angle::EntryPoint entryPoint,
324                              GLenum uniformType,
325                              GLsizei count,
326                              const GLint *value);
327 
ValidateUniformValue(const Context * context,angle::EntryPoint entryPoint,GLenum valueType,GLenum uniformType)328 ANGLE_INLINE bool ValidateUniformValue(const Context *context,
329                                        angle::EntryPoint entryPoint,
330                                        GLenum valueType,
331                                        GLenum uniformType)
332 {
333     // Check that the value type is compatible with uniform type.
334     // Do the cheaper test first, for a little extra speed.
335     if (valueType != uniformType && VariableBoolVectorType(valueType) != uniformType)
336     {
337         context->validationError(entryPoint, GL_INVALID_OPERATION, err::kUniformSizeMismatch);
338         return false;
339     }
340     return true;
341 }
342 
343 bool ValidateUniformMatrixValue(const Context *context,
344                                 angle::EntryPoint entryPoint,
345                                 GLenum valueType,
346                                 GLenum uniformType);
347 bool ValidateUniform(const Context *context,
348                      angle::EntryPoint entryPoint,
349                      GLenum uniformType,
350                      UniformLocation location,
351                      GLsizei count);
352 bool ValidateUniformMatrix(const Context *context,
353                            angle::EntryPoint entryPoint,
354                            GLenum matrixType,
355                            UniformLocation location,
356                            GLsizei count,
357                            GLboolean transpose);
358 bool ValidateGetBooleanvRobustANGLE(const Context *context,
359                                     angle::EntryPoint entryPoint,
360                                     GLenum pname,
361                                     GLsizei bufSize,
362                                     const GLsizei *length,
363                                     const GLboolean *params);
364 bool ValidateGetFloatvRobustANGLE(const Context *context,
365                                   angle::EntryPoint entryPoint,
366                                   GLenum pname,
367                                   GLsizei bufSize,
368                                   const GLsizei *length,
369                                   const GLfloat *params);
370 bool ValidateStateQuery(const Context *context,
371                         angle::EntryPoint entryPoint,
372                         GLenum pname,
373                         GLenum *nativeType,
374                         unsigned int *numParams);
375 bool ValidateGetIntegervRobustANGLE(const Context *context,
376                                     angle::EntryPoint entryPoint,
377                                     GLenum pname,
378                                     GLsizei bufSize,
379                                     const GLsizei *length,
380                                     const GLint *data);
381 bool ValidateGetInteger64vRobustANGLE(const Context *context,
382                                       angle::EntryPoint entryPoint,
383                                       GLenum pname,
384                                       GLsizei bufSize,
385                                       const GLsizei *length,
386                                       GLint64 *data);
387 bool ValidateRobustStateQuery(const Context *context,
388                               angle::EntryPoint entryPoint,
389                               GLenum pname,
390                               GLsizei bufSize,
391                               GLenum *nativeType,
392                               unsigned int *numParams);
393 
394 bool ValidateCopyImageSubDataBase(const Context *context,
395                                   angle::EntryPoint entryPoint,
396                                   GLuint srcName,
397                                   GLenum srcTarget,
398                                   GLint srcLevel,
399                                   GLint srcX,
400                                   GLint srcY,
401                                   GLint srcZ,
402                                   GLuint dstName,
403                                   GLenum dstTarget,
404                                   GLint dstLevel,
405                                   GLint dstX,
406                                   GLint dstY,
407                                   GLint dstZ,
408                                   GLsizei srcWidth,
409                                   GLsizei srcHeight,
410                                   GLsizei srcDepth);
411 
412 bool ValidateCopyTexImageParametersBase(const Context *context,
413                                         angle::EntryPoint entryPoint,
414                                         TextureTarget target,
415                                         GLint level,
416                                         GLenum internalformat,
417                                         bool isSubImage,
418                                         GLint xoffset,
419                                         GLint yoffset,
420                                         GLint zoffset,
421                                         GLint x,
422                                         GLint y,
423                                         GLsizei width,
424                                         GLsizei height,
425                                         GLint border,
426                                         Format *textureFormatOut);
427 
428 void RecordDrawModeError(const Context *context, angle::EntryPoint entryPoint, PrimitiveMode mode);
429 const char *ValidateDrawElementsStates(const Context *context);
430 
ValidateDrawBase(const Context * context,angle::EntryPoint entryPoint,PrimitiveMode mode)431 ANGLE_INLINE bool ValidateDrawBase(const Context *context,
432                                    angle::EntryPoint entryPoint,
433                                    PrimitiveMode mode)
434 {
435     intptr_t drawStatesError = context->getStateCache().getBasicDrawStatesError(context);
436     if (drawStatesError)
437     {
438         const char *errorMessage = reinterpret_cast<const char *>(drawStatesError);
439 
440         // All errors from ValidateDrawStates should return INVALID_OPERATION except Framebuffer
441         // Incomplete.
442         bool isFramebufferIncomplete = strcmp(errorMessage, err::kDrawFramebufferIncomplete) == 0;
443         GLenum errorCode =
444             isFramebufferIncomplete ? GL_INVALID_FRAMEBUFFER_OPERATION : GL_INVALID_OPERATION;
445         context->validationError(entryPoint, errorCode, errorMessage);
446         return false;
447     }
448 
449     if (!context->getStateCache().isValidDrawMode(mode))
450     {
451         RecordDrawModeError(context, entryPoint, mode);
452         return false;
453     }
454 
455     return true;
456 }
457 
458 bool ValidateDrawArraysInstancedBase(const Context *context,
459                                      angle::EntryPoint entryPoint,
460                                      PrimitiveMode mode,
461                                      GLint first,
462                                      GLsizei count,
463                                      GLsizei primcount);
464 bool ValidateDrawArraysInstancedANGLE(const Context *context,
465                                       angle::EntryPoint entryPoint,
466                                       PrimitiveMode mode,
467                                       GLint first,
468                                       GLsizei count,
469                                       GLsizei primcount);
470 bool ValidateDrawArraysInstancedEXT(const Context *context,
471                                     angle::EntryPoint entryPoint,
472                                     PrimitiveMode mode,
473                                     GLint first,
474                                     GLsizei count,
475                                     GLsizei primcount);
476 
477 bool ValidateDrawElementsInstancedBase(const Context *context,
478                                        angle::EntryPoint entryPoint,
479                                        PrimitiveMode mode,
480                                        GLsizei count,
481                                        DrawElementsType type,
482                                        const void *indices,
483                                        GLsizei primcount);
484 bool ValidateDrawElementsInstancedANGLE(const Context *context,
485                                         angle::EntryPoint entryPoint,
486                                         PrimitiveMode mode,
487                                         GLsizei count,
488                                         DrawElementsType type,
489                                         const void *indices,
490                                         GLsizei primcount);
491 bool ValidateDrawElementsInstancedEXT(const Context *context,
492                                       angle::EntryPoint entryPoint,
493                                       PrimitiveMode mode,
494                                       GLsizei count,
495                                       DrawElementsType type,
496                                       const void *indices,
497                                       GLsizei primcount);
498 
499 bool ValidateDrawInstancedANGLE(const Context *context, angle::EntryPoint entryPoint);
500 
501 bool ValidateGetUniformBase(const Context *context,
502                             angle::EntryPoint entryPoint,
503                             ShaderProgramID program,
504                             UniformLocation location);
505 bool ValidateSizedGetUniform(const Context *context,
506                              angle::EntryPoint entryPoint,
507                              ShaderProgramID program,
508                              UniformLocation location,
509                              GLsizei bufSize,
510                              GLsizei *length);
511 bool ValidateGetnUniformfvEXT(const Context *context,
512                               angle::EntryPoint entryPoint,
513                               ShaderProgramID program,
514                               UniformLocation location,
515                               GLsizei bufSize,
516                               const GLfloat *params);
517 bool ValidateGetnUniformfvRobustANGLE(const Context *context,
518                                       angle::EntryPoint entryPoint,
519                                       ShaderProgramID program,
520                                       UniformLocation location,
521                                       GLsizei bufSize,
522                                       const GLsizei *length,
523                                       const GLfloat *params);
524 bool ValidateGetnUniformivEXT(const Context *context,
525                               angle::EntryPoint entryPoint,
526                               ShaderProgramID program,
527                               UniformLocation location,
528                               GLsizei bufSize,
529                               const GLint *params);
530 bool ValidateGetnUniformivRobustANGLE(const Context *context,
531                                       angle::EntryPoint entryPoint,
532                                       ShaderProgramID program,
533                                       UniformLocation location,
534                                       GLsizei bufSize,
535                                       const GLsizei *length,
536                                       const GLint *params);
537 bool ValidateGetnUniformuivRobustANGLE(const Context *context,
538                                        angle::EntryPoint entryPoint,
539                                        ShaderProgramID program,
540                                        UniformLocation location,
541                                        GLsizei bufSize,
542                                        const GLsizei *length,
543                                        const GLuint *params);
544 bool ValidateGetUniformfvRobustANGLE(const Context *context,
545                                      angle::EntryPoint entryPoint,
546                                      ShaderProgramID program,
547                                      UniformLocation location,
548                                      GLsizei bufSize,
549                                      const GLsizei *length,
550                                      const GLfloat *params);
551 bool ValidateGetUniformivRobustANGLE(const Context *context,
552                                      angle::EntryPoint entryPoint,
553                                      ShaderProgramID program,
554                                      UniformLocation location,
555                                      GLsizei bufSize,
556                                      const GLsizei *length,
557                                      const GLint *params);
558 bool ValidateGetUniformuivRobustANGLE(const Context *context,
559                                       angle::EntryPoint entryPoint,
560                                       ShaderProgramID program,
561                                       UniformLocation location,
562                                       GLsizei bufSize,
563                                       const GLsizei *length,
564                                       const GLuint *params);
565 
566 bool ValidateDiscardFramebufferBase(const Context *context,
567                                     angle::EntryPoint entryPoint,
568                                     GLenum target,
569                                     GLsizei numAttachments,
570                                     const GLenum *attachments,
571                                     bool defaultFramebuffer);
572 
573 bool ValidateInsertEventMarkerEXT(const Context *context,
574                                   angle::EntryPoint entryPoint,
575                                   GLsizei length,
576                                   const char *marker);
577 bool ValidatePushGroupMarkerEXT(const Context *context,
578                                 angle::EntryPoint entryPoint,
579                                 GLsizei length,
580                                 const char *marker);
581 bool ValidateEGLImageObject(const Context *context,
582                             angle::EntryPoint entryPoint,
583                             TextureType type,
584                             GLeglImageOES image);
585 bool ValidateEGLImageTargetTexture2DOES(const Context *context,
586                                         angle::EntryPoint entryPoint,
587                                         TextureType type,
588                                         GLeglImageOES image);
589 bool ValidateEGLImageTargetRenderbufferStorageOES(const Context *context,
590                                                   angle::EntryPoint entryPoint,
591                                                   GLenum target,
592                                                   GLeglImageOES image);
593 
594 bool ValidateProgramBinaryBase(const Context *context,
595                                angle::EntryPoint entryPoint,
596                                ShaderProgramID program,
597                                GLenum binaryFormat,
598                                const void *binary,
599                                GLint length);
600 bool ValidateGetProgramBinaryBase(const Context *context,
601                                   angle::EntryPoint entryPoint,
602                                   ShaderProgramID program,
603                                   GLsizei bufSize,
604                                   const GLsizei *length,
605                                   const GLenum *binaryFormat,
606                                   const void *binary);
607 
608 bool ValidateDrawBuffersBase(const Context *context,
609                              angle::EntryPoint entryPoint,
610                              GLsizei n,
611                              const GLenum *bufs);
612 
613 bool ValidateGetBufferPointervBase(const Context *context,
614                                    angle::EntryPoint entryPoint,
615                                    BufferBinding target,
616                                    GLenum pname,
617                                    GLsizei *length,
618                                    void *const *params);
619 bool ValidateUnmapBufferBase(const Context *context,
620                              angle::EntryPoint entryPoint,
621                              BufferBinding target);
622 bool ValidateMapBufferRangeBase(const Context *context,
623                                 angle::EntryPoint entryPoint,
624                                 BufferBinding target,
625                                 GLintptr offset,
626                                 GLsizeiptr length,
627                                 GLbitfield access);
628 bool ValidateFlushMappedBufferRangeBase(const Context *context,
629                                         angle::EntryPoint entryPoint,
630                                         BufferBinding target,
631                                         GLintptr offset,
632                                         GLsizeiptr length);
633 
634 bool ValidateGenOrDelete(const Context *context, angle::EntryPoint entryPoint, GLint n);
635 
636 bool ValidateRobustEntryPoint(const Context *context,
637                               angle::EntryPoint entryPoint,
638                               GLsizei bufSize);
639 bool ValidateRobustBufferSize(const Context *context,
640                               angle::EntryPoint entryPoint,
641                               GLsizei bufSize,
642                               GLsizei numParams);
643 
644 bool ValidateGetFramebufferAttachmentParameterivBase(const Context *context,
645                                                      angle::EntryPoint entryPoint,
646                                                      GLenum target,
647                                                      GLenum attachment,
648                                                      GLenum pname,
649                                                      GLsizei *numParams);
650 
651 bool ValidateGetFramebufferParameterivBase(const Context *context,
652                                            angle::EntryPoint entryPoint,
653                                            GLenum target,
654                                            GLenum pname,
655                                            const GLint *params);
656 
657 bool ValidateGetBufferParameterBase(const Context *context,
658                                     angle::EntryPoint entryPoint,
659                                     BufferBinding target,
660                                     GLenum pname,
661                                     bool pointerVersion,
662                                     GLsizei *numParams);
663 
664 bool ValidateGetProgramivBase(const Context *context,
665                               angle::EntryPoint entryPoint,
666                               ShaderProgramID program,
667                               GLenum pname,
668                               GLsizei *numParams);
669 
670 bool ValidateGetRenderbufferParameterivBase(const Context *context,
671                                             angle::EntryPoint entryPoint,
672                                             GLenum target,
673                                             GLenum pname,
674                                             GLsizei *length);
675 
676 bool ValidateGetShaderivBase(const Context *context,
677                              angle::EntryPoint entryPoint,
678                              ShaderProgramID shader,
679                              GLenum pname,
680                              GLsizei *length);
681 
682 bool ValidateGetTexParameterBase(const Context *context,
683                                  angle::EntryPoint entryPoint,
684                                  TextureType target,
685                                  GLenum pname,
686                                  GLsizei *length);
687 
688 template <typename ParamType>
689 bool ValidateTexParameterBase(const Context *context,
690                               angle::EntryPoint entryPoint,
691                               TextureType target,
692                               GLenum pname,
693                               GLsizei bufSize,
694                               bool vectorParams,
695                               const ParamType *params);
696 
697 bool ValidateGetVertexAttribBase(const Context *context,
698                                  angle::EntryPoint entryPoint,
699                                  GLuint index,
700                                  GLenum pname,
701                                  GLsizei *length,
702                                  bool pointer,
703                                  bool pureIntegerEntryPoint);
704 
ValidateVertexFormat(const Context * context,angle::EntryPoint entryPoint,GLuint index,GLint size,VertexAttribTypeCase validation)705 ANGLE_INLINE bool ValidateVertexFormat(const Context *context,
706                                        angle::EntryPoint entryPoint,
707                                        GLuint index,
708                                        GLint size,
709                                        VertexAttribTypeCase validation)
710 {
711     const Caps &caps = context->getCaps();
712     if (index >= static_cast<GLuint>(caps.maxVertexAttributes))
713     {
714         context->validationError(entryPoint, GL_INVALID_VALUE,
715                                  err::kIndexExceedsMaxVertexAttribute);
716         return false;
717     }
718 
719     switch (validation)
720     {
721         case VertexAttribTypeCase::Invalid:
722             context->validationError(entryPoint, GL_INVALID_ENUM, err::kInvalidType);
723             return false;
724         case VertexAttribTypeCase::Valid:
725             if (size < 1 || size > 4)
726             {
727                 context->validationError(entryPoint, GL_INVALID_VALUE, err::kInvalidVertexAttrSize);
728                 return false;
729             }
730             break;
731         case VertexAttribTypeCase::ValidSize4Only:
732             if (size != 4)
733             {
734                 context->validationError(entryPoint, GL_INVALID_OPERATION,
735                                          err::kInvalidVertexAttribSize2101010);
736                 return false;
737             }
738             break;
739         case VertexAttribTypeCase::ValidSize3or4:
740             if (size != 3 && size != 4)
741             {
742                 context->validationError(entryPoint, GL_INVALID_OPERATION,
743                                          err::kInvalidVertexAttribSize1010102);
744                 return false;
745             }
746             break;
747     }
748 
749     return true;
750 }
751 
752 // Note: These byte, short, and int types are all converted to float for the shader.
ValidateFloatVertexFormat(const Context * context,angle::EntryPoint entryPoint,GLuint index,GLint size,VertexAttribType type)753 ANGLE_INLINE bool ValidateFloatVertexFormat(const Context *context,
754                                             angle::EntryPoint entryPoint,
755                                             GLuint index,
756                                             GLint size,
757                                             VertexAttribType type)
758 {
759     return ValidateVertexFormat(context, entryPoint, index, size,
760                                 context->getStateCache().getVertexAttribTypeValidation(type));
761 }
762 
ValidateIntegerVertexFormat(const Context * context,angle::EntryPoint entryPoint,GLuint index,GLint size,VertexAttribType type)763 ANGLE_INLINE bool ValidateIntegerVertexFormat(const Context *context,
764                                               angle::EntryPoint entryPoint,
765                                               GLuint index,
766                                               GLint size,
767                                               VertexAttribType type)
768 {
769     return ValidateVertexFormat(
770         context, entryPoint, index, size,
771         context->getStateCache().getIntegerVertexAttribTypeValidation(type));
772 }
773 
774 bool ValidateWebGLFramebufferAttachmentClearType(const Context *context,
775                                                  angle::EntryPoint entryPoint,
776                                                  GLint drawbuffer,
777                                                  const GLenum *validComponentTypes,
778                                                  size_t validComponentTypeCount);
779 
780 bool ValidateRobustCompressedTexImageBase(const Context *context,
781                                           angle::EntryPoint entryPoint,
782                                           GLsizei imageSize,
783                                           GLsizei dataSize);
784 
785 bool ValidateVertexAttribIndex(const Context *context, angle::EntryPoint entryPoint, GLuint index);
786 
787 bool ValidateGetActiveUniformBlockivBase(const Context *context,
788                                          angle::EntryPoint entryPoint,
789                                          ShaderProgramID program,
790                                          UniformBlockIndex uniformBlockIndex,
791                                          GLenum pname,
792                                          GLsizei *length);
793 
794 bool ValidateGetSamplerParameterBase(const Context *context,
795                                      angle::EntryPoint entryPoint,
796                                      SamplerID sampler,
797                                      GLenum pname,
798                                      GLsizei *length);
799 
800 template <typename ParamType>
801 bool ValidateSamplerParameterBase(const Context *context,
802                                   angle::EntryPoint entryPoint,
803                                   SamplerID sampler,
804                                   GLenum pname,
805                                   GLsizei bufSize,
806                                   bool vectorParams,
807                                   const ParamType *params);
808 
809 bool ValidateGetInternalFormativBase(const Context *context,
810                                      angle::EntryPoint entryPoint,
811                                      GLenum target,
812                                      GLenum internalformat,
813                                      GLenum pname,
814                                      GLsizei bufSize,
815                                      GLsizei *numParams);
816 
817 bool ValidateFramebufferNotMultisampled(const Context *context,
818                                         angle::EntryPoint entryPoint,
819                                         const Framebuffer *framebuffer,
820                                         bool checkReadBufferResourceSamples);
821 
822 bool ValidateMultitextureUnit(const Context *context, angle::EntryPoint entryPoint, GLenum texture);
823 
824 bool ValidateTransformFeedbackPrimitiveMode(const Context *context,
825                                             angle::EntryPoint entryPoint,
826                                             PrimitiveMode transformFeedbackPrimitiveMode,
827                                             PrimitiveMode renderPrimitiveMode);
828 
829 // Common validation for 2D and 3D variants of TexStorage*Multisample.
830 bool ValidateTexStorageMultisample(const Context *context,
831                                    angle::EntryPoint entryPoint,
832                                    TextureType target,
833                                    GLsizei samples,
834                                    GLint internalFormat,
835                                    GLsizei width,
836                                    GLsizei height);
837 
838 bool ValidateTexStorage2DMultisampleBase(const Context *context,
839                                          angle::EntryPoint entryPoint,
840                                          TextureType target,
841                                          GLsizei samples,
842                                          GLint internalFormat,
843                                          GLsizei width,
844                                          GLsizei height);
845 
846 bool ValidateGetTexLevelParameterBase(const Context *context,
847                                       angle::EntryPoint entryPoint,
848                                       TextureTarget target,
849                                       GLint level,
850                                       GLenum pname,
851                                       GLsizei *length);
852 
853 bool ValidateMapBufferBase(const Context *context,
854                            angle::EntryPoint entryPoint,
855                            BufferBinding target);
856 bool ValidateIndexedStateQuery(const Context *context,
857                                angle::EntryPoint entryPoint,
858                                GLenum pname,
859                                GLuint index,
860                                GLsizei *length);
861 bool ValidateES3TexImage2DParameters(const Context *context,
862                                      angle::EntryPoint entryPoint,
863                                      TextureTarget target,
864                                      GLint level,
865                                      GLenum internalformat,
866                                      bool isCompressed,
867                                      bool isSubImage,
868                                      GLint xoffset,
869                                      GLint yoffset,
870                                      GLint zoffset,
871                                      GLsizei width,
872                                      GLsizei height,
873                                      GLsizei depth,
874                                      GLint border,
875                                      GLenum format,
876                                      GLenum type,
877                                      GLsizei imageSize,
878                                      const void *pixels);
879 bool ValidateES3CopyTexImage2DParameters(const Context *context,
880                                          angle::EntryPoint entryPoint,
881                                          TextureTarget target,
882                                          GLint level,
883                                          GLenum internalformat,
884                                          bool isSubImage,
885                                          GLint xoffset,
886                                          GLint yoffset,
887                                          GLint zoffset,
888                                          GLint x,
889                                          GLint y,
890                                          GLsizei width,
891                                          GLsizei height,
892                                          GLint border);
893 bool ValidateES3TexStorageParametersBase(const Context *context,
894                                          angle::EntryPoint entryPoint,
895                                          TextureType target,
896                                          GLsizei levels,
897                                          GLenum internalformat,
898                                          GLsizei width,
899                                          GLsizei height,
900                                          GLsizei depth);
901 bool ValidateES3TexStorage2DParameters(const Context *context,
902                                        angle::EntryPoint entryPoint,
903                                        TextureType target,
904                                        GLsizei levels,
905                                        GLenum internalformat,
906                                        GLsizei width,
907                                        GLsizei height,
908                                        GLsizei depth);
909 bool ValidateES3TexStorage3DParameters(const Context *context,
910                                        angle::EntryPoint entryPoint,
911                                        TextureType target,
912                                        GLsizei levels,
913                                        GLenum internalformat,
914                                        GLsizei width,
915                                        GLsizei height,
916                                        GLsizei depth);
917 
918 bool ValidateGetMultisamplefvBase(const Context *context,
919                                   angle::EntryPoint entryPoint,
920                                   GLenum pname,
921                                   GLuint index,
922                                   const GLfloat *val);
923 bool ValidateSampleMaskiBase(const Context *context,
924                              angle::EntryPoint entryPoint,
925                              GLuint maskNumber,
926                              GLbitfield mask);
927 
928 bool ValidateProgramExecutableXFBBuffersPresent(const Context *context,
929                                                 const ProgramExecutable *programExecutable);
930 
931 // We should check with Khronos if returning INVALID_FRAMEBUFFER_OPERATION is OK when querying
932 // implementation format info for incomplete framebuffers. It seems like these queries are
933 // incongruent with the other errors.
934 // Inlined for speed.
935 template <GLenum ErrorCode = GL_INVALID_FRAMEBUFFER_OPERATION>
ValidateFramebufferComplete(const Context * context,angle::EntryPoint entryPoint,const Framebuffer * framebuffer)936 ANGLE_INLINE bool ValidateFramebufferComplete(const Context *context,
937                                               angle::EntryPoint entryPoint,
938                                               const Framebuffer *framebuffer)
939 {
940     const FramebufferStatus &framebufferStatus = framebuffer->checkStatus(context);
941     if (!framebufferStatus.isComplete())
942     {
943         ASSERT(framebufferStatus.reason != nullptr);
944         context->validationError(entryPoint, ErrorCode, framebufferStatus.reason);
945         return false;
946     }
947 
948     return true;
949 }
950 
951 const char *ValidateProgramPipelineDrawStates(const State &state,
952                                               const Extensions &extensions,
953                                               ProgramPipeline *programPipeline);
954 const char *ValidateProgramPipelineAttachedPrograms(ProgramPipeline *programPipeline);
955 const char *ValidateDrawStates(const Context *context);
956 
957 void RecordDrawAttribsError(const Context *context, angle::EntryPoint entryPoint);
958 
ValidateDrawAttribs(const Context * context,angle::EntryPoint entryPoint,int64_t maxVertex)959 ANGLE_INLINE bool ValidateDrawAttribs(const Context *context,
960                                       angle::EntryPoint entryPoint,
961                                       int64_t maxVertex)
962 {
963     if (maxVertex > context->getStateCache().getNonInstancedVertexElementLimit())
964     {
965         RecordDrawAttribsError(context, entryPoint);
966         return false;
967     }
968 
969     return true;
970 }
971 
ValidateDrawArraysAttribs(const Context * context,angle::EntryPoint entryPoint,GLint first,GLsizei count)972 ANGLE_INLINE bool ValidateDrawArraysAttribs(const Context *context,
973                                             angle::EntryPoint entryPoint,
974                                             GLint first,
975                                             GLsizei count)
976 {
977     if (!context->isBufferAccessValidationEnabled())
978     {
979         return true;
980     }
981 
982     // Check the computation of maxVertex doesn't overflow.
983     // - first < 0 has been checked as an error condition.
984     // - if count <= 0, skip validating no-op draw calls.
985     // From this we know maxVertex will be positive, and only need to check if it overflows GLint.
986     ASSERT(first >= 0);
987     ASSERT(count > 0);
988     int64_t maxVertex = static_cast<int64_t>(first) + static_cast<int64_t>(count) - 1;
989     if (maxVertex > static_cast<int64_t>(std::numeric_limits<GLint>::max()))
990     {
991         context->validationError(entryPoint, GL_INVALID_OPERATION, err::kIntegerOverflow);
992         return false;
993     }
994 
995     return ValidateDrawAttribs(context, entryPoint, maxVertex);
996 }
997 
ValidateDrawInstancedAttribs(const Context * context,angle::EntryPoint entryPoint,GLint primcount)998 ANGLE_INLINE bool ValidateDrawInstancedAttribs(const Context *context,
999                                                angle::EntryPoint entryPoint,
1000                                                GLint primcount)
1001 {
1002     if (!context->isBufferAccessValidationEnabled())
1003     {
1004         return true;
1005     }
1006 
1007     if ((primcount - 1) > context->getStateCache().getInstancedVertexElementLimit())
1008     {
1009         RecordDrawAttribsError(context, entryPoint);
1010         return false;
1011     }
1012 
1013     return true;
1014 }
1015 
ValidateDrawArraysCommon(const Context * context,angle::EntryPoint entryPoint,PrimitiveMode mode,GLint first,GLsizei count,GLsizei primcount)1016 ANGLE_INLINE bool ValidateDrawArraysCommon(const Context *context,
1017                                            angle::EntryPoint entryPoint,
1018                                            PrimitiveMode mode,
1019                                            GLint first,
1020                                            GLsizei count,
1021                                            GLsizei primcount)
1022 {
1023     if (first < 0)
1024     {
1025         context->validationError(entryPoint, GL_INVALID_VALUE, err::kNegativeStart);
1026         return false;
1027     }
1028 
1029     if (count <= 0)
1030     {
1031         if (count < 0)
1032         {
1033             context->validationError(entryPoint, GL_INVALID_VALUE, err::kNegativeCount);
1034             return false;
1035         }
1036 
1037         // Early exit.
1038         return ValidateDrawBase(context, entryPoint, mode);
1039     }
1040 
1041     if (primcount <= 0)
1042     {
1043         if (primcount < 0)
1044         {
1045             context->validationError(entryPoint, GL_INVALID_VALUE, err::kNegativeCount);
1046             return false;
1047         }
1048         // Early exit.
1049         return ValidateDrawBase(context, entryPoint, mode);
1050     }
1051 
1052     if (!ValidateDrawBase(context, entryPoint, mode))
1053     {
1054         return false;
1055     }
1056 
1057     if (context->getStateCache().isTransformFeedbackActiveUnpaused() &&
1058         !context->supportsGeometryOrTesselation())
1059     {
1060         const State &state                      = context->getState();
1061         TransformFeedback *curTransformFeedback = state.getCurrentTransformFeedback();
1062         if (!curTransformFeedback->checkBufferSpaceForDraw(count, primcount))
1063         {
1064             context->validationError(entryPoint, GL_INVALID_OPERATION,
1065                                      err::kTransformFeedbackBufferTooSmall);
1066             return false;
1067         }
1068     }
1069 
1070     return ValidateDrawArraysAttribs(context, entryPoint, first, count);
1071 }
1072 
ValidateDrawElementsBase(const Context * context,angle::EntryPoint entryPoint,PrimitiveMode mode,DrawElementsType type)1073 ANGLE_INLINE bool ValidateDrawElementsBase(const Context *context,
1074                                            angle::EntryPoint entryPoint,
1075                                            PrimitiveMode mode,
1076                                            DrawElementsType type)
1077 {
1078     if (!context->getStateCache().isValidDrawElementsType(type))
1079     {
1080         if (type == DrawElementsType::UnsignedInt)
1081         {
1082             context->validationError(entryPoint, GL_INVALID_ENUM, err::kTypeNotUnsignedShortByte);
1083             return false;
1084         }
1085 
1086         ASSERT(type == DrawElementsType::InvalidEnum);
1087         context->validationError(entryPoint, GL_INVALID_ENUM, err::kEnumNotSupported);
1088         return false;
1089     }
1090 
1091     intptr_t drawElementsError = context->getStateCache().getBasicDrawElementsError(context);
1092     if (drawElementsError)
1093     {
1094         // All errors from ValidateDrawElementsStates return INVALID_OPERATION.
1095         const char *errorMessage = reinterpret_cast<const char *>(drawElementsError);
1096         context->validationError(entryPoint, GL_INVALID_OPERATION, errorMessage);
1097         return false;
1098     }
1099 
1100     // Note that we are missing overflow checks for active transform feedback buffers.
1101     return true;
1102 }
1103 
ValidateDrawElementsCommon(const Context * context,angle::EntryPoint entryPoint,PrimitiveMode mode,GLsizei count,DrawElementsType type,const void * indices,GLsizei primcount)1104 ANGLE_INLINE bool ValidateDrawElementsCommon(const Context *context,
1105                                              angle::EntryPoint entryPoint,
1106                                              PrimitiveMode mode,
1107                                              GLsizei count,
1108                                              DrawElementsType type,
1109                                              const void *indices,
1110                                              GLsizei primcount)
1111 {
1112     if (!ValidateDrawElementsBase(context, entryPoint, mode, type))
1113     {
1114         return false;
1115     }
1116 
1117     ASSERT(isPow2(GetDrawElementsTypeSize(type)) && GetDrawElementsTypeSize(type) > 0);
1118 
1119     if (context->isWebGL())
1120     {
1121         GLuint typeBytes = GetDrawElementsTypeSize(type);
1122 
1123         if ((reinterpret_cast<uintptr_t>(indices) & static_cast<uintptr_t>(typeBytes - 1)) != 0)
1124         {
1125             // [WebGL 1.0] Section 6.4 Buffer Offset and Stride Requirements
1126             // The offset arguments to drawElements and [...], must be a multiple of the size of the
1127             // data type passed to the call, or an INVALID_OPERATION error is generated.
1128             context->validationError(entryPoint, GL_INVALID_OPERATION,
1129                                      err::kOffsetMustBeMultipleOfType);
1130             return false;
1131         }
1132 
1133         // [WebGL 1.0] Section 6.4 Buffer Offset and Stride Requirements
1134         // In addition the offset argument to drawElements must be non-negative or an INVALID_VALUE
1135         // error is generated.
1136         if (reinterpret_cast<intptr_t>(indices) < 0)
1137         {
1138             context->validationError(entryPoint, GL_INVALID_VALUE, err::kNegativeOffset);
1139             return false;
1140         }
1141     }
1142 
1143     if (count <= 0)
1144     {
1145         if (count < 0)
1146         {
1147             context->validationError(entryPoint, GL_INVALID_VALUE, err::kNegativeCount);
1148             return false;
1149         }
1150 
1151         // Early exit.
1152         return ValidateDrawBase(context, entryPoint, mode);
1153     }
1154 
1155     if (!ValidateDrawBase(context, entryPoint, mode))
1156     {
1157         return false;
1158     }
1159 
1160     const State &state         = context->getState();
1161     const VertexArray *vao     = state.getVertexArray();
1162     Buffer *elementArrayBuffer = vao->getElementArrayBuffer();
1163 
1164     if (!elementArrayBuffer)
1165     {
1166         if (!indices)
1167         {
1168             // This is an application error that would normally result in a crash, but we catch
1169             // it and return an error
1170             context->validationError(entryPoint, GL_INVALID_OPERATION,
1171                                      err::kElementArrayNoBufferOrPointer);
1172             return false;
1173         }
1174     }
1175     else
1176     {
1177         // The max possible type size is 8 and count is on 32 bits so doing the multiplication
1178         // in a 64 bit integer is safe. Also we are guaranteed that here count > 0.
1179         static_assert(std::is_same<int, GLsizei>::value, "GLsizei isn't the expected type");
1180         constexpr uint64_t kMaxTypeSize = 8;
1181         constexpr uint64_t kIntMax      = std::numeric_limits<int>::max();
1182         constexpr uint64_t kUint64Max   = std::numeric_limits<uint64_t>::max();
1183         static_assert(kIntMax < kUint64Max / kMaxTypeSize, "");
1184 
1185         uint64_t elementCount = static_cast<uint64_t>(count);
1186         ASSERT(elementCount > 0 && GetDrawElementsTypeSize(type) <= kMaxTypeSize);
1187 
1188         // Doing the multiplication here is overflow-safe
1189         uint64_t elementDataSizeNoOffset = elementCount << GetDrawElementsTypeShift(type);
1190 
1191         // The offset can be any value, check for overflows
1192         uint64_t offset = static_cast<uint64_t>(reinterpret_cast<uintptr_t>(indices));
1193         uint64_t elementDataSizeWithOffset = elementDataSizeNoOffset + offset;
1194         if (elementDataSizeWithOffset < elementDataSizeNoOffset)
1195         {
1196             context->validationError(entryPoint, GL_INVALID_OPERATION, err::kIntegerOverflow);
1197             return false;
1198         }
1199 
1200         // Related to possible test bug: https://github.com/KhronosGroup/WebGL/issues/3064
1201         if ((elementDataSizeWithOffset > static_cast<uint64_t>(elementArrayBuffer->getSize())) &&
1202             (primcount > 0))
1203         {
1204             context->validationError(entryPoint, GL_INVALID_OPERATION,
1205                                      err::kInsufficientBufferSize);
1206             return false;
1207         }
1208     }
1209 
1210     if (context->isBufferAccessValidationEnabled() && primcount > 0)
1211     {
1212         // Use the parameter buffer to retrieve and cache the index range.
1213         IndexRange indexRange{IndexRange::Undefined()};
1214         ANGLE_VALIDATION_TRY(vao->getIndexRange(context, type, count, indices, &indexRange));
1215 
1216         // If we use an index greater than our maximum supported index range, return an error.
1217         // The ES3 spec does not specify behaviour here, it is undefined, but ANGLE should
1218         // always return an error if possible here.
1219         if (static_cast<GLint64>(indexRange.end) >= context->getCaps().maxElementIndex)
1220         {
1221             context->validationError(entryPoint, GL_INVALID_OPERATION, err::kExceedsMaxElement);
1222             return false;
1223         }
1224 
1225         if (!ValidateDrawAttribs(context, entryPoint, static_cast<GLint>(indexRange.end)))
1226         {
1227             return false;
1228         }
1229 
1230         // No op if there are no real indices in the index data (all are primitive restart).
1231         return (indexRange.vertexIndexCount > 0);
1232     }
1233 
1234     return true;
1235 }
1236 
ValidateBindVertexArrayBase(const Context * context,angle::EntryPoint entryPoint,VertexArrayID array)1237 ANGLE_INLINE bool ValidateBindVertexArrayBase(const Context *context,
1238                                               angle::EntryPoint entryPoint,
1239                                               VertexArrayID array)
1240 {
1241     if (!context->isVertexArrayGenerated(array))
1242     {
1243         // The default VAO should always exist
1244         ASSERT(array.value != 0);
1245         context->validationError(entryPoint, GL_INVALID_OPERATION, err::kInvalidVertexArray);
1246         return false;
1247     }
1248 
1249     return true;
1250 }
1251 
ValidateVertexAttribIndex(const Context * context,angle::EntryPoint entryPoint,GLuint index)1252 ANGLE_INLINE bool ValidateVertexAttribIndex(const Context *context,
1253                                             angle::EntryPoint entryPoint,
1254                                             GLuint index)
1255 {
1256     if (index >= static_cast<GLuint>(context->getCaps().maxVertexAttributes))
1257     {
1258         context->validationError(entryPoint, GL_INVALID_VALUE,
1259                                  err::kIndexExceedsMaxVertexAttribute);
1260         return false;
1261     }
1262 
1263     return true;
1264 }
1265 }  // namespace gl
1266 
1267 #endif  // LIBANGLE_VALIDATION_ES_H_
1268