xref: /aosp_15_r20/external/angle/src/libANGLE/validationES.h (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
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                                      GLuint baseinstance);
466 bool ValidateDrawArraysInstancedANGLE(const Context *context,
467                                       angle::EntryPoint entryPoint,
468                                       PrimitiveMode mode,
469                                       GLint first,
470                                       GLsizei count,
471                                       GLsizei primcount);
472 bool ValidateDrawArraysInstancedEXT(const Context *context,
473                                     angle::EntryPoint entryPoint,
474                                     PrimitiveMode mode,
475                                     GLint first,
476                                     GLsizei count,
477                                     GLsizei primcount);
478 
479 bool ValidateDrawElementsInstancedBase(const Context *context,
480                                        angle::EntryPoint entryPoint,
481                                        PrimitiveMode mode,
482                                        GLsizei count,
483                                        DrawElementsType type,
484                                        const void *indices,
485                                        GLsizei primcount,
486                                        GLuint baseinstance);
487 bool ValidateDrawElementsInstancedANGLE(const Context *context,
488                                         angle::EntryPoint entryPoint,
489                                         PrimitiveMode mode,
490                                         GLsizei count,
491                                         DrawElementsType type,
492                                         const void *indices,
493                                         GLsizei primcount);
494 bool ValidateDrawElementsInstancedEXT(const Context *context,
495                                       angle::EntryPoint entryPoint,
496                                       PrimitiveMode mode,
497                                       GLsizei count,
498                                       DrawElementsType type,
499                                       const void *indices,
500                                       GLsizei primcount);
501 
502 bool ValidateDrawInstancedANGLE(const Context *context, angle::EntryPoint entryPoint);
503 
504 bool ValidateGetUniformBase(const Context *context,
505                             angle::EntryPoint entryPoint,
506                             ShaderProgramID program,
507                             UniformLocation location);
508 bool ValidateSizedGetUniform(const Context *context,
509                              angle::EntryPoint entryPoint,
510                              ShaderProgramID program,
511                              UniformLocation location,
512                              GLsizei bufSize,
513                              GLsizei *length);
514 bool ValidateGetnUniformfvEXT(const Context *context,
515                               angle::EntryPoint entryPoint,
516                               ShaderProgramID program,
517                               UniformLocation location,
518                               GLsizei bufSize,
519                               const GLfloat *params);
520 bool ValidateGetnUniformfvRobustANGLE(const Context *context,
521                                       angle::EntryPoint entryPoint,
522                                       ShaderProgramID program,
523                                       UniformLocation location,
524                                       GLsizei bufSize,
525                                       const GLsizei *length,
526                                       const GLfloat *params);
527 bool ValidateGetnUniformivEXT(const Context *context,
528                               angle::EntryPoint entryPoint,
529                               ShaderProgramID program,
530                               UniformLocation location,
531                               GLsizei bufSize,
532                               const GLint *params);
533 bool ValidateGetnUniformivRobustANGLE(const Context *context,
534                                       angle::EntryPoint entryPoint,
535                                       ShaderProgramID program,
536                                       UniformLocation location,
537                                       GLsizei bufSize,
538                                       const GLsizei *length,
539                                       const GLint *params);
540 bool ValidateGetnUniformuivRobustANGLE(const Context *context,
541                                        angle::EntryPoint entryPoint,
542                                        ShaderProgramID program,
543                                        UniformLocation location,
544                                        GLsizei bufSize,
545                                        const GLsizei *length,
546                                        const GLuint *params);
547 bool ValidateGetUniformfvRobustANGLE(const Context *context,
548                                      angle::EntryPoint entryPoint,
549                                      ShaderProgramID program,
550                                      UniformLocation location,
551                                      GLsizei bufSize,
552                                      const GLsizei *length,
553                                      const GLfloat *params);
554 bool ValidateGetUniformivRobustANGLE(const Context *context,
555                                      angle::EntryPoint entryPoint,
556                                      ShaderProgramID program,
557                                      UniformLocation location,
558                                      GLsizei bufSize,
559                                      const GLsizei *length,
560                                      const GLint *params);
561 bool ValidateGetUniformuivRobustANGLE(const Context *context,
562                                       angle::EntryPoint entryPoint,
563                                       ShaderProgramID program,
564                                       UniformLocation location,
565                                       GLsizei bufSize,
566                                       const GLsizei *length,
567                                       const GLuint *params);
568 
569 bool ValidateDiscardFramebufferBase(const Context *context,
570                                     angle::EntryPoint entryPoint,
571                                     GLenum target,
572                                     GLsizei numAttachments,
573                                     const GLenum *attachments,
574                                     bool defaultFramebuffer);
575 
576 bool ValidateInsertEventMarkerEXT(const Context *context,
577                                   angle::EntryPoint entryPoint,
578                                   GLsizei length,
579                                   const char *marker);
580 bool ValidatePushGroupMarkerEXT(const Context *context,
581                                 angle::EntryPoint entryPoint,
582                                 GLsizei length,
583                                 const char *marker);
584 bool ValidateEGLImageObject(const Context *context,
585                             angle::EntryPoint entryPoint,
586                             TextureType type,
587                             egl::ImageID image);
588 bool ValidateEGLImageTargetTexture2DOES(const Context *context,
589                                         angle::EntryPoint entryPoint,
590                                         TextureType type,
591                                         egl::ImageID image);
592 bool ValidateEGLImageTargetRenderbufferStorageOES(const Context *context,
593                                                   angle::EntryPoint entryPoint,
594                                                   GLenum target,
595                                                   egl::ImageID image);
596 
597 bool ValidateProgramBinaryBase(const Context *context,
598                                angle::EntryPoint entryPoint,
599                                ShaderProgramID program,
600                                GLenum binaryFormat,
601                                const void *binary,
602                                GLint length);
603 bool ValidateGetProgramBinaryBase(const Context *context,
604                                   angle::EntryPoint entryPoint,
605                                   ShaderProgramID program,
606                                   GLsizei bufSize,
607                                   const GLsizei *length,
608                                   const GLenum *binaryFormat,
609                                   const void *binary);
610 
611 bool ValidateDrawBuffersBase(const Context *context,
612                              angle::EntryPoint entryPoint,
613                              GLsizei n,
614                              const GLenum *bufs);
615 
616 bool ValidateGetBufferPointervBase(const Context *context,
617                                    angle::EntryPoint entryPoint,
618                                    BufferBinding target,
619                                    GLenum pname,
620                                    GLsizei *length,
621                                    void *const *params);
622 bool ValidateUnmapBufferBase(const Context *context,
623                              angle::EntryPoint entryPoint,
624                              BufferBinding target);
625 bool ValidateMapBufferRangeBase(const Context *context,
626                                 angle::EntryPoint entryPoint,
627                                 BufferBinding target,
628                                 GLintptr offset,
629                                 GLsizeiptr length,
630                                 GLbitfield access);
631 bool ValidateFlushMappedBufferRangeBase(const Context *context,
632                                         angle::EntryPoint entryPoint,
633                                         BufferBinding target,
634                                         GLintptr offset,
635                                         GLsizeiptr length);
636 
637 bool ValidateGenOrDelete(const Context *context, angle::EntryPoint entryPoint, GLint n);
638 
639 bool ValidateRobustEntryPoint(const Context *context,
640                               angle::EntryPoint entryPoint,
641                               GLsizei bufSize);
642 bool ValidateRobustBufferSize(const Context *context,
643                               angle::EntryPoint entryPoint,
644                               GLsizei bufSize,
645                               GLsizei numParams);
646 
647 bool ValidateGetFramebufferAttachmentParameterivBase(const Context *context,
648                                                      angle::EntryPoint entryPoint,
649                                                      GLenum target,
650                                                      GLenum attachment,
651                                                      GLenum pname,
652                                                      GLsizei *numParams);
653 
654 bool ValidateGetFramebufferParameterivBase(const Context *context,
655                                            angle::EntryPoint entryPoint,
656                                            GLenum target,
657                                            GLenum pname,
658                                            const GLint *params);
659 
660 bool ValidateGetBufferParameterBase(const Context *context,
661                                     angle::EntryPoint entryPoint,
662                                     BufferBinding target,
663                                     GLenum pname,
664                                     bool pointerVersion,
665                                     GLsizei *numParams);
666 
667 bool ValidateGetProgramivBase(const Context *context,
668                               angle::EntryPoint entryPoint,
669                               ShaderProgramID program,
670                               GLenum pname,
671                               GLsizei *numParams);
672 
673 bool ValidateGetRenderbufferParameterivBase(const Context *context,
674                                             angle::EntryPoint entryPoint,
675                                             GLenum target,
676                                             GLenum pname,
677                                             GLsizei *length);
678 
679 bool ValidateGetShaderivBase(const Context *context,
680                              angle::EntryPoint entryPoint,
681                              ShaderProgramID shader,
682                              GLenum pname,
683                              GLsizei *length);
684 
685 bool ValidateGetTexParameterBase(const Context *context,
686                                  angle::EntryPoint entryPoint,
687                                  TextureType target,
688                                  GLenum pname,
689                                  GLsizei *length);
690 
691 template <typename ParamType>
692 bool ValidateTexParameterBase(const Context *context,
693                               angle::EntryPoint entryPoint,
694                               TextureType target,
695                               GLenum pname,
696                               GLsizei bufSize,
697                               bool vectorParams,
698                               const ParamType *params);
699 
700 bool ValidateGetVertexAttribBase(const Context *context,
701                                  angle::EntryPoint entryPoint,
702                                  GLuint index,
703                                  GLenum pname,
704                                  GLsizei *length,
705                                  bool pointer,
706                                  bool pureIntegerEntryPoint);
707 
ValidateVertexFormat(const Context * context,angle::EntryPoint entryPoint,GLuint index,GLint size,VertexAttribTypeCase validation)708 ANGLE_INLINE bool ValidateVertexFormat(const Context *context,
709                                        angle::EntryPoint entryPoint,
710                                        GLuint index,
711                                        GLint size,
712                                        VertexAttribTypeCase validation)
713 {
714     const Caps &caps = context->getCaps();
715     if (index >= static_cast<GLuint>(caps.maxVertexAttributes))
716     {
717         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, err::kIndexExceedsMaxVertexAttribute);
718         return false;
719     }
720 
721     switch (validation)
722     {
723         case VertexAttribTypeCase::Invalid:
724             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, err::kInvalidType);
725             return false;
726         case VertexAttribTypeCase::Valid:
727             if (size < 1 || size > 4)
728             {
729                 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, err::kInvalidVertexAttrSize);
730                 return false;
731             }
732             break;
733         case VertexAttribTypeCase::ValidSize4Only:
734             if (size != 4)
735             {
736                 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, err::kInvalidVertexAttribSize2101010);
737                 return false;
738             }
739             break;
740         case VertexAttribTypeCase::ValidSize3or4:
741             if (size != 3 && size != 4)
742             {
743                 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, err::kInvalidVertexAttribSize1010102);
744                 return false;
745             }
746             break;
747     }
748 
749     return true;
750 }
751 
752 // Note: These byte, short, and int types are all converted to float for the shader.
ValidateFloatVertexFormat(const Context * context,angle::EntryPoint entryPoint,GLuint index,GLint size,VertexAttribType type)753 ANGLE_INLINE bool ValidateFloatVertexFormat(const Context *context,
754                                             angle::EntryPoint entryPoint,
755                                             GLuint index,
756                                             GLint size,
757                                             VertexAttribType type)
758 {
759     return ValidateVertexFormat(context, entryPoint, index, size,
760                                 context->getStateCache().getVertexAttribTypeValidation(type));
761 }
762 
ValidateIntegerVertexFormat(const Context * context,angle::EntryPoint entryPoint,GLuint index,GLint size,VertexAttribType type)763 ANGLE_INLINE bool ValidateIntegerVertexFormat(const Context *context,
764                                               angle::EntryPoint entryPoint,
765                                               GLuint index,
766                                               GLint size,
767                                               VertexAttribType type)
768 {
769     return ValidateVertexFormat(
770         context, entryPoint, index, size,
771         context->getStateCache().getIntegerVertexAttribTypeValidation(type));
772 }
773 
ValidateColorMasksForSharedExponentColorBuffers(const BlendStateExt & blendState,const Framebuffer * framebuffer)774 ANGLE_INLINE bool ValidateColorMasksForSharedExponentColorBuffers(const BlendStateExt &blendState,
775                                                                   const Framebuffer *framebuffer)
776 {
777     // Get a mask of draw buffers that have color writemasks
778     // incompatible with shared exponent color buffers.
779     // The compatible writemasks are RGBA, RGB0, 000A, 0000.
780     const BlendStateExt::ColorMaskStorage::Type rgbEnabledBits =
781         blendState.expandColorMaskValue(true, true, true, false);
782     const BlendStateExt::ColorMaskStorage::Type colorMaskNoAlphaBits =
783         blendState.getColorMaskBits() & rgbEnabledBits;
784     const DrawBufferMask incompatibleDiffMask =
785         BlendStateExt::ColorMaskStorage::GetDiffMask(colorMaskNoAlphaBits, 0) &
786         BlendStateExt::ColorMaskStorage::GetDiffMask(colorMaskNoAlphaBits, rgbEnabledBits);
787 
788     const DrawBufferMask sharedExponentBufferMask =
789         framebuffer->getActiveSharedExponentColorAttachmentDrawBufferMask();
790     return (sharedExponentBufferMask & incompatibleDiffMask).none();
791 }
792 
793 bool ValidateRobustCompressedTexImageBase(const Context *context,
794                                           angle::EntryPoint entryPoint,
795                                           GLsizei imageSize,
796                                           GLsizei dataSize);
797 
798 bool ValidateVertexAttribIndex(const PrivateState &state,
799                                ErrorSet *errors,
800                                angle::EntryPoint entryPoint,
801                                GLuint index);
802 
803 bool ValidateGetActiveUniformBlockivBase(const Context *context,
804                                          angle::EntryPoint entryPoint,
805                                          ShaderProgramID program,
806                                          UniformBlockIndex uniformBlockIndex,
807                                          GLenum pname,
808                                          GLsizei *length);
809 
810 bool ValidateGetSamplerParameterBase(const Context *context,
811                                      angle::EntryPoint entryPoint,
812                                      SamplerID sampler,
813                                      GLenum pname,
814                                      GLsizei *length);
815 
816 template <typename ParamType>
817 bool ValidateSamplerParameterBase(const Context *context,
818                                   angle::EntryPoint entryPoint,
819                                   SamplerID sampler,
820                                   GLenum pname,
821                                   GLsizei bufSize,
822                                   bool vectorParams,
823                                   const ParamType *params);
824 
825 bool ValidateGetInternalFormativBase(const Context *context,
826                                      angle::EntryPoint entryPoint,
827                                      GLenum target,
828                                      GLenum internalformat,
829                                      GLenum pname,
830                                      GLsizei bufSize,
831                                      GLsizei *numParams);
832 
833 bool ValidateFramebufferNotMultisampled(const Context *context,
834                                         angle::EntryPoint entryPoint,
835                                         const Framebuffer *framebuffer,
836                                         bool checkReadBufferResourceSamples);
837 
838 bool ValidateMultitextureUnit(const PrivateState &state,
839                               ErrorSet *errors,
840                               angle::EntryPoint entryPoint,
841                               GLenum texture);
842 
843 bool ValidateTransformFeedbackPrimitiveMode(const Context *context,
844                                             angle::EntryPoint entryPoint,
845                                             PrimitiveMode transformFeedbackPrimitiveMode,
846                                             PrimitiveMode renderPrimitiveMode);
847 
848 // Common validation for 2D and 3D variants of TexStorage*Multisample.
849 bool ValidateTexStorageMultisample(const Context *context,
850                                    angle::EntryPoint entryPoint,
851                                    TextureType target,
852                                    GLsizei samples,
853                                    GLint internalFormat,
854                                    GLsizei width,
855                                    GLsizei height);
856 
857 bool ValidateTexStorage2DMultisampleBase(const Context *context,
858                                          angle::EntryPoint entryPoint,
859                                          TextureType target,
860                                          GLsizei samples,
861                                          GLint internalFormat,
862                                          GLsizei width,
863                                          GLsizei height);
864 
865 bool ValidateTexStorage3DMultisampleBase(const Context *context,
866                                          angle::EntryPoint entryPoint,
867                                          TextureType target,
868                                          GLsizei samples,
869                                          GLenum internalformat,
870                                          GLsizei width,
871                                          GLsizei height,
872                                          GLsizei depth);
873 
874 bool ValidateGetTexLevelParameterBase(const Context *context,
875                                       angle::EntryPoint entryPoint,
876                                       TextureTarget target,
877                                       GLint level,
878                                       GLenum pname,
879                                       GLsizei *length);
880 
881 bool ValidateMapBufferBase(const Context *context,
882                            angle::EntryPoint entryPoint,
883                            BufferBinding target);
884 bool ValidateIndexedStateQuery(const Context *context,
885                                angle::EntryPoint entryPoint,
886                                GLenum pname,
887                                GLuint index,
888                                GLsizei *length);
889 bool ValidateES3TexImage2DParameters(const Context *context,
890                                      angle::EntryPoint entryPoint,
891                                      TextureTarget target,
892                                      GLint level,
893                                      GLenum internalformat,
894                                      bool isCompressed,
895                                      bool isSubImage,
896                                      GLint xoffset,
897                                      GLint yoffset,
898                                      GLint zoffset,
899                                      GLsizei width,
900                                      GLsizei height,
901                                      GLsizei depth,
902                                      GLint border,
903                                      GLenum format,
904                                      GLenum type,
905                                      GLsizei imageSize,
906                                      const void *pixels);
907 bool ValidateES3CopyTexImage2DParameters(const Context *context,
908                                          angle::EntryPoint entryPoint,
909                                          TextureTarget target,
910                                          GLint level,
911                                          GLenum internalformat,
912                                          bool isSubImage,
913                                          GLint xoffset,
914                                          GLint yoffset,
915                                          GLint zoffset,
916                                          GLint x,
917                                          GLint y,
918                                          GLsizei width,
919                                          GLsizei height,
920                                          GLint border);
921 bool ValidateES3TexStorageParametersBase(const Context *context,
922                                          angle::EntryPoint entryPoint,
923                                          TextureType target,
924                                          GLsizei levels,
925                                          GLenum internalformat,
926                                          GLsizei width,
927                                          GLsizei height,
928                                          GLsizei depth);
929 bool ValidateES3TexStorage2DParameters(const Context *context,
930                                        angle::EntryPoint entryPoint,
931                                        TextureType target,
932                                        GLsizei levels,
933                                        GLenum internalformat,
934                                        GLsizei width,
935                                        GLsizei height,
936                                        GLsizei depth);
937 bool ValidateES3TexStorage3DParameters(const Context *context,
938                                        angle::EntryPoint entryPoint,
939                                        TextureType target,
940                                        GLsizei levels,
941                                        GLenum internalformat,
942                                        GLsizei width,
943                                        GLsizei height,
944                                        GLsizei depth);
945 
946 bool ValidateGetMultisamplefvBase(const Context *context,
947                                   angle::EntryPoint entryPoint,
948                                   GLenum pname,
949                                   GLuint index,
950                                   const GLfloat *val);
951 bool ValidateSampleMaskiBase(const PrivateState &state,
952                              ErrorSet *errors,
953                              angle::EntryPoint entryPoint,
954                              GLuint maskNumber,
955                              GLbitfield mask);
956 
957 bool ValidateProgramExecutableXFBBuffersPresent(const Context *context,
958                                                 const ProgramExecutable *programExecutable);
959 
960 // We should check with Khronos if returning INVALID_FRAMEBUFFER_OPERATION is OK when querying
961 // implementation format info for incomplete framebuffers. It seems like these queries are
962 // incongruent with the other errors.
963 // Inlined for speed.
964 template <GLenum ErrorCode = GL_INVALID_FRAMEBUFFER_OPERATION>
ValidateFramebufferComplete(const Context * context,angle::EntryPoint entryPoint,const Framebuffer * framebuffer)965 ANGLE_INLINE bool ValidateFramebufferComplete(const Context *context,
966                                               angle::EntryPoint entryPoint,
967                                               const Framebuffer *framebuffer)
968 {
969     const FramebufferStatus &framebufferStatus = framebuffer->checkStatus(context);
970     if (!framebufferStatus.isComplete())
971     {
972         ASSERT(framebufferStatus.reason != nullptr);
973         ANGLE_VALIDATION_ERROR(ErrorCode, framebufferStatus.reason);
974         return false;
975     }
976 
977     return true;
978 }
979 
980 const char *ValidateProgramPipelineDrawStates(const State &state,
981                                               const Extensions &extensions,
982                                               ProgramPipeline *programPipeline);
983 const char *ValidateProgramPipelineAttachedPrograms(ProgramPipeline *programPipeline);
984 const char *ValidateDrawStates(const Context *context, GLenum *outErrorCode);
985 const char *ValidateProgramPipeline(const Context *context);
986 
987 void RecordDrawAttribsError(const Context *context, angle::EntryPoint entryPoint);
988 
ValidateDrawAttribs(const Context * context,angle::EntryPoint entryPoint,int64_t maxVertex)989 ANGLE_INLINE bool ValidateDrawAttribs(const Context *context,
990                                       angle::EntryPoint entryPoint,
991                                       int64_t maxVertex)
992 {
993     // For non-instanced attributes, the maximum vertex must be accessible in the attribute buffers.
994     // For instanced attributes, in non-instanced draw calls only attribute 0 is accessed.  In
995     // instanced draw calls, the instance limit is checked in ValidateDrawInstancedAttribs.
996     if (maxVertex >= context->getStateCache().getNonInstancedVertexElementLimit() ||
997         context->getStateCache().getInstancedVertexElementLimit() < 1)
998     {
999         RecordDrawAttribsError(context, entryPoint);
1000         return false;
1001     }
1002 
1003     return true;
1004 }
1005 
ValidateDrawArraysAttribs(const Context * context,angle::EntryPoint entryPoint,GLint first,GLsizei count)1006 ANGLE_INLINE bool ValidateDrawArraysAttribs(const Context *context,
1007                                             angle::EntryPoint entryPoint,
1008                                             GLint first,
1009                                             GLsizei count)
1010 {
1011     if (!context->isBufferAccessValidationEnabled())
1012     {
1013         return true;
1014     }
1015 
1016     // Check the computation of maxVertex doesn't overflow.
1017     // - first < 0 has been checked as an error condition.
1018     // - if count <= 0, skip validating no-op draw calls.
1019     // From this we know maxVertex will be positive, and only need to check if it overflows GLint.
1020     ASSERT(first >= 0);
1021     ASSERT(count > 0);
1022     int64_t maxVertex = static_cast<int64_t>(first) + static_cast<int64_t>(count) - 1;
1023     if (maxVertex > static_cast<int64_t>(std::numeric_limits<GLint>::max()))
1024     {
1025         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, err::kIntegerOverflow);
1026         return false;
1027     }
1028 
1029     return ValidateDrawAttribs(context, entryPoint, maxVertex);
1030 }
1031 
ValidateDrawInstancedAttribs(const Context * context,angle::EntryPoint entryPoint,GLint primcount,GLuint baseinstance)1032 ANGLE_INLINE bool ValidateDrawInstancedAttribs(const Context *context,
1033                                                angle::EntryPoint entryPoint,
1034                                                GLint primcount,
1035                                                GLuint baseinstance)
1036 {
1037     if (!context->isBufferAccessValidationEnabled())
1038     {
1039         return true;
1040     }
1041 
1042     // Validate that the buffers bound for the attributes can hold enough vertices for this
1043     // instanced draw.  For attributes with a divisor of 0, ValidateDrawAttribs already checks this.
1044     // Thus, the following only checks attributes with a non-zero divisor (i.e. "instanced").
1045     const GLint64 limit = context->getStateCache().getInstancedVertexElementLimit();
1046     if (baseinstance >= limit || primcount > limit - baseinstance)
1047     {
1048         RecordDrawAttribsError(context, entryPoint);
1049         return false;
1050     }
1051 
1052     return true;
1053 }
1054 
ValidateDrawArraysCommon(const Context * context,angle::EntryPoint entryPoint,PrimitiveMode mode,GLint first,GLsizei count,GLsizei primcount)1055 ANGLE_INLINE bool ValidateDrawArraysCommon(const Context *context,
1056                                            angle::EntryPoint entryPoint,
1057                                            PrimitiveMode mode,
1058                                            GLint first,
1059                                            GLsizei count,
1060                                            GLsizei primcount)
1061 {
1062     if (first < 0)
1063     {
1064         ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, err::kNegativeStart);
1065         return false;
1066     }
1067 
1068     if (count <= 0)
1069     {
1070         if (count < 0)
1071         {
1072             ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, err::kNegativeCount);
1073             return false;
1074         }
1075 
1076         // Early exit.
1077         return ValidateDrawBase(context, entryPoint, mode);
1078     }
1079 
1080     if (primcount <= 0)
1081     {
1082         if (primcount < 0)
1083         {
1084             ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, err::kNegativeCount);
1085             return false;
1086         }
1087         // Early exit.
1088         return ValidateDrawBase(context, entryPoint, mode);
1089     }
1090 
1091     if (!ValidateDrawBase(context, entryPoint, mode))
1092     {
1093         return false;
1094     }
1095 
1096     if (context->getStateCache().isTransformFeedbackActiveUnpaused() &&
1097         !context->supportsGeometryOrTesselation())
1098     {
1099         const State &state                      = context->getState();
1100         TransformFeedback *curTransformFeedback = state.getCurrentTransformFeedback();
1101         if (!curTransformFeedback->checkBufferSpaceForDraw(count, primcount))
1102         {
1103             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, err::kTransformFeedbackBufferTooSmall);
1104             return false;
1105         }
1106     }
1107 
1108     return ValidateDrawArraysAttribs(context, entryPoint, first, count);
1109 }
1110 
ValidateDrawElementsBase(const Context * context,angle::EntryPoint entryPoint,PrimitiveMode mode,DrawElementsType type)1111 ANGLE_INLINE bool ValidateDrawElementsBase(const Context *context,
1112                                            angle::EntryPoint entryPoint,
1113                                            PrimitiveMode mode,
1114                                            DrawElementsType type)
1115 {
1116     if (!context->getStateCache().isValidDrawElementsType(type))
1117     {
1118         if (type == DrawElementsType::UnsignedInt)
1119         {
1120             ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, err::kTypeNotUnsignedShortByte);
1121             return false;
1122         }
1123 
1124         ASSERT(type == DrawElementsType::InvalidEnum);
1125         ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, err::kEnumInvalid);
1126         return false;
1127     }
1128 
1129     intptr_t drawElementsError = context->getStateCache().getBasicDrawElementsError(context);
1130     if (drawElementsError)
1131     {
1132         // All errors from ValidateDrawElementsStates return INVALID_OPERATION.
1133         const char *errorMessage = reinterpret_cast<const char *>(drawElementsError);
1134         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, errorMessage);
1135         return false;
1136     }
1137 
1138     // Note that we are missing overflow checks for active transform feedback buffers.
1139     return true;
1140 }
1141 
ValidateDrawElementsCommon(const Context * context,angle::EntryPoint entryPoint,PrimitiveMode mode,GLsizei count,DrawElementsType type,const void * indices,GLsizei primcount)1142 ANGLE_INLINE bool ValidateDrawElementsCommon(const Context *context,
1143                                              angle::EntryPoint entryPoint,
1144                                              PrimitiveMode mode,
1145                                              GLsizei count,
1146                                              DrawElementsType type,
1147                                              const void *indices,
1148                                              GLsizei primcount)
1149 {
1150     if (!ValidateDrawElementsBase(context, entryPoint, mode, type))
1151     {
1152         return false;
1153     }
1154 
1155     ASSERT(isPow2(GetDrawElementsTypeSize(type)) && GetDrawElementsTypeSize(type) > 0);
1156 
1157     if (context->isWebGL())
1158     {
1159         GLuint typeBytes = GetDrawElementsTypeSize(type);
1160 
1161         if ((reinterpret_cast<uintptr_t>(indices) & static_cast<uintptr_t>(typeBytes - 1)) != 0)
1162         {
1163             // [WebGL 1.0] Section 6.4 Buffer Offset and Stride Requirements
1164             // The offset arguments to drawElements and [...], must be a multiple of the size of the
1165             // data type passed to the call, or an INVALID_OPERATION error is generated.
1166             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, err::kOffsetMustBeMultipleOfType);
1167             return false;
1168         }
1169 
1170         // [WebGL 1.0] Section 6.4 Buffer Offset and Stride Requirements
1171         // In addition the offset argument to drawElements must be non-negative or an INVALID_VALUE
1172         // error is generated.
1173         if (reinterpret_cast<intptr_t>(indices) < 0)
1174         {
1175             ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, err::kNegativeOffset);
1176             return false;
1177         }
1178     }
1179 
1180     if (count <= 0)
1181     {
1182         if (count < 0)
1183         {
1184             ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, err::kNegativeCount);
1185             return false;
1186         }
1187 
1188         // Early exit.
1189         return ValidateDrawBase(context, entryPoint, mode);
1190     }
1191 
1192     if (!ValidateDrawBase(context, entryPoint, mode))
1193     {
1194         return false;
1195     }
1196 
1197     const State &state         = context->getState();
1198     const VertexArray *vao     = state.getVertexArray();
1199     Buffer *elementArrayBuffer = vao->getElementArrayBuffer();
1200 
1201     if (!elementArrayBuffer)
1202     {
1203         if (!indices)
1204         {
1205             // This is an application error that would normally result in a crash, but we catch
1206             // it and return an error
1207             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, err::kElementArrayNoBufferOrPointer);
1208             return false;
1209         }
1210     }
1211     else
1212     {
1213         // The max possible type size is 8 and count is on 32 bits so doing the multiplication
1214         // in a 64 bit integer is safe. Also we are guaranteed that here count > 0.
1215         static_assert(std::is_same<int, GLsizei>::value, "GLsizei isn't the expected type");
1216         constexpr uint64_t kMaxTypeSize = 8;
1217         constexpr uint64_t kIntMax      = std::numeric_limits<int>::max();
1218         constexpr uint64_t kUint64Max   = std::numeric_limits<uint64_t>::max();
1219         static_assert(kIntMax < kUint64Max / kMaxTypeSize, "");
1220 
1221         uint64_t elementCount = static_cast<uint64_t>(count);
1222         ASSERT(elementCount > 0 && GetDrawElementsTypeSize(type) <= kMaxTypeSize);
1223 
1224         // Doing the multiplication here is overflow-safe
1225         uint64_t elementDataSizeNoOffset = elementCount << GetDrawElementsTypeShift(type);
1226 
1227         // The offset can be any value, check for overflows
1228         uint64_t offset = static_cast<uint64_t>(reinterpret_cast<uintptr_t>(indices));
1229         uint64_t elementDataSizeWithOffset = elementDataSizeNoOffset + offset;
1230         if (elementDataSizeWithOffset < elementDataSizeNoOffset)
1231         {
1232             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, err::kIntegerOverflow);
1233             return false;
1234         }
1235 
1236         // Related to possible test bug: https://github.com/KhronosGroup/WebGL/issues/3064
1237         if ((elementDataSizeWithOffset > static_cast<uint64_t>(elementArrayBuffer->getSize())) &&
1238             (primcount > 0))
1239         {
1240             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, err::kInsufficientBufferSize);
1241             return false;
1242         }
1243     }
1244 
1245     if (context->isBufferAccessValidationEnabled() && primcount > 0)
1246     {
1247         // Use the parameter buffer to retrieve and cache the index range.
1248         // TODO: this calculation should take basevertex into account for
1249         // glDrawElementsInstancedBaseVertexBaseInstanceEXT.  http://anglebug.com/41481166
1250         IndexRange indexRange{IndexRange::Undefined()};
1251         ANGLE_VALIDATION_TRY(vao->getIndexRange(context, type, count, indices, &indexRange));
1252 
1253         // If we use an index greater than our maximum supported index range, return an error.
1254         // The ES3 spec does not specify behaviour here, it is undefined, but ANGLE should
1255         // always return an error if possible here.
1256         if (static_cast<GLint64>(indexRange.end) >= context->getCaps().maxElementIndex)
1257         {
1258             ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, err::kExceedsMaxElement);
1259             return false;
1260         }
1261 
1262         if (!ValidateDrawAttribs(context, entryPoint, static_cast<GLint>(indexRange.end)))
1263         {
1264             return false;
1265         }
1266 
1267         // No op if there are no real indices in the index data (all are primitive restart).
1268         return (indexRange.vertexIndexCount > 0);
1269     }
1270 
1271     return true;
1272 }
1273 
ValidateBindVertexArrayBase(const Context * context,angle::EntryPoint entryPoint,VertexArrayID array)1274 ANGLE_INLINE bool ValidateBindVertexArrayBase(const Context *context,
1275                                               angle::EntryPoint entryPoint,
1276                                               VertexArrayID array)
1277 {
1278     if (!context->isVertexArrayGenerated(array))
1279     {
1280         // The default VAO should always exist
1281         ASSERT(array.value != 0);
1282         ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, err::kInvalidVertexArray);
1283         return false;
1284     }
1285 
1286     return true;
1287 }
1288 
ValidateVertexAttribIndex(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLuint index)1289 ANGLE_INLINE bool ValidateVertexAttribIndex(const PrivateState &state,
1290                                             ErrorSet *errors,
1291                                             angle::EntryPoint entryPoint,
1292                                             GLuint index)
1293 {
1294     if (index >= static_cast<GLuint>(state.getCaps().maxVertexAttributes))
1295     {
1296         errors->validationError(entryPoint, GL_INVALID_VALUE, err::kIndexExceedsMaxVertexAttribute);
1297         return false;
1298     }
1299 
1300     return true;
1301 }
1302 
1303 bool ValidateLogicOpCommon(const PrivateState &state,
1304                            ErrorSet *errors,
1305                            angle::EntryPoint entryPoint,
1306                            LogicalOperation opcodePacked);
1307 }  // namespace gl
1308 
1309 #endif  // LIBANGLE_VALIDATION_ES_H_
1310