tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

validationES.h (59611B)


      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 
    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 
    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 
    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.
    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 
    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>
    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 const char *ValidateProgramPipeline(const Context *context);
    957 
    958 void RecordDrawAttribsError(const Context *context, angle::EntryPoint entryPoint);
    959 
    960 ANGLE_INLINE bool ValidateDrawAttribs(const Context *context,
    961                                      angle::EntryPoint entryPoint,
    962                                      int64_t maxVertex)
    963 {
    964    if (maxVertex > context->getStateCache().getNonInstancedVertexElementLimit())
    965    {
    966        RecordDrawAttribsError(context, entryPoint);
    967        return false;
    968    }
    969 
    970    return true;
    971 }
    972 
    973 ANGLE_INLINE bool ValidateDrawArraysAttribs(const Context *context,
    974                                            angle::EntryPoint entryPoint,
    975                                            GLint first,
    976                                            GLsizei count)
    977 {
    978    if (!context->isBufferAccessValidationEnabled())
    979    {
    980        return true;
    981    }
    982 
    983    // Check the computation of maxVertex doesn't overflow.
    984    // - first < 0 has been checked as an error condition.
    985    // - if count <= 0, skip validating no-op draw calls.
    986    // From this we know maxVertex will be positive, and only need to check if it overflows GLint.
    987    ASSERT(first >= 0);
    988    ASSERT(count > 0);
    989    int64_t maxVertex = static_cast<int64_t>(first) + static_cast<int64_t>(count) - 1;
    990    if (maxVertex > static_cast<int64_t>(std::numeric_limits<GLint>::max()))
    991    {
    992        context->validationError(entryPoint, GL_INVALID_OPERATION, err::kIntegerOverflow);
    993        return false;
    994    }
    995 
    996    return ValidateDrawAttribs(context, entryPoint, maxVertex);
    997 }
    998 
    999 ANGLE_INLINE bool ValidateDrawInstancedAttribs(const Context *context,
   1000                                               angle::EntryPoint entryPoint,
   1001                                               GLint primcount)
   1002 {
   1003    if (!context->isBufferAccessValidationEnabled())
   1004    {
   1005        return true;
   1006    }
   1007 
   1008    if ((primcount - 1) > context->getStateCache().getInstancedVertexElementLimit())
   1009    {
   1010        RecordDrawAttribsError(context, entryPoint);
   1011        return false;
   1012    }
   1013 
   1014    return true;
   1015 }
   1016 
   1017 ANGLE_INLINE bool ValidateDrawArraysCommon(const Context *context,
   1018                                           angle::EntryPoint entryPoint,
   1019                                           PrimitiveMode mode,
   1020                                           GLint first,
   1021                                           GLsizei count,
   1022                                           GLsizei primcount)
   1023 {
   1024    if (first < 0)
   1025    {
   1026        context->validationError(entryPoint, GL_INVALID_VALUE, err::kNegativeStart);
   1027        return false;
   1028    }
   1029 
   1030    if (count <= 0)
   1031    {
   1032        if (count < 0)
   1033        {
   1034            context->validationError(entryPoint, GL_INVALID_VALUE, err::kNegativeCount);
   1035            return false;
   1036        }
   1037 
   1038        // Early exit.
   1039        return ValidateDrawBase(context, entryPoint, mode);
   1040    }
   1041 
   1042    if (primcount <= 0)
   1043    {
   1044        if (primcount < 0)
   1045        {
   1046            context->validationError(entryPoint, GL_INVALID_VALUE, err::kNegativeCount);
   1047            return false;
   1048        }
   1049        // Early exit.
   1050        return ValidateDrawBase(context, entryPoint, mode);
   1051    }
   1052 
   1053    if (!ValidateDrawBase(context, entryPoint, mode))
   1054    {
   1055        return false;
   1056    }
   1057 
   1058    if (context->getStateCache().isTransformFeedbackActiveUnpaused() &&
   1059        !context->supportsGeometryOrTesselation())
   1060    {
   1061        const State &state                      = context->getState();
   1062        TransformFeedback *curTransformFeedback = state.getCurrentTransformFeedback();
   1063        if (!curTransformFeedback->checkBufferSpaceForDraw(count, primcount))
   1064        {
   1065            context->validationError(entryPoint, GL_INVALID_OPERATION,
   1066                                     err::kTransformFeedbackBufferTooSmall);
   1067            return false;
   1068        }
   1069    }
   1070 
   1071    return ValidateDrawArraysAttribs(context, entryPoint, first, count);
   1072 }
   1073 
   1074 ANGLE_INLINE bool ValidateDrawElementsBase(const Context *context,
   1075                                           angle::EntryPoint entryPoint,
   1076                                           PrimitiveMode mode,
   1077                                           DrawElementsType type)
   1078 {
   1079    if (!context->getStateCache().isValidDrawElementsType(type))
   1080    {
   1081        if (type == DrawElementsType::UnsignedInt)
   1082        {
   1083            context->validationError(entryPoint, GL_INVALID_ENUM, err::kTypeNotUnsignedShortByte);
   1084            return false;
   1085        }
   1086 
   1087        ASSERT(type == DrawElementsType::InvalidEnum);
   1088        context->validationErrorF(entryPoint, GL_INVALID_ENUM, err::kEnumInvalid);
   1089        return false;
   1090    }
   1091 
   1092    intptr_t drawElementsError = context->getStateCache().getBasicDrawElementsError(context);
   1093    if (drawElementsError)
   1094    {
   1095        // All errors from ValidateDrawElementsStates return INVALID_OPERATION.
   1096        const char *errorMessage = reinterpret_cast<const char *>(drawElementsError);
   1097        context->validationError(entryPoint, GL_INVALID_OPERATION, errorMessage);
   1098        return false;
   1099    }
   1100 
   1101    // Note that we are missing overflow checks for active transform feedback buffers.
   1102    return true;
   1103 }
   1104 
   1105 ANGLE_INLINE bool ValidateDrawElementsCommon(const Context *context,
   1106                                             angle::EntryPoint entryPoint,
   1107                                             PrimitiveMode mode,
   1108                                             GLsizei count,
   1109                                             DrawElementsType type,
   1110                                             const void *indices,
   1111                                             GLsizei primcount)
   1112 {
   1113    if (!ValidateDrawElementsBase(context, entryPoint, mode, type))
   1114    {
   1115        return false;
   1116    }
   1117 
   1118    ASSERT(isPow2(GetDrawElementsTypeSize(type)) && GetDrawElementsTypeSize(type) > 0);
   1119 
   1120    if (context->isWebGL())
   1121    {
   1122        GLuint typeBytes = GetDrawElementsTypeSize(type);
   1123 
   1124        if ((reinterpret_cast<uintptr_t>(indices) & static_cast<uintptr_t>(typeBytes - 1)) != 0)
   1125        {
   1126            // [WebGL 1.0] Section 6.4 Buffer Offset and Stride Requirements
   1127            // The offset arguments to drawElements and [...], must be a multiple of the size of the
   1128            // data type passed to the call, or an INVALID_OPERATION error is generated.
   1129            context->validationError(entryPoint, GL_INVALID_OPERATION,
   1130                                     err::kOffsetMustBeMultipleOfType);
   1131            return false;
   1132        }
   1133 
   1134        // [WebGL 1.0] Section 6.4 Buffer Offset and Stride Requirements
   1135        // In addition the offset argument to drawElements must be non-negative or an INVALID_VALUE
   1136        // error is generated.
   1137        if (reinterpret_cast<intptr_t>(indices) < 0)
   1138        {
   1139            context->validationError(entryPoint, GL_INVALID_VALUE, err::kNegativeOffset);
   1140            return false;
   1141        }
   1142    }
   1143 
   1144    if (count <= 0)
   1145    {
   1146        if (count < 0)
   1147        {
   1148            context->validationError(entryPoint, GL_INVALID_VALUE, err::kNegativeCount);
   1149            return false;
   1150        }
   1151 
   1152        // Early exit.
   1153        return ValidateDrawBase(context, entryPoint, mode);
   1154    }
   1155 
   1156    if (!ValidateDrawBase(context, entryPoint, mode))
   1157    {
   1158        return false;
   1159    }
   1160 
   1161    const State &state         = context->getState();
   1162    const VertexArray *vao     = state.getVertexArray();
   1163    Buffer *elementArrayBuffer = vao->getElementArrayBuffer();
   1164 
   1165    if (!elementArrayBuffer)
   1166    {
   1167        if (!indices)
   1168        {
   1169            // This is an application error that would normally result in a crash, but we catch
   1170            // it and return an error
   1171            context->validationError(entryPoint, GL_INVALID_OPERATION,
   1172                                     err::kElementArrayNoBufferOrPointer);
   1173            return false;
   1174        }
   1175    }
   1176    else
   1177    {
   1178        // The max possible type size is 8 and count is on 32 bits so doing the multiplication
   1179        // in a 64 bit integer is safe. Also we are guaranteed that here count > 0.
   1180        static_assert(std::is_same<int, GLsizei>::value, "GLsizei isn't the expected type");
   1181        constexpr uint64_t kMaxTypeSize = 8;
   1182        constexpr uint64_t kIntMax      = std::numeric_limits<int>::max();
   1183        constexpr uint64_t kUint64Max   = std::numeric_limits<uint64_t>::max();
   1184        static_assert(kIntMax < kUint64Max / kMaxTypeSize, "");
   1185 
   1186        uint64_t elementCount = static_cast<uint64_t>(count);
   1187        ASSERT(elementCount > 0 && GetDrawElementsTypeSize(type) <= kMaxTypeSize);
   1188 
   1189        // Doing the multiplication here is overflow-safe
   1190        uint64_t elementDataSizeNoOffset = elementCount << GetDrawElementsTypeShift(type);
   1191 
   1192        // The offset can be any value, check for overflows
   1193        uint64_t offset = static_cast<uint64_t>(reinterpret_cast<uintptr_t>(indices));
   1194        uint64_t elementDataSizeWithOffset = elementDataSizeNoOffset + offset;
   1195        if (elementDataSizeWithOffset < elementDataSizeNoOffset)
   1196        {
   1197            context->validationError(entryPoint, GL_INVALID_OPERATION, err::kIntegerOverflow);
   1198            return false;
   1199        }
   1200 
   1201        // Related to possible test bug: https://github.com/KhronosGroup/WebGL/issues/3064
   1202        if ((elementDataSizeWithOffset > static_cast<uint64_t>(elementArrayBuffer->getSize())) &&
   1203            (primcount > 0))
   1204        {
   1205            context->validationError(entryPoint, GL_INVALID_OPERATION,
   1206                                     err::kInsufficientBufferSize);
   1207            return false;
   1208        }
   1209    }
   1210 
   1211    if (context->isBufferAccessValidationEnabled() && primcount > 0)
   1212    {
   1213        // Use the parameter buffer to retrieve and cache the index range.
   1214        IndexRange indexRange{IndexRange::Undefined()};
   1215        ANGLE_VALIDATION_TRY(vao->getIndexRange(context, type, count, indices, &indexRange));
   1216 
   1217        // If we use an index greater than our maximum supported index range, return an error.
   1218        // The ES3 spec does not specify behaviour here, it is undefined, but ANGLE should
   1219        // always return an error if possible here.
   1220        if (static_cast<GLint64>(indexRange.end) >= context->getCaps().maxElementIndex)
   1221        {
   1222            context->validationError(entryPoint, GL_INVALID_OPERATION, err::kExceedsMaxElement);
   1223            return false;
   1224        }
   1225 
   1226        if (!ValidateDrawAttribs(context, entryPoint, static_cast<GLint>(indexRange.end)))
   1227        {
   1228            return false;
   1229        }
   1230 
   1231        // No op if there are no real indices in the index data (all are primitive restart).
   1232        return (indexRange.vertexIndexCount > 0);
   1233    }
   1234 
   1235    return true;
   1236 }
   1237 
   1238 ANGLE_INLINE bool ValidateBindVertexArrayBase(const Context *context,
   1239                                              angle::EntryPoint entryPoint,
   1240                                              VertexArrayID array)
   1241 {
   1242    if (!context->isVertexArrayGenerated(array))
   1243    {
   1244        // The default VAO should always exist
   1245        ASSERT(array.value != 0);
   1246        context->validationError(entryPoint, GL_INVALID_OPERATION, err::kInvalidVertexArray);
   1247        return false;
   1248    }
   1249 
   1250    return true;
   1251 }
   1252 
   1253 ANGLE_INLINE bool ValidateVertexAttribIndex(const Context *context,
   1254                                            angle::EntryPoint entryPoint,
   1255                                            GLuint index)
   1256 {
   1257    if (index >= static_cast<GLuint>(context->getCaps().maxVertexAttributes))
   1258    {
   1259        context->validationError(entryPoint, GL_INVALID_VALUE,
   1260                                 err::kIndexExceedsMaxVertexAttribute);
   1261        return false;
   1262    }
   1263 
   1264    return true;
   1265 }
   1266 
   1267 bool ValidateLogicOpCommon(const Context *context,
   1268                           angle::EntryPoint entryPoint,
   1269                           LogicalOperation opcodePacked);
   1270 }  // namespace gl
   1271 
   1272 #endif  // LIBANGLE_VALIDATION_ES_H_