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