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