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