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