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