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, kNegativeBufSize);
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, memoryObjects);
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, memoryObjects);
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, semaphores);
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, semaphores);
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, params);
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, params);
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 params);
1923 }
1924
ValidateGetSamplerParameterIuivEXT(const Context * context,angle::EntryPoint entryPoint,SamplerID samplerPacked,GLenum pname,const GLuint * params)1925 bool ValidateGetSamplerParameterIuivEXT(const Context *context,
1926 angle::EntryPoint entryPoint,
1927 SamplerID samplerPacked,
1928 GLenum pname,
1929 const GLuint *params)
1930 {
1931 if (context->getClientMajorVersion() < 3)
1932 {
1933 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
1934 }
1935
1936 if (!context->getExtensions().textureBorderClampEXT)
1937 {
1938 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1939 return false;
1940 }
1941 return ValidateGetSamplerParameterBase(context, entryPoint, samplerPacked, pname, nullptr,
1942 params);
1943 }
1944
ValidateGetTexParameterIivEXT(const Context * context,angle::EntryPoint entryPoint,TextureType targetPacked,GLenum pname,const GLint * params)1945 bool ValidateGetTexParameterIivEXT(const Context *context,
1946 angle::EntryPoint entryPoint,
1947 TextureType targetPacked,
1948 GLenum pname,
1949 const GLint *params)
1950 {
1951 if (context->getClientMajorVersion() < 3)
1952 {
1953 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
1954 }
1955
1956 if (!context->getExtensions().textureBorderClampEXT)
1957 {
1958 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1959 return false;
1960 }
1961 return ValidateGetTexParameterBase(context, entryPoint, targetPacked, pname, nullptr);
1962 }
1963
ValidateGetTexParameterIuivEXT(const Context * context,angle::EntryPoint entryPoint,TextureType targetPacked,GLenum pname,const GLuint * params)1964 bool ValidateGetTexParameterIuivEXT(const Context *context,
1965 angle::EntryPoint entryPoint,
1966 TextureType targetPacked,
1967 GLenum pname,
1968 const GLuint *params)
1969 {
1970 if (context->getClientMajorVersion() < 3)
1971 {
1972 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
1973 }
1974
1975 if (!context->getExtensions().textureBorderClampEXT)
1976 {
1977 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1978 return false;
1979 }
1980 return ValidateGetTexParameterBase(context, entryPoint, targetPacked, pname, nullptr);
1981 }
1982
ValidateSamplerParameterIivEXT(const Context * context,angle::EntryPoint entryPoint,SamplerID samplerPacked,GLenum pname,const GLint * param)1983 bool ValidateSamplerParameterIivEXT(const Context *context,
1984 angle::EntryPoint entryPoint,
1985 SamplerID samplerPacked,
1986 GLenum pname,
1987 const GLint *param)
1988 {
1989 if (context->getClientMajorVersion() < 3)
1990 {
1991 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
1992 }
1993
1994 if (!context->getExtensions().textureBorderClampEXT)
1995 {
1996 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
1997 return false;
1998 }
1999 return ValidateSamplerParameterBase(context, entryPoint, samplerPacked, pname, -1, true, param);
2000 }
2001
ValidateSamplerParameterIuivEXT(const Context * context,angle::EntryPoint entryPoint,SamplerID samplerPacked,GLenum pname,const GLuint * param)2002 bool ValidateSamplerParameterIuivEXT(const Context *context,
2003 angle::EntryPoint entryPoint,
2004 SamplerID samplerPacked,
2005 GLenum pname,
2006 const GLuint *param)
2007 {
2008 if (context->getClientMajorVersion() < 3)
2009 {
2010 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
2011 }
2012
2013 if (!context->getExtensions().textureBorderClampEXT)
2014 {
2015 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
2016 return false;
2017 }
2018 return ValidateSamplerParameterBase(context, entryPoint, samplerPacked, pname, -1, true, param);
2019 }
2020
ValidateTexParameterIivEXT(const Context * context,angle::EntryPoint entryPoint,TextureType targetPacked,GLenum pname,const GLint * params)2021 bool ValidateTexParameterIivEXT(const Context *context,
2022 angle::EntryPoint entryPoint,
2023 TextureType targetPacked,
2024 GLenum pname,
2025 const GLint *params)
2026 {
2027 if (context->getClientMajorVersion() < 3)
2028 {
2029 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
2030 }
2031
2032 if (!context->getExtensions().textureBorderClampEXT)
2033 {
2034 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
2035 return false;
2036 }
2037 return ValidateTexParameterBase(context, entryPoint, targetPacked, pname, -1, true, params);
2038 }
2039
ValidateTexParameterIuivEXT(const Context * context,angle::EntryPoint entryPoint,TextureType targetPacked,GLenum pname,const GLuint * params)2040 bool ValidateTexParameterIuivEXT(const Context *context,
2041 angle::EntryPoint entryPoint,
2042 TextureType targetPacked,
2043 GLenum pname,
2044 const GLuint *params)
2045 {
2046 if (context->getClientMajorVersion() < 3)
2047 {
2048 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kES3Required);
2049 }
2050
2051 if (!context->getExtensions().textureBorderClampEXT)
2052 {
2053 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
2054 return false;
2055 }
2056 return ValidateTexParameterBase(context, entryPoint, targetPacked, pname, -1, true, params);
2057 }
2058
ValidateImportSemaphoreZirconHandleANGLE(const Context * context,angle::EntryPoint entryPoint,SemaphoreID semaphore,HandleType handleType,GLuint handle)2059 bool ValidateImportSemaphoreZirconHandleANGLE(const Context *context,
2060 angle::EntryPoint entryPoint,
2061 SemaphoreID semaphore,
2062 HandleType handleType,
2063 GLuint handle)
2064 {
2065 if (!context->getExtensions().semaphoreFuchsiaANGLE)
2066 {
2067 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
2068 return false;
2069 }
2070
2071 switch (handleType)
2072 {
2073 case HandleType::ZirconEvent:
2074 break;
2075 default:
2076 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidHandleType);
2077 return false;
2078 }
2079
2080 return true;
2081 }
2082
2083 namespace
2084 {
2085 enum class PLSExpectedStatus
2086 {
2087 Inactive,
2088 Active,
2089 Any
2090 };
2091
ValidatePLSCommon(const Context * context,angle::EntryPoint entryPoint,PLSExpectedStatus expectedStatus)2092 bool ValidatePLSCommon(const Context *context,
2093 angle::EntryPoint entryPoint,
2094 PLSExpectedStatus expectedStatus)
2095 {
2096 // Check that the pixel local storage extension is enabled at all.
2097 if (!context->getExtensions().shaderPixelLocalStorageANGLE)
2098 {
2099 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPLSExtensionNotEnabled);
2100 return false;
2101 }
2102
2103 Framebuffer *framebuffer = context->getState().getDrawFramebuffer();
2104 if (expectedStatus != PLSExpectedStatus::Active)
2105 {
2106 // INVALID_FRAMEBUFFER_OPERATION is generated if the default framebuffer object name 0 is
2107 // bound to DRAW_FRAMEBUFFER.
2108 if (framebuffer->id().value == 0)
2109 {
2110 ANGLE_VALIDATION_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION, kPLSDefaultFramebufferBound);
2111 return false;
2112 }
2113 }
2114
2115 // INVALID_FRAMEBUFFER_OPERATION is generated if pixel local storage on the draw framebuffer is
2116 // in an interrupted state.
2117 const PixelLocalStorage *pls = framebuffer->peekPixelLocalStorage();
2118 if (pls != nullptr && pls->interruptCount() != 0)
2119 {
2120 ANGLE_VALIDATION_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION, kPLSInterrupted);
2121 return false;
2122 }
2123
2124 if (expectedStatus == PLSExpectedStatus::Active)
2125 {
2126 // INVALID_OPERATION is generated if PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE is zero.
2127 if (context->getState().getPixelLocalStorageActivePlanes() == 0)
2128 {
2129 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPLSInactive);
2130 return false;
2131 }
2132 }
2133 else if (expectedStatus == PLSExpectedStatus::Inactive)
2134 {
2135 // INVALID_OPERATION is generated if PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE is nonzero.
2136 if (context->getState().getPixelLocalStorageActivePlanes() != 0)
2137 {
2138 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPLSActive);
2139 return false;
2140 }
2141 }
2142
2143 return true;
2144 }
2145
ValidatePLSCommon(const Context * context,angle::EntryPoint entryPoint,GLint plane,PLSExpectedStatus expectedStatus)2146 bool ValidatePLSCommon(const Context *context,
2147 angle::EntryPoint entryPoint,
2148 GLint plane,
2149 PLSExpectedStatus expectedStatus)
2150 {
2151 if (!ValidatePLSCommon(context, entryPoint, expectedStatus))
2152 {
2153 return false;
2154 }
2155
2156 // INVALID_VALUE is generated if <plane> < 0 or <plane> >= MAX_PIXEL_LOCAL_STORAGE_PLANES_ANGLE.
2157 if (plane < 0)
2158 {
2159 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kPLSPlaneLessThanZero);
2160 return false;
2161 }
2162 if (plane >= static_cast<GLint>(context->getCaps().maxPixelLocalStoragePlanes))
2163 {
2164 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kPLSPlaneOutOfRange);
2165 return false;
2166 }
2167
2168 return true;
2169 }
2170
ValidatePLSInternalformat(const Context * context,angle::EntryPoint entryPoint,GLenum internalformat)2171 bool ValidatePLSInternalformat(const Context *context,
2172 angle::EntryPoint entryPoint,
2173 GLenum internalformat)
2174 {
2175 // INVALID_ENUM is generated if <internalformat> is not one of the acceptable values in Table
2176 // X.2, or NONE.
2177 switch (internalformat)
2178 {
2179 case GL_RGBA8:
2180 case GL_RGBA8I:
2181 case GL_RGBA8UI:
2182 case GL_R32F:
2183 case GL_R32UI:
2184 return true;
2185 default:
2186 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kPLSInvalidInternalformat);
2187 return false;
2188 }
2189 }
2190
ValidatePLSTextureType(const Context * context,angle::EntryPoint entryPoint,Texture * tex,size_t * textureDepth)2191 bool ValidatePLSTextureType(const Context *context,
2192 angle::EntryPoint entryPoint,
2193 Texture *tex,
2194 size_t *textureDepth)
2195 {
2196 // INVALID_OPERATION is generated if <backingtexture> is nonzero
2197 // and not of type TEXTURE_2D or TEXTURE_2D_ARRAY.
2198 switch (tex->getType())
2199 {
2200 case TextureType::_2D:
2201 *textureDepth = 1;
2202 return true;
2203 case TextureType::_2DArray:
2204 *textureDepth = tex->getDepth(TextureTarget::_2DArray, 0);
2205 return true;
2206 default:
2207 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPLSInvalidTextureType);
2208 return false;
2209 }
2210 }
2211
ValidatePLSActiveBlendFunc(const Context * context,angle::EntryPoint entryPoint,gl::BlendFactorType blendFunc)2212 bool ValidatePLSActiveBlendFunc(const Context *context,
2213 angle::EntryPoint entryPoint,
2214 gl::BlendFactorType blendFunc)
2215 {
2216 // INVALID_OPERATION is generated if BLEND_DST_ALPHA, BLEND_DST_RGB, BLEND_SRC_ALPHA, or
2217 // BLEND_SRC_RGB, for any draw buffer, is a blend function requiring the secondary color input,
2218 // as specified in EXT_blend_func_extended.
2219 ASSERT(context->getState().getExtensions().blendFuncExtendedEXT);
2220 switch (blendFunc)
2221 {
2222 case gl::BlendFactorType::Src1Color:
2223 case gl::BlendFactorType::OneMinusSrc1Color:
2224 case gl::BlendFactorType::Src1Alpha:
2225 case gl::BlendFactorType::OneMinusSrc1Alpha:
2226 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPLSSecondaryBlendEnabled);
2227 return false;
2228 default:
2229 return true;
2230 }
2231 }
ValidatePLSActiveBlendEquation(const Context * context,angle::EntryPoint entryPoint,gl::BlendEquationType blendEquation)2232 bool ValidatePLSActiveBlendEquation(const Context *context,
2233 angle::EntryPoint entryPoint,
2234 gl::BlendEquationType blendEquation)
2235 {
2236 // INVALID_OPERATION is generated if BLEND_EQUATION_RGB and/or BLEND_EQUATION_ALPHA is an
2237 // advanced blend equation defined in KHR_blend_equation_advanced.
2238 ASSERT(context->getState().getExtensions().blendEquationAdvancedKHR);
2239 switch (blendEquation)
2240 {
2241 case gl::BlendEquationType::Multiply:
2242 case gl::BlendEquationType::Screen:
2243 case gl::BlendEquationType::Overlay:
2244 case gl::BlendEquationType::Darken:
2245 case gl::BlendEquationType::Lighten:
2246 case gl::BlendEquationType::Colordodge:
2247 case gl::BlendEquationType::Colorburn:
2248 case gl::BlendEquationType::Hardlight:
2249 case gl::BlendEquationType::Softlight:
2250 case gl::BlendEquationType::Difference:
2251 case gl::BlendEquationType::Exclusion:
2252 case gl::BlendEquationType::HslHue:
2253 case gl::BlendEquationType::HslSaturation:
2254 case gl::BlendEquationType::HslColor:
2255 case gl::BlendEquationType::HslLuminosity:
2256 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPLSAdvancedBlendEnabled);
2257 return false;
2258 default:
2259 return true;
2260 }
2261 }
2262
ValidatePLSLoadOperation(const Context * context,angle::EntryPoint entryPoint,GLenum loadop)2263 bool ValidatePLSLoadOperation(const Context *context, angle::EntryPoint entryPoint, GLenum loadop)
2264 {
2265 // INVALID_ENUM is generated if <loadops>[0..<n>-1] is not one of the Load Operations enumerated
2266 // in Table X.1.
2267 switch (loadop)
2268 {
2269 case GL_LOAD_OP_ZERO_ANGLE:
2270 case GL_LOAD_OP_CLEAR_ANGLE:
2271 case GL_LOAD_OP_LOAD_ANGLE:
2272 case GL_DONT_CARE:
2273 return true;
2274 default:
2275 ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kPLSInvalidLoadOperation, loadop);
2276 return false;
2277 }
2278 }
2279
ValidatePLSStoreOperation(const Context * context,angle::EntryPoint entryPoint,GLenum storeop)2280 bool ValidatePLSStoreOperation(const Context *context, angle::EntryPoint entryPoint, GLenum storeop)
2281 {
2282 // INVALID_ENUM is generated if <storeops>[0..PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE-1] is not
2283 // one of the Store Operations enumerated in Table X.2.
2284 switch (storeop)
2285 {
2286 case GL_STORE_OP_STORE_ANGLE:
2287 case GL_DONT_CARE:
2288 return true;
2289 default:
2290 ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kPLSInvalidStoreOperation, storeop);
2291 return false;
2292 }
2293 }
2294
ValidatePLSQueryCommon(const Context * context,angle::EntryPoint entryPoint,GLsizei paramCount,GLsizei bufSize,const void * params)2295 bool ValidatePLSQueryCommon(const Context *context,
2296 angle::EntryPoint entryPoint,
2297 GLsizei paramCount,
2298 GLsizei bufSize,
2299 const void *params)
2300 {
2301 // INVALID_OPERATION is generated if <bufSize> is not large enough to receive the requested
2302 // parameter.
2303 if (paramCount > bufSize)
2304 {
2305 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInsufficientParams);
2306 return false;
2307 }
2308 // INVALID_VALUE is generated if <params> is NULL.
2309 if (params == nullptr)
2310 {
2311 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kPLSParamsNULL);
2312 return false;
2313 }
2314 return true;
2315 }
2316 } // namespace
2317
ValidateFramebufferMemorylessPixelLocalStorageANGLE(const Context * context,angle::EntryPoint entryPoint,GLint plane,GLenum internalformat)2318 bool ValidateFramebufferMemorylessPixelLocalStorageANGLE(const Context *context,
2319 angle::EntryPoint entryPoint,
2320 GLint plane,
2321 GLenum internalformat)
2322 {
2323 if (!ValidatePLSCommon(context, entryPoint, plane, PLSExpectedStatus::Any))
2324 {
2325 return false;
2326 }
2327
2328 // INVALID_ENUM is generated if <internalformat> is not one of the acceptable values in Table
2329 // X.2, or NONE.
2330 if (internalformat != GL_NONE)
2331 {
2332 if (!ValidatePLSInternalformat(context, entryPoint, internalformat))
2333 {
2334 return false;
2335 }
2336 }
2337
2338 return true;
2339 }
2340
ValidateFramebufferTexturePixelLocalStorageANGLE(const Context * context,angle::EntryPoint entryPoint,GLint plane,TextureID backingtexture,GLint level,GLint layer)2341 bool ValidateFramebufferTexturePixelLocalStorageANGLE(const Context *context,
2342 angle::EntryPoint entryPoint,
2343 GLint plane,
2344 TextureID backingtexture,
2345 GLint level,
2346 GLint layer)
2347 {
2348 if (!ValidatePLSCommon(context, entryPoint, plane, PLSExpectedStatus::Any))
2349 {
2350 return false;
2351 }
2352
2353 if (backingtexture.value != 0)
2354 {
2355 Texture *tex = context->getTexture(backingtexture);
2356
2357 // INVALID_OPERATION is generated if <backingtexture> is not the name of an existing
2358 // immutable texture object, or zero.
2359 if (!tex)
2360 {
2361 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidTextureName);
2362 return false;
2363 }
2364 if (!tex->getImmutableFormat())
2365 {
2366 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kTextureIsNotImmutable);
2367 return false;
2368 }
2369
2370 // INVALID_OPERATION is generated if <backingtexture> is nonzero
2371 // and not of type GL_TEXTURE_2D or GL_TEXTURE_2D_ARRAY.
2372 size_t textureDepth;
2373 if (!ValidatePLSTextureType(context, entryPoint, tex, &textureDepth))
2374 {
2375 return false;
2376 }
2377
2378 // INVALID_VALUE is generated if <backingtexture> is nonzero and <level> < 0.
2379 if (level < 0)
2380 {
2381 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeLevel);
2382 return false;
2383 }
2384
2385 // INVALID_VALUE is generated if <backingtexture> is nonzero and <level> >= the
2386 // immutable number of mipmap levels in <backingtexture>.
2387 if (static_cast<GLuint>(level) >= tex->getImmutableLevels())
2388 {
2389 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kTextureLevelOutOfRange);
2390 return false;
2391 }
2392
2393 // INVALID_VALUE is generated if <backingtexture> is nonzero and <layer> < 0.
2394 if (layer < 0)
2395 {
2396 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeLayer);
2397 return false;
2398 }
2399
2400 // INVALID_VALUE is generated if <backingtexture> is nonzero and <layer> >= the immutable
2401 // number of texture layers in <backingtexture>.
2402 if ((size_t)layer >= textureDepth)
2403 {
2404 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kTextureLayerOutOfRange);
2405 return false;
2406 }
2407
2408 // INVALID_ENUM is generated if <backingtexture> is nonzero and its internalformat is not
2409 // one of the acceptable values in Table X.2.
2410 ASSERT(tex->getImmutableFormat());
2411 GLenum internalformat = tex->getState().getBaseLevelDesc().format.info->internalFormat;
2412 if (!ValidatePLSInternalformat(context, entryPoint, internalformat))
2413 {
2414 return false;
2415 }
2416 }
2417
2418 return true;
2419 }
2420
ValidateFramebufferPixelLocalClearValuefvANGLE(const Context * context,angle::EntryPoint entryPoint,GLint plane,const GLfloat[])2421 bool ValidateFramebufferPixelLocalClearValuefvANGLE(const Context *context,
2422 angle::EntryPoint entryPoint,
2423 GLint plane,
2424 const GLfloat[])
2425 {
2426 return ValidatePLSCommon(context, entryPoint, plane, PLSExpectedStatus::Inactive);
2427 }
2428
ValidateFramebufferPixelLocalClearValueivANGLE(const Context * context,angle::EntryPoint entryPoint,GLint plane,const GLint[])2429 bool ValidateFramebufferPixelLocalClearValueivANGLE(const Context *context,
2430 angle::EntryPoint entryPoint,
2431 GLint plane,
2432 const GLint[])
2433 {
2434 return ValidatePLSCommon(context, entryPoint, plane, PLSExpectedStatus::Inactive);
2435 }
2436
ValidateFramebufferPixelLocalClearValueuivANGLE(const Context * context,angle::EntryPoint entryPoint,GLint plane,const GLuint[])2437 bool ValidateFramebufferPixelLocalClearValueuivANGLE(const Context *context,
2438 angle::EntryPoint entryPoint,
2439 GLint plane,
2440 const GLuint[])
2441 {
2442 return ValidatePLSCommon(context, entryPoint, plane, PLSExpectedStatus::Inactive);
2443 }
2444
ValidateBeginPixelLocalStorageANGLE(const Context * context,angle::EntryPoint entryPoint,GLsizei n,const GLenum loadops[])2445 bool ValidateBeginPixelLocalStorageANGLE(const Context *context,
2446 angle::EntryPoint entryPoint,
2447 GLsizei n,
2448 const GLenum loadops[])
2449 {
2450 if (!ValidatePLSCommon(context, entryPoint, PLSExpectedStatus::Inactive))
2451 {
2452 return false;
2453 }
2454
2455 const State &state = context->getState();
2456 const Framebuffer *framebuffer = state.getDrawFramebuffer();
2457
2458 // INVALID_OPERATION is generated if the value of SAMPLE_BUFFERS is 1 (i.e., if rendering to a
2459 // multisampled framebuffer).
2460 if (framebuffer->getSamples(context) != 0)
2461 {
2462 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPLSMultisamplingEnabled);
2463 return false;
2464 }
2465
2466 // INVALID_OPERATION is generated if DITHER is enabled.
2467 if (state.isDitherEnabled())
2468 {
2469 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPLSDitherEnabled);
2470 return false;
2471 }
2472
2473 // INVALID_OPERATION is generated if TRANSFORM_FEEDBACK_ACTIVE is true.
2474 if (state.isTransformFeedbackActive())
2475 {
2476 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPLSTransformFeedbackActive);
2477 return false;
2478 }
2479
2480 // INVALID_OPERATION is generated if QCOM_tiled_rendering is active.
2481 if (context->getPrivateState().isTiledRendering())
2482 {
2483 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPLSTiledRenderingActive);
2484 return false;
2485 }
2486
2487 // INVALID_OPERATION is generated if BLEND_DST_ALPHA, BLEND_DST_RGB, BLEND_SRC_ALPHA, or
2488 // BLEND_SRC_RGB, for any draw buffer, is a blend function requiring the secondary color input,
2489 // as specified in EXT_blend_func_extended.
2490 if (state.getExtensions().blendFuncExtendedEXT)
2491 {
2492 for (GLsizei i = 0; i < state.getCaps().maxDrawBuffers; ++i)
2493 {
2494 const BlendStateExt &blend = state.getBlendStateExt();
2495 if (!ValidatePLSActiveBlendFunc(context, entryPoint, blend.getDstAlphaIndexed(i)) ||
2496 !ValidatePLSActiveBlendFunc(context, entryPoint, blend.getDstColorIndexed(i)) ||
2497 !ValidatePLSActiveBlendFunc(context, entryPoint, blend.getSrcAlphaIndexed(i)) ||
2498 !ValidatePLSActiveBlendFunc(context, entryPoint, blend.getSrcColorIndexed(i)))
2499 {
2500 return false;
2501 }
2502 }
2503 }
2504
2505 // INVALID_OPERATION is generated if BLEND_EQUATION_RGB and/or BLEND_EQUATION_ALPHA is an
2506 // advanced blend equation defined in KHR_blend_equation_advanced.
2507 if (state.getExtensions().blendEquationAdvancedKHR)
2508 {
2509 if (!ValidatePLSActiveBlendEquation(context, entryPoint,
2510 state.getBlendStateExt().getEquationColorIndexed(0)) ||
2511 !ValidatePLSActiveBlendEquation(context, entryPoint,
2512 state.getBlendStateExt().getEquationAlphaIndexed(0)))
2513 {
2514 return false;
2515 }
2516 }
2517 // INVALID_VALUE is generated if <n> < 1 or <n> > MAX_PIXEL_LOCAL_STORAGE_PLANES_ANGLE.
2518 if (n < 1)
2519 {
2520 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kPLSPlanesLessThanOne);
2521 return false;
2522 }
2523 if (n > static_cast<GLsizei>(context->getCaps().maxPixelLocalStoragePlanes))
2524 {
2525 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kPLSPlanesOutOfRange);
2526 return false;
2527 }
2528
2529 // INVALID_FRAMEBUFFER_OPERATION is generated if the draw framebuffer has an image attached to
2530 // any color attachment point on or after:
2531 //
2532 // COLOR_ATTACHMENT0 + MAX_COMBINED_DRAW_BUFFERS_AND_PIXEL_LOCAL_STORAGE_PLANES_ANGLE - <n>
2533 //
2534 const Caps &caps = context->getCaps();
2535 for (int i = caps.maxCombinedDrawBuffersAndPixelLocalStoragePlanes - n; i < caps.maxDrawBuffers;
2536 ++i)
2537 {
2538 if (framebuffer->getColorAttachment(i))
2539 {
2540 ANGLE_VALIDATION_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION,
2541 kPLSMaxCombinedDrawBuffersAndPlanesExceded);
2542 return false;
2543 }
2544 }
2545
2546 // INVALID_VALUE is generated if <loadops> is NULL.
2547 if (loadops == nullptr)
2548 {
2549 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kPLSLoadOpsNULL);
2550 return false;
2551 }
2552
2553 const PixelLocalStorage *pls = framebuffer->peekPixelLocalStorage();
2554 bool hasTextureBackedPLSPlanes = false;
2555 Extents textureBackedPLSExtents{};
2556
2557 for (GLsizei i = 0; i < n; ++i)
2558 {
2559 // INVALID_ENUM is generated if <loadops>[0..<n>-1] is not one of the Load Operations
2560 // enumerated in Table X.1.
2561 if (!ValidatePLSLoadOperation(context, entryPoint, loadops[i]))
2562 {
2563 return false;
2564 }
2565
2566 // INVALID_OPERATION is generated if a pixel local storage plane at index [0..<n>-1] is in a
2567 // deinitialized state.
2568 if (pls == nullptr || pls->getPlane(i).isDeinitialized())
2569 {
2570 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPLSEnablingDeinitializedPlane);
2571 return false;
2572 }
2573
2574 // [ANGLE_shader_pixel_local_storage] Section 4.4.2.X "Configuring Pixel Local Storage
2575 // on a Framebuffer": When a texture object is deleted, any pixel local storage plane to
2576 // which it was bound is automatically converted to a memoryless plane of matching
2577 // internalformat.
2578 const PixelLocalStoragePlane &plane = pls->getPlane(i);
2579
2580 Extents textureExtents;
2581 if (plane.getTextureImageExtents(context, &textureExtents))
2582 {
2583 // INVALID_OPERATION is generated if all enabled, texture-backed pixel local storage
2584 // planes do not have the same width and height.
2585 if (!hasTextureBackedPLSPlanes)
2586 {
2587 textureBackedPLSExtents = textureExtents;
2588 hasTextureBackedPLSPlanes = true;
2589 }
2590 else if (textureExtents != textureBackedPLSExtents)
2591 {
2592 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPLSMismatchedBackingTextureSizes);
2593 return false;
2594 }
2595 }
2596 else
2597 {
2598 // INVALID_OPERATION is generated if <loadops>[0..<n>-1] is LOAD_OP_LOAD_ANGLE and the
2599 // pixel local storage plane at that same index is memoryless.
2600 if (loadops[i] == GL_LOAD_OP_LOAD_ANGLE)
2601 {
2602 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPLSKeepingMemorylessPlane);
2603 return false;
2604 }
2605 }
2606
2607 if (!plane.isMemoryless())
2608 {
2609 ASSERT(plane.getTextureID() != TextureID());
2610
2611 const ImageIndex &planeImageIdx = plane.getTextureImageIndex();
2612 ASSERT(planeImageIdx.getLayerCount() == 1);
2613 ASSERT(planeImageIdx.getLevelIndex() >= 0);
2614
2615 // INVALID_OPERATION is generated if a single texture slice is bound to more than one
2616 // active pixel local storage plane.
2617 for (GLsizei j = i + 1; j < n; ++j)
2618 {
2619 const PixelLocalStoragePlane &otherPlane = pls->getPlane(j);
2620 if (!otherPlane.isMemoryless() &&
2621 plane.getTextureID() == otherPlane.getTextureID() &&
2622 planeImageIdx == otherPlane.getTextureImageIndex())
2623 {
2624 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPLSSingleTexImageMultiplePlanes);
2625 return false;
2626 }
2627 }
2628
2629 // INVALID_OPERATION is generated if a single texture slice is simultaneously bound to
2630 // an active pixel local storage plane and attached to an enabled drawbuffer.
2631 const GLuint maxDrawBuffersWithPLSPlanes = std::min<GLuint>(
2632 caps.maxCombinedDrawBuffersAndPixelLocalStoragePlanes - n, caps.maxDrawBuffers);
2633 for (GLuint j = 0; j < maxDrawBuffersWithPLSPlanes; ++j)
2634 {
2635 if (framebuffer->getDrawBufferMask().test(j) &&
2636 framebuffer->getColorAttachment(j)->isTextureWithId(plane.getTextureID()))
2637 {
2638 // Compare the ImageIndex values for the PLS plane and framebuffer attachment
2639 // manually; the framebuffer uses a layer index of -1 for texture2d attachments,
2640 // whereas PLS uses a layer index of 0.
2641 const ImageIndex &attachmentImageIdx =
2642 framebuffer->getColorAttachment(j)->getTextureImageIndex();
2643 ASSERT(attachmentImageIdx.getLayerCount() == 1);
2644 if (planeImageIdx.getType() == attachmentImageIdx.getType() &&
2645 planeImageIdx.getLevelIndex() == attachmentImageIdx.getLevelIndex() &&
2646 planeImageIdx.getLayerIndex() ==
2647 std::max(attachmentImageIdx.getLayerIndex(), 0))
2648 {
2649 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION,
2650 kPLSSingleTexImagePLSAndAttachment);
2651 return false;
2652 }
2653 }
2654 }
2655 }
2656 }
2657
2658 const FramebufferAttachment *firstAttachment =
2659 framebuffer->getState().getFirstNonNullAttachment();
2660 if (firstAttachment)
2661 {
2662 // INVALID_OPERATION is generated if the draw framebuffer has other attachments, and its
2663 // enabled, texture-backed pixel local storage planes do not have identical dimensions
2664 // with the rendering area.
2665 if (hasTextureBackedPLSPlanes &&
2666 textureBackedPLSExtents != framebuffer->getState().getAttachmentExtentsIntersection())
2667 {
2668 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPLSDimensionsDontMatchRenderingArea);
2669 return false;
2670 }
2671 }
2672 else
2673 {
2674 // INVALID_OPERATION is generated if the draw framebuffer has no attachments and no
2675 // enabled, texture-backed pixel local storage planes.
2676 if (!hasTextureBackedPLSPlanes)
2677 {
2678 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPLSNoAttachmentsNoTextureBacked);
2679 return false;
2680 }
2681 }
2682
2683 return true;
2684 }
2685
ValidateEndPixelLocalStorageANGLE(const Context * context,angle::EntryPoint entryPoint,GLsizei n,const GLenum storeops[])2686 bool ValidateEndPixelLocalStorageANGLE(const Context *context,
2687 angle::EntryPoint entryPoint,
2688 GLsizei n,
2689 const GLenum storeops[])
2690 {
2691 if (!ValidatePLSCommon(context, entryPoint, PLSExpectedStatus::Active))
2692 {
2693 return false;
2694 }
2695
2696 // INVALID_VALUE is generated if <n> != PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE.
2697 if (n != context->getState().getPixelLocalStorageActivePlanes())
2698 {
2699 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kPLSNNotEqualActivePlanes);
2700 return false;
2701 }
2702
2703 // INVALID_ENUM is generated if <storeops>[0..PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE-1] is not
2704 // one of the Store Operations enumerated in Table X.2.
2705 for (GLsizei i = 0; i < n; ++i)
2706 {
2707 if (!ValidatePLSStoreOperation(context, entryPoint, storeops[i]))
2708 {
2709 return false;
2710 }
2711 }
2712
2713 return true;
2714 }
2715
ValidatePixelLocalStorageBarrierANGLE(const Context * context,angle::EntryPoint entryPoint)2716 bool ValidatePixelLocalStorageBarrierANGLE(const Context *context, angle::EntryPoint entryPoint)
2717 {
2718 return ValidatePLSCommon(context, entryPoint, PLSExpectedStatus::Active);
2719 }
2720
ValidateFramebufferPixelLocalStorageInterruptANGLE(const Context * context,angle::EntryPoint entryPoint)2721 bool ValidateFramebufferPixelLocalStorageInterruptANGLE(const Context *context,
2722 angle::EntryPoint entryPoint)
2723 {
2724 // Check that the pixel local storage extension is enabled at all.
2725 if (!context->getExtensions().shaderPixelLocalStorageANGLE)
2726 {
2727 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPLSExtensionNotEnabled);
2728 return false;
2729 }
2730
2731 // INVALID_FRAMEBUFFER_OPERATION is generated if the current interrupt count on the draw
2732 // framebuffer is greater than or equal to 255.
2733 const PixelLocalStorage *pls =
2734 context->getState().getDrawFramebuffer()->peekPixelLocalStorage();
2735 if (pls != nullptr && pls->interruptCount() >= 255)
2736 {
2737 ANGLE_VALIDATION_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION, kPLSInterruptOverflow);
2738 return false;
2739 }
2740
2741 return true;
2742 }
2743
ValidateFramebufferPixelLocalStorageRestoreANGLE(const Context * context,angle::EntryPoint entryPoint)2744 bool ValidateFramebufferPixelLocalStorageRestoreANGLE(const Context *context,
2745 angle::EntryPoint entryPoint)
2746 {
2747 // Check that the pixel local storage extension is enabled at all.
2748 if (!context->getExtensions().shaderPixelLocalStorageANGLE)
2749 {
2750 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPLSExtensionNotEnabled);
2751 return false;
2752 }
2753
2754 // This command is ignored when the default framebuffer object name 0 is bound.
2755 const Framebuffer *framebuffer = context->getState().getDrawFramebuffer();
2756 if (context->getState().getDrawFramebuffer()->id().value == 0)
2757 {
2758 return true;
2759 }
2760
2761 // INVALID_FRAMEBUFFER_OPERATION is generated if pixel local storage on the draw framebuffer is
2762 // not in an interrupted state.
2763 const PixelLocalStorage *pls = framebuffer->peekPixelLocalStorage();
2764 if (pls == nullptr || pls->interruptCount() == 0)
2765 {
2766 ANGLE_VALIDATION_ERROR(GL_INVALID_FRAMEBUFFER_OPERATION, kPLSNotInterrupted);
2767 return false;
2768 }
2769
2770 return true;
2771 }
2772
ValidateGetFramebufferPixelLocalStorageParameterfvANGLE(const Context * context,angle::EntryPoint entryPoint,GLint plane,GLenum pname,const GLfloat * params)2773 bool ValidateGetFramebufferPixelLocalStorageParameterfvANGLE(const Context *context,
2774 angle::EntryPoint entryPoint,
2775 GLint plane,
2776 GLenum pname,
2777 const GLfloat *params)
2778 {
2779 return ValidateGetFramebufferPixelLocalStorageParameterfvRobustANGLE(
2780 context, entryPoint, plane, pname, std::numeric_limits<GLsizei>::max(), nullptr, params);
2781 }
2782
ValidateGetFramebufferPixelLocalStorageParameterivANGLE(const Context * context,angle::EntryPoint entryPoint,GLint plane,GLenum pname,const GLint * params)2783 bool ValidateGetFramebufferPixelLocalStorageParameterivANGLE(const Context *context,
2784 angle::EntryPoint entryPoint,
2785 GLint plane,
2786 GLenum pname,
2787 const GLint *params)
2788 {
2789 return ValidateGetFramebufferPixelLocalStorageParameterivRobustANGLE(
2790 context, entryPoint, plane, pname, std::numeric_limits<GLsizei>::max(), nullptr, params);
2791 }
2792
ValidateGetFramebufferPixelLocalStorageParameterfvRobustANGLE(const Context * context,angle::EntryPoint entryPoint,GLint plane,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLfloat * params)2793 bool ValidateGetFramebufferPixelLocalStorageParameterfvRobustANGLE(const Context *context,
2794 angle::EntryPoint entryPoint,
2795 GLint plane,
2796 GLenum pname,
2797 GLsizei bufSize,
2798 const GLsizei *length,
2799 const GLfloat *params)
2800 {
2801 if (!ValidatePLSCommon(context, entryPoint, plane, PLSExpectedStatus::Any))
2802 {
2803 return false;
2804 }
2805 GLsizei paramCount = 0;
2806 switch (pname)
2807 {
2808 case GL_PIXEL_LOCAL_CLEAR_VALUE_FLOAT_ANGLE:
2809 paramCount = 4;
2810 break;
2811 default:
2812 // INVALID_ENUM is generated if <pname> is not in Table 6.Y, or if the command issued is
2813 // not the associated "Get Command" for <pname> in Table 6.Y.
2814 ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
2815 return false;
2816 }
2817 return ValidatePLSQueryCommon(context, entryPoint, paramCount, bufSize, params);
2818 }
2819
ValidateGetFramebufferPixelLocalStorageParameterivRobustANGLE(const Context * context,angle::EntryPoint entryPoint,GLint plane,GLenum pname,GLsizei bufSize,const GLsizei * length,const GLint * params)2820 bool ValidateGetFramebufferPixelLocalStorageParameterivRobustANGLE(const Context *context,
2821 angle::EntryPoint entryPoint,
2822 GLint plane,
2823 GLenum pname,
2824 GLsizei bufSize,
2825 const GLsizei *length,
2826 const GLint *params)
2827 {
2828 if (!ValidatePLSCommon(context, entryPoint, plane, PLSExpectedStatus::Any))
2829 {
2830 return false;
2831 }
2832 GLsizei paramCount = 0;
2833 switch (pname)
2834 {
2835 case GL_PIXEL_LOCAL_FORMAT_ANGLE:
2836 case GL_PIXEL_LOCAL_TEXTURE_NAME_ANGLE:
2837 case GL_PIXEL_LOCAL_TEXTURE_LEVEL_ANGLE:
2838 case GL_PIXEL_LOCAL_TEXTURE_LAYER_ANGLE:
2839 paramCount = 1;
2840 break;
2841 case GL_PIXEL_LOCAL_CLEAR_VALUE_INT_ANGLE:
2842 case GL_PIXEL_LOCAL_CLEAR_VALUE_UNSIGNED_INT_ANGLE:
2843 paramCount = 4;
2844 break;
2845 default:
2846 // INVALID_ENUM is generated if <pname> is not in Table 6.Y, or if the command issued is
2847 // not the associated "Get Command" for <pname> in Table 6.Y.
2848 ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, pname);
2849 return false;
2850 }
2851 return ValidatePLSQueryCommon(context, entryPoint, paramCount, bufSize, params);
2852 }
2853
ValidateFramebufferFetchBarrierEXT(const Context * context,angle::EntryPoint entryPoint)2854 bool ValidateFramebufferFetchBarrierEXT(const Context *context, angle::EntryPoint entryPoint)
2855 {
2856 if (!context->getExtensions().shaderFramebufferFetchNonCoherentEXT)
2857 {
2858 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION,
2859 kFramebufferFetchNonCoherentExtensionNotEnabled);
2860 return false;
2861 }
2862 return true;
2863 }
2864
ValidatePatchParameteriEXT(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLenum pname,GLint value)2865 bool ValidatePatchParameteriEXT(const PrivateState &state,
2866 ErrorSet *errors,
2867 angle::EntryPoint entryPoint,
2868 GLenum pname,
2869 GLint value)
2870 {
2871 if (!state.getExtensions().tessellationShaderEXT)
2872 {
2873 errors->validationError(entryPoint, GL_INVALID_OPERATION, kTessellationShaderEXTNotEnabled);
2874 return false;
2875 }
2876
2877 return ValidatePatchParameteriBase(state, errors, entryPoint, pname, value);
2878 }
2879
ValidatePatchParameteriOES(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLenum pname,GLint value)2880 bool ValidatePatchParameteriOES(const PrivateState &state,
2881 ErrorSet *errors,
2882 angle::EntryPoint entryPoint,
2883 GLenum pname,
2884 GLint value)
2885 {
2886 if (!state.getExtensions().tessellationShaderOES)
2887 {
2888 errors->validationError(entryPoint, GL_INVALID_OPERATION, kTessellationShaderOESNotEnabled);
2889 return false;
2890 }
2891
2892 return ValidatePatchParameteriBase(state, errors, entryPoint, pname, value);
2893 }
2894
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)2895 bool ValidateTexStorageMemFlags2DANGLE(const Context *context,
2896 angle::EntryPoint entryPoint,
2897 TextureType targetPacked,
2898 GLsizei levels,
2899 GLenum internalFormat,
2900 GLsizei width,
2901 GLsizei height,
2902 MemoryObjectID memoryPacked,
2903 GLuint64 offset,
2904 GLbitfield createFlags,
2905 GLbitfield usageFlags,
2906 const void *imageCreateInfoPNext)
2907 {
2908 if (!context->getExtensions().memoryObjectFlagsANGLE)
2909 {
2910 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
2911 return false;
2912 }
2913
2914 if (!ValidateTexStorageMem2DEXT(context, entryPoint, targetPacked, levels, internalFormat,
2915 width, height, memoryPacked, offset))
2916 {
2917 return false;
2918 }
2919
2920 // |createFlags| and |usageFlags| must only have bits specified by the extension.
2921 constexpr GLbitfield kAllCreateFlags =
2922 GL_CREATE_SPARSE_BINDING_BIT_ANGLE | GL_CREATE_SPARSE_RESIDENCY_BIT_ANGLE |
2923 GL_CREATE_SPARSE_ALIASED_BIT_ANGLE | GL_CREATE_MUTABLE_FORMAT_BIT_ANGLE |
2924 GL_CREATE_CUBE_COMPATIBLE_BIT_ANGLE | GL_CREATE_ALIAS_BIT_ANGLE |
2925 GL_CREATE_SPLIT_INSTANCE_BIND_REGIONS_BIT_ANGLE | GL_CREATE_2D_ARRAY_COMPATIBLE_BIT_ANGLE |
2926 GL_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT_ANGLE | GL_CREATE_EXTENDED_USAGE_BIT_ANGLE |
2927 GL_CREATE_PROTECTED_BIT_ANGLE | GL_CREATE_DISJOINT_BIT_ANGLE |
2928 GL_CREATE_CORNER_SAMPLED_BIT_ANGLE | GL_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_ANGLE |
2929 GL_CREATE_SUBSAMPLED_BIT_ANGLE;
2930
2931 if ((createFlags & ~kAllCreateFlags) != 0)
2932 {
2933 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidExternalCreateFlags);
2934 return false;
2935 }
2936
2937 constexpr GLbitfield kAllUsageFlags =
2938 GL_USAGE_TRANSFER_SRC_BIT_ANGLE | GL_USAGE_TRANSFER_DST_BIT_ANGLE |
2939 GL_USAGE_SAMPLED_BIT_ANGLE | GL_USAGE_STORAGE_BIT_ANGLE |
2940 GL_USAGE_COLOR_ATTACHMENT_BIT_ANGLE | GL_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT_ANGLE |
2941 GL_USAGE_TRANSIENT_ATTACHMENT_BIT_ANGLE | GL_USAGE_INPUT_ATTACHMENT_BIT_ANGLE |
2942 GL_USAGE_SHADING_RATE_IMAGE_BIT_ANGLE | GL_USAGE_FRAGMENT_DENSITY_MAP_BIT_ANGLE;
2943
2944 if ((usageFlags & ~kAllUsageFlags) != 0)
2945 {
2946 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidExternalUsageFlags);
2947 return false;
2948 }
2949
2950 return true;
2951 }
2952
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)2953 bool ValidateTexStorageMemFlags2DMultisampleANGLE(const Context *context,
2954 angle::EntryPoint entryPoint,
2955 TextureType targetPacked,
2956 GLsizei samples,
2957 GLenum internalFormat,
2958 GLsizei width,
2959 GLsizei height,
2960 GLboolean fixedSampleLocations,
2961 MemoryObjectID memoryPacked,
2962 GLuint64 offset,
2963 GLbitfield createFlags,
2964 GLbitfield usageFlags,
2965 const void *imageCreateInfoPNext)
2966 {
2967 UNIMPLEMENTED();
2968 return false;
2969 }
2970
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)2971 bool ValidateTexStorageMemFlags3DANGLE(const Context *context,
2972 angle::EntryPoint entryPoint,
2973 TextureType targetPacked,
2974 GLsizei levels,
2975 GLenum internalFormat,
2976 GLsizei width,
2977 GLsizei height,
2978 GLsizei depth,
2979 MemoryObjectID memoryPacked,
2980 GLuint64 offset,
2981 GLbitfield createFlags,
2982 GLbitfield usageFlags,
2983 const void *imageCreateInfoPNext)
2984 {
2985 UNIMPLEMENTED();
2986 return false;
2987 }
2988
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)2989 bool ValidateTexStorageMemFlags3DMultisampleANGLE(const Context *context,
2990 angle::EntryPoint entryPoint,
2991 TextureType targetPacked,
2992 GLsizei samples,
2993 GLenum internalFormat,
2994 GLsizei width,
2995 GLsizei height,
2996 GLsizei depth,
2997 GLboolean fixedSampleLocations,
2998 MemoryObjectID memoryPacked,
2999 GLuint64 offset,
3000 GLbitfield createFlags,
3001 GLbitfield usageFlags,
3002 const void *imageCreateInfoPNext)
3003 {
3004 UNIMPLEMENTED();
3005 return false;
3006 }
3007
3008 // GL_EXT_buffer_storage
ValidateBufferStorageEXT(const Context * context,angle::EntryPoint entryPoint,BufferBinding targetPacked,GLsizeiptr size,const void * data,GLbitfield flags)3009 bool ValidateBufferStorageEXT(const Context *context,
3010 angle::EntryPoint entryPoint,
3011 BufferBinding targetPacked,
3012 GLsizeiptr size,
3013 const void *data,
3014 GLbitfield flags)
3015 {
3016 if (!context->isValidBufferBinding(targetPacked))
3017 {
3018 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidBufferTypes);
3019 return false;
3020 }
3021
3022 if (size <= 0)
3023 {
3024 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNonPositiveSize);
3025 return false;
3026 }
3027
3028 constexpr GLbitfield kAllUsageFlags =
3029 (GL_DYNAMIC_STORAGE_BIT_EXT | GL_MAP_READ_BIT | GL_MAP_WRITE_BIT |
3030 GL_MAP_PERSISTENT_BIT_EXT | GL_MAP_COHERENT_BIT_EXT | GL_CLIENT_STORAGE_BIT_EXT);
3031 if ((flags & ~kAllUsageFlags) != 0)
3032 {
3033 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidBufferUsageFlags);
3034 return false;
3035 }
3036
3037 if (((flags & GL_MAP_PERSISTENT_BIT_EXT) != 0) &&
3038 ((flags & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)) == 0))
3039 {
3040 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidBufferUsageFlags);
3041 return false;
3042 }
3043
3044 if (((flags & GL_MAP_COHERENT_BIT_EXT) != 0) && ((flags & GL_MAP_PERSISTENT_BIT_EXT) == 0))
3045 {
3046 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidBufferUsageFlags);
3047 return false;
3048 }
3049
3050 Buffer *buffer = context->getState().getTargetBuffer(targetPacked);
3051
3052 if (buffer == nullptr)
3053 {
3054 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBufferNotBound);
3055 return false;
3056 }
3057
3058 if (buffer->isImmutable())
3059 {
3060 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kBufferImmutable);
3061 return false;
3062 }
3063
3064 return true;
3065 }
3066
3067 // GL_EXT_clear_texture
ValidateClearTexImageEXT(const Context * context,angle::EntryPoint entryPoint,TextureID texturePacked,GLint level,GLenum format,GLenum type,const void * data)3068 bool ValidateClearTexImageEXT(const Context *context,
3069 angle::EntryPoint entryPoint,
3070 TextureID texturePacked,
3071 GLint level,
3072 GLenum format,
3073 GLenum type,
3074 const void *data)
3075 {
3076 return ValidateClearTexImageCommon(context, entryPoint, texturePacked, level, std::nullopt,
3077 format, type, data);
3078 }
3079
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)3080 bool ValidateClearTexSubImageEXT(const Context *context,
3081 angle::EntryPoint entryPoint,
3082 TextureID texturePacked,
3083 GLint level,
3084 GLint xoffset,
3085 GLint yoffset,
3086 GLint zoffset,
3087 GLsizei width,
3088 GLsizei height,
3089 GLsizei depth,
3090 GLenum format,
3091 GLenum type,
3092 const void *data)
3093 {
3094 return ValidateClearTexImageCommon(context, entryPoint, texturePacked, level,
3095 Box(xoffset, yoffset, zoffset, width, height, depth), format,
3096 type, data);
3097 }
3098
3099 // GL_EXT_clip_control
ValidateClipControlEXT(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,ClipOrigin originPacked,ClipDepthMode depthPacked)3100 bool ValidateClipControlEXT(const PrivateState &state,
3101 ErrorSet *errors,
3102 angle::EntryPoint entryPoint,
3103 ClipOrigin originPacked,
3104 ClipDepthMode depthPacked)
3105 {
3106 if (!state.getExtensions().clipControlEXT)
3107 {
3108 errors->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
3109 return false;
3110 }
3111
3112 if (originPacked == ClipOrigin::InvalidEnum)
3113 {
3114 errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidOriginEnum);
3115 return false;
3116 }
3117
3118 if (depthPacked == ClipDepthMode::InvalidEnum)
3119 {
3120 errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidDepthEnum);
3121 return false;
3122 }
3123
3124 return true;
3125 }
3126
3127 // GL_EXT_external_buffer
ValidateBufferStorageExternalEXT(const Context * context,angle::EntryPoint entryPoint,BufferBinding targetPacked,GLintptr offset,GLsizeiptr size,GLeglClientBufferEXT clientBuffer,GLbitfield flags)3128 bool ValidateBufferStorageExternalEXT(const Context *context,
3129 angle::EntryPoint entryPoint,
3130 BufferBinding targetPacked,
3131 GLintptr offset,
3132 GLsizeiptr size,
3133 GLeglClientBufferEXT clientBuffer,
3134 GLbitfield flags)
3135 {
3136 if (!ValidateBufferStorageEXT(context, entryPoint, targetPacked, size, nullptr, flags))
3137 {
3138 return false;
3139 }
3140
3141 if (offset != 0)
3142 {
3143 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kExternalBufferInvalidOffset);
3144 return false;
3145 }
3146
3147 if (clientBuffer == nullptr && size > 0)
3148 {
3149 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kClientBufferInvalid);
3150 return false;
3151 }
3152
3153 return true;
3154 }
3155
ValidateNamedBufferStorageExternalEXT(const Context * context,angle::EntryPoint entryPoint,GLuint buffer,GLintptr offset,GLsizeiptr size,GLeglClientBufferEXT clientBuffer,GLbitfield flags)3156 bool ValidateNamedBufferStorageExternalEXT(const Context *context,
3157 angle::EntryPoint entryPoint,
3158 GLuint buffer,
3159 GLintptr offset,
3160 GLsizeiptr size,
3161 GLeglClientBufferEXT clientBuffer,
3162 GLbitfield flags)
3163 {
3164 UNIMPLEMENTED();
3165 return false;
3166 }
3167
3168 // GL_ANGLE_polygon_mode
ValidatePolygonModeANGLE(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLenum face,PolygonMode modePacked)3169 bool ValidatePolygonModeANGLE(const PrivateState &state,
3170 ErrorSet *errors,
3171 angle::EntryPoint entryPoint,
3172 GLenum face,
3173 PolygonMode modePacked)
3174 {
3175 if (!state.getExtensions().polygonModeANGLE)
3176 {
3177 errors->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
3178 return false;
3179 }
3180
3181 if (face != GL_FRONT_AND_BACK)
3182 {
3183 errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidCullMode);
3184 return false;
3185 }
3186
3187 if (modePacked == PolygonMode::Point || modePacked == PolygonMode::InvalidEnum)
3188 {
3189 errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPolygonMode);
3190 return false;
3191 }
3192
3193 return true;
3194 }
3195
3196 // GL_NV_polygon_mode
ValidatePolygonModeNV(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLenum face,PolygonMode modePacked)3197 bool ValidatePolygonModeNV(const PrivateState &state,
3198 ErrorSet *errors,
3199 angle::EntryPoint entryPoint,
3200 GLenum face,
3201 PolygonMode modePacked)
3202 {
3203 if (!state.getExtensions().polygonModeNV)
3204 {
3205 errors->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
3206 return false;
3207 }
3208
3209 if (face != GL_FRONT_AND_BACK)
3210 {
3211 errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidCullMode);
3212 return false;
3213 }
3214
3215 if (modePacked == PolygonMode::InvalidEnum)
3216 {
3217 errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPolygonMode);
3218 return false;
3219 }
3220
3221 return true;
3222 }
3223
3224 // GL_EXT_polygon_offset_clamp
ValidatePolygonOffsetClampEXT(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLfloat factor,GLfloat units,GLfloat clamp)3225 bool ValidatePolygonOffsetClampEXT(const PrivateState &state,
3226 ErrorSet *errors,
3227 angle::EntryPoint entryPoint,
3228 GLfloat factor,
3229 GLfloat units,
3230 GLfloat clamp)
3231 {
3232 if (!state.getExtensions().polygonOffsetClampEXT)
3233 {
3234 errors->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
3235 return false;
3236 }
3237
3238 return true;
3239 }
3240
3241 // 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)3242 bool ValidatePrimitiveBoundingBoxEXT(const PrivateState &state,
3243 ErrorSet *errors,
3244 angle::EntryPoint entryPoint,
3245 GLfloat minX,
3246 GLfloat minY,
3247 GLfloat minZ,
3248 GLfloat minW,
3249 GLfloat maxX,
3250 GLfloat maxY,
3251 GLfloat maxZ,
3252 GLfloat maxW)
3253 {
3254 if (!state.getExtensions().primitiveBoundingBoxEXT)
3255 {
3256 errors->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
3257 return false;
3258 }
3259
3260 return true;
3261 }
3262
3263 // 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)3264 bool ValidatePrimitiveBoundingBoxOES(const PrivateState &state,
3265 ErrorSet *errors,
3266 angle::EntryPoint entryPoint,
3267 GLfloat minX,
3268 GLfloat minY,
3269 GLfloat minZ,
3270 GLfloat minW,
3271 GLfloat maxX,
3272 GLfloat maxY,
3273 GLfloat maxZ,
3274 GLfloat maxW)
3275 {
3276 if (!state.getExtensions().primitiveBoundingBoxOES)
3277 {
3278 errors->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
3279 return false;
3280 }
3281
3282 return true;
3283 }
3284
3285 // 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)3286 bool ValidateTexStorage3DMultisampleOES(const Context *context,
3287 angle::EntryPoint entryPoint,
3288 TextureType target,
3289 GLsizei samples,
3290 GLenum internalformat,
3291 GLsizei width,
3292 GLsizei height,
3293 GLsizei depth,
3294 GLboolean fixedsamplelocations)
3295 {
3296 if (!context->getExtensions().textureStorageMultisample2dArrayOES)
3297 {
3298 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3299 return false;
3300 }
3301
3302 return ValidateTexStorage3DMultisampleBase(context, entryPoint, target, samples, internalformat,
3303 width, height, depth);
3304 }
3305
3306 // GL_EXT_separate_shader_objects
ValidateActiveShaderProgramEXT(const Context * context,angle::EntryPoint entryPoint,ProgramPipelineID pipelinePacked,ShaderProgramID programPacked)3307 bool ValidateActiveShaderProgramEXT(const Context *context,
3308 angle::EntryPoint entryPoint,
3309 ProgramPipelineID pipelinePacked,
3310 ShaderProgramID programPacked)
3311 {
3312 if (!context->getExtensions().separateShaderObjectsEXT)
3313 {
3314 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3315 return false;
3316 }
3317
3318 return ValidateActiveShaderProgramBase(context, entryPoint, pipelinePacked, programPacked);
3319 }
3320
ValidateBindProgramPipelineEXT(const Context * context,angle::EntryPoint entryPoint,ProgramPipelineID pipelinePacked)3321 bool ValidateBindProgramPipelineEXT(const Context *context,
3322 angle::EntryPoint entryPoint,
3323 ProgramPipelineID pipelinePacked)
3324 {
3325 if (!context->getExtensions().separateShaderObjectsEXT)
3326 {
3327 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3328 return false;
3329 }
3330
3331 return ValidateBindProgramPipelineBase(context, entryPoint, pipelinePacked);
3332 }
3333
ValidateCreateShaderProgramvEXT(const Context * context,angle::EntryPoint entryPoint,ShaderType typePacked,GLsizei count,const GLchar ** strings)3334 bool ValidateCreateShaderProgramvEXT(const Context *context,
3335 angle::EntryPoint entryPoint,
3336 ShaderType typePacked,
3337 GLsizei count,
3338 const GLchar **strings)
3339 {
3340 if (!context->getExtensions().separateShaderObjectsEXT)
3341 {
3342 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3343 return false;
3344 }
3345
3346 return ValidateCreateShaderProgramvBase(context, entryPoint, typePacked, count, strings);
3347 }
3348
ValidateDeleteProgramPipelinesEXT(const Context * context,angle::EntryPoint entryPoint,GLsizei n,const ProgramPipelineID * pipelinesPacked)3349 bool ValidateDeleteProgramPipelinesEXT(const Context *context,
3350 angle::EntryPoint entryPoint,
3351 GLsizei n,
3352 const ProgramPipelineID *pipelinesPacked)
3353 {
3354 if (!context->getExtensions().separateShaderObjectsEXT)
3355 {
3356 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3357 return false;
3358 }
3359
3360 return ValidateDeleteProgramPipelinesBase(context, entryPoint, n, pipelinesPacked);
3361 }
3362
ValidateGenProgramPipelinesEXT(const Context * context,angle::EntryPoint entryPoint,GLsizei n,const ProgramPipelineID * pipelinesPacked)3363 bool ValidateGenProgramPipelinesEXT(const Context *context,
3364 angle::EntryPoint entryPoint,
3365 GLsizei n,
3366 const ProgramPipelineID *pipelinesPacked)
3367 {
3368 if (!context->getExtensions().separateShaderObjectsEXT)
3369 {
3370 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3371 return false;
3372 }
3373
3374 return ValidateGenProgramPipelinesBase(context, entryPoint, n, pipelinesPacked);
3375 }
3376
ValidateGetProgramPipelineInfoLogEXT(const Context * context,angle::EntryPoint entryPoint,ProgramPipelineID pipelinePacked,GLsizei bufSize,const GLsizei * length,const GLchar * infoLog)3377 bool ValidateGetProgramPipelineInfoLogEXT(const Context *context,
3378 angle::EntryPoint entryPoint,
3379 ProgramPipelineID pipelinePacked,
3380 GLsizei bufSize,
3381 const GLsizei *length,
3382 const GLchar *infoLog)
3383 {
3384 if (!context->getExtensions().separateShaderObjectsEXT)
3385 {
3386 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3387 return false;
3388 }
3389
3390 return ValidateGetProgramPipelineInfoLogBase(context, entryPoint, pipelinePacked, bufSize,
3391 length, infoLog);
3392 }
3393
ValidateGetProgramPipelineivEXT(const Context * context,angle::EntryPoint entryPoint,ProgramPipelineID pipelinePacked,GLenum pname,const GLint * params)3394 bool ValidateGetProgramPipelineivEXT(const Context *context,
3395 angle::EntryPoint entryPoint,
3396 ProgramPipelineID pipelinePacked,
3397 GLenum pname,
3398 const GLint *params)
3399 {
3400 if (!context->getExtensions().separateShaderObjectsEXT)
3401 {
3402 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3403 return false;
3404 }
3405
3406 return ValidateGetProgramPipelineivBase(context, entryPoint, pipelinePacked, pname, params);
3407 }
3408
ValidateIsProgramPipelineEXT(const Context * context,angle::EntryPoint entryPoint,ProgramPipelineID pipelinePacked)3409 bool ValidateIsProgramPipelineEXT(const Context *context,
3410 angle::EntryPoint entryPoint,
3411 ProgramPipelineID pipelinePacked)
3412 {
3413 if (!context->getExtensions().separateShaderObjectsEXT)
3414 {
3415 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3416 return false;
3417 }
3418
3419 return ValidateIsProgramPipelineBase(context, entryPoint, pipelinePacked);
3420 }
3421
ValidateProgramParameteriEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,GLenum pname,GLint value)3422 bool ValidateProgramParameteriEXT(const Context *context,
3423 angle::EntryPoint entryPoint,
3424 ShaderProgramID programPacked,
3425 GLenum pname,
3426 GLint value)
3427 {
3428 if (!context->getExtensions().separateShaderObjectsEXT)
3429 {
3430 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3431 return false;
3432 }
3433
3434 return ValidateProgramParameteriBase(context, entryPoint, programPacked, pname, value);
3435 }
3436
ValidateProgramUniform1fEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLfloat v0)3437 bool ValidateProgramUniform1fEXT(const Context *context,
3438 angle::EntryPoint entryPoint,
3439 ShaderProgramID programPacked,
3440 UniformLocation locationPacked,
3441 GLfloat v0)
3442 {
3443 if (!context->getExtensions().separateShaderObjectsEXT)
3444 {
3445 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3446 return false;
3447 }
3448
3449 return ValidateProgramUniform1fBase(context, entryPoint, programPacked, locationPacked, v0);
3450 }
3451
ValidateProgramUniform1fvEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLfloat * value)3452 bool ValidateProgramUniform1fvEXT(const Context *context,
3453 angle::EntryPoint entryPoint,
3454 ShaderProgramID programPacked,
3455 UniformLocation locationPacked,
3456 GLsizei count,
3457 const GLfloat *value)
3458 {
3459 if (!context->getExtensions().separateShaderObjectsEXT)
3460 {
3461 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3462 return false;
3463 }
3464
3465 return ValidateProgramUniform1fvBase(context, entryPoint, programPacked, locationPacked, count,
3466 value);
3467 }
3468
ValidateProgramUniform1iEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLint v0)3469 bool ValidateProgramUniform1iEXT(const Context *context,
3470 angle::EntryPoint entryPoint,
3471 ShaderProgramID programPacked,
3472 UniformLocation locationPacked,
3473 GLint v0)
3474 {
3475 if (!context->getExtensions().separateShaderObjectsEXT)
3476 {
3477 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3478 return false;
3479 }
3480
3481 return ValidateProgramUniform1iBase(context, entryPoint, programPacked, locationPacked, v0);
3482 }
3483
ValidateProgramUniform1ivEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLint * value)3484 bool ValidateProgramUniform1ivEXT(const Context *context,
3485 angle::EntryPoint entryPoint,
3486 ShaderProgramID programPacked,
3487 UniformLocation locationPacked,
3488 GLsizei count,
3489 const GLint *value)
3490 {
3491 if (!context->getExtensions().separateShaderObjectsEXT)
3492 {
3493 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3494 return false;
3495 }
3496
3497 return ValidateProgramUniform1ivBase(context, entryPoint, programPacked, locationPacked, count,
3498 value);
3499 }
3500
ValidateProgramUniform1uiEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLuint v0)3501 bool ValidateProgramUniform1uiEXT(const Context *context,
3502 angle::EntryPoint entryPoint,
3503 ShaderProgramID programPacked,
3504 UniformLocation locationPacked,
3505 GLuint v0)
3506 {
3507 if (!context->getExtensions().separateShaderObjectsEXT)
3508 {
3509 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3510 return false;
3511 }
3512
3513 return ValidateProgramUniform1uiBase(context, entryPoint, programPacked, locationPacked, v0);
3514 }
3515
ValidateProgramUniform1uivEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLuint * value)3516 bool ValidateProgramUniform1uivEXT(const Context *context,
3517 angle::EntryPoint entryPoint,
3518 ShaderProgramID programPacked,
3519 UniformLocation locationPacked,
3520 GLsizei count,
3521 const GLuint *value)
3522 {
3523 if (!context->getExtensions().separateShaderObjectsEXT)
3524 {
3525 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3526 return false;
3527 }
3528
3529 return ValidateProgramUniform1uivBase(context, entryPoint, programPacked, locationPacked, count,
3530 value);
3531 }
3532
ValidateProgramUniform2fEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLfloat v0,GLfloat v1)3533 bool ValidateProgramUniform2fEXT(const Context *context,
3534 angle::EntryPoint entryPoint,
3535 ShaderProgramID programPacked,
3536 UniformLocation locationPacked,
3537 GLfloat v0,
3538 GLfloat v1)
3539 {
3540 if (!context->getExtensions().separateShaderObjectsEXT)
3541 {
3542 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3543 return false;
3544 }
3545
3546 return ValidateProgramUniform2fBase(context, entryPoint, programPacked, locationPacked, v0, v1);
3547 }
3548
ValidateProgramUniform2fvEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLfloat * value)3549 bool ValidateProgramUniform2fvEXT(const Context *context,
3550 angle::EntryPoint entryPoint,
3551 ShaderProgramID programPacked,
3552 UniformLocation locationPacked,
3553 GLsizei count,
3554 const GLfloat *value)
3555 {
3556 if (!context->getExtensions().separateShaderObjectsEXT)
3557 {
3558 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3559 return false;
3560 }
3561
3562 return ValidateProgramUniform2fvBase(context, entryPoint, programPacked, locationPacked, count,
3563 value);
3564 }
3565
ValidateProgramUniform2iEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLint v0,GLint v1)3566 bool ValidateProgramUniform2iEXT(const Context *context,
3567 angle::EntryPoint entryPoint,
3568 ShaderProgramID programPacked,
3569 UniformLocation locationPacked,
3570 GLint v0,
3571 GLint v1)
3572 {
3573 if (!context->getExtensions().separateShaderObjectsEXT)
3574 {
3575 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3576 return false;
3577 }
3578
3579 return ValidateProgramUniform2iBase(context, entryPoint, programPacked, locationPacked, v0, v1);
3580 }
3581
ValidateProgramUniform2ivEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLint * value)3582 bool ValidateProgramUniform2ivEXT(const Context *context,
3583 angle::EntryPoint entryPoint,
3584 ShaderProgramID programPacked,
3585 UniformLocation locationPacked,
3586 GLsizei count,
3587 const GLint *value)
3588 {
3589 if (!context->getExtensions().separateShaderObjectsEXT)
3590 {
3591 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3592 return false;
3593 }
3594
3595 return ValidateProgramUniform2ivBase(context, entryPoint, programPacked, locationPacked, count,
3596 value);
3597 }
3598
ValidateProgramUniform2uiEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLuint v0,GLuint v1)3599 bool ValidateProgramUniform2uiEXT(const Context *context,
3600 angle::EntryPoint entryPoint,
3601 ShaderProgramID programPacked,
3602 UniformLocation locationPacked,
3603 GLuint v0,
3604 GLuint v1)
3605 {
3606 if (!context->getExtensions().separateShaderObjectsEXT)
3607 {
3608 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3609 return false;
3610 }
3611
3612 return ValidateProgramUniform2uiBase(context, entryPoint, programPacked, locationPacked, v0,
3613 v1);
3614 }
3615
ValidateProgramUniform2uivEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLuint * value)3616 bool ValidateProgramUniform2uivEXT(const Context *context,
3617 angle::EntryPoint entryPoint,
3618 ShaderProgramID programPacked,
3619 UniformLocation locationPacked,
3620 GLsizei count,
3621 const GLuint *value)
3622 {
3623 if (!context->getExtensions().separateShaderObjectsEXT)
3624 {
3625 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3626 return false;
3627 }
3628
3629 return ValidateProgramUniform2uivBase(context, entryPoint, programPacked, locationPacked, count,
3630 value);
3631 }
3632
ValidateProgramUniform3fEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLfloat v0,GLfloat v1,GLfloat v2)3633 bool ValidateProgramUniform3fEXT(const Context *context,
3634 angle::EntryPoint entryPoint,
3635 ShaderProgramID programPacked,
3636 UniformLocation locationPacked,
3637 GLfloat v0,
3638 GLfloat v1,
3639 GLfloat v2)
3640 {
3641 if (!context->getExtensions().separateShaderObjectsEXT)
3642 {
3643 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3644 return false;
3645 }
3646
3647 return ValidateProgramUniform3fBase(context, entryPoint, programPacked, locationPacked, v0, v1,
3648 v2);
3649 }
3650
ValidateProgramUniform3fvEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLfloat * value)3651 bool ValidateProgramUniform3fvEXT(const Context *context,
3652 angle::EntryPoint entryPoint,
3653 ShaderProgramID programPacked,
3654 UniformLocation locationPacked,
3655 GLsizei count,
3656 const GLfloat *value)
3657 {
3658 if (!context->getExtensions().separateShaderObjectsEXT)
3659 {
3660 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3661 return false;
3662 }
3663
3664 return ValidateProgramUniform3fvBase(context, entryPoint, programPacked, locationPacked, count,
3665 value);
3666 }
3667
ValidateProgramUniform3iEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLint v0,GLint v1,GLint v2)3668 bool ValidateProgramUniform3iEXT(const Context *context,
3669 angle::EntryPoint entryPoint,
3670 ShaderProgramID programPacked,
3671 UniformLocation locationPacked,
3672 GLint v0,
3673 GLint v1,
3674 GLint v2)
3675 {
3676 if (!context->getExtensions().separateShaderObjectsEXT)
3677 {
3678 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3679 return false;
3680 }
3681
3682 return ValidateProgramUniform3iBase(context, entryPoint, programPacked, locationPacked, v0, v1,
3683 v2);
3684 }
3685
ValidateProgramUniform3ivEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLint * value)3686 bool ValidateProgramUniform3ivEXT(const Context *context,
3687 angle::EntryPoint entryPoint,
3688 ShaderProgramID programPacked,
3689 UniformLocation locationPacked,
3690 GLsizei count,
3691 const GLint *value)
3692 {
3693 if (!context->getExtensions().separateShaderObjectsEXT)
3694 {
3695 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3696 return false;
3697 }
3698
3699 return ValidateProgramUniform3ivBase(context, entryPoint, programPacked, locationPacked, count,
3700 value);
3701 }
3702
ValidateProgramUniform3uiEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLuint v0,GLuint v1,GLuint v2)3703 bool ValidateProgramUniform3uiEXT(const Context *context,
3704 angle::EntryPoint entryPoint,
3705 ShaderProgramID programPacked,
3706 UniformLocation locationPacked,
3707 GLuint v0,
3708 GLuint v1,
3709 GLuint v2)
3710 {
3711 if (!context->getExtensions().separateShaderObjectsEXT)
3712 {
3713 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3714 return false;
3715 }
3716
3717 return ValidateProgramUniform3uiBase(context, entryPoint, programPacked, locationPacked, v0, v1,
3718 v2);
3719 }
3720
ValidateProgramUniform3uivEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLuint * value)3721 bool ValidateProgramUniform3uivEXT(const Context *context,
3722 angle::EntryPoint entryPoint,
3723 ShaderProgramID programPacked,
3724 UniformLocation locationPacked,
3725 GLsizei count,
3726 const GLuint *value)
3727 {
3728 if (!context->getExtensions().separateShaderObjectsEXT)
3729 {
3730 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3731 return false;
3732 }
3733
3734 return ValidateProgramUniform3uivBase(context, entryPoint, programPacked, locationPacked, count,
3735 value);
3736 }
3737
ValidateProgramUniform4fEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLfloat v0,GLfloat v1,GLfloat v2,GLfloat v3)3738 bool ValidateProgramUniform4fEXT(const Context *context,
3739 angle::EntryPoint entryPoint,
3740 ShaderProgramID programPacked,
3741 UniformLocation locationPacked,
3742 GLfloat v0,
3743 GLfloat v1,
3744 GLfloat v2,
3745 GLfloat v3)
3746 {
3747 if (!context->getExtensions().separateShaderObjectsEXT)
3748 {
3749 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3750 return false;
3751 }
3752
3753 return ValidateProgramUniform4fBase(context, entryPoint, programPacked, locationPacked, v0, v1,
3754 v2, v3);
3755 }
3756
ValidateProgramUniform4fvEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLfloat * value)3757 bool ValidateProgramUniform4fvEXT(const Context *context,
3758 angle::EntryPoint entryPoint,
3759 ShaderProgramID programPacked,
3760 UniformLocation locationPacked,
3761 GLsizei count,
3762 const GLfloat *value)
3763 {
3764 if (!context->getExtensions().separateShaderObjectsEXT)
3765 {
3766 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3767 return false;
3768 }
3769
3770 return ValidateProgramUniform4fvBase(context, entryPoint, programPacked, locationPacked, count,
3771 value);
3772 }
3773
ValidateProgramUniform4iEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLint v0,GLint v1,GLint v2,GLint v3)3774 bool ValidateProgramUniform4iEXT(const Context *context,
3775 angle::EntryPoint entryPoint,
3776 ShaderProgramID programPacked,
3777 UniformLocation locationPacked,
3778 GLint v0,
3779 GLint v1,
3780 GLint v2,
3781 GLint v3)
3782 {
3783 if (!context->getExtensions().separateShaderObjectsEXT)
3784 {
3785 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3786 return false;
3787 }
3788
3789 return ValidateProgramUniform4iBase(context, entryPoint, programPacked, locationPacked, v0, v1,
3790 v2, v3);
3791 }
3792
ValidateProgramUniform4ivEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLint * value)3793 bool ValidateProgramUniform4ivEXT(const Context *context,
3794 angle::EntryPoint entryPoint,
3795 ShaderProgramID programPacked,
3796 UniformLocation locationPacked,
3797 GLsizei count,
3798 const GLint *value)
3799 {
3800 return ValidateProgramUniform4ivBase(context, entryPoint, programPacked, locationPacked, count,
3801 value);
3802 }
3803
ValidateProgramUniform4uiEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLuint v0,GLuint v1,GLuint v2,GLuint v3)3804 bool ValidateProgramUniform4uiEXT(const Context *context,
3805 angle::EntryPoint entryPoint,
3806 ShaderProgramID programPacked,
3807 UniformLocation locationPacked,
3808 GLuint v0,
3809 GLuint v1,
3810 GLuint v2,
3811 GLuint v3)
3812 {
3813 if (!context->getExtensions().separateShaderObjectsEXT)
3814 {
3815 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3816 return false;
3817 }
3818
3819 return ValidateProgramUniform4uiBase(context, entryPoint, programPacked, locationPacked, v0, v1,
3820 v2, v3);
3821 }
3822
ValidateProgramUniform4uivEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,const GLuint * value)3823 bool ValidateProgramUniform4uivEXT(const Context *context,
3824 angle::EntryPoint entryPoint,
3825 ShaderProgramID programPacked,
3826 UniformLocation locationPacked,
3827 GLsizei count,
3828 const GLuint *value)
3829 {
3830 return ValidateProgramUniform4uivBase(context, entryPoint, programPacked, locationPacked, count,
3831 value);
3832 }
3833
ValidateProgramUniformMatrix2fvEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,GLboolean transpose,const GLfloat * value)3834 bool ValidateProgramUniformMatrix2fvEXT(const Context *context,
3835 angle::EntryPoint entryPoint,
3836 ShaderProgramID programPacked,
3837 UniformLocation locationPacked,
3838 GLsizei count,
3839 GLboolean transpose,
3840 const GLfloat *value)
3841 {
3842 if (!context->getExtensions().separateShaderObjectsEXT)
3843 {
3844 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3845 return false;
3846 }
3847
3848 return ValidateProgramUniformMatrix2fvBase(context, entryPoint, programPacked, locationPacked,
3849 count, transpose, value);
3850 }
3851
ValidateProgramUniformMatrix2x3fvEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,GLboolean transpose,const GLfloat * value)3852 bool ValidateProgramUniformMatrix2x3fvEXT(const Context *context,
3853 angle::EntryPoint entryPoint,
3854 ShaderProgramID programPacked,
3855 UniformLocation locationPacked,
3856 GLsizei count,
3857 GLboolean transpose,
3858 const GLfloat *value)
3859 {
3860 if (!context->getExtensions().separateShaderObjectsEXT)
3861 {
3862 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3863 return false;
3864 }
3865
3866 return ValidateProgramUniformMatrix2x3fvBase(context, entryPoint, programPacked, locationPacked,
3867 count, transpose, value);
3868 }
3869
ValidateProgramUniformMatrix2x4fvEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,GLboolean transpose,const GLfloat * value)3870 bool ValidateProgramUniformMatrix2x4fvEXT(const Context *context,
3871 angle::EntryPoint entryPoint,
3872 ShaderProgramID programPacked,
3873 UniformLocation locationPacked,
3874 GLsizei count,
3875 GLboolean transpose,
3876 const GLfloat *value)
3877 {
3878 if (!context->getExtensions().separateShaderObjectsEXT)
3879 {
3880 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3881 return false;
3882 }
3883
3884 return ValidateProgramUniformMatrix2x4fvBase(context, entryPoint, programPacked, locationPacked,
3885 count, transpose, value);
3886 }
3887
ValidateProgramUniformMatrix3fvEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,GLboolean transpose,const GLfloat * value)3888 bool ValidateProgramUniformMatrix3fvEXT(const Context *context,
3889 angle::EntryPoint entryPoint,
3890 ShaderProgramID programPacked,
3891 UniformLocation locationPacked,
3892 GLsizei count,
3893 GLboolean transpose,
3894 const GLfloat *value)
3895 {
3896 if (!context->getExtensions().separateShaderObjectsEXT)
3897 {
3898 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3899 return false;
3900 }
3901
3902 return ValidateProgramUniformMatrix3fvBase(context, entryPoint, programPacked, locationPacked,
3903 count, transpose, value);
3904 }
3905
ValidateProgramUniformMatrix3x2fvEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,GLboolean transpose,const GLfloat * value)3906 bool ValidateProgramUniformMatrix3x2fvEXT(const Context *context,
3907 angle::EntryPoint entryPoint,
3908 ShaderProgramID programPacked,
3909 UniformLocation locationPacked,
3910 GLsizei count,
3911 GLboolean transpose,
3912 const GLfloat *value)
3913 {
3914 if (!context->getExtensions().separateShaderObjectsEXT)
3915 {
3916 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3917 return false;
3918 }
3919
3920 return ValidateProgramUniformMatrix3x2fvBase(context, entryPoint, programPacked, locationPacked,
3921 count, transpose, value);
3922 }
3923
ValidateProgramUniformMatrix3x4fvEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,GLboolean transpose,const GLfloat * value)3924 bool ValidateProgramUniformMatrix3x4fvEXT(const Context *context,
3925 angle::EntryPoint entryPoint,
3926 ShaderProgramID programPacked,
3927 UniformLocation locationPacked,
3928 GLsizei count,
3929 GLboolean transpose,
3930 const GLfloat *value)
3931 {
3932 if (!context->getExtensions().separateShaderObjectsEXT)
3933 {
3934 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3935 return false;
3936 }
3937
3938 return ValidateProgramUniformMatrix3x4fvBase(context, entryPoint, programPacked, locationPacked,
3939 count, transpose, value);
3940 }
3941
ValidateProgramUniformMatrix4fvEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,GLboolean transpose,const GLfloat * value)3942 bool ValidateProgramUniformMatrix4fvEXT(const Context *context,
3943 angle::EntryPoint entryPoint,
3944 ShaderProgramID programPacked,
3945 UniformLocation locationPacked,
3946 GLsizei count,
3947 GLboolean transpose,
3948 const GLfloat *value)
3949 {
3950 if (!context->getExtensions().separateShaderObjectsEXT)
3951 {
3952 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3953 return false;
3954 }
3955
3956 return ValidateProgramUniformMatrix4fvBase(context, entryPoint, programPacked, locationPacked,
3957 count, transpose, value);
3958 }
3959
ValidateProgramUniformMatrix4x2fvEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,GLboolean transpose,const GLfloat * value)3960 bool ValidateProgramUniformMatrix4x2fvEXT(const Context *context,
3961 angle::EntryPoint entryPoint,
3962 ShaderProgramID programPacked,
3963 UniformLocation locationPacked,
3964 GLsizei count,
3965 GLboolean transpose,
3966 const GLfloat *value)
3967 {
3968 if (!context->getExtensions().separateShaderObjectsEXT)
3969 {
3970 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3971 return false;
3972 }
3973
3974 return ValidateProgramUniformMatrix4x2fvBase(context, entryPoint, programPacked, locationPacked,
3975 count, transpose, value);
3976 }
3977
ValidateProgramUniformMatrix4x3fvEXT(const Context * context,angle::EntryPoint entryPoint,ShaderProgramID programPacked,UniformLocation locationPacked,GLsizei count,GLboolean transpose,const GLfloat * value)3978 bool ValidateProgramUniformMatrix4x3fvEXT(const Context *context,
3979 angle::EntryPoint entryPoint,
3980 ShaderProgramID programPacked,
3981 UniformLocation locationPacked,
3982 GLsizei count,
3983 GLboolean transpose,
3984 const GLfloat *value)
3985 {
3986 if (!context->getExtensions().separateShaderObjectsEXT)
3987 {
3988 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
3989 return false;
3990 }
3991
3992 return ValidateProgramUniformMatrix4x3fvBase(context, entryPoint, programPacked, locationPacked,
3993 count, transpose, value);
3994 }
3995
ValidateUseProgramStagesEXT(const Context * context,angle::EntryPoint entryPoint,ProgramPipelineID pipelinePacked,GLbitfield stages,ShaderProgramID programPacked)3996 bool ValidateUseProgramStagesEXT(const Context *context,
3997 angle::EntryPoint entryPoint,
3998 ProgramPipelineID pipelinePacked,
3999 GLbitfield stages,
4000 ShaderProgramID programPacked)
4001 {
4002 if (!context->getExtensions().separateShaderObjectsEXT)
4003 {
4004 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
4005 return false;
4006 }
4007
4008 return ValidateUseProgramStagesBase(context, entryPoint, pipelinePacked, stages, programPacked);
4009 }
4010
ValidateValidateProgramPipelineEXT(const Context * context,angle::EntryPoint entryPoint,ProgramPipelineID pipelinePacked)4011 bool ValidateValidateProgramPipelineEXT(const Context *context,
4012 angle::EntryPoint entryPoint,
4013 ProgramPipelineID pipelinePacked)
4014 {
4015 if (!context->getExtensions().separateShaderObjectsEXT)
4016 {
4017 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
4018 return false;
4019 }
4020
4021 return ValidateValidateProgramPipelineBase(context, entryPoint, pipelinePacked);
4022 }
4023
4024 // GL_EXT_debug_label
ValidateGetObjectLabelEXT(const Context * context,angle::EntryPoint entryPoint,GLenum type,GLuint object,GLsizei bufSize,const GLsizei * length,const GLchar * label)4025 bool ValidateGetObjectLabelEXT(const Context *context,
4026 angle::EntryPoint entryPoint,
4027 GLenum type,
4028 GLuint object,
4029 GLsizei bufSize,
4030 const GLsizei *length,
4031 const GLchar *label)
4032 {
4033 if (!context->getExtensions().debugLabelEXT)
4034 {
4035 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
4036 return false;
4037 }
4038
4039 if (bufSize < 0)
4040 {
4041 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeBufSize);
4042 return false;
4043 }
4044
4045 return ValidateObjectIdentifierAndName(context, entryPoint, type, object);
4046 }
4047
ValidateLabelObjectEXT(const Context * context,angle::EntryPoint entryPoint,GLenum type,GLuint object,GLsizei length,const GLchar * label)4048 bool ValidateLabelObjectEXT(const Context *context,
4049 angle::EntryPoint entryPoint,
4050 GLenum type,
4051 GLuint object,
4052 GLsizei length,
4053 const GLchar *label)
4054 {
4055 if (!context->getExtensions().debugLabelEXT)
4056 {
4057 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
4058 return false;
4059 }
4060
4061 if (length < 0)
4062 {
4063 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kNegativeLength);
4064 return false;
4065 }
4066
4067 return ValidateObjectIdentifierAndName(context, entryPoint, type, object);
4068 }
4069
ValidateEGLImageTargetTextureStorageEXT(const Context * context,angle::EntryPoint entryPoint,GLuint texture,egl::ImageID image,const GLint * attrib_list)4070 bool ValidateEGLImageTargetTextureStorageEXT(const Context *context,
4071 angle::EntryPoint entryPoint,
4072 GLuint texture,
4073 egl::ImageID image,
4074 const GLint *attrib_list)
4075 {
4076 UNREACHABLE();
4077 return false;
4078 }
4079
ValidateEGLImageTargetTexStorageEXT(const Context * context,angle::EntryPoint entryPoint,GLenum target,egl::ImageID image,const GLint * attrib_list)4080 bool ValidateEGLImageTargetTexStorageEXT(const Context *context,
4081 angle::EntryPoint entryPoint,
4082 GLenum target,
4083 egl::ImageID image,
4084 const GLint *attrib_list)
4085 {
4086 if (!context->getExtensions().EGLImageStorageEXT)
4087 {
4088 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
4089 return false;
4090 }
4091
4092 gl::TextureType targetType = FromGLenum<TextureType>(target);
4093 switch (targetType)
4094 {
4095 case TextureType::External:
4096 if (!context->getExtensions().EGLImageExternalOES)
4097 {
4098 ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, ToGLenum(targetType));
4099 }
4100 break;
4101 case TextureType::CubeMapArray:
4102 if (!context->getExtensions().textureCubeMapArrayAny())
4103 {
4104 ANGLE_VALIDATION_ERRORF(GL_INVALID_ENUM, kEnumNotSupported, ToGLenum(targetType));
4105 }
4106 break;
4107 case TextureType::_2D:
4108 case TextureType::_2DArray:
4109 case TextureType::_3D:
4110 case TextureType::CubeMap:
4111 break;
4112 default:
4113 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidTextureTarget);
4114 return false;
4115 }
4116
4117 // Validate egl source image is valid
4118 egl::Image *imageObject = context->getDisplay()->getImage(image);
4119 if (!ValidateEGLImageObject(context, entryPoint, targetType, image))
4120 {
4121 return false;
4122 }
4123
4124 if (attrib_list != nullptr)
4125 {
4126 for (const GLint *attrib = attrib_list; attrib[0] != GL_NONE; attrib += 2)
4127 {
4128 switch (attrib[0])
4129 {
4130 case GL_SURFACE_COMPRESSION_EXT:
4131 switch (attrib[1])
4132 {
4133 case GL_SURFACE_COMPRESSION_FIXED_RATE_NONE_EXT:
4134 if (imageObject->isFixedRatedCompression(context))
4135 {
4136 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kAttributeNotMatch);
4137 return false;
4138 }
4139 break;
4140 case GL_SURFACE_COMPRESSION_FIXED_RATE_DEFAULT_EXT:
4141 break;
4142 default:
4143 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kAttributeNotValid);
4144 return false;
4145 }
4146 break;
4147 default:
4148 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kAttributeNotValid);
4149 return false;
4150 }
4151 }
4152 }
4153
4154 GLsizei levelCount = imageObject->getLevelCount();
4155 Extents size = imageObject->getExtents();
4156 GLsizei width = static_cast<GLsizei>(size.width);
4157 GLsizei height = static_cast<GLsizei>(size.height);
4158 GLsizei depth = static_cast<GLsizei>(size.depth);
4159 GLenum internalformat = imageObject->getFormat().info->sizedInternalFormat;
4160
4161 if (width < 1 || height < 1 || depth < 1 || levelCount < 1)
4162 {
4163 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kTextureSizeTooSmall);
4164 return false;
4165 }
4166
4167 if (!ValidateES3TexStorageParametersLevel(context, entryPoint, targetType, levelCount, width,
4168 height, depth))
4169 {
4170 // Error already generated.
4171 return false;
4172 }
4173
4174 if (targetType == TextureType::External)
4175 {
4176 const Caps &caps = context->getCaps();
4177 if (width > caps.max2DTextureSize || height > caps.max2DTextureSize)
4178 {
4179 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kResourceMaxTextureSize);
4180 return false;
4181 }
4182 }
4183 else if (!ValidateES3TexStorageParametersExtent(context, entryPoint, targetType, levelCount,
4184 width, height, depth))
4185 {
4186 // Error already generated.
4187 return false;
4188 }
4189
4190 if (!ValidateES3TexStorageParametersTexObject(context, entryPoint, targetType))
4191 {
4192 // Error already generated.
4193 return false;
4194 }
4195
4196 if (!ValidateES3TexStorageParametersFormat(context, entryPoint, targetType, levelCount,
4197 internalformat, width, height, depth))
4198 {
4199 // Error already generated.
4200 return false;
4201 }
4202
4203 return true;
4204 }
4205
ValidateAcquireTexturesANGLE(const Context * context,angle::EntryPoint entryPoint,GLuint numTextures,const TextureID * textures,const GLenum * layouts)4206 bool ValidateAcquireTexturesANGLE(const Context *context,
4207 angle::EntryPoint entryPoint,
4208 GLuint numTextures,
4209 const TextureID *textures,
4210 const GLenum *layouts)
4211 {
4212 if (!context->getExtensions().vulkanImageANGLE)
4213 {
4214 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
4215 return false;
4216 }
4217
4218 for (GLuint i = 0; i < numTextures; ++i)
4219 {
4220 if (!context->getTexture(textures[i]))
4221 {
4222 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidTextureName);
4223 return false;
4224 }
4225 if (!IsValidImageLayout(FromGLenum<ImageLayout>(layouts[i])))
4226 {
4227 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidImageLayout);
4228 return false;
4229 }
4230 }
4231
4232 return true;
4233 }
4234
ValidateReleaseTexturesANGLE(const Context * context,angle::EntryPoint entryPoint,GLuint numTextures,const TextureID * textures,const GLenum * layouts)4235 bool ValidateReleaseTexturesANGLE(const Context *context,
4236 angle::EntryPoint entryPoint,
4237 GLuint numTextures,
4238 const TextureID *textures,
4239 const GLenum *layouts)
4240 {
4241 if (!context->getExtensions().vulkanImageANGLE)
4242 {
4243 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
4244 return false;
4245 }
4246 for (GLuint i = 0; i < numTextures; ++i)
4247 {
4248 if (!context->getTexture(textures[i]))
4249 {
4250 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kInvalidTextureName);
4251 return false;
4252 }
4253 }
4254
4255 return true;
4256 }
4257
ValidateFramebufferParameteriMESA(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLenum pname,GLint param)4258 bool ValidateFramebufferParameteriMESA(const Context *context,
4259 angle::EntryPoint entryPoint,
4260 GLenum target,
4261 GLenum pname,
4262 GLint param)
4263 {
4264 if (pname != GL_FRAMEBUFFER_FLIP_Y_MESA)
4265 {
4266 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidPname);
4267 return false;
4268 }
4269 return ValidateFramebufferParameteriBase(context, entryPoint, target, pname, param);
4270 }
4271
ValidateGetFramebufferParameterivMESA(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLenum pname,const GLint * params)4272 bool ValidateGetFramebufferParameterivMESA(const Context *context,
4273 angle::EntryPoint entryPoint,
4274 GLenum target,
4275 GLenum pname,
4276 const GLint *params)
4277 {
4278 if (pname != GL_FRAMEBUFFER_FLIP_Y_MESA)
4279 {
4280 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidPname);
4281 return false;
4282 }
4283 return ValidateGetFramebufferParameterivBase(context, entryPoint, target, pname, params);
4284 }
4285
4286 // GL_AMD_performance_monitor
ValidateBeginPerfMonitorAMD(const Context * context,angle::EntryPoint entryPoint,GLuint monitor)4287 bool ValidateBeginPerfMonitorAMD(const Context *context,
4288 angle::EntryPoint entryPoint,
4289 GLuint monitor)
4290 {
4291 if (!context->getExtensions().performanceMonitorAMD)
4292 {
4293 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
4294 return false;
4295 }
4296
4297 return true;
4298 }
4299
ValidateDeletePerfMonitorsAMD(const Context * context,angle::EntryPoint entryPoint,GLsizei n,const GLuint * monitors)4300 bool ValidateDeletePerfMonitorsAMD(const Context *context,
4301 angle::EntryPoint entryPoint,
4302 GLsizei n,
4303 const GLuint *monitors)
4304 {
4305 if (!context->getExtensions().performanceMonitorAMD)
4306 {
4307 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
4308 return false;
4309 }
4310
4311 // Note: ANGLE does not really create monitor objects or track ids.
4312 return true;
4313 }
4314
ValidateEndPerfMonitorAMD(const Context * context,angle::EntryPoint entryPoint,GLuint monitor)4315 bool ValidateEndPerfMonitorAMD(const Context *context, angle::EntryPoint entryPoint, GLuint monitor)
4316 {
4317 if (!context->getExtensions().performanceMonitorAMD)
4318 {
4319 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
4320 return false;
4321 }
4322
4323 if (!context->getState().isPerfMonitorActive())
4324 {
4325 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kPerfMonitorNotActive);
4326 return false;
4327 }
4328
4329 return true;
4330 }
4331
ValidateGenPerfMonitorsAMD(const Context * context,angle::EntryPoint entryPoint,GLsizei n,const GLuint * monitors)4332 bool ValidateGenPerfMonitorsAMD(const Context *context,
4333 angle::EntryPoint entryPoint,
4334 GLsizei n,
4335 const GLuint *monitors)
4336 {
4337 if (!context->getExtensions().performanceMonitorAMD)
4338 {
4339 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
4340 return false;
4341 }
4342
4343 return true;
4344 }
4345
ValidateGetPerfMonitorCounterDataAMD(const Context * context,angle::EntryPoint entryPoint,GLuint monitor,GLenum pname,GLsizei dataSize,const GLuint * data,const GLint * bytesWritten)4346 bool ValidateGetPerfMonitorCounterDataAMD(const Context *context,
4347 angle::EntryPoint entryPoint,
4348 GLuint monitor,
4349 GLenum pname,
4350 GLsizei dataSize,
4351 const GLuint *data,
4352 const GLint *bytesWritten)
4353 {
4354 if (!context->getExtensions().performanceMonitorAMD)
4355 {
4356 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
4357 return false;
4358 }
4359
4360 if (monitor != 0)
4361 {
4362 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidPerfMonitor);
4363 return false;
4364 }
4365
4366 switch (pname)
4367 {
4368 case GL_PERFMON_RESULT_AVAILABLE_AMD:
4369 case GL_PERFMON_RESULT_SIZE_AMD:
4370 case GL_PERFMON_RESULT_AMD:
4371 break;
4372
4373 default:
4374 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidPname);
4375 return false;
4376 }
4377
4378 return true;
4379 }
4380
ValidateGetPerfMonitorCounterInfoAMD(const Context * context,angle::EntryPoint entryPoint,GLuint group,GLuint counter,GLenum pname,const void * data)4381 bool ValidateGetPerfMonitorCounterInfoAMD(const Context *context,
4382 angle::EntryPoint entryPoint,
4383 GLuint group,
4384 GLuint counter,
4385 GLenum pname,
4386 const void *data)
4387 {
4388 if (!context->getExtensions().performanceMonitorAMD)
4389 {
4390 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
4391 return false;
4392 }
4393
4394 const angle::PerfMonitorCounterGroups &groups = context->getPerfMonitorCounterGroups();
4395
4396 if (group >= groups.size())
4397 {
4398 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidPerfMonitorGroup);
4399 return false;
4400 }
4401
4402 if (counter >= groups[group].counters.size())
4403 {
4404 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidPerfMonitorCounter);
4405 return false;
4406 }
4407
4408 switch (pname)
4409 {
4410 case GL_COUNTER_TYPE_AMD:
4411 case GL_COUNTER_RANGE_AMD:
4412 break;
4413
4414 default:
4415 ANGLE_VALIDATION_ERROR(GL_INVALID_ENUM, kInvalidPname);
4416 return false;
4417 }
4418
4419 return true;
4420 }
4421
ValidateGetPerfMonitorCounterStringAMD(const Context * context,angle::EntryPoint entryPoint,GLuint group,GLuint counter,GLsizei bufSize,const GLsizei * length,const GLchar * counterString)4422 bool ValidateGetPerfMonitorCounterStringAMD(const Context *context,
4423 angle::EntryPoint entryPoint,
4424 GLuint group,
4425 GLuint counter,
4426 GLsizei bufSize,
4427 const GLsizei *length,
4428 const GLchar *counterString)
4429 {
4430 if (!context->getExtensions().performanceMonitorAMD)
4431 {
4432 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
4433 return false;
4434 }
4435
4436 const angle::PerfMonitorCounterGroups &groups = context->getPerfMonitorCounterGroups();
4437
4438 if (group >= groups.size())
4439 {
4440 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidPerfMonitorGroup);
4441 return false;
4442 }
4443
4444 if (counter >= groups[group].counters.size())
4445 {
4446 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidPerfMonitorCounter);
4447 return false;
4448 }
4449
4450 return true;
4451 }
4452
ValidateGetPerfMonitorCountersAMD(const Context * context,angle::EntryPoint entryPoint,GLuint group,const GLint * numCounters,const GLint * maxActiveCounters,GLsizei counterSize,const GLuint * counters)4453 bool ValidateGetPerfMonitorCountersAMD(const Context *context,
4454 angle::EntryPoint entryPoint,
4455 GLuint group,
4456 const GLint *numCounters,
4457 const GLint *maxActiveCounters,
4458 GLsizei counterSize,
4459 const GLuint *counters)
4460 {
4461 if (!context->getExtensions().performanceMonitorAMD)
4462 {
4463 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
4464 return false;
4465 }
4466
4467 const angle::PerfMonitorCounterGroups &groups = context->getPerfMonitorCounterGroups();
4468
4469 if (group >= groups.size())
4470 {
4471 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidPerfMonitorGroup);
4472 return false;
4473 }
4474
4475 return true;
4476 }
4477
ValidateGetPerfMonitorGroupStringAMD(const Context * context,angle::EntryPoint entryPoint,GLuint group,GLsizei bufSize,const GLsizei * length,const GLchar * groupString)4478 bool ValidateGetPerfMonitorGroupStringAMD(const Context *context,
4479 angle::EntryPoint entryPoint,
4480 GLuint group,
4481 GLsizei bufSize,
4482 const GLsizei *length,
4483 const GLchar *groupString)
4484 {
4485 if (!context->getExtensions().performanceMonitorAMD)
4486 {
4487 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
4488 return false;
4489 }
4490
4491 const angle::PerfMonitorCounterGroups &groups = context->getPerfMonitorCounterGroups();
4492
4493 if (group >= groups.size())
4494 {
4495 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidPerfMonitorGroup);
4496 return false;
4497 }
4498
4499 return true;
4500 }
4501
ValidateGetPerfMonitorGroupsAMD(const Context * context,angle::EntryPoint entryPoint,const GLint * numGroups,GLsizei groupsSize,const GLuint * groups)4502 bool ValidateGetPerfMonitorGroupsAMD(const Context *context,
4503 angle::EntryPoint entryPoint,
4504 const GLint *numGroups,
4505 GLsizei groupsSize,
4506 const GLuint *groups)
4507 {
4508 if (!context->getExtensions().performanceMonitorAMD)
4509 {
4510 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
4511 return false;
4512 }
4513
4514 return true;
4515 }
4516
ValidateSelectPerfMonitorCountersAMD(const Context * context,angle::EntryPoint entryPoint,GLuint monitor,GLboolean enable,GLuint group,GLint numCounters,const GLuint * counterList)4517 bool ValidateSelectPerfMonitorCountersAMD(const Context *context,
4518 angle::EntryPoint entryPoint,
4519 GLuint monitor,
4520 GLboolean enable,
4521 GLuint group,
4522 GLint numCounters,
4523 const GLuint *counterList)
4524 {
4525 if (!context->getExtensions().performanceMonitorAMD)
4526 {
4527 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
4528 return false;
4529 }
4530
4531 UNIMPLEMENTED();
4532 return false;
4533 }
4534
ValidateShadingRateQCOM(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,GLenum rate)4535 bool ValidateShadingRateQCOM(const PrivateState &state,
4536 ErrorSet *errors,
4537 angle::EntryPoint entryPoint,
4538 GLenum rate)
4539 {
4540 if (!state.getExtensions().shadingRateQCOM)
4541 {
4542 errors->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
4543 return false;
4544 }
4545
4546 gl::ShadingRate shadingRate = gl::FromGLenum<gl::ShadingRate>(rate);
4547 if (shadingRate == gl::ShadingRate::Undefined || shadingRate == gl::ShadingRate::InvalidEnum)
4548 {
4549 errors->validationError(entryPoint, GL_INVALID_ENUM, kInvalidShadingRate);
4550 return false;
4551 }
4552
4553 return true;
4554 }
4555
ValidateLogicOpANGLE(const PrivateState & state,ErrorSet * errors,angle::EntryPoint entryPoint,LogicalOperation opcodePacked)4556 bool ValidateLogicOpANGLE(const PrivateState &state,
4557 ErrorSet *errors,
4558 angle::EntryPoint entryPoint,
4559 LogicalOperation opcodePacked)
4560 {
4561 if (!state.getExtensions().logicOpANGLE)
4562 {
4563 errors->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled);
4564 return false;
4565 }
4566
4567 return ValidateLogicOpCommon(state, errors, entryPoint, opcodePacked);
4568 }
4569
ValidateFramebufferFoveationConfigQCOM(const Context * context,angle::EntryPoint entryPoint,FramebufferID framebufferPacked,GLuint numLayers,GLuint focalPointsPerLayer,GLuint requestedFeatures,const GLuint * providedFeatures)4570 bool ValidateFramebufferFoveationConfigQCOM(const Context *context,
4571 angle::EntryPoint entryPoint,
4572 FramebufferID framebufferPacked,
4573 GLuint numLayers,
4574 GLuint focalPointsPerLayer,
4575 GLuint requestedFeatures,
4576 const GLuint *providedFeatures)
4577 {
4578 Framebuffer *framebuffer = context->getFramebuffer(framebufferPacked);
4579
4580 // INVALID_VALUE is generated by FramebufferFoveationConfigQCOM if 'fbo' is not a valid
4581 // framebuffer.
4582 if (framebuffer == nullptr)
4583 {
4584 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidFramebufferName);
4585 return false;
4586 }
4587
4588 // INVALID_VALUE is generated by FramebufferFoveationConfigQCOM if 'numLayers' is greater than
4589 // GL_MAX_ARRAY_TEXTURE_LAYERS - 1.
4590 if (numLayers > static_cast<GLuint>(context->getState().getCaps().maxArrayTextureLayers) - 1)
4591 {
4592 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kFramebufferFoveationLayersExceedMaxArrayLayers);
4593 return false;
4594 }
4595
4596 // INVALID_VALUE is generated by FramebufferFoveationConfigQCOM if 'numFocalPoints' is greater
4597 // than implementation can support.
4598 if (focalPointsPerLayer > gl::IMPLEMENTATION_MAX_FOCAL_POINTS)
4599 {
4600 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kFocalPointsExceedMaxFocalPoints);
4601 return false;
4602 }
4603
4604 // INVALID_OPERATION is generated by FramebufferFoveationConfigQCOM if it is called for a fbo
4605 // that has already been cofigured for foveated rendering.
4606 if (framebuffer->isFoveationConfigured())
4607 {
4608 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kFramebufferFoveationAlreadyConfigured);
4609 return false;
4610 }
4611
4612 return true;
4613 }
4614
ValidateFramebufferFoveationParametersQCOM(const Context * context,angle::EntryPoint entryPoint,FramebufferID framebufferPacked,GLuint layer,GLuint focalPoint,GLfloat focalX,GLfloat focalY,GLfloat gainX,GLfloat gainY,GLfloat foveaArea)4615 bool ValidateFramebufferFoveationParametersQCOM(const Context *context,
4616 angle::EntryPoint entryPoint,
4617 FramebufferID framebufferPacked,
4618 GLuint layer,
4619 GLuint focalPoint,
4620 GLfloat focalX,
4621 GLfloat focalY,
4622 GLfloat gainX,
4623 GLfloat gainY,
4624 GLfloat foveaArea)
4625 {
4626 Framebuffer *framebuffer = context->getFramebuffer(framebufferPacked);
4627
4628 // INVALID_VALUE is generated by FramebufferFoveationParametersQCOM if 'fbo' is not a valid
4629 // framebuffer.
4630 if (framebuffer == nullptr)
4631 {
4632 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidFramebufferName);
4633 return false;
4634 }
4635
4636 // INVALID_OPERATION is generated by FramebufferFoveationParametersQCOM if 'fbo' has not been
4637 // configured for foveated rendering.
4638 if (!framebuffer->isFoveationConfigured())
4639 {
4640 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kFramebufferFoveationNotConfigured);
4641 return false;
4642 }
4643
4644 // INVALID_VALUE is generated by FramebufferFoveationParametersQCOM if 'layer' is greater than
4645 // or equal to the numLayers that the fbo was previously configured for in
4646 // FramebufferFoveationConfigQCOM.
4647 if (layer >= gl::IMPLEMENTATION_MAX_NUM_LAYERS)
4648 {
4649 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kFramebufferFoveationLayersExceedMaxArrayLayers);
4650 return false;
4651 }
4652
4653 // INVALID_VALUE is generated by FramebufferFoveationParametersQCOM if 'numFocalPoints' is
4654 // greater than implementation can support. INVALID_OPERATION is generated by
4655 if (focalPoint >= gl::IMPLEMENTATION_MAX_FOCAL_POINTS)
4656 {
4657 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kFocalPointsExceedMaxFocalPoints);
4658 return false;
4659 }
4660 return true;
4661 }
4662
ValidateTextureFoveationParametersQCOM(const Context * context,angle::EntryPoint entryPoint,TextureID texturePacked,GLuint layer,GLuint focalPoint,GLfloat focalX,GLfloat focalY,GLfloat gainX,GLfloat gainY,GLfloat foveaArea)4663 bool ValidateTextureFoveationParametersQCOM(const Context *context,
4664 angle::EntryPoint entryPoint,
4665 TextureID texturePacked,
4666 GLuint layer,
4667 GLuint focalPoint,
4668 GLfloat focalX,
4669 GLfloat focalY,
4670 GLfloat gainX,
4671 GLfloat gainY,
4672 GLfloat foveaArea)
4673 {
4674 Texture *texture = context->getTexture(texturePacked);
4675
4676 // INVALID_VALUE is generated by TextureFoveationParametersQCOM if 'texture' is not a valid
4677 // texture object.
4678 if (texture == nullptr)
4679 {
4680 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidTextureName);
4681 return false;
4682 }
4683
4684 // INVALID_OPERATION is generated by TextureFoveationParametersQCOM if 'texture' has not been
4685 // set as foveated. i.e. 'texture's parameter TEXTURE_FOVEATED_FEATURE_BITS_QCOM does not
4686 // contain FOVEATION_ENABLE_BIT_QCOM.
4687 if (!texture->isFoveationEnabled())
4688 {
4689 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kTextureFoveationNotEnabled);
4690 return false;
4691 }
4692
4693 // INVALID_VALUE is generated by TextureFoveationParametersQCOM if 'focalPoint' is larger than
4694 // TEXTURE_FOVEATED_NUM_FOCAL_POINTS_QUERY_QCOM minus one.
4695 if (focalPoint > texture->getNumFocalPoints() - 1)
4696 {
4697 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kFocalPointsExceedMaxFocalPoints);
4698 return false;
4699 }
4700
4701 return true;
4702 }
4703
ValidateEndTilingQCOM(const Context * context,angle::EntryPoint entryPoint,GLbitfield preserveMask)4704 bool ValidateEndTilingQCOM(const Context *context,
4705 angle::EntryPoint entryPoint,
4706 GLbitfield preserveMask)
4707 {
4708 if (!context->getExtensions().tiledRenderingQCOM)
4709 {
4710 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
4711 return false;
4712 }
4713
4714 const gl::PrivateState &privateState = context->getPrivateState();
4715 if (!privateState.isTiledRendering())
4716 {
4717 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kTilingEndCalledWithoutStart);
4718 return false;
4719 }
4720
4721 // preserveMask does not need to be validated. The bitfield covers the entire 32 bits of
4722 // GLbitfield and unbound attachments are siliently ignored like in glClear
4723
4724 return true;
4725 }
4726
ValidateStartTilingQCOM(const Context * context,angle::EntryPoint entryPoint,GLuint x,GLuint y,GLuint width,GLuint height,GLbitfield preserveMask)4727 bool ValidateStartTilingQCOM(const Context *context,
4728 angle::EntryPoint entryPoint,
4729 GLuint x,
4730 GLuint y,
4731 GLuint width,
4732 GLuint height,
4733 GLbitfield preserveMask)
4734 {
4735 if (!context->getExtensions().tiledRenderingQCOM)
4736 {
4737 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
4738 return false;
4739 }
4740
4741 const gl::PrivateState &privateState = context->getPrivateState();
4742 if (privateState.isTiledRendering())
4743 {
4744 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kTilingStartCalledWithoutEnd);
4745 return false;
4746 }
4747
4748 Framebuffer *framebuffer = context->getState().getDrawFramebuffer();
4749 const FramebufferStatus &framebufferStatus = framebuffer->checkStatus(context);
4750 if (!framebufferStatus.isComplete())
4751 {
4752 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, framebufferStatus.reason);
4753 return false;
4754 }
4755
4756 // preserveMask does not need to be validated. The bitfield covers the entire 32 bits of
4757 // GLbitfield and unbound attachments are siliently ignored like in glClear
4758
4759 return true;
4760 }
4761
ValidateTexStorageAttribs(const GLint * attrib_list)4762 bool ValidateTexStorageAttribs(const GLint *attrib_list)
4763 {
4764 if (nullptr != attrib_list && GL_NONE != *attrib_list)
4765 {
4766 attrib_list++;
4767 if (nullptr == attrib_list)
4768 {
4769 return false;
4770 }
4771
4772 if (*attrib_list == GL_SURFACE_COMPRESSION_FIXED_RATE_NONE_EXT ||
4773 *attrib_list == GL_SURFACE_COMPRESSION_FIXED_RATE_DEFAULT_EXT)
4774 {
4775 return true;
4776 }
4777 else if (*attrib_list >= GL_SURFACE_COMPRESSION_FIXED_RATE_1BPC_EXT &&
4778 *attrib_list <= GL_SURFACE_COMPRESSION_FIXED_RATE_12BPC_EXT)
4779 {
4780 return true;
4781 }
4782 else
4783 {
4784 return false;
4785 }
4786 }
4787
4788 return true;
4789 }
4790
ValidateTexStorageAttribs2DEXT(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLsizei levels,GLenum internalformat,GLsizei width,GLsizei height,const GLint * attrib_list)4791 bool ValidateTexStorageAttribs2DEXT(const Context *context,
4792 angle::EntryPoint entryPoint,
4793 GLenum target,
4794 GLsizei levels,
4795 GLenum internalformat,
4796 GLsizei width,
4797 GLsizei height,
4798 const GLint *attrib_list)
4799 {
4800 gl::TextureType targetType = FromGLenum<TextureType>(target);
4801 if (!context->getExtensions().textureStorageCompressionEXT)
4802 {
4803 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
4804 return false;
4805 }
4806
4807 if (ValidateTexStorageAttribs(attrib_list) == false)
4808 {
4809 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidAttribList);
4810 }
4811
4812 if (context->getClientMajorVersion() < 3)
4813 {
4814 return ValidateES2TexStorageParametersBase(context, entryPoint, targetType, levels,
4815 internalformat, width, height);
4816 }
4817
4818 if (context->getClientMajorVersion() >= 3)
4819 {
4820 return ValidateES3TexStorage2DParameters(context, entryPoint, targetType, levels,
4821 internalformat, width, height, 1);
4822 }
4823
4824 return true;
4825 }
4826
ValidateTexStorageAttribs3DEXT(const Context * context,angle::EntryPoint entryPoint,GLenum target,GLsizei levels,GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth,const GLint * attrib_list)4827 bool ValidateTexStorageAttribs3DEXT(const Context *context,
4828 angle::EntryPoint entryPoint,
4829 GLenum target,
4830 GLsizei levels,
4831 GLenum internalformat,
4832 GLsizei width,
4833 GLsizei height,
4834 GLsizei depth,
4835 const GLint *attrib_list)
4836 {
4837 gl::TextureType targetType = FromGLenum<TextureType>(target);
4838 if (!context->getExtensions().textureStorageCompressionEXT)
4839 {
4840 ANGLE_VALIDATION_ERROR(GL_INVALID_OPERATION, kExtensionNotEnabled);
4841 return false;
4842 }
4843
4844 if (ValidateTexStorageAttribs(attrib_list) == false)
4845 {
4846 ANGLE_VALIDATION_ERROR(GL_INVALID_VALUE, kInvalidAttribList);
4847 }
4848
4849 if (context->getClientMajorVersion() < 3)
4850 {
4851 return ValidateES2TexStorageParametersBase(context, entryPoint, targetType, levels,
4852 internalformat, width, height);
4853 }
4854
4855 if (context->getClientMajorVersion() >= 3)
4856 {
4857 return ValidateES3TexStorage3DParameters(context, entryPoint, targetType, levels,
4858 internalformat, width, height, depth);
4859 }
4860
4861 return true;
4862 }
4863
4864 } // namespace gl
4865