1 //
2 // Copyright 2019 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 // validationESEXT.cpp: Validation functions for OpenGL ES extension entry points.
7
8 #include "libANGLE/validationESEXT_autogen.h"
9
10 #include "libANGLE/Context.h"
11 #include "libANGLE/Display.h"
12 #include "libANGLE/ErrorStrings.h"
13 #include "libANGLE/MemoryObject.h"
14 #include "libANGLE/PixelLocalStorage.h"
15 #include "libANGLE/validationES.h"
16 #include "libANGLE/validationES2.h"
17 #include "libANGLE/validationES3.h"
18 #include "libANGLE/validationES31.h"
19 #include "libANGLE/validationES32.h"
20
21 #include <optional>
22
23 namespace gl
24 {
25 using namespace err;
26
27 namespace
28 {
29 template <typename ObjectT>
ValidateGetImageFormatAndType(const Context * context,angle::EntryPoint entryPoint,ObjectT * obj,GLenum format,GLenum type)30 bool ValidateGetImageFormatAndType(const Context *context,
31 angle::EntryPoint entryPoint,
32 ObjectT *obj,
33 GLenum format,
34 GLenum type)
35 {
36 GLenum implFormat = obj->getImplementationColorReadFormat(context);
37 if (!ValidES3Format(format) && (format != implFormat || format == GL_NONE))
38 {
39 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidFormat);
40 return false;
41 }
42
43 GLenum implType = obj->getImplementationColorReadType(context);
44 if (!ValidES3Type(type) && (type != implType || type == GL_NONE))
45 {
46 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidType);
47 return false;
48 }
49
50 // Format/type combinations are not yet validated.
51
52 return true;
53 }
54
IsValidImageLayout(ImageLayout layout)55 bool IsValidImageLayout(ImageLayout layout)
56 {
57 switch (layout)
58 {
59 case ImageLayout::Undefined:
60 case ImageLayout::General:
61 case ImageLayout::ColorAttachment:
62 case ImageLayout::DepthStencilAttachment:
63 case ImageLayout::DepthStencilReadOnlyAttachment:
64 case ImageLayout::ShaderReadOnly:
65 case ImageLayout::TransferSrc:
66 case ImageLayout::TransferDst:
67 case ImageLayout::DepthReadOnlyStencilAttachment:
68 case ImageLayout::DepthAttachmentStencilReadOnly:
69 return true;
70
71 default:
72 return false;
73 }
74 }
75
IsValidMemoryObjectParamater(const Context * context,angle::EntryPoint entryPoint,GLenum pname)76 bool IsValidMemoryObjectParamater(const Context *context,
77 angle::EntryPoint entryPoint,
78 GLenum pname)
79 {
80 switch (pname)
81 {
82 case GL_DEDICATED_MEMORY_OBJECT_EXT:
83 return true;
84
85 case GL_PROTECTED_MEMORY_OBJECT_EXT:
86 if (!context->getExtensions().protectedTexturesEXT)
87 {
88 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
89 return false;
90 }
91 return true;
92
93 default:
94 return false;
95 }
96 }
97
ValidateObjectIdentifierAndName(const Context * context,angle::EntryPoint entryPoint,GLenum identifier,GLuint name)98 bool ValidateObjectIdentifierAndName(const Context *context,
99 angle::EntryPoint entryPoint,
100 GLenum identifier,
101 GLuint name)
102 {
103 bool isGLES11 = context->getClientVersion() == Version(1, 1);
104 bool isGLES3 = context->getClientMajorVersion() >= 3;
105 bool isGLES31 = context->getClientVersion() >= Version(3, 1);
106 switch (identifier)
107 {
108 case GL_BUFFER_OBJECT_EXT:
109 if (context->getBuffer({name}) == nullptr)
110 {
111 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidBufferName);
112 return false;
113 }
114 return true;
115
116 case GL_SHADER_OBJECT_EXT:
117 if (isGLES11)
118 {
119 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidType);
120 return false;
121 }
122 if (context->getShaderNoResolveCompile({name}) == nullptr)
123 {
124 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidShaderName);
125 return false;
126 }
127 return true;
128
129 case GL_PROGRAM_OBJECT_EXT:
130 if (isGLES11)
131 {
132 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidType);
133 return false;
134 }
135 if (context->getProgramNoResolveLink({name}) == nullptr)
136 {
137 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidProgramName);
138 return false;
139 }
140 return true;
141
142 case GL_VERTEX_ARRAY_OBJECT_EXT:
143 if (!isGLES3 && !context->getExtensions().vertexArrayObjectOES)
144 {
145 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidType);
146 return false;
147 }
148 if (context->getVertexArray({name}) == nullptr)
149 {
150 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidVertexArrayName);
151 return false;
152 }
153 return true;
154
155 case GL_QUERY_OBJECT_EXT:
156 if (!isGLES3 && !context->getExtensions().occlusionQueryBooleanEXT)
157 {
158 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidType);
159 return false;
160 }
161 if (context->getQuery({name}) == nullptr)
162 {
163 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidQueryName);
164 return false;
165 }
166 return true;
167
168 case GL_TRANSFORM_FEEDBACK:
169 if (!isGLES3)
170 {
171 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidType);
172 return false;
173 }
174 if (context->getTransformFeedback({name}) == nullptr)
175 {
176 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidTransformFeedbackName);
177 return false;
178 }
179 return true;
180
181 case GL_SAMPLER:
182 if (!isGLES3)
183 {
184 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidType);
185 return false;
186 }
187 if (context->getSampler({name}) == nullptr)
188 {
189 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidSamplerName);
190 return false;
191 }
192 return true;
193
194 case GL_TEXTURE:
195 if (context->getTexture({name}) == nullptr)
196 {
197 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidTextureName);
198 return false;
199 }
200 return true;
201
202 case GL_RENDERBUFFER:
203 if (!context->isRenderbuffer({name}))
204 {
205 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidRenderbufferName);
206 return false;
207 }
208 return true;
209
210 case GL_FRAMEBUFFER:
211 if (context->getFramebuffer({name}) == nullptr)
212 {
213 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidFramebufferName);
214 return false;
215 }
216 return true;
217
218 case GL_PROGRAM_PIPELINE_OBJECT_EXT:
219 if (!isGLES31 && !context->getExtensions().separateShaderObjectsEXT)
220 {
221 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidType);
222 return false;
223 }
224 if (context->getProgramPipeline({name}) == nullptr)
225 {
226 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidProgramPipelineName);
227 return false;
228 }
229 return true;
230
231 default:
232 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidIndentifier);
233 return false;
234 }
235 }
236
ValidateClearTexImageFormat(const Context * context,angle::EntryPoint entryPoint,TextureType textureType,const Format & textureFormat,GLenum format,GLenum type)237 bool ValidateClearTexImageFormat(const Context *context,
238 angle::EntryPoint entryPoint,
239 TextureType textureType,
240 const Format &textureFormat,
241 GLenum format,
242 GLenum type)
243 {
244 if (textureFormat.info->compressed)
245 {
246 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kTextureIsCompressed);
247 return false;
248 }
249
250 if (!ValidateTexImageFormatCombination(context, entryPoint, textureType,
251 textureFormat.info->internalFormat, format, type))
252 {
253 return false;
254 }
255
256 return true;
257 }
258
ValidateClearTexImageCommon(const Context * context,angle::EntryPoint entryPoint,TextureID texturePacked,GLint level,const std::optional<Box> & area,GLenum format,GLenum type,const void * data)259 bool ValidateClearTexImageCommon(const Context *context,
260 angle::EntryPoint entryPoint,
261 TextureID texturePacked,
262 GLint level,
263 const std::optional<Box> &area,
264 GLenum format,
265 GLenum type,
266 const void *data)
267 {
268 if (!context->getExtensions().clearTextureEXT)
269 {
270 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
271 return false;
272 }
273
274 if (texturePacked.value == 0)
275 {
276 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kMissingTextureName);
277 return false;
278 }
279
280 Texture *tex = context->getTexture(texturePacked);
281 if (tex == nullptr)
282 {
283 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kMissingTextureName);
284 return false;
285 }
286
287 if (tex->getType() == TextureType::Buffer)
288 {
289 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBufferTextureNotAllowed);
290 return false;
291 }
292
293 if (!ValidMipLevel(context, tex->getType(), level))
294 {
295 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidMipLevel);
296 return false;
297 }
298
299 if (area.has_value() && (area->x < 0 || area->y < 0 || area->z < 0 || area->width < 0 ||
300 area->height < 0 || area->depth < 0))
301 {
302 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kNegativeOffset);
303 return false;
304 }
305
306 if (tex->getType() == TextureType::CubeMap)
307 {
308 if (area.has_value() && area->z + area->depth > 6)
309 {
310 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kDestinationTextureTooSmall);
311 return false;
312 }
313
314 ImageIndexIterator it = ImageIndexIterator::MakeGeneric(
315 tex->getType(), level, level + 1, area.has_value() ? area->z : ImageIndex::kEntireLevel,
316 area.has_value() ? area->z + area->depth : ImageIndex::kEntireLevel);
317 while (it.hasNext())
318 {
319 const ImageIndex index = it.next();
320 TextureTarget target = index.getTarget();
321 const Extents extents = tex->getExtents(target, level);
322
323 if (!tex->getState().getImageDesc(index).format.valid())
324 {
325 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kDestinationLevelNotDefined);
326 return false;
327 }
328
329 if (area.has_value() &&
330 (area->x + area->width > extents.width || area->y + area->height > extents.height))
331 {
332 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kDestinationTextureTooSmall);
333 return false;
334 }
335
336 if (!ValidateClearTexImageFormat(context, entryPoint, tex->getType(),
337 tex->getFormat(target, level), format, type))
338 {
339 return false;
340 }
341 }
342 }
343 else
344 {
345 TextureTarget target = NonCubeTextureTypeToTarget(tex->getType());
346 const Extents extents = tex->getExtents(target, level);
347
348 if (!tex->getState().getImageDesc(target, level).format.valid())
349 {
350 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kDestinationLevelNotDefined);
351 return false;
352 }
353
354 if (area.has_value() &&
355 (area->x + area->width > extents.width || area->y + area->height > extents.height ||
356 area->z + area->depth > extents.depth))
357 {
358 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kDestinationTextureTooSmall);
359 return false;
360 }
361
362 if (!ValidateClearTexImageFormat(context, entryPoint, tex->getType(),
363 tex->getFormat(target, level), format, type))
364 {
365 return false;
366 }
367 }
368
369 return true;
370 }
371
372 } // namespace
373
ValidateGetTexImage(const Context * context,angle::EntryPoint entryPoint,TextureTarget target,GLint level)374 bool ValidateGetTexImage(const Context *context,
375 angle::EntryPoint entryPoint,
376 TextureTarget target,
377 GLint level)
378 {
379 if (!context->getExtensions().getImageANGLE)
380 {
381 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kGetImageExtensionNotEnabled);
382 return false;
383 }
384
385 if (!ValidTexture2DDestinationTarget(context, target) &&
386 !ValidTexture3DDestinationTarget(context, target))
387 {
388 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidTextureTarget);
389 return false;
390 }
391
392 if (level < 0)
393 {
394 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeLevel);
395 return false;
396 }
397
398 TextureType textureType = TextureTargetToType(target);
399 if (!ValidMipLevel(context, textureType, level))
400 {
401 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidMipLevel);
402 return false;
403 }
404
405 return true;
406 }
407
ValidateGetTexImageANGLE(const Context * context,angle::EntryPoint entryPoint,TextureTarget target,GLint level,GLenum format,GLenum type,const void * pixels)408 bool ValidateGetTexImageANGLE(const Context *context,
409 angle::EntryPoint entryPoint,
410 TextureTarget target,
411 GLint level,
412 GLenum format,
413 GLenum type,
414 const void *pixels)
415 {
416 if (!ValidateGetTexImage(context, entryPoint, target, level))
417 {
418 return false;
419 }
420
421 Texture *texture = context->getTextureByTarget(target);
422
423 if (!ValidateGetImageFormatAndType(context, entryPoint, texture, format, type))
424 {
425 return false;
426 }
427
428 GLsizei width = static_cast<GLsizei>(texture->getWidth(target, level));
429 GLsizei height = static_cast<GLsizei>(texture->getHeight(target, level));
430 if (!ValidatePixelPack(context, entryPoint, format, type, 0, 0, width, height, -1, nullptr,
431 pixels))
432 {
433 return false;
434 }
435
436 if (texture->getFormat(target, level).info->compressed)
437 {
438 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kGetImageCompressed);
439 return false;
440 }
441
442 return true;
443 }
444
ValidateGetCompressedTexImageANGLE(const Context * context,angle::EntryPoint entryPoint,TextureTarget target,GLint level,const void * pixels)445 bool ValidateGetCompressedTexImageANGLE(const Context *context,
446 angle::EntryPoint entryPoint,
447 TextureTarget target,
448 GLint level,
449 const void *pixels)
450 {
451 if (!ValidateGetTexImage(context, entryPoint, target, level))
452 {
453 return false;
454 }
455
456 Texture *texture = context->getTextureByTarget(target);
457 if (!texture->getFormat(target, level).info->compressed)
458 {
459 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kGetImageNotCompressed);
460 return false;
461 }
462
463 return true;
464 }
465
ValidateGetRenderbufferImageANGLE(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLenum format,GLenum type,const void * pixels)466 bool ValidateGetRenderbufferImageANGLE(const Context *context,
467 angle::EntryPoint entryPoint,
468 GLenum target,
469 GLenum format,
470 GLenum type,
471 const void *pixels)
472 {
473 if (!context->getExtensions().getImageANGLE)
474 {
475 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kGetImageExtensionNotEnabled);
476 return false;
477 }
478
479 if (target != GL_RENDERBUFFER)
480 {
481 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidRenderbufferTarget);
482 return false;
483 }
484
485 Renderbuffer *renderbuffer = context->getState().getCurrentRenderbuffer();
486
487 if (!ValidateGetImageFormatAndType(context, entryPoint, renderbuffer, format, type))
488 {
489 return false;
490 }
491
492 GLsizei width = renderbuffer->getWidth();
493 GLsizei height = renderbuffer->getHeight();
494 if (!ValidatePixelPack(context, entryPoint, format, type, 0, 0, width, height, -1, nullptr,
495 pixels))
496 {
497 return false;
498 }
499
500 return true;
501 }
502
ValidateDrawElementsBaseVertexEXT(const Context * context,angle::EntryPoint entryPoint,PrimitiveMode mode,GLsizei count,DrawElementsType type,const void * indices,GLint basevertex)503 bool ValidateDrawElementsBaseVertexEXT(const Context *context,
504 angle::EntryPoint entryPoint,
505 PrimitiveMode mode,
506 GLsizei count,
507 DrawElementsType type,
508 const void *indices,
509 GLint basevertex)
510 {
511 if (!context->getExtensions().drawElementsBaseVertexAny())
512 {
513 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
514 return false;
515 }
516
517 return ValidateDrawElementsCommon(context, entryPoint, mode, count, type, indices, 1);
518 }
519
ValidateDrawElementsInstancedBaseVertexEXT(const Context * context,angle::EntryPoint entryPoint,PrimitiveMode mode,GLsizei count,DrawElementsType type,const void * indices,GLsizei instancecount,GLint basevertex)520 bool ValidateDrawElementsInstancedBaseVertexEXT(const Context *context,
521 angle::EntryPoint entryPoint,
522 PrimitiveMode mode,
523 GLsizei count,
524 DrawElementsType type,
525 const void *indices,
526 GLsizei instancecount,
527 GLint basevertex)
528 {
529 if (!context->getExtensions().drawElementsBaseVertexAny())
530 {
531 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
532 return false;
533 }
534
535 return ValidateDrawElementsInstancedBase(context, entryPoint, mode, count, type, indices,
536 instancecount, 0);
537 }
538
ValidateDrawRangeElementsBaseVertexEXT(const Context * context,angle::EntryPoint entryPoint,PrimitiveMode mode,GLuint start,GLuint end,GLsizei count,DrawElementsType type,const void * indices,GLint basevertex)539 bool ValidateDrawRangeElementsBaseVertexEXT(const Context *context,
540 angle::EntryPoint entryPoint,
541 PrimitiveMode mode,
542 GLuint start,
543 GLuint end,
544 GLsizei count,
545 DrawElementsType type,
546 const void *indices,
547 GLint basevertex)
548 {
549 if (!context->getExtensions().drawElementsBaseVertexAny())
550 {
551 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
552 return false;
553 }
554
555 if (end < start)
556 {
557 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidElementRange);
558 return false;
559 }
560
561 if (!ValidateDrawElementsCommon(context, entryPoint, mode, count, type, indices, 1))
562 {
563 return false;
564 }
565
566 // Skip range checks for no-op calls.
567 if (count <= 0)
568 {
569 return true;
570 }
571
572 // Note that resolving the index range is a bit slow. We should probably optimize this.
573 IndexRange indexRange;
574 ANGLE_VALIDATION_TRY(context->getState().getVertexArray()->getIndexRange(context, type, count,
575 indices, &indexRange));
576
577 if (indexRange.end > end || indexRange.start < start)
578 {
579 // GL spec says that behavior in this case is undefined - generating an error is fine.
580 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExceedsElementRange);
581 return false;
582 }
583 return true;
584 }
585
ValidateMultiDrawElementsBaseVertexEXT(const Context * context,angle::EntryPoint entryPoint,PrimitiveMode mode,const GLsizei * count,DrawElementsType type,const void * const * indices,GLsizei drawcount,const GLint * basevertex)586 bool ValidateMultiDrawElementsBaseVertexEXT(const Context *context,
587 angle::EntryPoint entryPoint,
588 PrimitiveMode mode,
589 const GLsizei *count,
590 DrawElementsType type,
591 const void *const *indices,
592 GLsizei drawcount,
593 const GLint *basevertex)
594 {
595 return true;
596 }
597
ValidateMultiDrawArraysIndirectEXT(const Context * context,angle::EntryPoint entryPoint,PrimitiveMode modePacked,const void * indirect,GLsizei drawcount,GLsizei stride)598 bool ValidateMultiDrawArraysIndirectEXT(const Context *context,
599 angle::EntryPoint entryPoint,
600 PrimitiveMode modePacked,
601 const void *indirect,
602 GLsizei drawcount,
603 GLsizei stride)
604 {
605 if (!ValidateMultiDrawIndirectBase(context, entryPoint, drawcount, stride))
606 {
607 return false;
608 }
609
610 if (!ValidateDrawArraysIndirect(context, entryPoint, modePacked, indirect))
611 {
612 return false;
613 }
614
615 return true;
616 }
617
ValidateMultiDrawElementsIndirectEXT(const Context * context,angle::EntryPoint entryPoint,PrimitiveMode modePacked,DrawElementsType typePacked,const void * indirect,GLsizei drawcount,GLsizei stride)618 bool ValidateMultiDrawElementsIndirectEXT(const Context *context,
619 angle::EntryPoint entryPoint,
620 PrimitiveMode modePacked,
621 DrawElementsType typePacked,
622 const void *indirect,
623 GLsizei drawcount,
624 GLsizei stride)
625 {
626 if (!ValidateMultiDrawIndirectBase(context, entryPoint, drawcount, stride))
627 {
628 return false;
629 }
630
631 const State &state = context->getState();
632 TransformFeedback *curTransformFeedback = state.getCurrentTransformFeedback();
633 if (!ValidateDrawElementsIndirect(context, entryPoint, modePacked, typePacked, indirect))
634 {
635 return false;
636 }
637
638 if (curTransformFeedback && curTransformFeedback->isActive() &&
639 !curTransformFeedback->isPaused())
640 {
641 // EXT_geometry_shader allows transform feedback to work with all draw commands.
642 // [EXT_geometry_shader] Section 12.1, "Transform Feedback"
643 if (context->getExtensions().geometryShaderAny() || context->getClientVersion() >= ES_3_2)
644 {
645 if (!ValidateTransformFeedbackPrimitiveMode(
646 context, entryPoint, curTransformFeedback->getPrimitiveMode(), modePacked))
647 {
648 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidDrawModeTransformFeedback);
649 return false;
650 }
651 }
652 else
653 {
654 // An INVALID_OPERATION error is generated if transform feedback is active and not
655 // paused.
656 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kUnsupportedDrawModeForTransformFeedback);
657 return false;
658 }
659 }
660
661 return true;
662 }
663
ValidateDrawArraysInstancedBaseInstanceEXT(const Context * context,angle::EntryPoint entryPoint,PrimitiveMode mode,GLint first,GLsizei count,GLsizei instanceCount,GLuint baseInstance)664 bool ValidateDrawArraysInstancedBaseInstanceEXT(const Context *context,
665 angle::EntryPoint entryPoint,
666 PrimitiveMode mode,
667 GLint first,
668 GLsizei count,
669 GLsizei instanceCount,
670 GLuint baseInstance)
671 {
672 if (!context->getExtensions().baseInstanceEXT)
673 {
674 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
675 return false;
676 }
677
678 return ValidateDrawArraysInstancedBase(context, entryPoint, mode, first, count, instanceCount,
679 baseInstance);
680 }
681
ValidateDrawElementsInstancedBaseInstanceEXT(const Context * context,angle::EntryPoint entryPoint,PrimitiveMode mode,GLsizei count,DrawElementsType type,void const * indices,GLsizei instancecount,GLuint baseinstance)682 bool ValidateDrawElementsInstancedBaseInstanceEXT(const Context *context,
683 angle::EntryPoint entryPoint,
684 PrimitiveMode mode,
685 GLsizei count,
686 DrawElementsType type,
687 void const *indices,
688 GLsizei instancecount,
689 GLuint baseinstance)
690 {
691 if (!context->getExtensions().baseInstanceEXT)
692 {
693 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
694 return false;
695 }
696
697 return ValidateDrawElementsInstancedBase(context, entryPoint, mode, count, type, indices,
698 instancecount, baseinstance);
699 }
700
ValidateDrawElementsInstancedBaseVertexBaseInstanceEXT(const Context * context,angle::EntryPoint entryPoint,PrimitiveMode mode,GLsizei count,DrawElementsType typePacked,const void * indices,GLsizei instancecount,GLint basevertex,GLuint baseinstance)701 bool ValidateDrawElementsInstancedBaseVertexBaseInstanceEXT(const Context *context,
702 angle::EntryPoint entryPoint,
703 PrimitiveMode mode,
704 GLsizei count,
705 DrawElementsType typePacked,
706 const void *indices,
707 GLsizei instancecount,
708 GLint basevertex,
709 GLuint baseinstance)
710 {
711 if (!context->getExtensions().baseInstanceEXT)
712 {
713 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
714 return false;
715 }
716
717 return ValidateDrawElementsInstancedBase(context, entryPoint, mode, count, typePacked, indices,
718 instancecount, baseinstance);
719 }
720
ValidateDrawElementsBaseVertexOES(const Context * context,angle::EntryPoint entryPoint,PrimitiveMode mode,GLsizei count,DrawElementsType type,const void * indices,GLint basevertex)721 bool ValidateDrawElementsBaseVertexOES(const Context *context,
722 angle::EntryPoint entryPoint,
723 PrimitiveMode mode,
724 GLsizei count,
725 DrawElementsType type,
726 const void *indices,
727 GLint basevertex)
728 {
729 if (!context->getExtensions().drawElementsBaseVertexAny())
730 {
731 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
732 return false;
733 }
734
735 return ValidateDrawElementsCommon(context, entryPoint, mode, count, type, indices, 1);
736 }
737
ValidateDrawElementsInstancedBaseVertexOES(const Context * context,angle::EntryPoint entryPoint,PrimitiveMode mode,GLsizei count,DrawElementsType type,const void * indices,GLsizei instancecount,GLint basevertex)738 bool ValidateDrawElementsInstancedBaseVertexOES(const Context *context,
739 angle::EntryPoint entryPoint,
740 PrimitiveMode mode,
741 GLsizei count,
742 DrawElementsType type,
743 const void *indices,
744 GLsizei instancecount,
745 GLint basevertex)
746 {
747 if (!context->getExtensions().drawElementsBaseVertexAny())
748 {
749 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
750 return false;
751 }
752
753 return ValidateDrawElementsInstancedBase(context, entryPoint, mode, count, type, indices,
754 instancecount, 0);
755 }
756
ValidateDrawRangeElementsBaseVertexOES(const Context * context,angle::EntryPoint entryPoint,PrimitiveMode mode,GLuint start,GLuint end,GLsizei count,DrawElementsType type,const void * indices,GLint basevertex)757 bool ValidateDrawRangeElementsBaseVertexOES(const Context *context,
758 angle::EntryPoint entryPoint,
759 PrimitiveMode mode,
760 GLuint start,
761 GLuint end,
762 GLsizei count,
763 DrawElementsType type,
764 const void *indices,
765 GLint basevertex)
766 {
767 if (!context->getExtensions().drawElementsBaseVertexAny())
768 {
769 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
770 return false;
771 }
772
773 if (end < start)
774 {
775 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidElementRange);
776 return false;
777 }
778
779 if (!ValidateDrawElementsCommon(context, entryPoint, mode, count, type, indices, 1))
780 {
781 return false;
782 }
783
784 // Skip range checks for no-op calls.
785 if (count <= 0)
786 {
787 return true;
788 }
789
790 // Note that resolving the index range is a bit slow. We should probably optimize this.
791 IndexRange indexRange;
792 ANGLE_VALIDATION_TRY(context->getState().getVertexArray()->getIndexRange(context, type, count,
793 indices, &indexRange));
794
795 if (indexRange.end > end || indexRange.start < start)
796 {
797 // GL spec says that behavior in this case is undefined - generating an error is fine.
798 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExceedsElementRange);
799 return false;
800 }
801 return true;
802 }
803
804 // GL_KHR_blend_equation_advanced
ValidateBlendBarrierKHR(const Context * context,angle::EntryPoint entryPoint)805 bool ValidateBlendBarrierKHR(const Context *context, angle::EntryPoint entryPoint)
806 {
807 if (context->getClientVersion() < ES_2_0)
808 {
809 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES2Required);
810 return false;
811 }
812
813 if (!context->getExtensions().blendEquationAdvancedKHR)
814 {
815 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kAdvancedBlendExtensionNotEnabled);
816 }
817
818 return true;
819 }
820
ValidateGetGraphicsResetStatusKHR(const Context * context,angle::EntryPoint entryPoint)821 bool ValidateGetGraphicsResetStatusKHR(const Context *context, angle::EntryPoint entryPoint)
822 {
823 if (context->getClientVersion() < ES_2_0)
824 {
825 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES2Required);
826 return false;
827 }
828
829 if (!context->getExtensions().robustnessKHR)
830 {
831 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
832 return false;
833 }
834
835 return true;
836 }
837
ValidateGetnUniformfvKHR(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei bufSize,const GLfloat * params)838 bool ValidateGetnUniformfvKHR(const Context *context,
839 angle::EntryPoint entryPoint,
840 ShaderProgramID programPacked,
841 UniformLocation locationPacked,
842 GLsizei bufSize,
843 const GLfloat *params)
844 {
845 if (context->getClientVersion() < ES_2_0)
846 {
847 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES2Required);
848 return false;
849 }
850
851 if (!context->getExtensions().robustnessKHR)
852 {
853 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
854 return false;
855 }
856
857 return ValidateSizedGetUniform(context, entryPoint, programPacked, locationPacked, bufSize,
858 nullptr);
859 }
860
ValidateGetnUniformivKHR(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei bufSize,const GLint * params)861 bool ValidateGetnUniformivKHR(const Context *context,
862 angle::EntryPoint entryPoint,
863 ShaderProgramID programPacked,
864 UniformLocation locationPacked,
865 GLsizei bufSize,
866 const GLint *params)
867 {
868 if (context->getClientVersion() < ES_2_0)
869 {
870 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES2Required);
871 return false;
872 }
873
874 if (!context->getExtensions().robustnessKHR)
875 {
876 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
877 return false;
878 }
879
880 return ValidateSizedGetUniform(context, entryPoint, programPacked, locationPacked, bufSize,
881 nullptr);
882 }
883
ValidateGetnUniformuivKHR(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei bufSize,const GLuint * params)884 bool ValidateGetnUniformuivKHR(const Context *context,
885 angle::EntryPoint entryPoint,
886 ShaderProgramID programPacked,
887 UniformLocation locationPacked,
888 GLsizei bufSize,
889 const GLuint *params)
890 {
891 // Based on the spec, if ES 3.0 or later is not supported, all references to GetnUniformuiv
892 // should be removed.
893 if (context->getClientVersion() < ES_3_0)
894 {
895 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
896 return false;
897 }
898
899 if (!context->getExtensions().robustnessKHR)
900 {
901 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
902 return false;
903 }
904
905 return ValidateSizedGetUniform(context, entryPoint, programPacked, locationPacked, bufSize,
906 nullptr);
907 }
908
ValidateReadnPixelsKHR(const Context * context,angle::EntryPoint entryPoint,GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,GLsizei bufSize,const void * data)909 bool ValidateReadnPixelsKHR(const Context *context,
910 angle::EntryPoint entryPoint,
911 GLint x,
912 GLint y,
913 GLsizei width,
914 GLsizei height,
915 GLenum format,
916 GLenum type,
917 GLsizei bufSize,
918 const void *data)
919 {
920 if (context->getClientVersion() < ES_2_0)
921 {
922 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES2Required);
923 return false;
924 }
925
926 if (!context->getExtensions().robustnessKHR)
927 {
928 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
929 return false;
930 }
931
932 if (bufSize < 0)
933 {
934 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeBufferSize);
935 return false;
936 }
937
938 return ValidateReadPixelsBase(context, entryPoint, x, y, width, height, format, type, bufSize,
939 nullptr, nullptr, nullptr, data);
940 }
941
ValidateBlendEquationOES(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLenum mode)942 bool ValidateBlendEquationOES(const PrivateState &state,
943 ErrorSet *errors,
944 angle::EntryPoint entryPoint,
945 GLenum mode)
946 {
947 if (!state.getExtensions().blendSubtractOES)
948 {
949 errors->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
950 return false;
951 }
952
953 switch (mode)
954 {
955 case GL_FUNC_ADD_OES:
956 case GL_FUNC_SUBTRACT_OES:
957 case GL_FUNC_REVERSE_SUBTRACT_OES:
958 return true;
959 default:
960 errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidBlendEquation);
961 return false;
962 }
963 }
964
ValidateBlendEquationSeparateiEXT(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLuint buf,GLenum modeRGB,GLenum modeAlpha)965 bool ValidateBlendEquationSeparateiEXT(const PrivateState &state,
966 ErrorSet *errors,
967 angle::EntryPoint entryPoint,
968 GLuint buf,
969 GLenum modeRGB,
970 GLenum modeAlpha)
971 {
972 if (!state.getExtensions().drawBuffersIndexedEXT)
973 {
974 errors->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
975 return false;
976 }
977
978 return ValidateBlendEquationSeparatei(state, errors, entryPoint, buf, modeRGB, modeAlpha);
979 }
980
ValidateBlendEquationiEXT(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLuint buf,GLenum mode)981 bool ValidateBlendEquationiEXT(const PrivateState &state,
982 ErrorSet *errors,
983 angle::EntryPoint entryPoint,
984 GLuint buf,
985 GLenum mode)
986 {
987 if (!state.getExtensions().drawBuffersIndexedEXT)
988 {
989 errors->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
990 return false;
991 }
992
993 return ValidateBlendEquationi(state, errors, entryPoint, buf, mode);
994 }
995
ValidateBlendFuncSeparateiEXT(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLuint buf,GLenum srcRGB,GLenum dstRGB,GLenum srcAlpha,GLenum dstAlpha)996 bool ValidateBlendFuncSeparateiEXT(const PrivateState &state,
997 ErrorSet *errors,
998 angle::EntryPoint entryPoint,
999 GLuint buf,
1000 GLenum srcRGB,
1001 GLenum dstRGB,
1002 GLenum srcAlpha,
1003 GLenum dstAlpha)
1004 {
1005 if (!state.getExtensions().drawBuffersIndexedEXT)
1006 {
1007 errors->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
1008 return false;
1009 }
1010
1011 return ValidateBlendFuncSeparatei(state, errors, entryPoint, buf, srcRGB, dstRGB, srcAlpha,
1012 dstAlpha);
1013 }
1014
ValidateBlendFunciEXT(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLuint buf,GLenum src,GLenum dst)1015 bool ValidateBlendFunciEXT(const PrivateState &state,
1016 ErrorSet *errors,
1017 angle::EntryPoint entryPoint,
1018 GLuint buf,
1019 GLenum src,
1020 GLenum dst)
1021 {
1022 if (!state.getExtensions().drawBuffersIndexedEXT)
1023 {
1024 errors->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
1025 return false;
1026 }
1027
1028 return ValidateBlendFunci(state, errors, entryPoint, buf, src, dst);
1029 }
1030
ValidateColorMaskiEXT(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLuint index,GLboolean r,GLboolean g,GLboolean b,GLboolean a)1031 bool ValidateColorMaskiEXT(const PrivateState &state,
1032 ErrorSet *errors,
1033 angle::EntryPoint entryPoint,
1034 GLuint index,
1035 GLboolean r,
1036 GLboolean g,
1037 GLboolean b,
1038 GLboolean a)
1039 {
1040 if (!state.getExtensions().drawBuffersIndexedEXT)
1041 {
1042 errors->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
1043 return false;
1044 }
1045
1046 return ValidateColorMaski(state, errors, entryPoint, index, r, g, b, a);
1047 }
1048
ValidateDisableiEXT(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLenum target,GLuint index)1049 bool ValidateDisableiEXT(const PrivateState &state,
1050 ErrorSet *errors,
1051 angle::EntryPoint entryPoint,
1052 GLenum target,
1053 GLuint index)
1054 {
1055 if (!state.getExtensions().drawBuffersIndexedEXT)
1056 {
1057 errors->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
1058 return false;
1059 }
1060
1061 return ValidateDisablei(state, errors, entryPoint, target, index);
1062 }
1063
ValidateEnableiEXT(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLenum target,GLuint index)1064 bool ValidateEnableiEXT(const PrivateState &state,
1065 ErrorSet *errors,
1066 angle::EntryPoint entryPoint,
1067 GLenum target,
1068 GLuint index)
1069 {
1070 if (!state.getExtensions().drawBuffersIndexedEXT)
1071 {
1072 errors->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
1073 return false;
1074 }
1075
1076 return ValidateEnablei(state, errors, entryPoint, target, index);
1077 }
1078
ValidateIsEnablediEXT(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLenum target,GLuint index)1079 bool ValidateIsEnablediEXT(const PrivateState &state,
1080 ErrorSet *errors,
1081 angle::EntryPoint entryPoint,
1082 GLenum target,
1083 GLuint index)
1084 {
1085 if (!state.getExtensions().drawBuffersIndexedEXT)
1086 {
1087 errors->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
1088 return false;
1089 }
1090
1091 return ValidateIsEnabledi(state, errors, entryPoint, target, index);
1092 }
1093
ValidateBlendEquationSeparateiOES(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLuint buf,GLenum modeRGB,GLenum modeAlpha)1094 bool ValidateBlendEquationSeparateiOES(const PrivateState &state,
1095 ErrorSet *errors,
1096 angle::EntryPoint entryPoint,
1097 GLuint buf,
1098 GLenum modeRGB,
1099 GLenum modeAlpha)
1100 {
1101 if (!state.getExtensions().drawBuffersIndexedOES)
1102 {
1103 errors->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
1104 return false;
1105 }
1106
1107 return ValidateBlendEquationSeparatei(state, errors, entryPoint, buf, modeRGB, modeAlpha);
1108 }
1109
ValidateBlendEquationiOES(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLuint buf,GLenum mode)1110 bool ValidateBlendEquationiOES(const PrivateState &state,
1111 ErrorSet *errors,
1112 angle::EntryPoint entryPoint,
1113 GLuint buf,
1114 GLenum mode)
1115 {
1116 if (!state.getExtensions().drawBuffersIndexedOES)
1117 {
1118 errors->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
1119 return false;
1120 }
1121
1122 return ValidateBlendEquationi(state, errors, entryPoint, buf, mode);
1123 }
1124
ValidateBlendFuncSeparateiOES(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLuint buf,GLenum srcRGB,GLenum dstRGB,GLenum srcAlpha,GLenum dstAlpha)1125 bool ValidateBlendFuncSeparateiOES(const PrivateState &state,
1126 ErrorSet *errors,
1127 angle::EntryPoint entryPoint,
1128 GLuint buf,
1129 GLenum srcRGB,
1130 GLenum dstRGB,
1131 GLenum srcAlpha,
1132 GLenum dstAlpha)
1133 {
1134 if (!state.getExtensions().drawBuffersIndexedOES)
1135 {
1136 errors->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
1137 return false;
1138 }
1139
1140 return ValidateBlendFuncSeparatei(state, errors, entryPoint, buf, srcRGB, dstRGB, srcAlpha,
1141 dstAlpha);
1142 }
1143
ValidateBlendFunciOES(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLuint buf,GLenum src,GLenum dst)1144 bool ValidateBlendFunciOES(const PrivateState &state,
1145 ErrorSet *errors,
1146 angle::EntryPoint entryPoint,
1147 GLuint buf,
1148 GLenum src,
1149 GLenum dst)
1150 {
1151 if (!state.getExtensions().drawBuffersIndexedOES)
1152 {
1153 errors->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
1154 return false;
1155 }
1156
1157 return ValidateBlendFunci(state, errors, entryPoint, buf, src, dst);
1158 }
1159
ValidateColorMaskiOES(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLuint index,GLboolean r,GLboolean g,GLboolean b,GLboolean a)1160 bool ValidateColorMaskiOES(const PrivateState &state,
1161 ErrorSet *errors,
1162 angle::EntryPoint entryPoint,
1163 GLuint index,
1164 GLboolean r,
1165 GLboolean g,
1166 GLboolean b,
1167 GLboolean a)
1168 {
1169 if (!state.getExtensions().drawBuffersIndexedOES)
1170 {
1171 errors->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
1172 return false;
1173 }
1174
1175 return ValidateColorMaski(state, errors, entryPoint, index, r, g, b, a);
1176 }
1177
ValidateDisableiOES(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLenum target,GLuint index)1178 bool ValidateDisableiOES(const PrivateState &state,
1179 ErrorSet *errors,
1180 angle::EntryPoint entryPoint,
1181 GLenum target,
1182 GLuint index)
1183 {
1184 if (!state.getExtensions().drawBuffersIndexedOES)
1185 {
1186 errors->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
1187 return false;
1188 }
1189
1190 return ValidateDisablei(state, errors, entryPoint, target, index);
1191 }
1192
ValidateEnableiOES(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLenum target,GLuint index)1193 bool ValidateEnableiOES(const PrivateState &state,
1194 ErrorSet *errors,
1195 angle::EntryPoint entryPoint,
1196 GLenum target,
1197 GLuint index)
1198 {
1199 if (!state.getExtensions().drawBuffersIndexedOES)
1200 {
1201 errors->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
1202 return false;
1203 }
1204
1205 return ValidateEnablei(state, errors, entryPoint, target, index);
1206 }
1207
ValidateIsEnablediOES(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLenum target,GLuint index)1208 bool ValidateIsEnablediOES(const PrivateState &state,
1209 ErrorSet *errors,
1210 angle::EntryPoint entryPoint,
1211 GLenum target,
1212 GLuint index)
1213 {
1214 if (!state.getExtensions().drawBuffersIndexedOES)
1215 {
1216 errors->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
1217 return false;
1218 }
1219
1220 return ValidateIsEnabledi(state, errors, entryPoint, target, index);
1221 }
1222
ValidateProvokingVertexANGLE(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,ProvokingVertexConvention provokeModePacked)1223 bool ValidateProvokingVertexANGLE(const PrivateState &state,
1224 ErrorSet *errors,
1225 angle::EntryPoint entryPoint,
1226 ProvokingVertexConvention provokeModePacked)
1227 {
1228 if (!state.getExtensions().provokingVertexANGLE)
1229 {
1230 errors->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
1231 return false;
1232 }
1233
1234 switch (provokeModePacked)
1235 {
1236 case ProvokingVertexConvention::FirstVertexConvention:
1237 case ProvokingVertexConvention::LastVertexConvention:
1238 break;
1239 default:
1240 errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidProvokingVertex);
1241 return false;
1242 }
1243
1244 return true;
1245 }
1246
ValidateGetInteger64vEXT(const Context * context,angle::EntryPoint entryPoint,GLenum pname,const GLint64 * data)1247 bool ValidateGetInteger64vEXT(const Context *context,
1248 angle::EntryPoint entryPoint,
1249 GLenum pname,
1250 const GLint64 *data)
1251 {
1252 if (!context->getExtensions().disjointTimerQueryEXT)
1253 {
1254 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1255 return false;
1256 }
1257
1258 GLenum nativeType = GL_NONE;
1259 unsigned int numParams = 0;
1260 if (!ValidateStateQuery(context, entryPoint, pname, &nativeType, &numParams))
1261 {
1262 return false;
1263 }
1264
1265 return true;
1266 }
1267
ValidateCopyImageSubDataEXT(const Context * context,angle::EntryPoint entryPoint,GLuint srcName,GLenum srcTarget,GLint srcLevel,GLint srcX,GLint srcY,GLint srcZ,GLuint dstName,GLenum dstTarget,GLint dstLevel,GLint dstX,GLint dstY,GLint dstZ,GLsizei srcWidth,GLsizei srcHeight,GLsizei srcDepth)1268 bool ValidateCopyImageSubDataEXT(const Context *context,
1269 angle::EntryPoint entryPoint,
1270 GLuint srcName,
1271 GLenum srcTarget,
1272 GLint srcLevel,
1273 GLint srcX,
1274 GLint srcY,
1275 GLint srcZ,
1276 GLuint dstName,
1277 GLenum dstTarget,
1278 GLint dstLevel,
1279 GLint dstX,
1280 GLint dstY,
1281 GLint dstZ,
1282 GLsizei srcWidth,
1283 GLsizei srcHeight,
1284 GLsizei srcDepth)
1285 {
1286 if (!context->getExtensions().copyImageEXT)
1287 {
1288 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1289 return false;
1290 }
1291
1292 return ValidateCopyImageSubDataBase(context, entryPoint, srcName, srcTarget, srcLevel, srcX,
1293 srcY, srcZ, dstName, dstTarget, dstLevel, dstX, dstY, dstZ,
1294 srcWidth, srcHeight, srcDepth);
1295 }
1296
ValidateCopyImageSubDataOES(const Context * context,angle::EntryPoint entryPoint,GLuint srcName,GLenum srcTarget,GLint srcLevel,GLint srcX,GLint srcY,GLint srcZ,GLuint dstName,GLenum dstTarget,GLint dstLevel,GLint dstX,GLint dstY,GLint dstZ,GLsizei srcWidth,GLsizei srcHeight,GLsizei srcDepth)1297 bool ValidateCopyImageSubDataOES(const Context *context,
1298 angle::EntryPoint entryPoint,
1299 GLuint srcName,
1300 GLenum srcTarget,
1301 GLint srcLevel,
1302 GLint srcX,
1303 GLint srcY,
1304 GLint srcZ,
1305 GLuint dstName,
1306 GLenum dstTarget,
1307 GLint dstLevel,
1308 GLint dstX,
1309 GLint dstY,
1310 GLint dstZ,
1311 GLsizei srcWidth,
1312 GLsizei srcHeight,
1313 GLsizei srcDepth)
1314 {
1315 if (!context->getExtensions().copyImageOES)
1316 {
1317 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1318 return false;
1319 }
1320
1321 return ValidateCopyImageSubDataBase(context, entryPoint, srcName, srcTarget, srcLevel, srcX,
1322 srcY, srcZ, dstName, dstTarget, dstLevel, dstX, dstY, dstZ,
1323 srcWidth, srcHeight, srcDepth);
1324 }
1325
ValidateBufferStorageMemEXT(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLsizeiptr size,MemoryObjectID memory,GLuint64 offset)1326 bool ValidateBufferStorageMemEXT(const Context *context,
1327 angle::EntryPoint entryPoint,
1328 TextureType target,
1329 GLsizeiptr size,
1330 MemoryObjectID memory,
1331 GLuint64 offset)
1332 {
1333 if (!context->getExtensions().memoryObjectEXT)
1334 {
1335 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1336 return false;
1337 }
1338
1339 UNIMPLEMENTED();
1340 return false;
1341 }
1342
ValidateCreateMemoryObjectsEXT(const Context * context,angle::EntryPoint entryPoint,GLsizei n,const MemoryObjectID * memoryObjects)1343 bool ValidateCreateMemoryObjectsEXT(const Context *context,
1344 angle::EntryPoint entryPoint,
1345 GLsizei n,
1346 const MemoryObjectID *memoryObjects)
1347 {
1348 if (!context->getExtensions().memoryObjectEXT)
1349 {
1350 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1351 return false;
1352 }
1353
1354 return ValidateGenOrDelete(context, entryPoint, n);
1355 }
1356
ValidateDeleteMemoryObjectsEXT(const Context * context,angle::EntryPoint entryPoint,GLsizei n,const MemoryObjectID * memoryObjects)1357 bool ValidateDeleteMemoryObjectsEXT(const Context *context,
1358 angle::EntryPoint entryPoint,
1359 GLsizei n,
1360 const MemoryObjectID *memoryObjects)
1361 {
1362 if (!context->getExtensions().memoryObjectEXT)
1363 {
1364 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1365 return false;
1366 }
1367
1368 return ValidateGenOrDelete(context, entryPoint, n);
1369 }
1370
ValidateGetMemoryObjectParameterivEXT(const Context * context,angle::EntryPoint entryPoint,MemoryObjectID memoryObject,GLenum pname,const GLint * params)1371 bool ValidateGetMemoryObjectParameterivEXT(const Context *context,
1372 angle::EntryPoint entryPoint,
1373 MemoryObjectID memoryObject,
1374 GLenum pname,
1375 const GLint *params)
1376 {
1377 if (!context->getExtensions().memoryObjectEXT)
1378 {
1379 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1380 return false;
1381 }
1382
1383 const MemoryObject *memory = context->getMemoryObject(memoryObject);
1384 if (memory == nullptr)
1385 {
1386 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidMemoryObject);
1387 }
1388
1389 if (!IsValidMemoryObjectParamater(context, entryPoint, pname))
1390 {
1391 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidMemoryObjectParameter);
1392 return false;
1393 }
1394
1395 return true;
1396 }
1397
ValidateGetUnsignedBytevEXT(const Context * context,angle::EntryPoint entryPoint,GLenum pname,const GLubyte * data)1398 bool ValidateGetUnsignedBytevEXT(const Context *context,
1399 angle::EntryPoint entryPoint,
1400 GLenum pname,
1401 const GLubyte *data)
1402 {
1403 if (!context->getExtensions().memoryObjectEXT && !context->getExtensions().semaphoreEXT)
1404 {
1405 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1406 return false;
1407 }
1408
1409 UNIMPLEMENTED();
1410 return false;
1411 }
1412
ValidateGetUnsignedBytei_vEXT(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLuint index,const GLubyte * data)1413 bool ValidateGetUnsignedBytei_vEXT(const Context *context,
1414 angle::EntryPoint entryPoint,
1415 GLenum target,
1416 GLuint index,
1417 const GLubyte *data)
1418 {
1419 if (!context->getExtensions().memoryObjectEXT && !context->getExtensions().semaphoreEXT)
1420 {
1421 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1422 return false;
1423 }
1424
1425 UNIMPLEMENTED();
1426 return false;
1427 }
1428
ValidateIsMemoryObjectEXT(const Context * context,angle::EntryPoint entryPoint,MemoryObjectID memoryObject)1429 bool ValidateIsMemoryObjectEXT(const Context *context,
1430 angle::EntryPoint entryPoint,
1431 MemoryObjectID memoryObject)
1432 {
1433 if (!context->getExtensions().memoryObjectEXT)
1434 {
1435 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1436 return false;
1437 }
1438
1439 return true;
1440 }
1441
ValidateMemoryObjectParameterivEXT(const Context * context,angle::EntryPoint entryPoint,MemoryObjectID memoryObject,GLenum pname,const GLint * params)1442 bool ValidateMemoryObjectParameterivEXT(const Context *context,
1443 angle::EntryPoint entryPoint,
1444 MemoryObjectID memoryObject,
1445 GLenum pname,
1446 const GLint *params)
1447 {
1448 if (!context->getExtensions().memoryObjectEXT)
1449 {
1450 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1451 return false;
1452 }
1453
1454 const MemoryObject *memory = context->getMemoryObject(memoryObject);
1455 if (memory == nullptr)
1456 {
1457 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidMemoryObject);
1458 return false;
1459 }
1460
1461 if (memory->isImmutable())
1462 {
1463 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kImmutableMemoryObject);
1464 return false;
1465 }
1466
1467 if (!IsValidMemoryObjectParamater(context, entryPoint, pname))
1468 {
1469 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidMemoryObjectParameter);
1470 return false;
1471 }
1472
1473 return true;
1474 }
1475
ValidateTexStorageMem2DEXT(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLsizei levels,GLenum internalFormat,GLsizei width,GLsizei height,MemoryObjectID memory,GLuint64 offset)1476 bool ValidateTexStorageMem2DEXT(const Context *context,
1477 angle::EntryPoint entryPoint,
1478 TextureType target,
1479 GLsizei levels,
1480 GLenum internalFormat,
1481 GLsizei width,
1482 GLsizei height,
1483 MemoryObjectID memory,
1484 GLuint64 offset)
1485 {
1486 if (!context->getExtensions().memoryObjectEXT)
1487 {
1488 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1489 return false;
1490 }
1491
1492 if (context->getClientMajorVersion() < 3)
1493 {
1494 return ValidateES2TexStorageParametersBase(context, entryPoint, target, levels,
1495 internalFormat, width, height);
1496 }
1497
1498 ASSERT(context->getClientMajorVersion() >= 3);
1499 return ValidateES3TexStorage2DParameters(context, entryPoint, target, levels, internalFormat,
1500 width, height, 1);
1501 }
1502
ValidateTexStorageMem3DEXT(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLsizei levels,GLenum internalFormat,GLsizei width,GLsizei height,GLsizei depth,MemoryObjectID memory,GLuint64 offset)1503 bool ValidateTexStorageMem3DEXT(const Context *context,
1504 angle::EntryPoint entryPoint,
1505 TextureType target,
1506 GLsizei levels,
1507 GLenum internalFormat,
1508 GLsizei width,
1509 GLsizei height,
1510 GLsizei depth,
1511 MemoryObjectID memory,
1512 GLuint64 offset)
1513 {
1514 if (!context->getExtensions().memoryObjectEXT)
1515 {
1516 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1517 return false;
1518 }
1519
1520 UNIMPLEMENTED();
1521 return false;
1522 }
1523
ValidateImportMemoryFdEXT(const Context * context,angle::EntryPoint entryPoint,MemoryObjectID memory,GLuint64 size,HandleType handleType,GLint fd)1524 bool ValidateImportMemoryFdEXT(const Context *context,
1525 angle::EntryPoint entryPoint,
1526 MemoryObjectID memory,
1527 GLuint64 size,
1528 HandleType handleType,
1529 GLint fd)
1530 {
1531 if (!context->getExtensions().memoryObjectFdEXT)
1532 {
1533 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1534 return false;
1535 }
1536
1537 switch (handleType)
1538 {
1539 case HandleType::OpaqueFd:
1540 break;
1541 default:
1542 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidHandleType);
1543 return false;
1544 }
1545
1546 return true;
1547 }
1548
ValidateImportMemoryZirconHandleANGLE(const Context * context,angle::EntryPoint entryPoint,MemoryObjectID memory,GLuint64 size,HandleType handleType,GLuint handle)1549 bool ValidateImportMemoryZirconHandleANGLE(const Context *context,
1550 angle::EntryPoint entryPoint,
1551 MemoryObjectID memory,
1552 GLuint64 size,
1553 HandleType handleType,
1554 GLuint handle)
1555 {
1556 if (!context->getExtensions().memoryObjectFuchsiaANGLE)
1557 {
1558 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1559 return false;
1560 }
1561
1562 switch (handleType)
1563 {
1564 case HandleType::ZirconVmo:
1565 break;
1566 default:
1567 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidHandleType);
1568 return false;
1569 }
1570
1571 return true;
1572 }
1573
ValidateDeleteSemaphoresEXT(const Context * context,angle::EntryPoint entryPoint,GLsizei n,const SemaphoreID * semaphores)1574 bool ValidateDeleteSemaphoresEXT(const Context *context,
1575 angle::EntryPoint entryPoint,
1576 GLsizei n,
1577 const SemaphoreID *semaphores)
1578 {
1579 if (!context->getExtensions().semaphoreEXT)
1580 {
1581 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1582 return false;
1583 }
1584
1585 return ValidateGenOrDelete(context, entryPoint, n);
1586 }
1587
ValidateGenSemaphoresEXT(const Context * context,angle::EntryPoint entryPoint,GLsizei n,const SemaphoreID * semaphores)1588 bool ValidateGenSemaphoresEXT(const Context *context,
1589 angle::EntryPoint entryPoint,
1590 GLsizei n,
1591 const SemaphoreID *semaphores)
1592 {
1593 if (!context->getExtensions().semaphoreEXT)
1594 {
1595 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1596 return false;
1597 }
1598
1599 return ValidateGenOrDelete(context, entryPoint, n);
1600 }
1601
ValidateGetSemaphoreParameterui64vEXT(const Context * context,angle::EntryPoint entryPoint,SemaphoreID semaphore,GLenum pname,const GLuint64 * params)1602 bool ValidateGetSemaphoreParameterui64vEXT(const Context *context,
1603 angle::EntryPoint entryPoint,
1604 SemaphoreID semaphore,
1605 GLenum pname,
1606 const GLuint64 *params)
1607 {
1608 if (!context->getExtensions().semaphoreEXT)
1609 {
1610 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1611 return false;
1612 }
1613
1614 UNIMPLEMENTED();
1615 return false;
1616 }
1617
ValidateIsSemaphoreEXT(const Context * context,angle::EntryPoint entryPoint,SemaphoreID semaphore)1618 bool ValidateIsSemaphoreEXT(const Context *context,
1619 angle::EntryPoint entryPoint,
1620 SemaphoreID semaphore)
1621 {
1622 if (!context->getExtensions().semaphoreEXT)
1623 {
1624 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1625 return false;
1626 }
1627
1628 return true;
1629 }
1630
ValidateSemaphoreParameterui64vEXT(const Context * context,angle::EntryPoint entryPoint,SemaphoreID semaphore,GLenum pname,const GLuint64 * params)1631 bool ValidateSemaphoreParameterui64vEXT(const Context *context,
1632 angle::EntryPoint entryPoint,
1633 SemaphoreID semaphore,
1634 GLenum pname,
1635 const GLuint64 *params)
1636 {
1637 if (!context->getExtensions().semaphoreEXT)
1638 {
1639 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1640 return false;
1641 }
1642
1643 UNIMPLEMENTED();
1644 return false;
1645 }
1646
ValidateSignalSemaphoreEXT(const Context * context,angle::EntryPoint entryPoint,SemaphoreID semaphore,GLuint numBufferBarriers,const BufferID * buffers,GLuint numTextureBarriers,const TextureID * textures,const GLenum * dstLayouts)1647 bool ValidateSignalSemaphoreEXT(const Context *context,
1648 angle::EntryPoint entryPoint,
1649 SemaphoreID semaphore,
1650 GLuint numBufferBarriers,
1651 const BufferID *buffers,
1652 GLuint numTextureBarriers,
1653 const TextureID *textures,
1654 const GLenum *dstLayouts)
1655 {
1656 if (!context->getExtensions().semaphoreEXT)
1657 {
1658 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1659 return false;
1660 }
1661
1662 for (GLuint i = 0; i < numBufferBarriers; ++i)
1663 {
1664 if (!context->getBuffer(buffers[i]))
1665 {
1666 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidBufferName);
1667 return false;
1668 }
1669 }
1670
1671 for (GLuint i = 0; i < numTextureBarriers; ++i)
1672 {
1673 if (!context->getTexture(textures[i]))
1674 {
1675 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidTextureName);
1676 return false;
1677 }
1678 if (!IsValidImageLayout(FromGLenum<ImageLayout>(dstLayouts[i])))
1679 {
1680 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidImageLayout);
1681 return false;
1682 }
1683 }
1684
1685 return true;
1686 }
1687
ValidateWaitSemaphoreEXT(const Context * context,angle::EntryPoint entryPoint,SemaphoreID semaphore,GLuint numBufferBarriers,const BufferID * buffers,GLuint numTextureBarriers,const TextureID * textures,const GLenum * srcLayouts)1688 bool ValidateWaitSemaphoreEXT(const Context *context,
1689 angle::EntryPoint entryPoint,
1690 SemaphoreID semaphore,
1691 GLuint numBufferBarriers,
1692 const BufferID *buffers,
1693 GLuint numTextureBarriers,
1694 const TextureID *textures,
1695 const GLenum *srcLayouts)
1696 {
1697 if (!context->getExtensions().semaphoreEXT)
1698 {
1699 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1700 return false;
1701 }
1702
1703 for (GLuint i = 0; i < numBufferBarriers; ++i)
1704 {
1705 if (!context->getBuffer(buffers[i]))
1706 {
1707 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidBufferName);
1708 return false;
1709 }
1710 }
1711
1712 for (GLuint i = 0; i < numTextureBarriers; ++i)
1713 {
1714 if (!context->getTexture(textures[i]))
1715 {
1716 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidTextureName);
1717 return false;
1718 }
1719 if (!IsValidImageLayout(FromGLenum<ImageLayout>(srcLayouts[i])))
1720 {
1721 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidImageLayout);
1722 return false;
1723 }
1724 }
1725
1726 return true;
1727 }
1728
ValidateImportSemaphoreFdEXT(const Context * context,angle::EntryPoint entryPoint,SemaphoreID semaphore,HandleType handleType,GLint fd)1729 bool ValidateImportSemaphoreFdEXT(const Context *context,
1730 angle::EntryPoint entryPoint,
1731 SemaphoreID semaphore,
1732 HandleType handleType,
1733 GLint fd)
1734 {
1735 if (!context->getExtensions().semaphoreFdEXT)
1736 {
1737 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1738 return false;
1739 }
1740
1741 switch (handleType)
1742 {
1743 case HandleType::OpaqueFd:
1744 break;
1745 default:
1746 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidHandleType);
1747 return false;
1748 }
1749
1750 return true;
1751 }
1752
ValidateGetTexParameterIivOES(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLenum pname,const GLint * params)1753 bool ValidateGetTexParameterIivOES(const Context *context,
1754 angle::EntryPoint entryPoint,
1755 TextureType target,
1756 GLenum pname,
1757 const GLint *params)
1758 {
1759 if (context->getClientMajorVersion() < 3)
1760 {
1761 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
1762 }
1763
1764 if (!context->getExtensions().textureBorderClampOES)
1765 {
1766 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1767 return false;
1768 }
1769 return ValidateGetTexParameterBase(context, entryPoint, target, pname, nullptr);
1770 }
1771
ValidateGetTexParameterIuivOES(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLenum pname,const GLuint * params)1772 bool ValidateGetTexParameterIuivOES(const Context *context,
1773 angle::EntryPoint entryPoint,
1774 TextureType target,
1775 GLenum pname,
1776 const GLuint *params)
1777 {
1778 if (context->getClientMajorVersion() < 3)
1779 {
1780 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
1781 }
1782
1783 if (!context->getExtensions().textureBorderClampOES)
1784 {
1785 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1786 }
1787 return ValidateGetTexParameterBase(context, entryPoint, target, pname, nullptr);
1788 }
1789
ValidateTexParameterIivOES(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLenum pname,const GLint * params)1790 bool ValidateTexParameterIivOES(const Context *context,
1791 angle::EntryPoint entryPoint,
1792 TextureType target,
1793 GLenum pname,
1794 const GLint *params)
1795 {
1796 if (context->getClientMajorVersion() < 3)
1797 {
1798 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
1799 }
1800
1801 if (!context->getExtensions().textureBorderClampOES)
1802 {
1803 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1804 return false;
1805 }
1806 return ValidateTexParameterBase(context, entryPoint, target, pname, -1, true, params);
1807 }
1808
ValidateTexParameterIuivOES(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLenum pname,const GLuint * params)1809 bool ValidateTexParameterIuivOES(const Context *context,
1810 angle::EntryPoint entryPoint,
1811 TextureType target,
1812 GLenum pname,
1813 const GLuint *params)
1814 {
1815 if (context->getClientMajorVersion() < 3)
1816 {
1817 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
1818 }
1819
1820 if (!context->getExtensions().textureBorderClampOES)
1821 {
1822 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1823 return false;
1824 }
1825
1826 return ValidateTexParameterBase(context, entryPoint, target, pname, -1, true, params);
1827 }
1828
ValidateGetSamplerParameterIivOES(const Context * context,angle::EntryPoint entryPoint,SamplerID sampler,GLenum pname,const GLint * params)1829 bool ValidateGetSamplerParameterIivOES(const Context *context,
1830 angle::EntryPoint entryPoint,
1831 SamplerID sampler,
1832 GLenum pname,
1833 const GLint *params)
1834 {
1835 if (context->getClientMajorVersion() < 3)
1836 {
1837 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
1838 }
1839
1840 if (!context->getExtensions().textureBorderClampOES)
1841 {
1842 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1843 return false;
1844 }
1845 return ValidateGetSamplerParameterBase(context, entryPoint, sampler, pname, nullptr);
1846 }
1847
ValidateGetSamplerParameterIuivOES(const Context * context,angle::EntryPoint entryPoint,SamplerID sampler,GLenum pname,const GLuint * params)1848 bool ValidateGetSamplerParameterIuivOES(const Context *context,
1849 angle::EntryPoint entryPoint,
1850 SamplerID sampler,
1851 GLenum pname,
1852 const GLuint *params)
1853 {
1854 if (context->getClientMajorVersion() < 3)
1855 {
1856 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
1857 }
1858
1859 if (!context->getExtensions().textureBorderClampOES)
1860 {
1861 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1862 return false;
1863 }
1864 return ValidateGetSamplerParameterBase(context, entryPoint, sampler, pname, nullptr);
1865 }
1866
ValidateSamplerParameterIivOES(const Context * context,angle::EntryPoint entryPoint,SamplerID sampler,GLenum pname,const GLint * params)1867 bool ValidateSamplerParameterIivOES(const Context *context,
1868 angle::EntryPoint entryPoint,
1869 SamplerID sampler,
1870 GLenum pname,
1871 const GLint *params)
1872 {
1873 if (context->getClientMajorVersion() < 3)
1874 {
1875 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
1876 }
1877
1878 if (!context->getExtensions().textureBorderClampOES)
1879 {
1880 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1881 return false;
1882 }
1883 return ValidateSamplerParameterBase(context, entryPoint, sampler, pname, -1, true, params);
1884 }
1885
ValidateSamplerParameterIuivOES(const Context * context,angle::EntryPoint entryPoint,SamplerID sampler,GLenum pname,const GLuint * params)1886 bool ValidateSamplerParameterIuivOES(const Context *context,
1887 angle::EntryPoint entryPoint,
1888 SamplerID sampler,
1889 GLenum pname,
1890 const GLuint *params)
1891 {
1892 if (context->getClientMajorVersion() < 3)
1893 {
1894 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
1895 }
1896
1897 if (!context->getExtensions().textureBorderClampOES)
1898 {
1899 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1900 return false;
1901 }
1902 return ValidateSamplerParameterBase(context, entryPoint, sampler, pname, -1, true, params);
1903 }
1904
ValidateGetSamplerParameterIivEXT(const Context * context,angle::EntryPoint entryPoint,SamplerID samplerPacked,GLenum pname,const GLint * params)1905 bool ValidateGetSamplerParameterIivEXT(const Context *context,
1906 angle::EntryPoint entryPoint,
1907 SamplerID samplerPacked,
1908 GLenum pname,
1909 const GLint *params)
1910 {
1911 if (context->getClientMajorVersion() < 3)
1912 {
1913 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
1914 }
1915
1916 if (!context->getExtensions().textureBorderClampEXT)
1917 {
1918 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1919 return false;
1920 }
1921 return ValidateGetSamplerParameterBase(context, entryPoint, samplerPacked, pname, nullptr);
1922 }
1923
ValidateGetSamplerParameterIuivEXT(const Context * context,angle::EntryPoint entryPoint,SamplerID samplerPacked,GLenum pname,const GLuint * params)1924 bool ValidateGetSamplerParameterIuivEXT(const Context *context,
1925 angle::EntryPoint entryPoint,
1926 SamplerID samplerPacked,
1927 GLenum pname,
1928 const GLuint *params)
1929 {
1930 if (context->getClientMajorVersion() < 3)
1931 {
1932 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
1933 }
1934
1935 if (!context->getExtensions().textureBorderClampEXT)
1936 {
1937 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1938 return false;
1939 }
1940 return ValidateGetSamplerParameterBase(context, entryPoint, samplerPacked, pname, nullptr);
1941 }
1942
ValidateGetTexParameterIivEXT(const Context * context,angle::EntryPoint entryPoint,TextureType targetPacked,GLenum pname,const GLint * params)1943 bool ValidateGetTexParameterIivEXT(const Context *context,
1944 angle::EntryPoint entryPoint,
1945 TextureType targetPacked,
1946 GLenum pname,
1947 const GLint *params)
1948 {
1949 if (context->getClientMajorVersion() < 3)
1950 {
1951 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
1952 }
1953
1954 if (!context->getExtensions().textureBorderClampEXT)
1955 {
1956 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1957 return false;
1958 }
1959 return ValidateGetTexParameterBase(context, entryPoint, targetPacked, pname, nullptr);
1960 }
1961
ValidateGetTexParameterIuivEXT(const Context * context,angle::EntryPoint entryPoint,TextureType targetPacked,GLenum pname,const GLuint * params)1962 bool ValidateGetTexParameterIuivEXT(const Context *context,
1963 angle::EntryPoint entryPoint,
1964 TextureType targetPacked,
1965 GLenum pname,
1966 const GLuint *params)
1967 {
1968 if (context->getClientMajorVersion() < 3)
1969 {
1970 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
1971 }
1972
1973 if (!context->getExtensions().textureBorderClampEXT)
1974 {
1975 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1976 return false;
1977 }
1978 return ValidateGetTexParameterBase(context, entryPoint, targetPacked, pname, nullptr);
1979 }
1980
ValidateSamplerParameterIivEXT(const Context * context,angle::EntryPoint entryPoint,SamplerID samplerPacked,GLenum pname,const GLint * param)1981 bool ValidateSamplerParameterIivEXT(const Context *context,
1982 angle::EntryPoint entryPoint,
1983 SamplerID samplerPacked,
1984 GLenum pname,
1985 const GLint *param)
1986 {
1987 if (context->getClientMajorVersion() < 3)
1988 {
1989 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
1990 }
1991
1992 if (!context->getExtensions().textureBorderClampEXT)
1993 {
1994 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1995 return false;
1996 }
1997 return ValidateSamplerParameterBase(context, entryPoint, samplerPacked, pname, -1, true, param);
1998 }
1999
ValidateSamplerParameterIuivEXT(const Context * context,angle::EntryPoint entryPoint,SamplerID samplerPacked,GLenum pname,const GLuint * param)2000 bool ValidateSamplerParameterIuivEXT(const Context *context,
2001 angle::EntryPoint entryPoint,
2002 SamplerID samplerPacked,
2003 GLenum pname,
2004 const GLuint *param)
2005 {
2006 if (context->getClientMajorVersion() < 3)
2007 {
2008 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
2009 }
2010
2011 if (!context->getExtensions().textureBorderClampEXT)
2012 {
2013 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
2014 return false;
2015 }
2016 return ValidateSamplerParameterBase(context, entryPoint, samplerPacked, pname, -1, true, param);
2017 }
2018
ValidateTexParameterIivEXT(const Context * context,angle::EntryPoint entryPoint,TextureType targetPacked,GLenum pname,const GLint * params)2019 bool ValidateTexParameterIivEXT(const Context *context,
2020 angle::EntryPoint entryPoint,
2021 TextureType targetPacked,
2022 GLenum pname,
2023 const GLint *params)
2024 {
2025 if (context->getClientMajorVersion() < 3)
2026 {
2027 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
2028 }
2029
2030 if (!context->getExtensions().textureBorderClampEXT)
2031 {
2032 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
2033 return false;
2034 }
2035 return ValidateTexParameterBase(context, entryPoint, targetPacked, pname, -1, true, params);
2036 }
2037
ValidateTexParameterIuivEXT(const Context * context,angle::EntryPoint entryPoint,TextureType targetPacked,GLenum pname,const GLuint * params)2038 bool ValidateTexParameterIuivEXT(const Context *context,
2039 angle::EntryPoint entryPoint,
2040 TextureType targetPacked,
2041 GLenum pname,
2042 const GLuint *params)
2043 {
2044 if (context->getClientMajorVersion() < 3)
2045 {
2046 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
2047 }
2048
2049 if (!context->getExtensions().textureBorderClampEXT)
2050 {
2051 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
2052 return false;
2053 }
2054 return ValidateTexParameterBase(context, entryPoint, targetPacked, pname, -1, true, params);
2055 }
2056
ValidateImportSemaphoreZirconHandleANGLE(const Context * context,angle::EntryPoint entryPoint,SemaphoreID semaphore,HandleType handleType,GLuint handle)2057 bool ValidateImportSemaphoreZirconHandleANGLE(const Context *context,
2058 angle::EntryPoint entryPoint,
2059 SemaphoreID semaphore,
2060 HandleType handleType,
2061 GLuint handle)
2062 {
2063 if (!context->getExtensions().semaphoreFuchsiaANGLE)
2064 {
2065 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
2066 return false;
2067 }
2068
2069 switch (handleType)
2070 {
2071 case HandleType::ZirconEvent:
2072 break;
2073 default:
2074 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidHandleType);
2075 return false;
2076 }
2077
2078 return true;
2079 }
2080
2081 namespace
2082 {
2083 enum class PLSExpectedStatus
2084 {
2085 Inactive,
2086 Active,
2087 Any
2088 };
2089
ValidatePLSCommon(const Context * context,angle::EntryPoint entryPoint,PLSExpectedStatus expectedStatus)2090 bool ValidatePLSCommon(const Context *context,
2091 angle::EntryPoint entryPoint,
2092 PLSExpectedStatus expectedStatus)
2093 {
2094 // Check that the pixel local storage extension is enabled at all.
2095 if (!context->getExtensions().shaderPixelLocalStorageANGLE)
2096 {
2097 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPLSExtensionNotEnabled);
2098 return false;
2099 }
2100
2101 Framebuffer *framebuffer = context->getState().getDrawFramebuffer();
2102 if (expectedStatus != PLSExpectedStatus::Active)
2103 {
2104 // INVALID_FRAMEBUFFER_OPERATION is generated if the default framebuffer object name 0 is
2105 // bound to DRAW_FRAMEBUFFER.
2106 if (framebuffer->id().value == 0)
2107 {
2108 ANGLE_VALIDATION_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION, kPLSDefaultFramebufferBound);
2109 return false;
2110 }
2111 }
2112
2113 // INVALID_FRAMEBUFFER_OPERATION is generated if pixel local storage on the draw framebuffer is
2114 // in an interrupted state.
2115 const PixelLocalStorage *pls = framebuffer->peekPixelLocalStorage();
2116 if (pls != nullptr && pls->interruptCount() != 0)
2117 {
2118 ANGLE_VALIDATION_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION, kPLSInterrupted);
2119 return false;
2120 }
2121
2122 if (expectedStatus == PLSExpectedStatus::Active)
2123 {
2124 // INVALID_OPERATION is generated if PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE is zero.
2125 if (context->getState().getPixelLocalStorageActivePlanes() == 0)
2126 {
2127 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPLSInactive);
2128 return false;
2129 }
2130 }
2131 else
2132 {
2133 // PLSExpectedStatus::Inactive is validated by the allow list.
2134 ASSERT(expectedStatus != PLSExpectedStatus::Inactive ||
2135 context->getState().getPixelLocalStorageActivePlanes() == 0);
2136 }
2137
2138 return true;
2139 }
2140
ValidatePLSCommon(const Context * context,angle::EntryPoint entryPoint,GLint plane,PLSExpectedStatus expectedStatus)2141 bool ValidatePLSCommon(const Context *context,
2142 angle::EntryPoint entryPoint,
2143 GLint plane,
2144 PLSExpectedStatus expectedStatus)
2145 {
2146 if (!ValidatePLSCommon(context, entryPoint, expectedStatus))
2147 {
2148 return false;
2149 }
2150
2151 // INVALID_VALUE is generated if <plane> < 0 or <plane> >= MAX_PIXEL_LOCAL_STORAGE_PLANES_ANGLE.
2152 if (plane < 0)
2153 {
2154 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kPLSPlaneLessThanZero);
2155 return false;
2156 }
2157 if (plane >= static_cast<GLint>(context->getCaps().maxPixelLocalStoragePlanes))
2158 {
2159 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kPLSPlaneOutOfRange);
2160 return false;
2161 }
2162
2163 return true;
2164 }
2165
ValidatePLSInternalformat(const Context * context,angle::EntryPoint entryPoint,GLenum internalformat)2166 bool ValidatePLSInternalformat(const Context *context,
2167 angle::EntryPoint entryPoint,
2168 GLenum internalformat)
2169 {
2170 // INVALID_ENUM is generated if <internalformat> is not one of the acceptable values in Table
2171 // X.2, or NONE.
2172 switch (internalformat)
2173 {
2174 case GL_RGBA8:
2175 case GL_RGBA8I:
2176 case GL_RGBA8UI:
2177 case GL_R32F:
2178 case GL_R32UI:
2179 return true;
2180 default:
2181 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kPLSInvalidInternalformat);
2182 return false;
2183 }
2184 }
2185
ValidatePLSTextureType(const Context * context,angle::EntryPoint entryPoint,Texture * tex,size_t * textureDepth)2186 bool ValidatePLSTextureType(const Context *context,
2187 angle::EntryPoint entryPoint,
2188 Texture *tex,
2189 size_t *textureDepth)
2190 {
2191 // INVALID_OPERATION is generated if <backingtexture> is nonzero
2192 // and not of type TEXTURE_2D or TEXTURE_2D_ARRAY.
2193 switch (tex->getType())
2194 {
2195 case TextureType::_2D:
2196 *textureDepth = 1;
2197 return true;
2198 case TextureType::_2DArray:
2199 *textureDepth = tex->getDepth(TextureTarget::_2DArray, 0);
2200 return true;
2201 default:
2202 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPLSInvalidTextureType);
2203 return false;
2204 }
2205 }
2206
ValidatePLSActiveBlendFunc(const Context * context,angle::EntryPoint entryPoint,gl::BlendFactorType blendFunc)2207 bool ValidatePLSActiveBlendFunc(const Context *context,
2208 angle::EntryPoint entryPoint,
2209 gl::BlendFactorType blendFunc)
2210 {
2211 // INVALID_OPERATION is generated if BLEND_DST_ALPHA, BLEND_DST_RGB, BLEND_SRC_ALPHA, or
2212 // BLEND_SRC_RGB, for any draw buffer, is a blend function requiring the secondary color input,
2213 // as specified in EXT_blend_func_extended.
2214 ASSERT(context->getState().getExtensions().blendFuncExtendedEXT);
2215 switch (blendFunc)
2216 {
2217 case gl::BlendFactorType::Src1Color:
2218 case gl::BlendFactorType::OneMinusSrc1Color:
2219 case gl::BlendFactorType::Src1Alpha:
2220 case gl::BlendFactorType::OneMinusSrc1Alpha:
2221 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPLSSecondaryBlendEnabled);
2222 return false;
2223 default:
2224 return true;
2225 }
2226 }
ValidatePLSActiveBlendEquation(const Context * context,angle::EntryPoint entryPoint,gl::BlendEquationType blendEquation)2227 bool ValidatePLSActiveBlendEquation(const Context *context,
2228 angle::EntryPoint entryPoint,
2229 gl::BlendEquationType blendEquation)
2230 {
2231 // INVALID_OPERATION is generated if BLEND_EQUATION_RGB and/or BLEND_EQUATION_ALPHA is an
2232 // advanced blend equation defined in KHR_blend_equation_advanced.
2233 ASSERT(context->getState().getExtensions().blendEquationAdvancedKHR);
2234 switch (blendEquation)
2235 {
2236 case gl::BlendEquationType::Multiply:
2237 case gl::BlendEquationType::Screen:
2238 case gl::BlendEquationType::Overlay:
2239 case gl::BlendEquationType::Darken:
2240 case gl::BlendEquationType::Lighten:
2241 case gl::BlendEquationType::Colordodge:
2242 case gl::BlendEquationType::Colorburn:
2243 case gl::BlendEquationType::Hardlight:
2244 case gl::BlendEquationType::Softlight:
2245 case gl::BlendEquationType::Difference:
2246 case gl::BlendEquationType::Exclusion:
2247 case gl::BlendEquationType::HslHue:
2248 case gl::BlendEquationType::HslSaturation:
2249 case gl::BlendEquationType::HslColor:
2250 case gl::BlendEquationType::HslLuminosity:
2251 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPLSAdvancedBlendEnabled);
2252 return false;
2253 default:
2254 return true;
2255 }
2256 }
2257
ValidatePLSLoadOperation(const Context * context,angle::EntryPoint entryPoint,GLenum loadop)2258 bool ValidatePLSLoadOperation(const Context *context, angle::EntryPoint entryPoint, GLenum loadop)
2259 {
2260 // INVALID_ENUM is generated if <loadops>[0..<n>-1] is not one of the Load Operations enumerated
2261 // in Table X.1.
2262 switch (loadop)
2263 {
2264 case GL_LOAD_OP_ZERO_ANGLE:
2265 case GL_LOAD_OP_CLEAR_ANGLE:
2266 case GL_LOAD_OP_LOAD_ANGLE:
2267 case GL_DONT_CARE:
2268 return true;
2269 default:
2270 ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kPLSInvalidLoadOperation, loadop);
2271 return false;
2272 }
2273 }
2274
ValidatePLSStoreOperation(const Context * context,angle::EntryPoint entryPoint,GLenum storeop)2275 bool ValidatePLSStoreOperation(const Context *context, angle::EntryPoint entryPoint, GLenum storeop)
2276 {
2277 // INVALID_ENUM is generated if <storeops>[0..PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE-1] is not
2278 // one of the Store Operations enumerated in Table X.2.
2279 switch (storeop)
2280 {
2281 case GL_STORE_OP_STORE_ANGLE:
2282 case GL_DONT_CARE:
2283 return true;
2284 default:
2285 ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kPLSInvalidStoreOperation, storeop);
2286 return false;
2287 }
2288 }
2289
ValidatePLSQueryCommon(const Context * context,angle::EntryPoint entryPoint,GLsizei paramCount,GLsizei bufSize,const void * params)2290 bool ValidatePLSQueryCommon(const Context *context,
2291 angle::EntryPoint entryPoint,
2292 GLsizei paramCount,
2293 GLsizei bufSize,
2294 const void *params)
2295 {
2296 // INVALID_OPERATION is generated if <bufSize> is not large enough to receive the requested
2297 // parameter.
2298 if (paramCount > bufSize)
2299 {
2300 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInsufficientParams);
2301 return false;
2302 }
2303 // INVALID_VALUE is generated if <params> is NULL.
2304 if (params == nullptr)
2305 {
2306 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kPLSParamsNULL);
2307 return false;
2308 }
2309 return true;
2310 }
2311 } // namespace
2312
ValidateFramebufferMemorylessPixelLocalStorageANGLE(const Context * context,angle::EntryPoint entryPoint,GLint plane,GLenum internalformat)2313 bool ValidateFramebufferMemorylessPixelLocalStorageANGLE(const Context *context,
2314 angle::EntryPoint entryPoint,
2315 GLint plane,
2316 GLenum internalformat)
2317 {
2318 if (!ValidatePLSCommon(context, entryPoint, plane, PLSExpectedStatus::Any))
2319 {
2320 return false;
2321 }
2322
2323 // INVALID_ENUM is generated if <internalformat> is not one of the acceptable values in Table
2324 // X.2, or NONE.
2325 if (internalformat != GL_NONE)
2326 {
2327 if (!ValidatePLSInternalformat(context, entryPoint, internalformat))
2328 {
2329 return false;
2330 }
2331 }
2332
2333 return true;
2334 }
2335
ValidateFramebufferTexturePixelLocalStorageANGLE(const Context * context,angle::EntryPoint entryPoint,GLint plane,TextureID backingtexture,GLint level,GLint layer)2336 bool ValidateFramebufferTexturePixelLocalStorageANGLE(const Context *context,
2337 angle::EntryPoint entryPoint,
2338 GLint plane,
2339 TextureID backingtexture,
2340 GLint level,
2341 GLint layer)
2342 {
2343 if (!ValidatePLSCommon(context, entryPoint, plane, PLSExpectedStatus::Any))
2344 {
2345 return false;
2346 }
2347
2348 if (backingtexture.value != 0)
2349 {
2350 Texture *tex = context->getTexture(backingtexture);
2351
2352 // INVALID_OPERATION is generated if <backingtexture> is not the name of an existing
2353 // immutable texture object, or zero.
2354 if (!tex)
2355 {
2356 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidTextureName);
2357 return false;
2358 }
2359 if (!tex->getImmutableFormat())
2360 {
2361 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kTextureIsNotImmutable);
2362 return false;
2363 }
2364
2365 // INVALID_OPERATION is generated if <backingtexture> is nonzero
2366 // and not of type GL_TEXTURE_2D or GL_TEXTURE_2D_ARRAY.
2367 size_t textureDepth;
2368 if (!ValidatePLSTextureType(context, entryPoint, tex, &textureDepth))
2369 {
2370 return false;
2371 }
2372
2373 // INVALID_VALUE is generated if <backingtexture> is nonzero and <level> < 0.
2374 if (level < 0)
2375 {
2376 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeLevel);
2377 return false;
2378 }
2379
2380 // INVALID_VALUE is generated if <backingtexture> is nonzero and <level> >= the
2381 // immutable number of mipmap levels in <backingtexture>.
2382 if (static_cast<GLuint>(level) >= tex->getImmutableLevels())
2383 {
2384 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kTextureLevelOutOfRange);
2385 return false;
2386 }
2387
2388 // INVALID_VALUE is generated if <backingtexture> is nonzero and <layer> < 0.
2389 if (layer < 0)
2390 {
2391 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeLayer);
2392 return false;
2393 }
2394
2395 // INVALID_VALUE is generated if <backingtexture> is nonzero and <layer> >= the immutable
2396 // number of texture layers in <backingtexture>.
2397 if ((size_t)layer >= textureDepth)
2398 {
2399 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kTextureLayerOutOfRange);
2400 return false;
2401 }
2402
2403 // INVALID_ENUM is generated if <backingtexture> is nonzero and its internalformat is not
2404 // one of the acceptable values in Table X.2.
2405 ASSERT(tex->getImmutableFormat());
2406 GLenum internalformat = tex->getState().getBaseLevelDesc().format.info->internalFormat;
2407 if (!ValidatePLSInternalformat(context, entryPoint, internalformat))
2408 {
2409 return false;
2410 }
2411 }
2412
2413 return true;
2414 }
2415
ValidateFramebufferPixelLocalClearValuefvANGLE(const Context * context,angle::EntryPoint entryPoint,GLint plane,const GLfloat[])2416 bool ValidateFramebufferPixelLocalClearValuefvANGLE(const Context *context,
2417 angle::EntryPoint entryPoint,
2418 GLint plane,
2419 const GLfloat[])
2420 {
2421 return ValidatePLSCommon(context, entryPoint, plane, PLSExpectedStatus::Inactive);
2422 }
2423
ValidateFramebufferPixelLocalClearValueivANGLE(const Context * context,angle::EntryPoint entryPoint,GLint plane,const GLint[])2424 bool ValidateFramebufferPixelLocalClearValueivANGLE(const Context *context,
2425 angle::EntryPoint entryPoint,
2426 GLint plane,
2427 const GLint[])
2428 {
2429 return ValidatePLSCommon(context, entryPoint, plane, PLSExpectedStatus::Inactive);
2430 }
2431
ValidateFramebufferPixelLocalClearValueuivANGLE(const Context * context,angle::EntryPoint entryPoint,GLint plane,const GLuint[])2432 bool ValidateFramebufferPixelLocalClearValueuivANGLE(const Context *context,
2433 angle::EntryPoint entryPoint,
2434 GLint plane,
2435 const GLuint[])
2436 {
2437 return ValidatePLSCommon(context, entryPoint, plane, PLSExpectedStatus::Inactive);
2438 }
2439
ValidateBeginPixelLocalStorageANGLE(const Context * context,angle::EntryPoint entryPoint,GLsizei n,const GLenum loadops[])2440 bool ValidateBeginPixelLocalStorageANGLE(const Context *context,
2441 angle::EntryPoint entryPoint,
2442 GLsizei n,
2443 const GLenum loadops[])
2444 {
2445 if (!ValidatePLSCommon(context, entryPoint, PLSExpectedStatus::Inactive))
2446 {
2447 return false;
2448 }
2449
2450 const State &state = context->getState();
2451 const Framebuffer *framebuffer = state.getDrawFramebuffer();
2452
2453 // INVALID_OPERATION is generated if the value of SAMPLE_BUFFERS is 1 (i.e., if rendering to a
2454 // multisampled framebuffer).
2455 if (framebuffer->getSamples(context) != 0)
2456 {
2457 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPLSMultisamplingEnabled);
2458 return false;
2459 }
2460
2461 // INVALID_OPERATION is generated if DITHER is enabled.
2462 if (state.isDitherEnabled())
2463 {
2464 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPLSDitherEnabled);
2465 return false;
2466 }
2467
2468 // INVALID_OPERATION is generated if RASTERIZER_DISCARD is enabled.
2469 if (state.isRasterizerDiscardEnabled())
2470 {
2471 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPLSRasterizerDiscardEnabled);
2472 return false;
2473 }
2474
2475 // INVALID_OPERATION is generated if TRANSFORM_FEEDBACK_ACTIVE is true.
2476 if (state.isTransformFeedbackActive())
2477 {
2478 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPLSTransformFeedbackActive);
2479 return false;
2480 }
2481
2482 // INVALID_OPERATION is generated if BLEND_DST_ALPHA, BLEND_DST_RGB, BLEND_SRC_ALPHA, or
2483 // BLEND_SRC_RGB, for any draw buffer, is a blend function requiring the secondary color input,
2484 // as specified in EXT_blend_func_extended.
2485 if (state.getExtensions().blendFuncExtendedEXT)
2486 {
2487 for (GLsizei i = 0; i < state.getCaps().maxDrawBuffers; ++i)
2488 {
2489 const BlendStateExt &blend = state.getBlendStateExt();
2490 if (!ValidatePLSActiveBlendFunc(context, entryPoint, blend.getDstAlphaIndexed(i)) ||
2491 !ValidatePLSActiveBlendFunc(context, entryPoint, blend.getDstColorIndexed(i)) ||
2492 !ValidatePLSActiveBlendFunc(context, entryPoint, blend.getSrcAlphaIndexed(i)) ||
2493 !ValidatePLSActiveBlendFunc(context, entryPoint, blend.getSrcColorIndexed(i)))
2494 {
2495 return false;
2496 }
2497 }
2498 }
2499
2500 // INVALID_OPERATION is generated if BLEND_EQUATION_RGB and/or BLEND_EQUATION_ALPHA is an
2501 // advanced blend equation defined in KHR_blend_equation_advanced.
2502 if (state.getExtensions().blendEquationAdvancedKHR)
2503 {
2504 if (!ValidatePLSActiveBlendEquation(context, entryPoint,
2505 state.getBlendStateExt().getEquationColorIndexed(0)) ||
2506 !ValidatePLSActiveBlendEquation(context, entryPoint,
2507 state.getBlendStateExt().getEquationAlphaIndexed(0)))
2508 {
2509 return false;
2510 }
2511 }
2512 // INVALID_VALUE is generated if <n> < 1 or <n> > MAX_PIXEL_LOCAL_STORAGE_PLANES_ANGLE.
2513 if (n < 1)
2514 {
2515 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kPLSPlanesLessThanOne);
2516 return false;
2517 }
2518 if (n > static_cast<GLsizei>(context->getCaps().maxPixelLocalStoragePlanes))
2519 {
2520 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kPLSPlanesOutOfRange);
2521 return false;
2522 }
2523
2524 // INVALID_FRAMEBUFFER_OPERATION is generated if the draw framebuffer has an image attached to
2525 // any color attachment point on or after:
2526 //
2527 // COLOR_ATTACHMENT0 +
2528 // MAX_COLOR_ATTACHMENTS_WITH_ACTIVE_PIXEL_LOCAL_STORAGE_ANGLE
2529 //
2530 const Caps &caps = context->getCaps();
2531 for (int i = caps.maxColorAttachmentsWithActivePixelLocalStorage; i < caps.maxColorAttachments;
2532 ++i)
2533 {
2534 if (framebuffer->getColorAttachment(i))
2535 {
2536 ANGLE_VALIDATION_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION,
2537 kPLSMaxColorAttachmentsExceded);
2538 return false;
2539 }
2540 }
2541
2542 // INVALID_FRAMEBUFFER_OPERATION is generated if the draw framebuffer has an image attached to
2543 // any color attachment point on or after:
2544 //
2545 // COLOR_ATTACHMENT0 + MAX_COMBINED_DRAW_BUFFERS_AND_PIXEL_LOCAL_STORAGE_PLANES_ANGLE - <n>
2546 //
2547 for (GLuint i = caps.maxCombinedDrawBuffersAndPixelLocalStoragePlanes - n;
2548 i < caps.maxColorAttachmentsWithActivePixelLocalStorage; ++i)
2549 {
2550 if (framebuffer->getColorAttachment(i))
2551 {
2552 ANGLE_VALIDATION_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION,
2553 kPLSMaxCombinedDrawBuffersAndPlanesExceded);
2554 return false;
2555 }
2556 }
2557
2558 // INVALID_VALUE is generated if <loadops> is NULL.
2559 if (loadops == nullptr)
2560 {
2561 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kPLSLoadOpsNULL);
2562 return false;
2563 }
2564
2565 const PixelLocalStorage *pls = framebuffer->peekPixelLocalStorage();
2566 bool hasTextureBackedPLSPlanes = false;
2567 Extents textureBackedPLSExtents{};
2568
2569 for (GLsizei i = 0; i < n; ++i)
2570 {
2571 // INVALID_ENUM is generated if <loadops>[0..<n>-1] is not one of the Load Operations
2572 // enumerated in Table X.1.
2573 if (!ValidatePLSLoadOperation(context, entryPoint, loadops[i]))
2574 {
2575 return false;
2576 }
2577
2578 // INVALID_OPERATION is generated if a pixel local storage plane at index [0..<n>-1] is in a
2579 // deinitialized state.
2580 if (pls == nullptr || pls->getPlane(i).isDeinitialized())
2581 {
2582 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPLSEnablingDeinitializedPlane);
2583 return false;
2584 }
2585
2586 // [ANGLE_shader_pixel_local_storage] Section 4.4.2.X "Configuring Pixel Local Storage
2587 // on a Framebuffer": When a texture object is deleted, any pixel local storage plane to
2588 // which it was bound is automatically converted to a memoryless plane of matching
2589 // internalformat.
2590 const PixelLocalStoragePlane &plane = pls->getPlane(i);
2591
2592 Extents textureExtents;
2593 if (plane.getTextureImageExtents(context, &textureExtents))
2594 {
2595 // INVALID_OPERATION is generated if all enabled, texture-backed pixel local storage
2596 // planes do not have the same width and height.
2597 if (!hasTextureBackedPLSPlanes)
2598 {
2599 textureBackedPLSExtents = textureExtents;
2600 hasTextureBackedPLSPlanes = true;
2601 }
2602 else if (textureExtents != textureBackedPLSExtents)
2603 {
2604 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPLSMismatchedBackingTextureSizes);
2605 return false;
2606 }
2607 }
2608 else
2609 {
2610 // INVALID_OPERATION is generated if <loadops>[0..<n>-1] is
2611 // LOAD_OP_LOAD_ANGLE and the pixel local storage plane at that same
2612 // index is memoryless.
2613 if (loadops[i] == GL_LOAD_OP_LOAD_ANGLE)
2614 {
2615 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPLSKeepingMemorylessPlane);
2616 return false;
2617 }
2618 }
2619 }
2620
2621 const FramebufferAttachment *firstAttachment =
2622 framebuffer->getState().getFirstNonNullAttachment();
2623 if (firstAttachment)
2624 {
2625 // INVALID_OPERATION is generated if the draw framebuffer has other attachments, and its
2626 // enabled, texture-backed pixel local storage planes do not have identical dimensions
2627 // with the rendering area.
2628 if (hasTextureBackedPLSPlanes &&
2629 textureBackedPLSExtents != framebuffer->getState().getAttachmentExtentsIntersection())
2630 {
2631 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPLSDimensionsDontMatchRenderingArea);
2632 return false;
2633 }
2634 }
2635 else
2636 {
2637 // INVALID_OPERATION is generated if the draw framebuffer has no attachments and no
2638 // enabled, texture-backed pixel local storage planes.
2639 if (!hasTextureBackedPLSPlanes)
2640 {
2641 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPLSNoAttachmentsNoTextureBacked);
2642 return false;
2643 }
2644 }
2645
2646 // INVALID_OPERATION is generated if a single texture image is bound to more than one pixel
2647 // local storage plane.
2648 //
2649 // TODO(anglebug.com/40096838): Block feedback loops
2650 //
2651
2652 // INVALID_OPERATION is generated if a single texture image is simultaneously bound to a pixel
2653 // local storage plane and attached to the draw framebuffer.
2654 //
2655 // TODO(anglebug.com/40096838): Block feedback loops
2656 //
2657
2658 return true;
2659 }
2660
ValidateEndPixelLocalStorageANGLE(const Context * context,angle::EntryPoint entryPoint,GLsizei n,const GLenum storeops[])2661 bool ValidateEndPixelLocalStorageANGLE(const Context *context,
2662 angle::EntryPoint entryPoint,
2663 GLsizei n,
2664 const GLenum storeops[])
2665 {
2666 if (!ValidatePLSCommon(context, entryPoint, PLSExpectedStatus::Active))
2667 {
2668 return false;
2669 }
2670
2671 // INVALID_VALUE is generated if <n> != PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE.
2672 if (n != context->getState().getPixelLocalStorageActivePlanes())
2673 {
2674 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kPLSNNotEqualActivePlanes);
2675 return false;
2676 }
2677
2678 // INVALID_ENUM is generated if <storeops>[0..PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE-1] is not
2679 // one of the Store Operations enumerated in Table X.2.
2680 for (GLsizei i = 0; i < n; ++i)
2681 {
2682 if (!ValidatePLSStoreOperation(context, entryPoint, storeops[i]))
2683 {
2684 return false;
2685 }
2686 }
2687
2688 return true;
2689 }
2690
ValidatePixelLocalStorageBarrierANGLE(const Context * context,angle::EntryPoint entryPoint)2691 bool ValidatePixelLocalStorageBarrierANGLE(const Context *context, angle::EntryPoint entryPoint)
2692 {
2693 return ValidatePLSCommon(context, entryPoint, PLSExpectedStatus::Active);
2694 }
2695
ValidateFramebufferPixelLocalStorageInterruptANGLE(const Context * context,angle::EntryPoint entryPoint)2696 bool ValidateFramebufferPixelLocalStorageInterruptANGLE(const Context *context,
2697 angle::EntryPoint entryPoint)
2698 {
2699 // Check that the pixel local storage extension is enabled at all.
2700 if (!context->getExtensions().shaderPixelLocalStorageANGLE)
2701 {
2702 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPLSExtensionNotEnabled);
2703 return false;
2704 }
2705
2706 // INVALID_FRAMEBUFFER_OPERATION is generated if the current interrupt count on the draw
2707 // framebuffer is greater than or equal to 255.
2708 const PixelLocalStorage *pls =
2709 context->getState().getDrawFramebuffer()->peekPixelLocalStorage();
2710 if (pls != nullptr && pls->interruptCount() >= 255)
2711 {
2712 ANGLE_VALIDATION_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION, kPLSInterruptOverflow);
2713 return false;
2714 }
2715
2716 return true;
2717 }
2718
ValidateFramebufferPixelLocalStorageRestoreANGLE(const Context * context,angle::EntryPoint entryPoint)2719 bool ValidateFramebufferPixelLocalStorageRestoreANGLE(const Context *context,
2720 angle::EntryPoint entryPoint)
2721 {
2722 // Check that the pixel local storage extension is enabled at all.
2723 if (!context->getExtensions().shaderPixelLocalStorageANGLE)
2724 {
2725 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPLSExtensionNotEnabled);
2726 return false;
2727 }
2728
2729 // This command is ignored when the default framebuffer object name 0 is bound.
2730 const Framebuffer *framebuffer = context->getState().getDrawFramebuffer();
2731 if (context->getState().getDrawFramebuffer()->id().value == 0)
2732 {
2733 return true;
2734 }
2735
2736 // INVALID_FRAMEBUFFER_OPERATION is generated if pixel local storage on the draw framebuffer is
2737 // not in an interrupted state.
2738 const PixelLocalStorage *pls = framebuffer->peekPixelLocalStorage();
2739 if (pls == nullptr || pls->interruptCount() == 0)
2740 {
2741 ANGLE_VALIDATION_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION, kPLSNotInterrupted);
2742 return false;
2743 }
2744
2745 return true;
2746 }
2747
ValidateGetFramebufferPixelLocalStorageParameterfvANGLE(const Context * context,angle::EntryPoint entryPoint,GLint plane,GLenum pname,const GLfloat * params)2748 bool ValidateGetFramebufferPixelLocalStorageParameterfvANGLE(const Context *context,
2749 angle::EntryPoint entryPoint,
2750 GLint plane,
2751 GLenum pname,
2752 const GLfloat *params)
2753 {
2754 return ValidateGetFramebufferPixelLocalStorageParameterfvRobustANGLE(
2755 context, entryPoint, plane, pname, std::numeric_limits<GLsizei>::max(), nullptr, params);
2756 }
2757
ValidateGetFramebufferPixelLocalStorageParameterivANGLE(const Context * context,angle::EntryPoint entryPoint,GLint plane,GLenum pname,const GLint * params)2758 bool ValidateGetFramebufferPixelLocalStorageParameterivANGLE(const Context *context,
2759 angle::EntryPoint entryPoint,
2760 GLint plane,
2761 GLenum pname,
2762 const GLint *params)
2763 {
2764 return ValidateGetFramebufferPixelLocalStorageParameterivRobustANGLE(
2765 context, entryPoint, plane, pname, std::numeric_limits<GLsizei>::max(), nullptr, params);
2766 }
2767
ValidateGetFramebufferPixelLocalStorageParameterfvRobustANGLE(const Context * context,angle::EntryPoint entryPoint,GLint plane,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLfloat * params)2768 bool ValidateGetFramebufferPixelLocalStorageParameterfvRobustANGLE(const Context *context,
2769 angle::EntryPoint entryPoint,
2770 GLint plane,
2771 GLenum pname,
2772 GLsizei bufSize,
2773 const GLsizei *length,
2774 const GLfloat *params)
2775 {
2776 if (!ValidatePLSCommon(context, entryPoint, plane, PLSExpectedStatus::Any))
2777 {
2778 return false;
2779 }
2780 GLsizei paramCount = 0;
2781 switch (pname)
2782 {
2783 case GL_PIXEL_LOCAL_CLEAR_VALUE_FLOAT_ANGLE:
2784 paramCount = 4;
2785 break;
2786 default:
2787 // INVALID_ENUM is generated if <pname> is not in Table 6.Y, or if the command issued is
2788 // not the associated "Get Command" for <pname> in Table 6.Y.
2789 ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
2790 return false;
2791 }
2792 return ValidatePLSQueryCommon(context, entryPoint, paramCount, bufSize, params);
2793 }
2794
ValidateGetFramebufferPixelLocalStorageParameterivRobustANGLE(const Context * context,angle::EntryPoint entryPoint,GLint plane,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLint * params)2795 bool ValidateGetFramebufferPixelLocalStorageParameterivRobustANGLE(const Context *context,
2796 angle::EntryPoint entryPoint,
2797 GLint plane,
2798 GLenum pname,
2799 GLsizei bufSize,
2800 const GLsizei *length,
2801 const GLint *params)
2802 {
2803 if (!ValidatePLSCommon(context, entryPoint, plane, PLSExpectedStatus::Any))
2804 {
2805 return false;
2806 }
2807 GLsizei paramCount = 0;
2808 switch (pname)
2809 {
2810 case GL_PIXEL_LOCAL_FORMAT_ANGLE:
2811 case GL_PIXEL_LOCAL_TEXTURE_NAME_ANGLE:
2812 case GL_PIXEL_LOCAL_TEXTURE_LEVEL_ANGLE:
2813 case GL_PIXEL_LOCAL_TEXTURE_LAYER_ANGLE:
2814 paramCount = 1;
2815 break;
2816 case GL_PIXEL_LOCAL_CLEAR_VALUE_INT_ANGLE:
2817 case GL_PIXEL_LOCAL_CLEAR_VALUE_UNSIGNED_INT_ANGLE:
2818 paramCount = 4;
2819 break;
2820 default:
2821 // INVALID_ENUM is generated if <pname> is not in Table 6.Y, or if the command issued is
2822 // not the associated "Get Command" for <pname> in Table 6.Y.
2823 ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
2824 return false;
2825 }
2826 return ValidatePLSQueryCommon(context, entryPoint, paramCount, bufSize, params);
2827 }
2828
ValidateFramebufferFetchBarrierEXT(const Context * context,angle::EntryPoint entryPoint)2829 bool ValidateFramebufferFetchBarrierEXT(const Context *context, angle::EntryPoint entryPoint)
2830 {
2831 if (!context->getExtensions().shaderFramebufferFetchNonCoherentEXT)
2832 {
2833 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION,
2834 kFramebufferFetchNonCoherentExtensionNotEnabled);
2835 return false;
2836 }
2837 return true;
2838 }
2839
ValidatePatchParameteriEXT(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLenum pname,GLint value)2840 bool ValidatePatchParameteriEXT(const PrivateState &state,
2841 ErrorSet *errors,
2842 angle::EntryPoint entryPoint,
2843 GLenum pname,
2844 GLint value)
2845 {
2846 if (!state.getExtensions().tessellationShaderEXT)
2847 {
2848 errors->validationError(entryPoint, GL_INVALID_OPERATION, kTessellationShaderEXTNotEnabled);
2849 return false;
2850 }
2851
2852 return ValidatePatchParameteriBase(state, errors, entryPoint, pname, value);
2853 }
2854
ValidatePatchParameteriOES(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLenum pname,GLint value)2855 bool ValidatePatchParameteriOES(const PrivateState &state,
2856 ErrorSet *errors,
2857 angle::EntryPoint entryPoint,
2858 GLenum pname,
2859 GLint value)
2860 {
2861 if (!state.getExtensions().tessellationShaderOES)
2862 {
2863 errors->validationError(entryPoint, GL_INVALID_OPERATION, kTessellationShaderOESNotEnabled);
2864 return false;
2865 }
2866
2867 return ValidatePatchParameteriBase(state, errors, entryPoint, pname, value);
2868 }
2869
ValidateTexStorageMemFlags2DANGLE(const Context * context,angle::EntryPoint entryPoint,TextureType targetPacked,GLsizei levels,GLenum internalFormat,GLsizei width,GLsizei height,MemoryObjectID memoryPacked,GLuint64 offset,GLbitfield createFlags,GLbitfield usageFlags,const void * imageCreateInfoPNext)2870 bool ValidateTexStorageMemFlags2DANGLE(const Context *context,
2871 angle::EntryPoint entryPoint,
2872 TextureType targetPacked,
2873 GLsizei levels,
2874 GLenum internalFormat,
2875 GLsizei width,
2876 GLsizei height,
2877 MemoryObjectID memoryPacked,
2878 GLuint64 offset,
2879 GLbitfield createFlags,
2880 GLbitfield usageFlags,
2881 const void *imageCreateInfoPNext)
2882 {
2883 if (!context->getExtensions().memoryObjectFlagsANGLE)
2884 {
2885 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
2886 return false;
2887 }
2888
2889 if (!ValidateTexStorageMem2DEXT(context, entryPoint, targetPacked, levels, internalFormat,
2890 width, height, memoryPacked, offset))
2891 {
2892 return false;
2893 }
2894
2895 // |createFlags| and |usageFlags| must only have bits specified by the extension.
2896 constexpr GLbitfield kAllCreateFlags =
2897 GL_CREATE_SPARSE_BINDING_BIT_ANGLE | GL_CREATE_SPARSE_RESIDENCY_BIT_ANGLE |
2898 GL_CREATE_SPARSE_ALIASED_BIT_ANGLE | GL_CREATE_MUTABLE_FORMAT_BIT_ANGLE |
2899 GL_CREATE_CUBE_COMPATIBLE_BIT_ANGLE | GL_CREATE_ALIAS_BIT_ANGLE |
2900 GL_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT_ANGLE | GL_CREATE_2D_ARRAY_COMPATIBLE_BIT_ANGLE |
2901 GL_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT_ANGLE | GL_CREATE_EXTENDED_USAGE_BIT_ANGLE |
2902 GL_CREATE_PROTECTED_BIT_ANGLE | GL_CREATE_DISJOINT_BIT_ANGLE |
2903 GL_CREATE_CORNER_SAMPLED_BIT_ANGLE | GL_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_ANGLE |
2904 GL_CREATE_SUBSAMPLED_BIT_ANGLE;
2905
2906 if ((createFlags & ~kAllCreateFlags) != 0)
2907 {
2908 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidExternalCreateFlags);
2909 return false;
2910 }
2911
2912 constexpr GLbitfield kAllUsageFlags =
2913 GL_USAGE_TRANSFER_SRC_BIT_ANGLE | GL_USAGE_TRANSFER_DST_BIT_ANGLE |
2914 GL_USAGE_SAMPLED_BIT_ANGLE | GL_USAGE_STORAGE_BIT_ANGLE |
2915 GL_USAGE_COLOR_ATTACHMENT_BIT_ANGLE | GL_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT_ANGLE |
2916 GL_USAGE_TRANSIENT_ATTACHMENT_BIT_ANGLE | GL_USAGE_INPUT_ATTACHMENT_BIT_ANGLE |
2917 GL_USAGE_SHADING_RATE_IMAGE_BIT_ANGLE | GL_USAGE_FRAGMENT_DENSITY_MAP_BIT_ANGLE;
2918
2919 if ((usageFlags & ~kAllUsageFlags) != 0)
2920 {
2921 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidExternalUsageFlags);
2922 return false;
2923 }
2924
2925 return true;
2926 }
2927
ValidateTexStorageMemFlags2DMultisampleANGLE(const Context * context,angle::EntryPoint entryPoint,TextureType targetPacked,GLsizei samples,GLenum internalFormat,GLsizei width,GLsizei height,GLboolean fixedSampleLocations,MemoryObjectID memoryPacked,GLuint64 offset,GLbitfield createFlags,GLbitfield usageFlags,const void * imageCreateInfoPNext)2928 bool ValidateTexStorageMemFlags2DMultisampleANGLE(const Context *context,
2929 angle::EntryPoint entryPoint,
2930 TextureType targetPacked,
2931 GLsizei samples,
2932 GLenum internalFormat,
2933 GLsizei width,
2934 GLsizei height,
2935 GLboolean fixedSampleLocations,
2936 MemoryObjectID memoryPacked,
2937 GLuint64 offset,
2938 GLbitfield createFlags,
2939 GLbitfield usageFlags,
2940 const void *imageCreateInfoPNext)
2941 {
2942 UNIMPLEMENTED();
2943 return false;
2944 }
2945
ValidateTexStorageMemFlags3DANGLE(const Context * context,angle::EntryPoint entryPoint,TextureType targetPacked,GLsizei levels,GLenum internalFormat,GLsizei width,GLsizei height,GLsizei depth,MemoryObjectID memoryPacked,GLuint64 offset,GLbitfield createFlags,GLbitfield usageFlags,const void * imageCreateInfoPNext)2946 bool ValidateTexStorageMemFlags3DANGLE(const Context *context,
2947 angle::EntryPoint entryPoint,
2948 TextureType targetPacked,
2949 GLsizei levels,
2950 GLenum internalFormat,
2951 GLsizei width,
2952 GLsizei height,
2953 GLsizei depth,
2954 MemoryObjectID memoryPacked,
2955 GLuint64 offset,
2956 GLbitfield createFlags,
2957 GLbitfield usageFlags,
2958 const void *imageCreateInfoPNext)
2959 {
2960 UNIMPLEMENTED();
2961 return false;
2962 }
2963
ValidateTexStorageMemFlags3DMultisampleANGLE(const Context * context,angle::EntryPoint entryPoint,TextureType targetPacked,GLsizei samples,GLenum internalFormat,GLsizei width,GLsizei height,GLsizei depth,GLboolean fixedSampleLocations,MemoryObjectID memoryPacked,GLuint64 offset,GLbitfield createFlags,GLbitfield usageFlags,const void * imageCreateInfoPNext)2964 bool ValidateTexStorageMemFlags3DMultisampleANGLE(const Context *context,
2965 angle::EntryPoint entryPoint,
2966 TextureType targetPacked,
2967 GLsizei samples,
2968 GLenum internalFormat,
2969 GLsizei width,
2970 GLsizei height,
2971 GLsizei depth,
2972 GLboolean fixedSampleLocations,
2973 MemoryObjectID memoryPacked,
2974 GLuint64 offset,
2975 GLbitfield createFlags,
2976 GLbitfield usageFlags,
2977 const void *imageCreateInfoPNext)
2978 {
2979 UNIMPLEMENTED();
2980 return false;
2981 }
2982
2983 // GL_EXT_buffer_storage
ValidateBufferStorageEXT(const Context * context,angle::EntryPoint entryPoint,BufferBinding targetPacked,GLsizeiptr size,const void * data,GLbitfield flags)2984 bool ValidateBufferStorageEXT(const Context *context,
2985 angle::EntryPoint entryPoint,
2986 BufferBinding targetPacked,
2987 GLsizeiptr size,
2988 const void *data,
2989 GLbitfield flags)
2990 {
2991 if (!context->isValidBufferBinding(targetPacked))
2992 {
2993 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidBufferTypes);
2994 return false;
2995 }
2996
2997 if (size <= 0)
2998 {
2999 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNonPositiveSize);
3000 return false;
3001 }
3002
3003 constexpr GLbitfield kAllUsageFlags =
3004 (GL_DYNAMIC_STORAGE_BIT_EXT | GL_MAP_READ_BIT | GL_MAP_WRITE_BIT |
3005 GL_MAP_PERSISTENT_BIT_EXT | GL_MAP_COHERENT_BIT_EXT | GL_CLIENT_STORAGE_BIT_EXT);
3006 if ((flags & ~kAllUsageFlags) != 0)
3007 {
3008 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidBufferUsageFlags);
3009 return false;
3010 }
3011
3012 if (((flags & GL_MAP_PERSISTENT_BIT_EXT) != 0) &&
3013 ((flags & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)) == 0))
3014 {
3015 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidBufferUsageFlags);
3016 return false;
3017 }
3018
3019 if (((flags & GL_MAP_COHERENT_BIT_EXT) != 0) && ((flags & GL_MAP_PERSISTENT_BIT_EXT) == 0))
3020 {
3021 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidBufferUsageFlags);
3022 return false;
3023 }
3024
3025 Buffer *buffer = context->getState().getTargetBuffer(targetPacked);
3026
3027 if (buffer == nullptr)
3028 {
3029 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBufferNotBound);
3030 return false;
3031 }
3032
3033 if (buffer->isImmutable())
3034 {
3035 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBufferImmutable);
3036 return false;
3037 }
3038
3039 return true;
3040 }
3041
3042 // GL_EXT_clear_texture
ValidateClearTexImageEXT(const Context * context,angle::EntryPoint entryPoint,TextureID texturePacked,GLint level,GLenum format,GLenum type,const void * data)3043 bool ValidateClearTexImageEXT(const Context *context,
3044 angle::EntryPoint entryPoint,
3045 TextureID texturePacked,
3046 GLint level,
3047 GLenum format,
3048 GLenum type,
3049 const void *data)
3050 {
3051 return ValidateClearTexImageCommon(context, entryPoint, texturePacked, level, std::nullopt,
3052 format, type, data);
3053 }
3054
ValidateClearTexSubImageEXT(const Context * context,angle::EntryPoint entryPoint,TextureID texturePacked,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLsizei depth,GLenum format,GLenum type,const void * data)3055 bool ValidateClearTexSubImageEXT(const Context *context,
3056 angle::EntryPoint entryPoint,
3057 TextureID texturePacked,
3058 GLint level,
3059 GLint xoffset,
3060 GLint yoffset,
3061 GLint zoffset,
3062 GLsizei width,
3063 GLsizei height,
3064 GLsizei depth,
3065 GLenum format,
3066 GLenum type,
3067 const void *data)
3068 {
3069 return ValidateClearTexImageCommon(context, entryPoint, texturePacked, level,
3070 Box(xoffset, yoffset, zoffset, width, height, depth), format,
3071 type, data);
3072 }
3073
3074 // GL_EXT_clip_control
ValidateClipControlEXT(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,ClipOrigin originPacked,ClipDepthMode depthPacked)3075 bool ValidateClipControlEXT(const PrivateState &state,
3076 ErrorSet *errors,
3077 angle::EntryPoint entryPoint,
3078 ClipOrigin originPacked,
3079 ClipDepthMode depthPacked)
3080 {
3081 if (!state.getExtensions().clipControlEXT)
3082 {
3083 errors->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
3084 return false;
3085 }
3086
3087 if (originPacked == ClipOrigin::InvalidEnum)
3088 {
3089 errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidOriginEnum);
3090 return false;
3091 }
3092
3093 if (depthPacked == ClipDepthMode::InvalidEnum)
3094 {
3095 errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidDepthEnum);
3096 return false;
3097 }
3098
3099 return true;
3100 }
3101
3102 // GL_EXT_external_buffer
ValidateBufferStorageExternalEXT(const Context * context,angle::EntryPoint entryPoint,BufferBinding targetPacked,GLintptr offset,GLsizeiptr size,GLeglClientBufferEXT clientBuffer,GLbitfield flags)3103 bool ValidateBufferStorageExternalEXT(const Context *context,
3104 angle::EntryPoint entryPoint,
3105 BufferBinding targetPacked,
3106 GLintptr offset,
3107 GLsizeiptr size,
3108 GLeglClientBufferEXT clientBuffer,
3109 GLbitfield flags)
3110 {
3111 if (!ValidateBufferStorageEXT(context, entryPoint, targetPacked, size, nullptr, flags))
3112 {
3113 return false;
3114 }
3115
3116 if (offset != 0)
3117 {
3118 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kExternalBufferInvalidOffset);
3119 return false;
3120 }
3121
3122 if (clientBuffer == nullptr && size > 0)
3123 {
3124 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kClientBufferInvalid);
3125 return false;
3126 }
3127
3128 return true;
3129 }
3130
ValidateNamedBufferStorageExternalEXT(const Context * context,angle::EntryPoint entryPoint,GLuint buffer,GLintptr offset,GLsizeiptr size,GLeglClientBufferEXT clientBuffer,GLbitfield flags)3131 bool ValidateNamedBufferStorageExternalEXT(const Context *context,
3132 angle::EntryPoint entryPoint,
3133 GLuint buffer,
3134 GLintptr offset,
3135 GLsizeiptr size,
3136 GLeglClientBufferEXT clientBuffer,
3137 GLbitfield flags)
3138 {
3139 UNIMPLEMENTED();
3140 return false;
3141 }
3142
3143 // GL_ANGLE_polygon_mode
ValidatePolygonModeANGLE(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLenum face,PolygonMode modePacked)3144 bool ValidatePolygonModeANGLE(const PrivateState &state,
3145 ErrorSet *errors,
3146 angle::EntryPoint entryPoint,
3147 GLenum face,
3148 PolygonMode modePacked)
3149 {
3150 if (!state.getExtensions().polygonModeANGLE)
3151 {
3152 errors->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
3153 return false;
3154 }
3155
3156 if (face != GL_FRONT_AND_BACK)
3157 {
3158 errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidCullMode);
3159 return false;
3160 }
3161
3162 if (modePacked == PolygonMode::Point || modePacked == PolygonMode::InvalidEnum)
3163 {
3164 errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPolygonMode);
3165 return false;
3166 }
3167
3168 return true;
3169 }
3170
3171 // GL_NV_polygon_mode
ValidatePolygonModeNV(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLenum face,PolygonMode modePacked)3172 bool ValidatePolygonModeNV(const PrivateState &state,
3173 ErrorSet *errors,
3174 angle::EntryPoint entryPoint,
3175 GLenum face,
3176 PolygonMode modePacked)
3177 {
3178 if (!state.getExtensions().polygonModeNV)
3179 {
3180 errors->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
3181 return false;
3182 }
3183
3184 if (face != GL_FRONT_AND_BACK)
3185 {
3186 errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidCullMode);
3187 return false;
3188 }
3189
3190 if (modePacked == PolygonMode::InvalidEnum)
3191 {
3192 errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPolygonMode);
3193 return false;
3194 }
3195
3196 return true;
3197 }
3198
3199 // GL_EXT_polygon_offset_clamp
ValidatePolygonOffsetClampEXT(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLfloat factor,GLfloat units,GLfloat clamp)3200 bool ValidatePolygonOffsetClampEXT(const PrivateState &state,
3201 ErrorSet *errors,
3202 angle::EntryPoint entryPoint,
3203 GLfloat factor,
3204 GLfloat units,
3205 GLfloat clamp)
3206 {
3207 if (!state.getExtensions().polygonOffsetClampEXT)
3208 {
3209 errors->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
3210 return false;
3211 }
3212
3213 return true;
3214 }
3215
3216 // GL_EXT_primitive_bounding_box
ValidatePrimitiveBoundingBoxEXT(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLfloat minX,GLfloat minY,GLfloat minZ,GLfloat minW,GLfloat maxX,GLfloat maxY,GLfloat maxZ,GLfloat maxW)3217 bool ValidatePrimitiveBoundingBoxEXT(const PrivateState &state,
3218 ErrorSet *errors,
3219 angle::EntryPoint entryPoint,
3220 GLfloat minX,
3221 GLfloat minY,
3222 GLfloat minZ,
3223 GLfloat minW,
3224 GLfloat maxX,
3225 GLfloat maxY,
3226 GLfloat maxZ,
3227 GLfloat maxW)
3228 {
3229 if (!state.getExtensions().primitiveBoundingBoxEXT)
3230 {
3231 errors->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
3232 return false;
3233 }
3234
3235 return true;
3236 }
3237
3238 // GL_OES_primitive_bounding_box
ValidatePrimitiveBoundingBoxOES(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLfloat minX,GLfloat minY,GLfloat minZ,GLfloat minW,GLfloat maxX,GLfloat maxY,GLfloat maxZ,GLfloat maxW)3239 bool ValidatePrimitiveBoundingBoxOES(const PrivateState &state,
3240 ErrorSet *errors,
3241 angle::EntryPoint entryPoint,
3242 GLfloat minX,
3243 GLfloat minY,
3244 GLfloat minZ,
3245 GLfloat minW,
3246 GLfloat maxX,
3247 GLfloat maxY,
3248 GLfloat maxZ,
3249 GLfloat maxW)
3250 {
3251 if (!state.getExtensions().primitiveBoundingBoxOES)
3252 {
3253 errors->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
3254 return false;
3255 }
3256
3257 return true;
3258 }
3259
3260 // GL_OES_texture_storage_multisample_2d_array
ValidateTexStorage3DMultisampleOES(const Context * context,angle::EntryPoint entryPoint,TextureType target,GLsizei samples,GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth,GLboolean fixedsamplelocations)3261 bool ValidateTexStorage3DMultisampleOES(const Context *context,
3262 angle::EntryPoint entryPoint,
3263 TextureType target,
3264 GLsizei samples,
3265 GLenum internalformat,
3266 GLsizei width,
3267 GLsizei height,
3268 GLsizei depth,
3269 GLboolean fixedsamplelocations)
3270 {
3271 if (!context->getExtensions().textureStorageMultisample2dArrayOES)
3272 {
3273 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3274 return false;
3275 }
3276
3277 return ValidateTexStorage3DMultisampleBase(context, entryPoint, target, samples, internalformat,
3278 width, height, depth);
3279 }
3280
3281 // GL_EXT_separate_shader_objects
ValidateActiveShaderProgramEXT(const Context * context,angle::EntryPoint entryPoint,ProgramPipelineID pipelinePacked,ShaderProgramID programPacked)3282 bool ValidateActiveShaderProgramEXT(const Context *context,
3283 angle::EntryPoint entryPoint,
3284 ProgramPipelineID pipelinePacked,
3285 ShaderProgramID programPacked)
3286 {
3287 if (!context->getExtensions().separateShaderObjectsEXT)
3288 {
3289 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3290 return false;
3291 }
3292
3293 return ValidateActiveShaderProgramBase(context, entryPoint, pipelinePacked, programPacked);
3294 }
3295
ValidateBindProgramPipelineEXT(const Context * context,angle::EntryPoint entryPoint,ProgramPipelineID pipelinePacked)3296 bool ValidateBindProgramPipelineEXT(const Context *context,
3297 angle::EntryPoint entryPoint,
3298 ProgramPipelineID pipelinePacked)
3299 {
3300 if (!context->getExtensions().separateShaderObjectsEXT)
3301 {
3302 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3303 return false;
3304 }
3305
3306 return ValidateBindProgramPipelineBase(context, entryPoint, pipelinePacked);
3307 }
3308
ValidateCreateShaderProgramvEXT(const Context * context,angle::EntryPoint entryPoint,ShaderType typePacked,GLsizei count,const GLchar ** strings)3309 bool ValidateCreateShaderProgramvEXT(const Context *context,
3310 angle::EntryPoint entryPoint,
3311 ShaderType typePacked,
3312 GLsizei count,
3313 const GLchar **strings)
3314 {
3315 if (!context->getExtensions().separateShaderObjectsEXT)
3316 {
3317 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3318 return false;
3319 }
3320
3321 return ValidateCreateShaderProgramvBase(context, entryPoint, typePacked, count, strings);
3322 }
3323
ValidateDeleteProgramPipelinesEXT(const Context * context,angle::EntryPoint entryPoint,GLsizei n,const ProgramPipelineID * pipelinesPacked)3324 bool ValidateDeleteProgramPipelinesEXT(const Context *context,
3325 angle::EntryPoint entryPoint,
3326 GLsizei n,
3327 const ProgramPipelineID *pipelinesPacked)
3328 {
3329 if (!context->getExtensions().separateShaderObjectsEXT)
3330 {
3331 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3332 return false;
3333 }
3334
3335 return ValidateDeleteProgramPipelinesBase(context, entryPoint, n, pipelinesPacked);
3336 }
3337
ValidateGenProgramPipelinesEXT(const Context * context,angle::EntryPoint entryPoint,GLsizei n,const ProgramPipelineID * pipelinesPacked)3338 bool ValidateGenProgramPipelinesEXT(const Context *context,
3339 angle::EntryPoint entryPoint,
3340 GLsizei n,
3341 const ProgramPipelineID *pipelinesPacked)
3342 {
3343 if (!context->getExtensions().separateShaderObjectsEXT)
3344 {
3345 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3346 return false;
3347 }
3348
3349 return ValidateGenProgramPipelinesBase(context, entryPoint, n, pipelinesPacked);
3350 }
3351
ValidateGetProgramPipelineInfoLogEXT(const Context * context,angle::EntryPoint entryPoint,ProgramPipelineID pipelinePacked,GLsizei bufSize,const GLsizei * length,const GLchar * infoLog)3352 bool ValidateGetProgramPipelineInfoLogEXT(const Context *context,
3353 angle::EntryPoint entryPoint,
3354 ProgramPipelineID pipelinePacked,
3355 GLsizei bufSize,
3356 const GLsizei *length,
3357 const GLchar *infoLog)
3358 {
3359 if (!context->getExtensions().separateShaderObjectsEXT)
3360 {
3361 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3362 return false;
3363 }
3364
3365 return ValidateGetProgramPipelineInfoLogBase(context, entryPoint, pipelinePacked, bufSize,
3366 length, infoLog);
3367 }
3368
ValidateGetProgramPipelineivEXT(const Context * context,angle::EntryPoint entryPoint,ProgramPipelineID pipelinePacked,GLenum pname,const GLint * params)3369 bool ValidateGetProgramPipelineivEXT(const Context *context,
3370 angle::EntryPoint entryPoint,
3371 ProgramPipelineID pipelinePacked,
3372 GLenum pname,
3373 const GLint *params)
3374 {
3375 if (!context->getExtensions().separateShaderObjectsEXT)
3376 {
3377 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3378 return false;
3379 }
3380
3381 return ValidateGetProgramPipelineivBase(context, entryPoint, pipelinePacked, pname, params);
3382 }
3383
ValidateIsProgramPipelineEXT(const Context * context,angle::EntryPoint entryPoint,ProgramPipelineID pipelinePacked)3384 bool ValidateIsProgramPipelineEXT(const Context *context,
3385 angle::EntryPoint entryPoint,
3386 ProgramPipelineID pipelinePacked)
3387 {
3388 if (!context->getExtensions().separateShaderObjectsEXT)
3389 {
3390 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3391 return false;
3392 }
3393
3394 return ValidateIsProgramPipelineBase(context, entryPoint, pipelinePacked);
3395 }
3396
ValidateProgramParameteriEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,GLenum pname,GLint value)3397 bool ValidateProgramParameteriEXT(const Context *context,
3398 angle::EntryPoint entryPoint,
3399 ShaderProgramID programPacked,
3400 GLenum pname,
3401 GLint value)
3402 {
3403 if (!context->getExtensions().separateShaderObjectsEXT)
3404 {
3405 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3406 return false;
3407 }
3408
3409 return ValidateProgramParameteriBase(context, entryPoint, programPacked, pname, value);
3410 }
3411
ValidateProgramUniform1fEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLfloat v0)3412 bool ValidateProgramUniform1fEXT(const Context *context,
3413 angle::EntryPoint entryPoint,
3414 ShaderProgramID programPacked,
3415 UniformLocation locationPacked,
3416 GLfloat v0)
3417 {
3418 if (!context->getExtensions().separateShaderObjectsEXT)
3419 {
3420 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3421 return false;
3422 }
3423
3424 return ValidateProgramUniform1fBase(context, entryPoint, programPacked, locationPacked, v0);
3425 }
3426
ValidateProgramUniform1fvEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLfloat * value)3427 bool ValidateProgramUniform1fvEXT(const Context *context,
3428 angle::EntryPoint entryPoint,
3429 ShaderProgramID programPacked,
3430 UniformLocation locationPacked,
3431 GLsizei count,
3432 const GLfloat *value)
3433 {
3434 if (!context->getExtensions().separateShaderObjectsEXT)
3435 {
3436 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3437 return false;
3438 }
3439
3440 return ValidateProgramUniform1fvBase(context, entryPoint, programPacked, locationPacked, count,
3441 value);
3442 }
3443
ValidateProgramUniform1iEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLint v0)3444 bool ValidateProgramUniform1iEXT(const Context *context,
3445 angle::EntryPoint entryPoint,
3446 ShaderProgramID programPacked,
3447 UniformLocation locationPacked,
3448 GLint v0)
3449 {
3450 if (!context->getExtensions().separateShaderObjectsEXT)
3451 {
3452 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3453 return false;
3454 }
3455
3456 return ValidateProgramUniform1iBase(context, entryPoint, programPacked, locationPacked, v0);
3457 }
3458
ValidateProgramUniform1ivEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLint * value)3459 bool ValidateProgramUniform1ivEXT(const Context *context,
3460 angle::EntryPoint entryPoint,
3461 ShaderProgramID programPacked,
3462 UniformLocation locationPacked,
3463 GLsizei count,
3464 const GLint *value)
3465 {
3466 if (!context->getExtensions().separateShaderObjectsEXT)
3467 {
3468 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3469 return false;
3470 }
3471
3472 return ValidateProgramUniform1ivBase(context, entryPoint, programPacked, locationPacked, count,
3473 value);
3474 }
3475
ValidateProgramUniform1uiEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLuint v0)3476 bool ValidateProgramUniform1uiEXT(const Context *context,
3477 angle::EntryPoint entryPoint,
3478 ShaderProgramID programPacked,
3479 UniformLocation locationPacked,
3480 GLuint v0)
3481 {
3482 if (!context->getExtensions().separateShaderObjectsEXT)
3483 {
3484 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3485 return false;
3486 }
3487
3488 return ValidateProgramUniform1uiBase(context, entryPoint, programPacked, locationPacked, v0);
3489 }
3490
ValidateProgramUniform1uivEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLuint * value)3491 bool ValidateProgramUniform1uivEXT(const Context *context,
3492 angle::EntryPoint entryPoint,
3493 ShaderProgramID programPacked,
3494 UniformLocation locationPacked,
3495 GLsizei count,
3496 const GLuint *value)
3497 {
3498 if (!context->getExtensions().separateShaderObjectsEXT)
3499 {
3500 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3501 return false;
3502 }
3503
3504 return ValidateProgramUniform1uivBase(context, entryPoint, programPacked, locationPacked, count,
3505 value);
3506 }
3507
ValidateProgramUniform2fEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLfloat v0,GLfloat v1)3508 bool ValidateProgramUniform2fEXT(const Context *context,
3509 angle::EntryPoint entryPoint,
3510 ShaderProgramID programPacked,
3511 UniformLocation locationPacked,
3512 GLfloat v0,
3513 GLfloat v1)
3514 {
3515 if (!context->getExtensions().separateShaderObjectsEXT)
3516 {
3517 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3518 return false;
3519 }
3520
3521 return ValidateProgramUniform2fBase(context, entryPoint, programPacked, locationPacked, v0, v1);
3522 }
3523
ValidateProgramUniform2fvEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLfloat * value)3524 bool ValidateProgramUniform2fvEXT(const Context *context,
3525 angle::EntryPoint entryPoint,
3526 ShaderProgramID programPacked,
3527 UniformLocation locationPacked,
3528 GLsizei count,
3529 const GLfloat *value)
3530 {
3531 if (!context->getExtensions().separateShaderObjectsEXT)
3532 {
3533 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3534 return false;
3535 }
3536
3537 return ValidateProgramUniform2fvBase(context, entryPoint, programPacked, locationPacked, count,
3538 value);
3539 }
3540
ValidateProgramUniform2iEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLint v0,GLint v1)3541 bool ValidateProgramUniform2iEXT(const Context *context,
3542 angle::EntryPoint entryPoint,
3543 ShaderProgramID programPacked,
3544 UniformLocation locationPacked,
3545 GLint v0,
3546 GLint v1)
3547 {
3548 if (!context->getExtensions().separateShaderObjectsEXT)
3549 {
3550 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3551 return false;
3552 }
3553
3554 return ValidateProgramUniform2iBase(context, entryPoint, programPacked, locationPacked, v0, v1);
3555 }
3556
ValidateProgramUniform2ivEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLint * value)3557 bool ValidateProgramUniform2ivEXT(const Context *context,
3558 angle::EntryPoint entryPoint,
3559 ShaderProgramID programPacked,
3560 UniformLocation locationPacked,
3561 GLsizei count,
3562 const GLint *value)
3563 {
3564 if (!context->getExtensions().separateShaderObjectsEXT)
3565 {
3566 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3567 return false;
3568 }
3569
3570 return ValidateProgramUniform2ivBase(context, entryPoint, programPacked, locationPacked, count,
3571 value);
3572 }
3573
ValidateProgramUniform2uiEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLuint v0,GLuint v1)3574 bool ValidateProgramUniform2uiEXT(const Context *context,
3575 angle::EntryPoint entryPoint,
3576 ShaderProgramID programPacked,
3577 UniformLocation locationPacked,
3578 GLuint v0,
3579 GLuint v1)
3580 {
3581 if (!context->getExtensions().separateShaderObjectsEXT)
3582 {
3583 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3584 return false;
3585 }
3586
3587 return ValidateProgramUniform2uiBase(context, entryPoint, programPacked, locationPacked, v0,
3588 v1);
3589 }
3590
ValidateProgramUniform2uivEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLuint * value)3591 bool ValidateProgramUniform2uivEXT(const Context *context,
3592 angle::EntryPoint entryPoint,
3593 ShaderProgramID programPacked,
3594 UniformLocation locationPacked,
3595 GLsizei count,
3596 const GLuint *value)
3597 {
3598 if (!context->getExtensions().separateShaderObjectsEXT)
3599 {
3600 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3601 return false;
3602 }
3603
3604 return ValidateProgramUniform2uivBase(context, entryPoint, programPacked, locationPacked, count,
3605 value);
3606 }
3607
ValidateProgramUniform3fEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLfloat v0,GLfloat v1,GLfloat v2)3608 bool ValidateProgramUniform3fEXT(const Context *context,
3609 angle::EntryPoint entryPoint,
3610 ShaderProgramID programPacked,
3611 UniformLocation locationPacked,
3612 GLfloat v0,
3613 GLfloat v1,
3614 GLfloat v2)
3615 {
3616 if (!context->getExtensions().separateShaderObjectsEXT)
3617 {
3618 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3619 return false;
3620 }
3621
3622 return ValidateProgramUniform3fBase(context, entryPoint, programPacked, locationPacked, v0, v1,
3623 v2);
3624 }
3625
ValidateProgramUniform3fvEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLfloat * value)3626 bool ValidateProgramUniform3fvEXT(const Context *context,
3627 angle::EntryPoint entryPoint,
3628 ShaderProgramID programPacked,
3629 UniformLocation locationPacked,
3630 GLsizei count,
3631 const GLfloat *value)
3632 {
3633 if (!context->getExtensions().separateShaderObjectsEXT)
3634 {
3635 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3636 return false;
3637 }
3638
3639 return ValidateProgramUniform3fvBase(context, entryPoint, programPacked, locationPacked, count,
3640 value);
3641 }
3642
ValidateProgramUniform3iEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLint v0,GLint v1,GLint v2)3643 bool ValidateProgramUniform3iEXT(const Context *context,
3644 angle::EntryPoint entryPoint,
3645 ShaderProgramID programPacked,
3646 UniformLocation locationPacked,
3647 GLint v0,
3648 GLint v1,
3649 GLint v2)
3650 {
3651 if (!context->getExtensions().separateShaderObjectsEXT)
3652 {
3653 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3654 return false;
3655 }
3656
3657 return ValidateProgramUniform3iBase(context, entryPoint, programPacked, locationPacked, v0, v1,
3658 v2);
3659 }
3660
ValidateProgramUniform3ivEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLint * value)3661 bool ValidateProgramUniform3ivEXT(const Context *context,
3662 angle::EntryPoint entryPoint,
3663 ShaderProgramID programPacked,
3664 UniformLocation locationPacked,
3665 GLsizei count,
3666 const GLint *value)
3667 {
3668 if (!context->getExtensions().separateShaderObjectsEXT)
3669 {
3670 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3671 return false;
3672 }
3673
3674 return ValidateProgramUniform3ivBase(context, entryPoint, programPacked, locationPacked, count,
3675 value);
3676 }
3677
ValidateProgramUniform3uiEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLuint v0,GLuint v1,GLuint v2)3678 bool ValidateProgramUniform3uiEXT(const Context *context,
3679 angle::EntryPoint entryPoint,
3680 ShaderProgramID programPacked,
3681 UniformLocation locationPacked,
3682 GLuint v0,
3683 GLuint v1,
3684 GLuint v2)
3685 {
3686 if (!context->getExtensions().separateShaderObjectsEXT)
3687 {
3688 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3689 return false;
3690 }
3691
3692 return ValidateProgramUniform3uiBase(context, entryPoint, programPacked, locationPacked, v0, v1,
3693 v2);
3694 }
3695
ValidateProgramUniform3uivEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLuint * value)3696 bool ValidateProgramUniform3uivEXT(const Context *context,
3697 angle::EntryPoint entryPoint,
3698 ShaderProgramID programPacked,
3699 UniformLocation locationPacked,
3700 GLsizei count,
3701 const GLuint *value)
3702 {
3703 if (!context->getExtensions().separateShaderObjectsEXT)
3704 {
3705 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3706 return false;
3707 }
3708
3709 return ValidateProgramUniform3uivBase(context, entryPoint, programPacked, locationPacked, count,
3710 value);
3711 }
3712
ValidateProgramUniform4fEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLfloat v0,GLfloat v1,GLfloat v2,GLfloat v3)3713 bool ValidateProgramUniform4fEXT(const Context *context,
3714 angle::EntryPoint entryPoint,
3715 ShaderProgramID programPacked,
3716 UniformLocation locationPacked,
3717 GLfloat v0,
3718 GLfloat v1,
3719 GLfloat v2,
3720 GLfloat v3)
3721 {
3722 if (!context->getExtensions().separateShaderObjectsEXT)
3723 {
3724 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3725 return false;
3726 }
3727
3728 return ValidateProgramUniform4fBase(context, entryPoint, programPacked, locationPacked, v0, v1,
3729 v2, v3);
3730 }
3731
ValidateProgramUniform4fvEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLfloat * value)3732 bool ValidateProgramUniform4fvEXT(const Context *context,
3733 angle::EntryPoint entryPoint,
3734 ShaderProgramID programPacked,
3735 UniformLocation locationPacked,
3736 GLsizei count,
3737 const GLfloat *value)
3738 {
3739 if (!context->getExtensions().separateShaderObjectsEXT)
3740 {
3741 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3742 return false;
3743 }
3744
3745 return ValidateProgramUniform4fvBase(context, entryPoint, programPacked, locationPacked, count,
3746 value);
3747 }
3748
ValidateProgramUniform4iEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLint v0,GLint v1,GLint v2,GLint v3)3749 bool ValidateProgramUniform4iEXT(const Context *context,
3750 angle::EntryPoint entryPoint,
3751 ShaderProgramID programPacked,
3752 UniformLocation locationPacked,
3753 GLint v0,
3754 GLint v1,
3755 GLint v2,
3756 GLint v3)
3757 {
3758 if (!context->getExtensions().separateShaderObjectsEXT)
3759 {
3760 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3761 return false;
3762 }
3763
3764 return ValidateProgramUniform4iBase(context, entryPoint, programPacked, locationPacked, v0, v1,
3765 v2, v3);
3766 }
3767
ValidateProgramUniform4ivEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLint * value)3768 bool ValidateProgramUniform4ivEXT(const Context *context,
3769 angle::EntryPoint entryPoint,
3770 ShaderProgramID programPacked,
3771 UniformLocation locationPacked,
3772 GLsizei count,
3773 const GLint *value)
3774 {
3775 return ValidateProgramUniform4ivBase(context, entryPoint, programPacked, locationPacked, count,
3776 value);
3777 }
3778
ValidateProgramUniform4uiEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLuint v0,GLuint v1,GLuint v2,GLuint v3)3779 bool ValidateProgramUniform4uiEXT(const Context *context,
3780 angle::EntryPoint entryPoint,
3781 ShaderProgramID programPacked,
3782 UniformLocation locationPacked,
3783 GLuint v0,
3784 GLuint v1,
3785 GLuint v2,
3786 GLuint v3)
3787 {
3788 if (!context->getExtensions().separateShaderObjectsEXT)
3789 {
3790 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3791 return false;
3792 }
3793
3794 return ValidateProgramUniform4uiBase(context, entryPoint, programPacked, locationPacked, v0, v1,
3795 v2, v3);
3796 }
3797
ValidateProgramUniform4uivEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLuint * value)3798 bool ValidateProgramUniform4uivEXT(const Context *context,
3799 angle::EntryPoint entryPoint,
3800 ShaderProgramID programPacked,
3801 UniformLocation locationPacked,
3802 GLsizei count,
3803 const GLuint *value)
3804 {
3805 return ValidateProgramUniform4uivBase(context, entryPoint, programPacked, locationPacked, count,
3806 value);
3807 }
3808
ValidateProgramUniformMatrix2fvEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,GLboolean transpose,const GLfloat * value)3809 bool ValidateProgramUniformMatrix2fvEXT(const Context *context,
3810 angle::EntryPoint entryPoint,
3811 ShaderProgramID programPacked,
3812 UniformLocation locationPacked,
3813 GLsizei count,
3814 GLboolean transpose,
3815 const GLfloat *value)
3816 {
3817 if (!context->getExtensions().separateShaderObjectsEXT)
3818 {
3819 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3820 return false;
3821 }
3822
3823 return ValidateProgramUniformMatrix2fvBase(context, entryPoint, programPacked, locationPacked,
3824 count, transpose, value);
3825 }
3826
ValidateProgramUniformMatrix2x3fvEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,GLboolean transpose,const GLfloat * value)3827 bool ValidateProgramUniformMatrix2x3fvEXT(const Context *context,
3828 angle::EntryPoint entryPoint,
3829 ShaderProgramID programPacked,
3830 UniformLocation locationPacked,
3831 GLsizei count,
3832 GLboolean transpose,
3833 const GLfloat *value)
3834 {
3835 if (!context->getExtensions().separateShaderObjectsEXT)
3836 {
3837 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3838 return false;
3839 }
3840
3841 return ValidateProgramUniformMatrix2x3fvBase(context, entryPoint, programPacked, locationPacked,
3842 count, transpose, value);
3843 }
3844
ValidateProgramUniformMatrix2x4fvEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,GLboolean transpose,const GLfloat * value)3845 bool ValidateProgramUniformMatrix2x4fvEXT(const Context *context,
3846 angle::EntryPoint entryPoint,
3847 ShaderProgramID programPacked,
3848 UniformLocation locationPacked,
3849 GLsizei count,
3850 GLboolean transpose,
3851 const GLfloat *value)
3852 {
3853 if (!context->getExtensions().separateShaderObjectsEXT)
3854 {
3855 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3856 return false;
3857 }
3858
3859 return ValidateProgramUniformMatrix2x4fvBase(context, entryPoint, programPacked, locationPacked,
3860 count, transpose, value);
3861 }
3862
ValidateProgramUniformMatrix3fvEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,GLboolean transpose,const GLfloat * value)3863 bool ValidateProgramUniformMatrix3fvEXT(const Context *context,
3864 angle::EntryPoint entryPoint,
3865 ShaderProgramID programPacked,
3866 UniformLocation locationPacked,
3867 GLsizei count,
3868 GLboolean transpose,
3869 const GLfloat *value)
3870 {
3871 if (!context->getExtensions().separateShaderObjectsEXT)
3872 {
3873 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3874 return false;
3875 }
3876
3877 return ValidateProgramUniformMatrix3fvBase(context, entryPoint, programPacked, locationPacked,
3878 count, transpose, value);
3879 }
3880
ValidateProgramUniformMatrix3x2fvEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,GLboolean transpose,const GLfloat * value)3881 bool ValidateProgramUniformMatrix3x2fvEXT(const Context *context,
3882 angle::EntryPoint entryPoint,
3883 ShaderProgramID programPacked,
3884 UniformLocation locationPacked,
3885 GLsizei count,
3886 GLboolean transpose,
3887 const GLfloat *value)
3888 {
3889 if (!context->getExtensions().separateShaderObjectsEXT)
3890 {
3891 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3892 return false;
3893 }
3894
3895 return ValidateProgramUniformMatrix3x2fvBase(context, entryPoint, programPacked, locationPacked,
3896 count, transpose, value);
3897 }
3898
ValidateProgramUniformMatrix3x4fvEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,GLboolean transpose,const GLfloat * value)3899 bool ValidateProgramUniformMatrix3x4fvEXT(const Context *context,
3900 angle::EntryPoint entryPoint,
3901 ShaderProgramID programPacked,
3902 UniformLocation locationPacked,
3903 GLsizei count,
3904 GLboolean transpose,
3905 const GLfloat *value)
3906 {
3907 if (!context->getExtensions().separateShaderObjectsEXT)
3908 {
3909 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3910 return false;
3911 }
3912
3913 return ValidateProgramUniformMatrix3x4fvBase(context, entryPoint, programPacked, locationPacked,
3914 count, transpose, value);
3915 }
3916
ValidateProgramUniformMatrix4fvEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,GLboolean transpose,const GLfloat * value)3917 bool ValidateProgramUniformMatrix4fvEXT(const Context *context,
3918 angle::EntryPoint entryPoint,
3919 ShaderProgramID programPacked,
3920 UniformLocation locationPacked,
3921 GLsizei count,
3922 GLboolean transpose,
3923 const GLfloat *value)
3924 {
3925 if (!context->getExtensions().separateShaderObjectsEXT)
3926 {
3927 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3928 return false;
3929 }
3930
3931 return ValidateProgramUniformMatrix4fvBase(context, entryPoint, programPacked, locationPacked,
3932 count, transpose, value);
3933 }
3934
ValidateProgramUniformMatrix4x2fvEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,GLboolean transpose,const GLfloat * value)3935 bool ValidateProgramUniformMatrix4x2fvEXT(const Context *context,
3936 angle::EntryPoint entryPoint,
3937 ShaderProgramID programPacked,
3938 UniformLocation locationPacked,
3939 GLsizei count,
3940 GLboolean transpose,
3941 const GLfloat *value)
3942 {
3943 if (!context->getExtensions().separateShaderObjectsEXT)
3944 {
3945 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3946 return false;
3947 }
3948
3949 return ValidateProgramUniformMatrix4x2fvBase(context, entryPoint, programPacked, locationPacked,
3950 count, transpose, value);
3951 }
3952
ValidateProgramUniformMatrix4x3fvEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,GLboolean transpose,const GLfloat * value)3953 bool ValidateProgramUniformMatrix4x3fvEXT(const Context *context,
3954 angle::EntryPoint entryPoint,
3955 ShaderProgramID programPacked,
3956 UniformLocation locationPacked,
3957 GLsizei count,
3958 GLboolean transpose,
3959 const GLfloat *value)
3960 {
3961 if (!context->getExtensions().separateShaderObjectsEXT)
3962 {
3963 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3964 return false;
3965 }
3966
3967 return ValidateProgramUniformMatrix4x3fvBase(context, entryPoint, programPacked, locationPacked,
3968 count, transpose, value);
3969 }
3970
ValidateUseProgramStagesEXT(const Context * context,angle::EntryPoint entryPoint,ProgramPipelineID pipelinePacked,GLbitfield stages,ShaderProgramID programPacked)3971 bool ValidateUseProgramStagesEXT(const Context *context,
3972 angle::EntryPoint entryPoint,
3973 ProgramPipelineID pipelinePacked,
3974 GLbitfield stages,
3975 ShaderProgramID programPacked)
3976 {
3977 if (!context->getExtensions().separateShaderObjectsEXT)
3978 {
3979 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3980 return false;
3981 }
3982
3983 return ValidateUseProgramStagesBase(context, entryPoint, pipelinePacked, stages, programPacked);
3984 }
3985
ValidateValidateProgramPipelineEXT(const Context * context,angle::EntryPoint entryPoint,ProgramPipelineID pipelinePacked)3986 bool ValidateValidateProgramPipelineEXT(const Context *context,
3987 angle::EntryPoint entryPoint,
3988 ProgramPipelineID pipelinePacked)
3989 {
3990 if (!context->getExtensions().separateShaderObjectsEXT)
3991 {
3992 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3993 return false;
3994 }
3995
3996 return ValidateValidateProgramPipelineBase(context, entryPoint, pipelinePacked);
3997 }
3998
3999 // GL_EXT_debug_label
ValidateGetObjectLabelEXT(const Context * context,angle::EntryPoint entryPoint,GLenum type,GLuint object,GLsizei bufSize,const GLsizei * length,const GLchar * label)4000 bool ValidateGetObjectLabelEXT(const Context *context,
4001 angle::EntryPoint entryPoint,
4002 GLenum type,
4003 GLuint object,
4004 GLsizei bufSize,
4005 const GLsizei *length,
4006 const GLchar *label)
4007 {
4008 if (!context->getExtensions().debugLabelEXT)
4009 {
4010 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
4011 return false;
4012 }
4013
4014 if (bufSize < 0)
4015 {
4016 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeBufferSize);
4017 return false;
4018 }
4019
4020 return ValidateObjectIdentifierAndName(context, entryPoint, type, object);
4021 }
4022
ValidateLabelObjectEXT(const Context * context,angle::EntryPoint entryPoint,GLenum type,GLuint object,GLsizei length,const GLchar * label)4023 bool ValidateLabelObjectEXT(const Context *context,
4024 angle::EntryPoint entryPoint,
4025 GLenum type,
4026 GLuint object,
4027 GLsizei length,
4028 const GLchar *label)
4029 {
4030 if (!context->getExtensions().debugLabelEXT)
4031 {
4032 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
4033 return false;
4034 }
4035
4036 if (length < 0)
4037 {
4038 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeLength);
4039 return false;
4040 }
4041
4042 return ValidateObjectIdentifierAndName(context, entryPoint, type, object);
4043 }
4044
ValidateEGLImageTargetTextureStorageEXT(const Context * context,angle::EntryPoint entryPoint,GLuint texture,egl::ImageID image,const GLint * attrib_list)4045 bool ValidateEGLImageTargetTextureStorageEXT(const Context *context,
4046 angle::EntryPoint entryPoint,
4047 GLuint texture,
4048 egl::ImageID image,
4049 const GLint *attrib_list)
4050 {
4051 UNREACHABLE();
4052 return false;
4053 }
4054
ValidateEGLImageTargetTexStorageEXT(const Context * context,angle::EntryPoint entryPoint,GLenum target,egl::ImageID image,const GLint * attrib_list)4055 bool ValidateEGLImageTargetTexStorageEXT(const Context *context,
4056 angle::EntryPoint entryPoint,
4057 GLenum target,
4058 egl::ImageID image,
4059 const GLint *attrib_list)
4060 {
4061 if (!context->getExtensions().EGLImageStorageEXT)
4062 {
4063 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
4064 return false;
4065 }
4066
4067 gl::TextureType targetType = FromGLenum<TextureType>(target);
4068 switch (targetType)
4069 {
4070 case TextureType::External:
4071 if (!context->getExtensions().EGLImageExternalOES)
4072 {
4073 ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, ToGLenum(targetType));
4074 }
4075 break;
4076 case TextureType::CubeMapArray:
4077 if (!context->getExtensions().textureCubeMapArrayAny())
4078 {
4079 ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, ToGLenum(targetType));
4080 }
4081 break;
4082 case TextureType::_2D:
4083 case TextureType::_2DArray:
4084 case TextureType::_3D:
4085 case TextureType::CubeMap:
4086 break;
4087 default:
4088 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidTextureTarget);
4089 return false;
4090 }
4091
4092 // Validate egl source image is valid
4093 egl::Image *imageObject = context->getDisplay()->getImage(image);
4094 if (!ValidateEGLImageObject(context, entryPoint, targetType, image))
4095 {
4096 return false;
4097 }
4098
4099 if (attrib_list != nullptr)
4100 {
4101 for (const GLint *attrib = attrib_list; attrib[0] != GL_NONE; attrib += 2)
4102 {
4103 switch (attrib[0])
4104 {
4105 case GL_SURFACE_COMPRESSION_EXT:
4106 switch (attrib[1])
4107 {
4108 case GL_SURFACE_COMPRESSION_FIXED_RATE_NONE_EXT:
4109 if (imageObject->isFixedRatedCompression(context))
4110 {
4111 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kAttributeNotMatch);
4112 return false;
4113 }
4114 break;
4115 case GL_SURFACE_COMPRESSION_FIXED_RATE_DEFAULT_EXT:
4116 break;
4117 default:
4118 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kAttributeNotValid);
4119 return false;
4120 }
4121 break;
4122 default:
4123 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kAttributeNotValid);
4124 return false;
4125 }
4126 }
4127 }
4128
4129 GLsizei levelCount = imageObject->getLevelCount();
4130 Extents size = imageObject->getExtents();
4131 GLsizei width = static_cast<GLsizei>(size.width);
4132 GLsizei height = static_cast<GLsizei>(size.height);
4133 GLsizei depth = static_cast<GLsizei>(size.depth);
4134 GLenum internalformat = imageObject->getFormat().info->sizedInternalFormat;
4135
4136 if (width < 1 || height < 1 || depth < 1 || levelCount < 1)
4137 {
4138 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kTextureSizeTooSmall);
4139 return false;
4140 }
4141
4142 if (!ValidateES3TexStorageParametersLevel(context, entryPoint, targetType, levelCount, width,
4143 height, depth))
4144 {
4145 // Error already generated.
4146 return false;
4147 }
4148
4149 if (targetType == TextureType::External)
4150 {
4151 const Caps &caps = context->getCaps();
4152 if (width > caps.max2DTextureSize || height > caps.max2DTextureSize)
4153 {
4154 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kResourceMaxTextureSize);
4155 return false;
4156 }
4157 }
4158 else if (!ValidateES3TexStorageParametersExtent(context, entryPoint, targetType, levelCount,
4159 width, height, depth))
4160 {
4161 // Error already generated.
4162 return false;
4163 }
4164
4165 if (!ValidateES3TexStorageParametersTexObject(context, entryPoint, targetType))
4166 {
4167 // Error already generated.
4168 return false;
4169 }
4170
4171 if (!ValidateES3TexStorageParametersFormat(context, entryPoint, targetType, levelCount,
4172 internalformat, width, height, depth))
4173 {
4174 // Error already generated.
4175 return false;
4176 }
4177
4178 return true;
4179 }
4180
ValidateAcquireTexturesANGLE(const Context * context,angle::EntryPoint entryPoint,GLuint numTextures,const TextureID * textures,const GLenum * layouts)4181 bool ValidateAcquireTexturesANGLE(const Context *context,
4182 angle::EntryPoint entryPoint,
4183 GLuint numTextures,
4184 const TextureID *textures,
4185 const GLenum *layouts)
4186 {
4187 if (!context->getExtensions().vulkanImageANGLE)
4188 {
4189 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
4190 return false;
4191 }
4192
4193 for (GLuint i = 0; i < numTextures; ++i)
4194 {
4195 if (!context->getTexture(textures[i]))
4196 {
4197 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidTextureName);
4198 return false;
4199 }
4200 if (!IsValidImageLayout(FromGLenum<ImageLayout>(layouts[i])))
4201 {
4202 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidImageLayout);
4203 return false;
4204 }
4205 }
4206
4207 return true;
4208 }
4209
ValidateReleaseTexturesANGLE(const Context * context,angle::EntryPoint entryPoint,GLuint numTextures,const TextureID * textures,const GLenum * layouts)4210 bool ValidateReleaseTexturesANGLE(const Context *context,
4211 angle::EntryPoint entryPoint,
4212 GLuint numTextures,
4213 const TextureID *textures,
4214 const GLenum *layouts)
4215 {
4216 if (!context->getExtensions().vulkanImageANGLE)
4217 {
4218 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
4219 return false;
4220 }
4221 for (GLuint i = 0; i < numTextures; ++i)
4222 {
4223 if (!context->getTexture(textures[i]))
4224 {
4225 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidTextureName);
4226 return false;
4227 }
4228 }
4229
4230 return true;
4231 }
4232
ValidateFramebufferParameteriMESA(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLenum pname,GLint param)4233 bool ValidateFramebufferParameteriMESA(const Context *context,
4234 angle::EntryPoint entryPoint,
4235 GLenum target,
4236 GLenum pname,
4237 GLint param)
4238 {
4239 if (pname != GL_FRAMEBUFFER_FLIP_Y_MESA)
4240 {
4241 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidPname);
4242 return false;
4243 }
4244 return ValidateFramebufferParameteriBase(context, entryPoint, target, pname, param);
4245 }
4246
ValidateGetFramebufferParameterivMESA(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLenum pname,const GLint * params)4247 bool ValidateGetFramebufferParameterivMESA(const Context *context,
4248 angle::EntryPoint entryPoint,
4249 GLenum target,
4250 GLenum pname,
4251 const GLint *params)
4252 {
4253 if (pname != GL_FRAMEBUFFER_FLIP_Y_MESA)
4254 {
4255 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidPname);
4256 return false;
4257 }
4258 return ValidateGetFramebufferParameterivBase(context, entryPoint, target, pname, params);
4259 }
4260
4261 // GL_AMD_performance_monitor
ValidateBeginPerfMonitorAMD(const Context * context,angle::EntryPoint entryPoint,GLuint monitor)4262 bool ValidateBeginPerfMonitorAMD(const Context *context,
4263 angle::EntryPoint entryPoint,
4264 GLuint monitor)
4265 {
4266 if (!context->getExtensions().performanceMonitorAMD)
4267 {
4268 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
4269 return false;
4270 }
4271
4272 return true;
4273 }
4274
ValidateDeletePerfMonitorsAMD(const Context * context,angle::EntryPoint entryPoint,GLsizei n,const GLuint * monitors)4275 bool ValidateDeletePerfMonitorsAMD(const Context *context,
4276 angle::EntryPoint entryPoint,
4277 GLsizei n,
4278 const GLuint *monitors)
4279 {
4280 if (!context->getExtensions().performanceMonitorAMD)
4281 {
4282 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
4283 return false;
4284 }
4285
4286 // Note: ANGLE does not really create monitor objects or track ids.
4287 return true;
4288 }
4289
ValidateEndPerfMonitorAMD(const Context * context,angle::EntryPoint entryPoint,GLuint monitor)4290 bool ValidateEndPerfMonitorAMD(const Context *context, angle::EntryPoint entryPoint, GLuint monitor)
4291 {
4292 if (!context->getExtensions().performanceMonitorAMD)
4293 {
4294 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
4295 return false;
4296 }
4297
4298 if (!context->getState().isPerfMonitorActive())
4299 {
4300 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPerfMonitorNotActive);
4301 return false;
4302 }
4303
4304 return true;
4305 }
4306
ValidateGenPerfMonitorsAMD(const Context * context,angle::EntryPoint entryPoint,GLsizei n,const GLuint * monitors)4307 bool ValidateGenPerfMonitorsAMD(const Context *context,
4308 angle::EntryPoint entryPoint,
4309 GLsizei n,
4310 const GLuint *monitors)
4311 {
4312 if (!context->getExtensions().performanceMonitorAMD)
4313 {
4314 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
4315 return false;
4316 }
4317
4318 return true;
4319 }
4320
ValidateGetPerfMonitorCounterDataAMD(const Context * context,angle::EntryPoint entryPoint,GLuint monitor,GLenum pname,GLsizei dataSize,const GLuint * data,const GLint * bytesWritten)4321 bool ValidateGetPerfMonitorCounterDataAMD(const Context *context,
4322 angle::EntryPoint entryPoint,
4323 GLuint monitor,
4324 GLenum pname,
4325 GLsizei dataSize,
4326 const GLuint *data,
4327 const GLint *bytesWritten)
4328 {
4329 if (!context->getExtensions().performanceMonitorAMD)
4330 {
4331 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
4332 return false;
4333 }
4334
4335 if (monitor != 0)
4336 {
4337 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidPerfMonitor);
4338 return false;
4339 }
4340
4341 switch (pname)
4342 {
4343 case GL_PERFMON_RESULT_AVAILABLE_AMD:
4344 case GL_PERFMON_RESULT_SIZE_AMD:
4345 case GL_PERFMON_RESULT_AMD:
4346 break;
4347
4348 default:
4349 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidPname);
4350 return false;
4351 }
4352
4353 return true;
4354 }
4355
ValidateGetPerfMonitorCounterInfoAMD(const Context * context,angle::EntryPoint entryPoint,GLuint group,GLuint counter,GLenum pname,const void * data)4356 bool ValidateGetPerfMonitorCounterInfoAMD(const Context *context,
4357 angle::EntryPoint entryPoint,
4358 GLuint group,
4359 GLuint counter,
4360 GLenum pname,
4361 const void *data)
4362 {
4363 if (!context->getExtensions().performanceMonitorAMD)
4364 {
4365 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
4366 return false;
4367 }
4368
4369 const angle::PerfMonitorCounterGroups &groups = context->getPerfMonitorCounterGroups();
4370
4371 if (group >= groups.size())
4372 {
4373 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidPerfMonitorGroup);
4374 return false;
4375 }
4376
4377 if (counter >= groups[group].counters.size())
4378 {
4379 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidPerfMonitorCounter);
4380 return false;
4381 }
4382
4383 switch (pname)
4384 {
4385 case GL_COUNTER_TYPE_AMD:
4386 case GL_COUNTER_RANGE_AMD:
4387 break;
4388
4389 default:
4390 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidPname);
4391 return false;
4392 }
4393
4394 return true;
4395 }
4396
ValidateGetPerfMonitorCounterStringAMD(const Context * context,angle::EntryPoint entryPoint,GLuint group,GLuint counter,GLsizei bufSize,const GLsizei * length,const GLchar * counterString)4397 bool ValidateGetPerfMonitorCounterStringAMD(const Context *context,
4398 angle::EntryPoint entryPoint,
4399 GLuint group,
4400 GLuint counter,
4401 GLsizei bufSize,
4402 const GLsizei *length,
4403 const GLchar *counterString)
4404 {
4405 if (!context->getExtensions().performanceMonitorAMD)
4406 {
4407 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
4408 return false;
4409 }
4410
4411 const angle::PerfMonitorCounterGroups &groups = context->getPerfMonitorCounterGroups();
4412
4413 if (group >= groups.size())
4414 {
4415 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidPerfMonitorGroup);
4416 return false;
4417 }
4418
4419 if (counter >= groups[group].counters.size())
4420 {
4421 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidPerfMonitorCounter);
4422 return false;
4423 }
4424
4425 return true;
4426 }
4427
ValidateGetPerfMonitorCountersAMD(const Context * context,angle::EntryPoint entryPoint,GLuint group,const GLint * numCounters,const GLint * maxActiveCounters,GLsizei counterSize,const GLuint * counters)4428 bool ValidateGetPerfMonitorCountersAMD(const Context *context,
4429 angle::EntryPoint entryPoint,
4430 GLuint group,
4431 const GLint *numCounters,
4432 const GLint *maxActiveCounters,
4433 GLsizei counterSize,
4434 const GLuint *counters)
4435 {
4436 if (!context->getExtensions().performanceMonitorAMD)
4437 {
4438 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
4439 return false;
4440 }
4441
4442 const angle::PerfMonitorCounterGroups &groups = context->getPerfMonitorCounterGroups();
4443
4444 if (group >= groups.size())
4445 {
4446 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidPerfMonitorGroup);
4447 return false;
4448 }
4449
4450 return true;
4451 }
4452
ValidateGetPerfMonitorGroupStringAMD(const Context * context,angle::EntryPoint entryPoint,GLuint group,GLsizei bufSize,const GLsizei * length,const GLchar * groupString)4453 bool ValidateGetPerfMonitorGroupStringAMD(const Context *context,
4454 angle::EntryPoint entryPoint,
4455 GLuint group,
4456 GLsizei bufSize,
4457 const GLsizei *length,
4458 const GLchar *groupString)
4459 {
4460 if (!context->getExtensions().performanceMonitorAMD)
4461 {
4462 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
4463 return false;
4464 }
4465
4466 const angle::PerfMonitorCounterGroups &groups = context->getPerfMonitorCounterGroups();
4467
4468 if (group >= groups.size())
4469 {
4470 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidPerfMonitorGroup);
4471 return false;
4472 }
4473
4474 return true;
4475 }
4476
ValidateGetPerfMonitorGroupsAMD(const Context * context,angle::EntryPoint entryPoint,const GLint * numGroups,GLsizei groupsSize,const GLuint * groups)4477 bool ValidateGetPerfMonitorGroupsAMD(const Context *context,
4478 angle::EntryPoint entryPoint,
4479 const GLint *numGroups,
4480 GLsizei groupsSize,
4481 const GLuint *groups)
4482 {
4483 if (!context->getExtensions().performanceMonitorAMD)
4484 {
4485 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
4486 return false;
4487 }
4488
4489 return true;
4490 }
4491
ValidateSelectPerfMonitorCountersAMD(const Context * context,angle::EntryPoint entryPoint,GLuint monitor,GLboolean enable,GLuint group,GLint numCounters,const GLuint * counterList)4492 bool ValidateSelectPerfMonitorCountersAMD(const Context *context,
4493 angle::EntryPoint entryPoint,
4494 GLuint monitor,
4495 GLboolean enable,
4496 GLuint group,
4497 GLint numCounters,
4498 const GLuint *counterList)
4499 {
4500 if (!context->getExtensions().performanceMonitorAMD)
4501 {
4502 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
4503 return false;
4504 }
4505
4506 UNIMPLEMENTED();
4507 return false;
4508 }
4509
ValidateShadingRateQCOM(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLenum rate)4510 bool ValidateShadingRateQCOM(const PrivateState &state,
4511 ErrorSet *errors,
4512 angle::EntryPoint entryPoint,
4513 GLenum rate)
4514 {
4515 if (!state.getExtensions().shadingRateQCOM)
4516 {
4517 errors->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
4518 return false;
4519 }
4520
4521 gl::ShadingRate shadingRate = gl::FromGLenum<gl::ShadingRate>(rate);
4522 if (shadingRate == gl::ShadingRate::Undefined || shadingRate == gl::ShadingRate::InvalidEnum)
4523 {
4524 errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidShadingRate);
4525 return false;
4526 }
4527
4528 return true;
4529 }
4530
ValidateLogicOpANGLE(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,LogicalOperation opcodePacked)4531 bool ValidateLogicOpANGLE(const PrivateState &state,
4532 ErrorSet *errors,
4533 angle::EntryPoint entryPoint,
4534 LogicalOperation opcodePacked)
4535 {
4536 if (!state.getExtensions().logicOpANGLE)
4537 {
4538 errors->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
4539 return false;
4540 }
4541
4542 return ValidateLogicOpCommon(state, errors, entryPoint, opcodePacked);
4543 }
4544
ValidateFramebufferFoveationConfigQCOM(const Context * context,angle::EntryPoint entryPoint,FramebufferID framebufferPacked,GLuint numLayers,GLuint focalPointsPerLayer,GLuint requestedFeatures,const GLuint * providedFeatures)4545 bool ValidateFramebufferFoveationConfigQCOM(const Context *context,
4546 angle::EntryPoint entryPoint,
4547 FramebufferID framebufferPacked,
4548 GLuint numLayers,
4549 GLuint focalPointsPerLayer,
4550 GLuint requestedFeatures,
4551 const GLuint *providedFeatures)
4552 {
4553 Framebuffer *framebuffer = context->getFramebuffer(framebufferPacked);
4554
4555 // INVALID_VALUE is generated by FramebufferFoveationConfigQCOM if 'fbo' is not a valid
4556 // framebuffer.
4557 if (framebuffer == nullptr)
4558 {
4559 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidFramebufferName);
4560 return false;
4561 }
4562
4563 // INVALID_VALUE is generated by FramebufferFoveationConfigQCOM if 'numLayers' is greater than
4564 // GL_MAX_ARRAY_TEXTURE_LAYERS - 1.
4565 if (numLayers > static_cast<GLuint>(context->getState().getCaps().maxArrayTextureLayers) - 1)
4566 {
4567 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kFramebufferFoveationLayersExceedMaxArrayLayers);
4568 return false;
4569 }
4570
4571 // INVALID_VALUE is generated by FramebufferFoveationConfigQCOM if 'numFocalPoints' is greater
4572 // than implementation can support.
4573 if (focalPointsPerLayer > gl::IMPLEMENTATION_MAX_FOCAL_POINTS)
4574 {
4575 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kFocalPointsExceedMaxFocalPoints);
4576 return false;
4577 }
4578
4579 // INVALID_OPERATION is generated by FramebufferFoveationConfigQCOM if it is called for a fbo
4580 // that has already been cofigured for foveated rendering.
4581 if (framebuffer->isFoveationConfigured())
4582 {
4583 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kFramebufferFoveationAlreadyConfigured);
4584 return false;
4585 }
4586
4587 return true;
4588 }
4589
ValidateFramebufferFoveationParametersQCOM(const Context * context,angle::EntryPoint entryPoint,FramebufferID framebufferPacked,GLuint layer,GLuint focalPoint,GLfloat focalX,GLfloat focalY,GLfloat gainX,GLfloat gainY,GLfloat foveaArea)4590 bool ValidateFramebufferFoveationParametersQCOM(const Context *context,
4591 angle::EntryPoint entryPoint,
4592 FramebufferID framebufferPacked,
4593 GLuint layer,
4594 GLuint focalPoint,
4595 GLfloat focalX,
4596 GLfloat focalY,
4597 GLfloat gainX,
4598 GLfloat gainY,
4599 GLfloat foveaArea)
4600 {
4601 Framebuffer *framebuffer = context->getFramebuffer(framebufferPacked);
4602
4603 // INVALID_VALUE is generated by FramebufferFoveationParametersQCOM if 'fbo' is not a valid
4604 // framebuffer.
4605 if (framebuffer == nullptr)
4606 {
4607 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidFramebufferName);
4608 return false;
4609 }
4610
4611 // INVALID_OPERATION is generated by FramebufferFoveationParametersQCOM if 'fbo' has not been
4612 // configured for foveated rendering.
4613 if (!framebuffer->isFoveationConfigured())
4614 {
4615 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kFramebufferFoveationNotConfigured);
4616 return false;
4617 }
4618
4619 // INVALID_VALUE is generated by FramebufferFoveationParametersQCOM if 'layer' is greater than
4620 // or equal to the numLayers that the fbo was previously configured for in
4621 // FramebufferFoveationConfigQCOM.
4622 if (layer >= gl::IMPLEMENTATION_MAX_NUM_LAYERS)
4623 {
4624 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kFramebufferFoveationLayersExceedMaxArrayLayers);
4625 return false;
4626 }
4627
4628 // INVALID_VALUE is generated by FramebufferFoveationParametersQCOM if 'numFocalPoints' is
4629 // greater than implementation can support. INVALID_OPERATION is generated by
4630 if (focalPoint >= gl::IMPLEMENTATION_MAX_FOCAL_POINTS)
4631 {
4632 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kFocalPointsExceedMaxFocalPoints);
4633 return false;
4634 }
4635 return true;
4636 }
4637
ValidateTextureFoveationParametersQCOM(const Context * context,angle::EntryPoint entryPoint,TextureID texturePacked,GLuint layer,GLuint focalPoint,GLfloat focalX,GLfloat focalY,GLfloat gainX,GLfloat gainY,GLfloat foveaArea)4638 bool ValidateTextureFoveationParametersQCOM(const Context *context,
4639 angle::EntryPoint entryPoint,
4640 TextureID texturePacked,
4641 GLuint layer,
4642 GLuint focalPoint,
4643 GLfloat focalX,
4644 GLfloat focalY,
4645 GLfloat gainX,
4646 GLfloat gainY,
4647 GLfloat foveaArea)
4648 {
4649 Texture *texture = context->getTexture(texturePacked);
4650
4651 // INVALID_VALUE is generated by TextureFoveationParametersQCOM if 'texture' is not a valid
4652 // texture object.
4653 if (texture == nullptr)
4654 {
4655 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidTextureName);
4656 return false;
4657 }
4658
4659 // INVALID_OPERATION is generated by TextureFoveationParametersQCOM if 'texture' has not been
4660 // set as foveated. i.e. 'texture's parameter TEXTURE_FOVEATED_FEATURE_BITS_QCOM does not
4661 // contain FOVEATION_ENABLE_BIT_QCOM.
4662 if (!texture->isFoveationEnabled())
4663 {
4664 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kTextureFoveationNotEnabled);
4665 return false;
4666 }
4667
4668 // INVALID_VALUE is generated by TextureFoveationParametersQCOM if 'focalPoint' is larger than
4669 // TEXTURE_FOVEATED_NUM_FOCAL_POINTS_QUERY_QCOM minus one.
4670 if (focalPoint > texture->getNumFocalPoints() - 1)
4671 {
4672 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kFocalPointsExceedMaxFocalPoints);
4673 return false;
4674 }
4675
4676 return true;
4677 }
4678
ValidateEndTilingQCOM(const Context * context,angle::EntryPoint entryPoint,GLbitfield preserveMask)4679 bool ValidateEndTilingQCOM(const Context *context,
4680 angle::EntryPoint entryPoint,
4681 GLbitfield preserveMask)
4682 {
4683 if (!context->getExtensions().tiledRenderingQCOM)
4684 {
4685 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
4686 return false;
4687 }
4688
4689 const gl::PrivateState &privateState = context->getPrivateState();
4690 if (!privateState.isTiledRendering())
4691 {
4692 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kTilingEndCalledWithoutStart);
4693 return false;
4694 }
4695
4696 // preserveMask does not need to be validated. The bitfield covers the entire 32 bits of
4697 // GLbitfield and unbound attachments are siliently ignored like in glClear
4698
4699 return true;
4700 }
4701
ValidateStartTilingQCOM(const Context * context,angle::EntryPoint entryPoint,GLuint x,GLuint y,GLuint width,GLuint height,GLbitfield preserveMask)4702 bool ValidateStartTilingQCOM(const Context *context,
4703 angle::EntryPoint entryPoint,
4704 GLuint x,
4705 GLuint y,
4706 GLuint width,
4707 GLuint height,
4708 GLbitfield preserveMask)
4709 {
4710 if (!context->getExtensions().tiledRenderingQCOM)
4711 {
4712 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
4713 return false;
4714 }
4715
4716 const gl::PrivateState &privateState = context->getPrivateState();
4717 if (privateState.isTiledRendering())
4718 {
4719 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kTilingStartCalledWithoutEnd);
4720 return false;
4721 }
4722
4723 Framebuffer *framebuffer = context->getState().getDrawFramebuffer();
4724 const FramebufferStatus &framebufferStatus = framebuffer->checkStatus(context);
4725 if (!framebufferStatus.isComplete())
4726 {
4727 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, framebufferStatus.reason);
4728 return false;
4729 }
4730
4731 // preserveMask does not need to be validated. The bitfield covers the entire 32 bits of
4732 // GLbitfield and unbound attachments are siliently ignored like in glClear
4733
4734 return true;
4735 }
4736
ValidateTexStorageAttribs(const GLint * attrib_list)4737 bool ValidateTexStorageAttribs(const GLint *attrib_list)
4738 {
4739 if (nullptr != attrib_list && GL_NONE != *attrib_list)
4740 {
4741 attrib_list++;
4742 if (nullptr == attrib_list)
4743 {
4744 return false;
4745 }
4746
4747 if (*attrib_list == GL_SURFACE_COMPRESSION_FIXED_RATE_NONE_EXT ||
4748 *attrib_list == GL_SURFACE_COMPRESSION_FIXED_RATE_DEFAULT_EXT)
4749 {
4750 return true;
4751 }
4752 else if (*attrib_list >= GL_SURFACE_COMPRESSION_FIXED_RATE_1BPC_EXT &&
4753 *attrib_list <= GL_SURFACE_COMPRESSION_FIXED_RATE_12BPC_EXT)
4754 {
4755 return true;
4756 }
4757 else
4758 {
4759 return false;
4760 }
4761 }
4762
4763 return true;
4764 }
4765
ValidateTexStorageAttribs2DEXT(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLsizei levels,GLenum internalformat,GLsizei width,GLsizei height,const GLint * attrib_list)4766 bool ValidateTexStorageAttribs2DEXT(const Context *context,
4767 angle::EntryPoint entryPoint,
4768 GLenum target,
4769 GLsizei levels,
4770 GLenum internalformat,
4771 GLsizei width,
4772 GLsizei height,
4773 const GLint *attrib_list)
4774 {
4775 gl::TextureType targetType = FromGLenum<TextureType>(target);
4776 if (!context->getExtensions().textureStorageCompressionEXT)
4777 {
4778 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
4779 return false;
4780 }
4781
4782 if (ValidateTexStorageAttribs(attrib_list) == false)
4783 {
4784 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidAttribList);
4785 }
4786
4787 if (context->getClientMajorVersion() < 3)
4788 {
4789 return ValidateES2TexStorageParametersBase(context, entryPoint, targetType, levels,
4790 internalformat, width, height);
4791 }
4792
4793 if (context->getClientMajorVersion() >= 3)
4794 {
4795 return ValidateES3TexStorage2DParameters(context, entryPoint, targetType, levels,
4796 internalformat, width, height, 1);
4797 }
4798
4799 return true;
4800 }
4801
ValidateTexStorageAttribs3DEXT(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLsizei levels,GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth,const GLint * attrib_list)4802 bool ValidateTexStorageAttribs3DEXT(const Context *context,
4803 angle::EntryPoint entryPoint,
4804 GLenum target,
4805 GLsizei levels,
4806 GLenum internalformat,
4807 GLsizei width,
4808 GLsizei height,
4809 GLsizei depth,
4810 const GLint *attrib_list)
4811 {
4812 gl::TextureType targetType = FromGLenum<TextureType>(target);
4813 if (!context->getExtensions().textureStorageCompressionEXT)
4814 {
4815 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
4816 return false;
4817 }
4818
4819 if (ValidateTexStorageAttribs(attrib_list) == false)
4820 {
4821 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidAttribList);
4822 }
4823
4824 if (context->getClientMajorVersion() < 3)
4825 {
4826 return ValidateES2TexStorageParametersBase(context, entryPoint, targetType, levels,
4827 internalformat, width, height);
4828 }
4829
4830 if (context->getClientMajorVersion() >= 3)
4831 {
4832 return ValidateES3TexStorage3DParameters(context, entryPoint, targetType, levels,
4833 internalformat, width, height, depth);
4834 }
4835
4836 return true;
4837 }
4838
4839 } // namespace gl
4840