validationES31.cpp (115998B)
1 // 2 // Copyright 2016 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 7 // validationES31.cpp: Validation functions for OpenGL ES 3.1 entry point parameters 8 9 #include "libANGLE/validationES31_autogen.h" 10 11 #include "libANGLE/Context.h" 12 #include "libANGLE/ErrorStrings.h" 13 #include "libANGLE/Framebuffer.h" 14 #include "libANGLE/ProgramExecutable.h" 15 #include "libANGLE/VertexArray.h" 16 #include "libANGLE/validationES.h" 17 #include "libANGLE/validationES2_autogen.h" 18 #include "libANGLE/validationES31.h" 19 #include "libANGLE/validationES3_autogen.h" 20 21 #include "common/utilities.h" 22 23 using namespace angle; 24 25 namespace gl 26 { 27 using namespace err; 28 29 namespace 30 { 31 32 bool ValidateNamedProgramInterface(GLenum programInterface) 33 { 34 switch (programInterface) 35 { 36 case GL_UNIFORM: 37 case GL_UNIFORM_BLOCK: 38 case GL_PROGRAM_INPUT: 39 case GL_PROGRAM_OUTPUT: 40 case GL_TRANSFORM_FEEDBACK_VARYING: 41 case GL_BUFFER_VARIABLE: 42 case GL_SHADER_STORAGE_BLOCK: 43 return true; 44 default: 45 return false; 46 } 47 } 48 49 bool ValidateLocationProgramInterface(GLenum programInterface) 50 { 51 switch (programInterface) 52 { 53 case GL_UNIFORM: 54 case GL_PROGRAM_INPUT: 55 case GL_PROGRAM_OUTPUT: 56 return true; 57 default: 58 return false; 59 } 60 } 61 62 bool ValidateProgramInterface(GLenum programInterface) 63 { 64 return (programInterface == GL_ATOMIC_COUNTER_BUFFER || 65 ValidateNamedProgramInterface(programInterface)); 66 } 67 68 bool ValidateProgramResourceProperty(const Context *context, 69 angle::EntryPoint entryPoint, 70 GLenum prop) 71 { 72 ASSERT(context); 73 switch (prop) 74 { 75 case GL_ACTIVE_VARIABLES: 76 case GL_BUFFER_BINDING: 77 case GL_NUM_ACTIVE_VARIABLES: 78 79 case GL_ARRAY_SIZE: 80 81 case GL_ARRAY_STRIDE: 82 case GL_BLOCK_INDEX: 83 case GL_IS_ROW_MAJOR: 84 case GL_MATRIX_STRIDE: 85 86 case GL_ATOMIC_COUNTER_BUFFER_INDEX: 87 88 case GL_BUFFER_DATA_SIZE: 89 90 case GL_LOCATION: 91 92 case GL_NAME_LENGTH: 93 94 case GL_OFFSET: 95 96 case GL_REFERENCED_BY_VERTEX_SHADER: 97 case GL_REFERENCED_BY_FRAGMENT_SHADER: 98 case GL_REFERENCED_BY_COMPUTE_SHADER: 99 100 case GL_TOP_LEVEL_ARRAY_SIZE: 101 case GL_TOP_LEVEL_ARRAY_STRIDE: 102 103 case GL_TYPE: 104 return true; 105 106 case GL_REFERENCED_BY_GEOMETRY_SHADER_EXT: 107 return context->getExtensions().geometryShaderAny() || 108 context->getClientVersion() >= ES_3_2; 109 110 case GL_REFERENCED_BY_TESS_CONTROL_SHADER_EXT: 111 case GL_REFERENCED_BY_TESS_EVALUATION_SHADER_EXT: 112 case GL_IS_PER_PATCH_EXT: 113 return context->getExtensions().tessellationShaderEXT || 114 context->getClientVersion() >= ES_3_2; 115 116 case GL_LOCATION_INDEX_EXT: 117 return context->getExtensions().blendFuncExtendedEXT; 118 119 default: 120 return false; 121 } 122 } 123 124 // GLES 3.10 spec: Page 82 -- Table 7.2 125 bool ValidateProgramResourcePropertyByInterface(GLenum prop, GLenum programInterface) 126 { 127 switch (prop) 128 { 129 case GL_ACTIVE_VARIABLES: 130 case GL_BUFFER_BINDING: 131 case GL_NUM_ACTIVE_VARIABLES: 132 { 133 switch (programInterface) 134 { 135 case GL_ATOMIC_COUNTER_BUFFER: 136 case GL_SHADER_STORAGE_BLOCK: 137 case GL_UNIFORM_BLOCK: 138 return true; 139 default: 140 return false; 141 } 142 } 143 144 case GL_ARRAY_SIZE: 145 { 146 switch (programInterface) 147 { 148 case GL_BUFFER_VARIABLE: 149 case GL_PROGRAM_INPUT: 150 case GL_PROGRAM_OUTPUT: 151 case GL_TRANSFORM_FEEDBACK_VARYING: 152 case GL_UNIFORM: 153 return true; 154 default: 155 return false; 156 } 157 } 158 159 case GL_ARRAY_STRIDE: 160 case GL_BLOCK_INDEX: 161 case GL_IS_ROW_MAJOR: 162 case GL_MATRIX_STRIDE: 163 { 164 switch (programInterface) 165 { 166 case GL_BUFFER_VARIABLE: 167 case GL_UNIFORM: 168 return true; 169 default: 170 return false; 171 } 172 } 173 174 case GL_ATOMIC_COUNTER_BUFFER_INDEX: 175 { 176 if (programInterface == GL_UNIFORM) 177 { 178 return true; 179 } 180 return false; 181 } 182 183 case GL_BUFFER_DATA_SIZE: 184 { 185 switch (programInterface) 186 { 187 case GL_ATOMIC_COUNTER_BUFFER: 188 case GL_SHADER_STORAGE_BLOCK: 189 case GL_UNIFORM_BLOCK: 190 return true; 191 default: 192 return false; 193 } 194 } 195 196 case GL_LOCATION: 197 { 198 return ValidateLocationProgramInterface(programInterface); 199 } 200 201 case GL_LOCATION_INDEX_EXT: 202 { 203 // EXT_blend_func_extended 204 return (programInterface == GL_PROGRAM_OUTPUT); 205 } 206 207 case GL_NAME_LENGTH: 208 { 209 return ValidateNamedProgramInterface(programInterface); 210 } 211 212 case GL_OFFSET: 213 { 214 switch (programInterface) 215 { 216 case GL_BUFFER_VARIABLE: 217 case GL_UNIFORM: 218 return true; 219 default: 220 return false; 221 } 222 } 223 224 case GL_REFERENCED_BY_VERTEX_SHADER: 225 case GL_REFERENCED_BY_FRAGMENT_SHADER: 226 case GL_REFERENCED_BY_COMPUTE_SHADER: 227 case GL_REFERENCED_BY_GEOMETRY_SHADER_EXT: 228 case GL_REFERENCED_BY_TESS_CONTROL_SHADER_EXT: 229 case GL_REFERENCED_BY_TESS_EVALUATION_SHADER_EXT: 230 { 231 switch (programInterface) 232 { 233 case GL_ATOMIC_COUNTER_BUFFER: 234 case GL_BUFFER_VARIABLE: 235 case GL_PROGRAM_INPUT: 236 case GL_PROGRAM_OUTPUT: 237 case GL_SHADER_STORAGE_BLOCK: 238 case GL_UNIFORM: 239 case GL_UNIFORM_BLOCK: 240 return true; 241 default: 242 return false; 243 } 244 } 245 246 case GL_TOP_LEVEL_ARRAY_SIZE: 247 case GL_TOP_LEVEL_ARRAY_STRIDE: 248 { 249 if (programInterface == GL_BUFFER_VARIABLE) 250 { 251 return true; 252 } 253 return false; 254 } 255 256 case GL_TYPE: 257 { 258 switch (programInterface) 259 { 260 case GL_BUFFER_VARIABLE: 261 case GL_PROGRAM_INPUT: 262 case GL_PROGRAM_OUTPUT: 263 case GL_TRANSFORM_FEEDBACK_VARYING: 264 case GL_UNIFORM: 265 return true; 266 default: 267 return false; 268 } 269 } 270 case GL_IS_PER_PATCH_EXT: 271 switch (programInterface) 272 { 273 case GL_PROGRAM_INPUT: 274 case GL_PROGRAM_OUTPUT: 275 return true; 276 } 277 return false; 278 279 default: 280 return false; 281 } 282 } 283 284 bool ValidateProgramResourceIndex(const Program *programObject, 285 GLenum programInterface, 286 GLuint index) 287 { 288 switch (programInterface) 289 { 290 case GL_PROGRAM_INPUT: 291 return (index < 292 static_cast<GLuint>(programObject->getState().getProgramInputs().size())); 293 294 case GL_PROGRAM_OUTPUT: 295 return (index < static_cast<GLuint>(programObject->getOutputResourceCount())); 296 297 case GL_UNIFORM: 298 return (index < static_cast<GLuint>(programObject->getActiveUniformCount())); 299 300 case GL_BUFFER_VARIABLE: 301 return (index < static_cast<GLuint>(programObject->getActiveBufferVariableCount())); 302 303 case GL_SHADER_STORAGE_BLOCK: 304 return (index < static_cast<GLuint>(programObject->getActiveShaderStorageBlockCount())); 305 306 case GL_UNIFORM_BLOCK: 307 return (index < programObject->getActiveUniformBlockCount()); 308 309 case GL_ATOMIC_COUNTER_BUFFER: 310 return (index < programObject->getActiveAtomicCounterBufferCount()); 311 312 case GL_TRANSFORM_FEEDBACK_VARYING: 313 return (index < static_cast<GLuint>(programObject->getTransformFeedbackVaryingCount())); 314 315 default: 316 UNREACHABLE(); 317 return false; 318 } 319 } 320 321 bool ValidateProgramUniformBase(const Context *context, 322 angle::EntryPoint entryPoint, 323 GLenum valueType, 324 ShaderProgramID program, 325 UniformLocation location, 326 GLsizei count) 327 { 328 const LinkedUniform *uniform = nullptr; 329 Program *programObject = GetValidProgram(context, entryPoint, program); 330 return ValidateUniformCommonBase(context, entryPoint, programObject, location, count, 331 &uniform) && 332 ValidateUniformValue(context, entryPoint, valueType, uniform->type); 333 } 334 335 bool ValidateProgramUniformMatrixBase(const Context *context, 336 angle::EntryPoint entryPoint, 337 GLenum valueType, 338 ShaderProgramID program, 339 UniformLocation location, 340 GLsizei count, 341 GLboolean transpose) 342 { 343 const LinkedUniform *uniform = nullptr; 344 Program *programObject = GetValidProgram(context, entryPoint, program); 345 return ValidateUniformCommonBase(context, entryPoint, programObject, location, count, 346 &uniform) && 347 ValidateUniformMatrixValue(context, entryPoint, valueType, uniform->type); 348 } 349 350 bool ValidateVertexAttribFormatCommon(const Context *context, 351 angle::EntryPoint entryPoint, 352 GLuint relativeOffset) 353 { 354 if (context->getClientVersion() < ES_3_1) 355 { 356 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); 357 return false; 358 } 359 360 const Caps &caps = context->getCaps(); 361 if (relativeOffset > static_cast<GLuint>(caps.maxVertexAttribRelativeOffset)) 362 { 363 context->validationError(entryPoint, GL_INVALID_VALUE, kRelativeOffsetTooLarge); 364 return false; 365 } 366 367 // [OpenGL ES 3.1] Section 10.3.1 page 243: 368 // An INVALID_OPERATION error is generated if the default vertex array object is bound. 369 if (context->getState().getVertexArrayId().value == 0) 370 { 371 context->validationError(entryPoint, GL_INVALID_OPERATION, kDefaultVertexArray); 372 return false; 373 } 374 375 return true; 376 } 377 378 } // anonymous namespace 379 380 bool ValidateGetBooleani_v(const Context *context, 381 angle::EntryPoint entryPoint, 382 GLenum target, 383 GLuint index, 384 const GLboolean *data) 385 { 386 if (context->getClientVersion() < ES_3_1 && !context->getExtensions().drawBuffersIndexedAny()) 387 { 388 context->validationError(entryPoint, GL_INVALID_OPERATION, 389 kES31OrDrawBuffersIndexedExtensionNotAvailable); 390 return false; 391 } 392 393 if (!ValidateIndexedStateQuery(context, entryPoint, target, index, nullptr)) 394 { 395 return false; 396 } 397 398 return true; 399 } 400 401 bool ValidateGetBooleani_vRobustANGLE(const Context *context, 402 angle::EntryPoint entryPoint, 403 GLenum target, 404 GLuint index, 405 GLsizei bufSize, 406 const GLsizei *length, 407 const GLboolean *data) 408 { 409 if (context->getClientVersion() < ES_3_1 && !context->getExtensions().drawBuffersIndexedAny()) 410 { 411 context->validationError(entryPoint, GL_INVALID_OPERATION, 412 kES31OrDrawBuffersIndexedExtensionNotAvailable); 413 return false; 414 } 415 416 if (!ValidateRobustEntryPoint(context, entryPoint, bufSize)) 417 { 418 return false; 419 } 420 421 GLsizei numParams = 0; 422 423 if (!ValidateIndexedStateQuery(context, entryPoint, target, index, &numParams)) 424 { 425 return false; 426 } 427 428 if (!ValidateRobustBufferSize(context, entryPoint, bufSize, numParams)) 429 { 430 return false; 431 } 432 433 SetRobustLengthParam(length, numParams); 434 return true; 435 } 436 437 bool ValidateDrawIndirectBase(const Context *context, 438 angle::EntryPoint entryPoint, 439 PrimitiveMode mode, 440 const void *indirect) 441 { 442 if (context->getClientVersion() < ES_3_1) 443 { 444 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); 445 return false; 446 } 447 448 // Here the third parameter 1 is only to pass the count validation. 449 if (!ValidateDrawBase(context, entryPoint, mode)) 450 { 451 return false; 452 } 453 454 const State &state = context->getState(); 455 456 // An INVALID_OPERATION error is generated if zero is bound to VERTEX_ARRAY_BINDING, 457 // DRAW_INDIRECT_BUFFER or to any enabled vertex array. 458 if (state.getVertexArrayId().value == 0) 459 { 460 context->validationError(entryPoint, GL_INVALID_OPERATION, kDefaultVertexArray); 461 return false; 462 } 463 464 if (context->getStateCache().hasAnyActiveClientAttrib()) 465 { 466 context->validationError(entryPoint, GL_INVALID_OPERATION, kClientDataInVertexArray); 467 return false; 468 } 469 470 Buffer *drawIndirectBuffer = state.getTargetBuffer(BufferBinding::DrawIndirect); 471 if (!drawIndirectBuffer) 472 { 473 context->validationError(entryPoint, GL_INVALID_OPERATION, kDrawIndirectBufferNotBound); 474 return false; 475 } 476 477 // An INVALID_VALUE error is generated if indirect is not a multiple of the size, in basic 478 // machine units, of uint. 479 GLint64 offset = reinterpret_cast<GLint64>(indirect); 480 if ((static_cast<GLuint>(offset) % sizeof(GLuint)) != 0) 481 { 482 context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidIndirectOffset); 483 return false; 484 } 485 486 return true; 487 } 488 489 bool ValidateDrawArraysIndirect(const Context *context, 490 angle::EntryPoint entryPoint, 491 PrimitiveMode mode, 492 const void *indirect) 493 { 494 const State &state = context->getState(); 495 TransformFeedback *curTransformFeedback = state.getCurrentTransformFeedback(); 496 if (curTransformFeedback && curTransformFeedback->isActive() && 497 !curTransformFeedback->isPaused()) 498 { 499 // EXT_geometry_shader allows transform feedback to work with all draw commands. 500 // [EXT_geometry_shader] Section 12.1, "Transform Feedback" 501 if (context->getExtensions().geometryShaderAny() || context->getClientVersion() >= ES_3_2) 502 { 503 if (!ValidateTransformFeedbackPrimitiveMode( 504 context, entryPoint, curTransformFeedback->getPrimitiveMode(), mode)) 505 { 506 context->validationError(entryPoint, GL_INVALID_OPERATION, 507 kInvalidDrawModeTransformFeedback); 508 return false; 509 } 510 } 511 else 512 { 513 // An INVALID_OPERATION error is generated if transform feedback is active and not 514 // paused. 515 context->validationError(entryPoint, GL_INVALID_OPERATION, 516 kUnsupportedDrawModeForTransformFeedback); 517 return false; 518 } 519 } 520 521 if (!ValidateDrawIndirectBase(context, entryPoint, mode, indirect)) 522 return false; 523 524 Buffer *drawIndirectBuffer = state.getTargetBuffer(BufferBinding::DrawIndirect); 525 CheckedNumeric<size_t> checkedOffset(reinterpret_cast<size_t>(indirect)); 526 // In OpenGL ES3.1 spec, session 10.5, it defines the struct of DrawArraysIndirectCommand 527 // which's size is 4 * sizeof(uint). 528 auto checkedSum = checkedOffset + 4 * sizeof(GLuint); 529 if (!checkedSum.IsValid() || 530 checkedSum.ValueOrDie() > static_cast<size_t>(drawIndirectBuffer->getSize())) 531 { 532 context->validationError(entryPoint, GL_INVALID_OPERATION, kParamOverflow); 533 return false; 534 } 535 536 return true; 537 } 538 539 bool ValidateDrawElementsIndirect(const Context *context, 540 angle::EntryPoint entryPoint, 541 PrimitiveMode mode, 542 DrawElementsType type, 543 const void *indirect) 544 { 545 if (!ValidateDrawElementsBase(context, entryPoint, mode, type)) 546 { 547 return false; 548 } 549 550 const State &state = context->getState(); 551 const VertexArray *vao = state.getVertexArray(); 552 Buffer *elementArrayBuffer = vao->getElementArrayBuffer(); 553 if (!elementArrayBuffer) 554 { 555 context->validationError(entryPoint, GL_INVALID_OPERATION, kMustHaveElementArrayBinding); 556 return false; 557 } 558 559 if (!ValidateDrawIndirectBase(context, entryPoint, mode, indirect)) 560 return false; 561 562 Buffer *drawIndirectBuffer = state.getTargetBuffer(BufferBinding::DrawIndirect); 563 CheckedNumeric<size_t> checkedOffset(reinterpret_cast<size_t>(indirect)); 564 // In OpenGL ES3.1 spec, session 10.5, it defines the struct of DrawElementsIndirectCommand 565 // which's size is 5 * sizeof(uint). 566 auto checkedSum = checkedOffset + 5 * sizeof(GLuint); 567 if (!checkedSum.IsValid() || 568 checkedSum.ValueOrDie() > static_cast<size_t>(drawIndirectBuffer->getSize())) 569 { 570 context->validationError(entryPoint, GL_INVALID_OPERATION, kParamOverflow); 571 return false; 572 } 573 574 return true; 575 } 576 577 bool ValidateMultiDrawIndirectBase(const Context *context, 578 angle::EntryPoint entryPoint, 579 GLsizei drawcount, 580 GLsizei stride) 581 { 582 if (!context->getExtensions().multiDrawIndirectEXT) 583 { 584 context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); 585 return false; 586 } 587 588 // An INVALID_VALUE error is generated if stride is neither 0 nor a multiple of 4. 589 if ((stride & 3) != 0) 590 { 591 context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidDrawBufferValue); 592 return false; 593 } 594 595 // An INVALID_VALUE error is generated if drawcount is not positive. 596 if (drawcount <= 0) 597 { 598 context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidValueNonPositive); 599 return false; 600 } 601 602 return true; 603 } 604 605 bool ValidateProgramUniform1iBase(const Context *context, 606 angle::EntryPoint entryPoint, 607 ShaderProgramID program, 608 UniformLocation location, 609 GLint v0) 610 { 611 return ValidateProgramUniform1ivBase(context, entryPoint, program, location, 1, &v0); 612 } 613 614 bool ValidateProgramUniform2iBase(const Context *context, 615 angle::EntryPoint entryPoint, 616 ShaderProgramID program, 617 UniformLocation location, 618 GLint v0, 619 GLint v1) 620 { 621 GLint xy[2] = {v0, v1}; 622 return ValidateProgramUniform2ivBase(context, entryPoint, program, location, 1, xy); 623 } 624 625 bool ValidateProgramUniform3iBase(const Context *context, 626 angle::EntryPoint entryPoint, 627 ShaderProgramID program, 628 UniformLocation location, 629 GLint v0, 630 GLint v1, 631 GLint v2) 632 { 633 GLint xyz[3] = {v0, v1, v2}; 634 return ValidateProgramUniform3ivBase(context, entryPoint, program, location, 1, xyz); 635 } 636 637 bool ValidateProgramUniform4iBase(const Context *context, 638 angle::EntryPoint entryPoint, 639 ShaderProgramID program, 640 UniformLocation location, 641 GLint v0, 642 GLint v1, 643 GLint v2, 644 GLint v3) 645 { 646 GLint xyzw[4] = {v0, v1, v2, v3}; 647 return ValidateProgramUniform4ivBase(context, entryPoint, program, location, 1, xyzw); 648 } 649 650 bool ValidateProgramUniform1uiBase(const Context *context, 651 angle::EntryPoint entryPoint, 652 ShaderProgramID program, 653 UniformLocation location, 654 GLuint v0) 655 { 656 return ValidateProgramUniform1uivBase(context, entryPoint, program, location, 1, &v0); 657 } 658 659 bool ValidateProgramUniform2uiBase(const Context *context, 660 angle::EntryPoint entryPoint, 661 ShaderProgramID program, 662 UniformLocation location, 663 GLuint v0, 664 GLuint v1) 665 { 666 GLuint xy[2] = {v0, v1}; 667 return ValidateProgramUniform2uivBase(context, entryPoint, program, location, 1, xy); 668 } 669 670 bool ValidateProgramUniform3uiBase(const Context *context, 671 angle::EntryPoint entryPoint, 672 ShaderProgramID program, 673 UniformLocation location, 674 GLuint v0, 675 GLuint v1, 676 GLuint v2) 677 { 678 GLuint xyz[3] = {v0, v1, v2}; 679 return ValidateProgramUniform3uivBase(context, entryPoint, program, location, 1, xyz); 680 } 681 682 bool ValidateProgramUniform4uiBase(const Context *context, 683 angle::EntryPoint entryPoint, 684 ShaderProgramID program, 685 UniformLocation location, 686 GLuint v0, 687 GLuint v1, 688 GLuint v2, 689 GLuint v3) 690 { 691 GLuint xyzw[4] = {v0, v1, v2, v3}; 692 return ValidateProgramUniform4uivBase(context, entryPoint, program, location, 1, xyzw); 693 } 694 695 bool ValidateProgramUniform1fBase(const Context *context, 696 angle::EntryPoint entryPoint, 697 ShaderProgramID program, 698 UniformLocation location, 699 GLfloat v0) 700 { 701 return ValidateProgramUniform1fvBase(context, entryPoint, program, location, 1, &v0); 702 } 703 704 bool ValidateProgramUniform2fBase(const Context *context, 705 angle::EntryPoint entryPoint, 706 ShaderProgramID program, 707 UniformLocation location, 708 GLfloat v0, 709 GLfloat v1) 710 { 711 GLfloat xy[2] = {v0, v1}; 712 return ValidateProgramUniform2fvBase(context, entryPoint, program, location, 1, xy); 713 } 714 715 bool ValidateProgramUniform3fBase(const Context *context, 716 angle::EntryPoint entryPoint, 717 ShaderProgramID program, 718 UniformLocation location, 719 GLfloat v0, 720 GLfloat v1, 721 GLfloat v2) 722 { 723 GLfloat xyz[3] = {v0, v1, v2}; 724 return ValidateProgramUniform3fvBase(context, entryPoint, program, location, 1, xyz); 725 } 726 727 bool ValidateProgramUniform4fBase(const Context *context, 728 angle::EntryPoint entryPoint, 729 ShaderProgramID program, 730 UniformLocation location, 731 GLfloat v0, 732 GLfloat v1, 733 GLfloat v2, 734 GLfloat v3) 735 { 736 GLfloat xyzw[4] = {v0, v1, v2, v3}; 737 return ValidateProgramUniform4fvBase(context, entryPoint, program, location, 1, xyzw); 738 } 739 740 bool ValidateProgramUniform1ivBase(const Context *context, 741 angle::EntryPoint entryPoint, 742 ShaderProgramID program, 743 UniformLocation location, 744 GLsizei count, 745 const GLint *value) 746 { 747 const LinkedUniform *uniform = nullptr; 748 Program *programObject = GetValidProgram(context, entryPoint, program); 749 return ValidateUniformCommonBase(context, entryPoint, programObject, location, count, 750 &uniform) && 751 ValidateUniform1ivValue(context, entryPoint, uniform->type, count, value); 752 } 753 754 bool ValidateProgramUniform2ivBase(const Context *context, 755 angle::EntryPoint entryPoint, 756 ShaderProgramID program, 757 UniformLocation location, 758 GLsizei count, 759 const GLint *value) 760 { 761 return ValidateProgramUniformBase(context, entryPoint, GL_INT_VEC2, program, location, count); 762 } 763 764 bool ValidateProgramUniform3ivBase(const Context *context, 765 angle::EntryPoint entryPoint, 766 ShaderProgramID program, 767 UniformLocation location, 768 GLsizei count, 769 const GLint *value) 770 { 771 return ValidateProgramUniformBase(context, entryPoint, GL_INT_VEC3, program, location, count); 772 } 773 774 bool ValidateProgramUniform4ivBase(const Context *context, 775 angle::EntryPoint entryPoint, 776 ShaderProgramID program, 777 UniformLocation location, 778 GLsizei count, 779 const GLint *value) 780 { 781 return ValidateProgramUniformBase(context, entryPoint, GL_INT_VEC4, program, location, count); 782 } 783 784 bool ValidateProgramUniform1uivBase(const Context *context, 785 angle::EntryPoint entryPoint, 786 ShaderProgramID program, 787 UniformLocation location, 788 GLsizei count, 789 const GLuint *value) 790 { 791 return ValidateProgramUniformBase(context, entryPoint, GL_UNSIGNED_INT, program, location, 792 count); 793 } 794 795 bool ValidateProgramUniform2uivBase(const Context *context, 796 angle::EntryPoint entryPoint, 797 ShaderProgramID program, 798 UniformLocation location, 799 GLsizei count, 800 const GLuint *value) 801 { 802 return ValidateProgramUniformBase(context, entryPoint, GL_UNSIGNED_INT_VEC2, program, location, 803 count); 804 } 805 806 bool ValidateProgramUniform3uivBase(const Context *context, 807 angle::EntryPoint entryPoint, 808 ShaderProgramID program, 809 UniformLocation location, 810 GLsizei count, 811 const GLuint *value) 812 { 813 return ValidateProgramUniformBase(context, entryPoint, GL_UNSIGNED_INT_VEC3, program, location, 814 count); 815 } 816 817 bool ValidateProgramUniform4uivBase(const Context *context, 818 angle::EntryPoint entryPoint, 819 ShaderProgramID program, 820 UniformLocation location, 821 GLsizei count, 822 const GLuint *value) 823 { 824 return ValidateProgramUniformBase(context, entryPoint, GL_UNSIGNED_INT_VEC4, program, location, 825 count); 826 } 827 828 bool ValidateProgramUniform1fvBase(const Context *context, 829 angle::EntryPoint entryPoint, 830 ShaderProgramID program, 831 UniformLocation location, 832 GLsizei count, 833 const GLfloat *value) 834 { 835 return ValidateProgramUniformBase(context, entryPoint, GL_FLOAT, program, location, count); 836 } 837 838 bool ValidateProgramUniform2fvBase(const Context *context, 839 angle::EntryPoint entryPoint, 840 ShaderProgramID program, 841 UniformLocation location, 842 GLsizei count, 843 const GLfloat *value) 844 { 845 return ValidateProgramUniformBase(context, entryPoint, GL_FLOAT_VEC2, program, location, count); 846 } 847 848 bool ValidateProgramUniform3fvBase(const Context *context, 849 angle::EntryPoint entryPoint, 850 ShaderProgramID program, 851 UniformLocation location, 852 GLsizei count, 853 const GLfloat *value) 854 { 855 return ValidateProgramUniformBase(context, entryPoint, GL_FLOAT_VEC3, program, location, count); 856 } 857 858 bool ValidateProgramUniform4fvBase(const Context *context, 859 angle::EntryPoint entryPoint, 860 ShaderProgramID program, 861 UniformLocation location, 862 GLsizei count, 863 const GLfloat *value) 864 { 865 return ValidateProgramUniformBase(context, entryPoint, GL_FLOAT_VEC4, program, location, count); 866 } 867 868 bool ValidateProgramUniformMatrix2fvBase(const Context *context, 869 angle::EntryPoint entryPoint, 870 ShaderProgramID program, 871 UniformLocation location, 872 GLsizei count, 873 GLboolean transpose, 874 const GLfloat *value) 875 { 876 return ValidateProgramUniformMatrixBase(context, entryPoint, GL_FLOAT_MAT2, program, location, 877 count, transpose); 878 } 879 880 bool ValidateProgramUniformMatrix3fvBase(const Context *context, 881 angle::EntryPoint entryPoint, 882 ShaderProgramID program, 883 UniformLocation location, 884 GLsizei count, 885 GLboolean transpose, 886 const GLfloat *value) 887 { 888 return ValidateProgramUniformMatrixBase(context, entryPoint, GL_FLOAT_MAT3, program, location, 889 count, transpose); 890 } 891 892 bool ValidateProgramUniformMatrix4fvBase(const Context *context, 893 angle::EntryPoint entryPoint, 894 ShaderProgramID program, 895 UniformLocation location, 896 GLsizei count, 897 GLboolean transpose, 898 const GLfloat *value) 899 { 900 return ValidateProgramUniformMatrixBase(context, entryPoint, GL_FLOAT_MAT4, program, location, 901 count, transpose); 902 } 903 904 bool ValidateProgramUniformMatrix2x3fvBase(const Context *context, 905 angle::EntryPoint entryPoint, 906 ShaderProgramID program, 907 UniformLocation location, 908 GLsizei count, 909 GLboolean transpose, 910 const GLfloat *value) 911 { 912 return ValidateProgramUniformMatrixBase(context, entryPoint, GL_FLOAT_MAT2x3, program, location, 913 count, transpose); 914 } 915 916 bool ValidateProgramUniformMatrix3x2fvBase(const Context *context, 917 angle::EntryPoint entryPoint, 918 ShaderProgramID program, 919 UniformLocation location, 920 GLsizei count, 921 GLboolean transpose, 922 const GLfloat *value) 923 { 924 return ValidateProgramUniformMatrixBase(context, entryPoint, GL_FLOAT_MAT3x2, program, location, 925 count, transpose); 926 } 927 928 bool ValidateProgramUniformMatrix2x4fvBase(const Context *context, 929 angle::EntryPoint entryPoint, 930 ShaderProgramID program, 931 UniformLocation location, 932 GLsizei count, 933 GLboolean transpose, 934 const GLfloat *value) 935 { 936 return ValidateProgramUniformMatrixBase(context, entryPoint, GL_FLOAT_MAT2x4, program, location, 937 count, transpose); 938 } 939 940 bool ValidateProgramUniformMatrix4x2fvBase(const Context *context, 941 angle::EntryPoint entryPoint, 942 ShaderProgramID program, 943 UniformLocation location, 944 GLsizei count, 945 GLboolean transpose, 946 const GLfloat *value) 947 { 948 return ValidateProgramUniformMatrixBase(context, entryPoint, GL_FLOAT_MAT4x2, program, location, 949 count, transpose); 950 } 951 952 bool ValidateProgramUniformMatrix3x4fvBase(const Context *context, 953 angle::EntryPoint entryPoint, 954 ShaderProgramID program, 955 UniformLocation location, 956 GLsizei count, 957 GLboolean transpose, 958 const GLfloat *value) 959 { 960 return ValidateProgramUniformMatrixBase(context, entryPoint, GL_FLOAT_MAT3x4, program, location, 961 count, transpose); 962 } 963 964 bool ValidateProgramUniformMatrix4x3fvBase(const Context *context, 965 angle::EntryPoint entryPoint, 966 ShaderProgramID program, 967 UniformLocation location, 968 GLsizei count, 969 GLboolean transpose, 970 const GLfloat *value) 971 { 972 return ValidateProgramUniformMatrixBase(context, entryPoint, GL_FLOAT_MAT4x3, program, location, 973 count, transpose); 974 } 975 976 bool ValidateGetTexLevelParameterfv(const Context *context, 977 angle::EntryPoint entryPoint, 978 TextureTarget target, 979 GLint level, 980 GLenum pname, 981 const GLfloat *params) 982 { 983 if (context->getClientVersion() < ES_3_1) 984 { 985 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); 986 return false; 987 } 988 989 return ValidateGetTexLevelParameterBase(context, entryPoint, target, level, pname, nullptr); 990 } 991 992 bool ValidateGetTexLevelParameterfvRobustANGLE(const Context *context, 993 angle::EntryPoint entryPoint, 994 TextureTarget target, 995 GLint level, 996 GLenum pname, 997 GLsizei bufSize, 998 const GLsizei *length, 999 const GLfloat *params) 1000 { 1001 UNIMPLEMENTED(); 1002 return false; 1003 } 1004 1005 bool ValidateGetTexLevelParameteriv(const Context *context, 1006 angle::EntryPoint entryPoint, 1007 TextureTarget target, 1008 GLint level, 1009 GLenum pname, 1010 const GLint *params) 1011 { 1012 if (context->getClientVersion() < ES_3_1) 1013 { 1014 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); 1015 return false; 1016 } 1017 1018 return ValidateGetTexLevelParameterBase(context, entryPoint, target, level, pname, nullptr); 1019 } 1020 1021 bool ValidateGetTexLevelParameterivRobustANGLE(const Context *context, 1022 angle::EntryPoint entryPoint, 1023 TextureTarget target, 1024 GLint level, 1025 GLenum pname, 1026 GLsizei bufSize, 1027 const GLsizei *length, 1028 const GLint *params) 1029 { 1030 UNIMPLEMENTED(); 1031 return false; 1032 } 1033 1034 bool ValidateTexStorage2DMultisample(const Context *context, 1035 angle::EntryPoint entryPoint, 1036 TextureType target, 1037 GLsizei samples, 1038 GLenum internalFormat, 1039 GLsizei width, 1040 GLsizei height, 1041 GLboolean fixedSampleLocations) 1042 { 1043 if (context->getClientVersion() < ES_3_1) 1044 { 1045 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); 1046 return false; 1047 } 1048 1049 return ValidateTexStorage2DMultisampleBase(context, entryPoint, target, samples, internalFormat, 1050 width, height); 1051 } 1052 1053 bool ValidateTexStorageMem2DMultisampleEXT(const Context *context, 1054 angle::EntryPoint entryPoint, 1055 TextureType target, 1056 GLsizei samples, 1057 GLenum internalFormat, 1058 GLsizei width, 1059 GLsizei height, 1060 GLboolean fixedSampleLocations, 1061 MemoryObjectID memory, 1062 GLuint64 offset) 1063 { 1064 if (!context->getExtensions().memoryObjectEXT) 1065 { 1066 context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); 1067 return false; 1068 } 1069 1070 UNIMPLEMENTED(); 1071 return false; 1072 } 1073 1074 bool ValidateGetMultisamplefv(const Context *context, 1075 angle::EntryPoint entryPoint, 1076 GLenum pname, 1077 GLuint index, 1078 const GLfloat *val) 1079 { 1080 if (context->getClientVersion() < ES_3_1) 1081 { 1082 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); 1083 return false; 1084 } 1085 1086 return ValidateGetMultisamplefvBase(context, entryPoint, pname, index, val); 1087 } 1088 1089 bool ValidateGetMultisamplefvRobustANGLE(const Context *context, 1090 angle::EntryPoint entryPoint, 1091 GLenum pname, 1092 GLuint index, 1093 GLsizei bufSize, 1094 const GLsizei *length, 1095 const GLfloat *val) 1096 { 1097 UNIMPLEMENTED(); 1098 return false; 1099 } 1100 1101 bool ValidateFramebufferParameteri(const Context *context, 1102 angle::EntryPoint entryPoint, 1103 GLenum target, 1104 GLenum pname, 1105 GLint param) 1106 { 1107 if (context->getClientVersion() < ES_3_1) 1108 { 1109 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); 1110 return false; 1111 } 1112 1113 return ValidateFramebufferParameteriBase(context, entryPoint, target, pname, param); 1114 } 1115 1116 bool ValidateGetFramebufferParameteriv(const Context *context, 1117 angle::EntryPoint entryPoint, 1118 GLenum target, 1119 GLenum pname, 1120 const GLint *params) 1121 { 1122 if (context->getClientVersion() < ES_3_1) 1123 { 1124 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); 1125 return false; 1126 } 1127 1128 return ValidateGetFramebufferParameterivBase(context, entryPoint, target, pname, params); 1129 } 1130 1131 bool ValidateGetFramebufferParameterivRobustANGLE(const Context *context, 1132 angle::EntryPoint entryPoint, 1133 GLenum target, 1134 GLenum pname, 1135 GLsizei bufSize, 1136 const GLsizei *length, 1137 const GLint *params) 1138 { 1139 UNIMPLEMENTED(); 1140 return false; 1141 } 1142 1143 bool ValidateGetProgramResourceIndex(const Context *context, 1144 angle::EntryPoint entryPoint, 1145 ShaderProgramID program, 1146 GLenum programInterface, 1147 const GLchar *name) 1148 { 1149 if (context->getClientVersion() < ES_3_1) 1150 { 1151 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); 1152 return false; 1153 } 1154 1155 Program *programObject = GetValidProgram(context, entryPoint, program); 1156 if (programObject == nullptr) 1157 { 1158 return false; 1159 } 1160 1161 if (!ValidateNamedProgramInterface(programInterface)) 1162 { 1163 context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidProgramInterface); 1164 return false; 1165 } 1166 1167 return true; 1168 } 1169 1170 bool ValidateBindVertexBuffer(const Context *context, 1171 angle::EntryPoint entryPoint, 1172 GLuint bindingIndex, 1173 BufferID buffer, 1174 GLintptr offset, 1175 GLsizei stride) 1176 { 1177 if (context->getClientVersion() < ES_3_1) 1178 { 1179 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); 1180 return false; 1181 } 1182 1183 if (!context->isBufferGenerated(buffer)) 1184 { 1185 context->validationError(entryPoint, GL_INVALID_OPERATION, kObjectNotGenerated); 1186 return false; 1187 } 1188 1189 const Caps &caps = context->getCaps(); 1190 if (bindingIndex >= static_cast<GLuint>(caps.maxVertexAttribBindings)) 1191 { 1192 context->validationError(entryPoint, GL_INVALID_VALUE, kExceedsMaxVertexAttribBindings); 1193 return false; 1194 } 1195 1196 if (offset < 0) 1197 { 1198 context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeOffset); 1199 return false; 1200 } 1201 1202 if (stride < 0 || stride > caps.maxVertexAttribStride) 1203 { 1204 context->validationError(entryPoint, GL_INVALID_VALUE, kExceedsMaxVertexAttribStride); 1205 return false; 1206 } 1207 1208 // [OpenGL ES 3.1] Section 10.3.1 page 244: 1209 // An INVALID_OPERATION error is generated if the default vertex array object is bound. 1210 if (context->getState().getVertexArrayId().value == 0) 1211 { 1212 context->validationError(entryPoint, GL_INVALID_OPERATION, kDefaultVertexArray); 1213 return false; 1214 } 1215 1216 return true; 1217 } 1218 1219 bool ValidateVertexBindingDivisor(const Context *context, 1220 angle::EntryPoint entryPoint, 1221 GLuint bindingIndex, 1222 GLuint divisor) 1223 { 1224 if (context->getClientVersion() < ES_3_1) 1225 { 1226 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); 1227 return false; 1228 } 1229 1230 const Caps &caps = context->getCaps(); 1231 if (bindingIndex >= static_cast<GLuint>(caps.maxVertexAttribBindings)) 1232 { 1233 context->validationError(entryPoint, GL_INVALID_VALUE, kExceedsMaxVertexAttribBindings); 1234 return false; 1235 } 1236 1237 // [OpenGL ES 3.1] Section 10.3.1 page 243: 1238 // An INVALID_OPERATION error is generated if the default vertex array object is bound. 1239 if (context->getState().getVertexArrayId().value == 0) 1240 { 1241 context->validationError(entryPoint, GL_INVALID_OPERATION, kDefaultVertexArray); 1242 return false; 1243 } 1244 1245 return true; 1246 } 1247 1248 bool ValidateVertexAttribFormat(const Context *context, 1249 angle::EntryPoint entryPoint, 1250 GLuint attribindex, 1251 GLint size, 1252 VertexAttribType type, 1253 GLboolean normalized, 1254 GLuint relativeoffset) 1255 { 1256 if (!ValidateVertexAttribFormatCommon(context, entryPoint, relativeoffset)) 1257 { 1258 return false; 1259 } 1260 1261 return ValidateFloatVertexFormat(context, entryPoint, attribindex, size, type); 1262 } 1263 1264 bool ValidateVertexAttribIFormat(const Context *context, 1265 angle::EntryPoint entryPoint, 1266 GLuint attribindex, 1267 GLint size, 1268 VertexAttribType type, 1269 GLuint relativeoffset) 1270 { 1271 if (!ValidateVertexAttribFormatCommon(context, entryPoint, relativeoffset)) 1272 { 1273 return false; 1274 } 1275 1276 return ValidateIntegerVertexFormat(context, entryPoint, attribindex, size, type); 1277 } 1278 1279 bool ValidateVertexAttribBinding(const Context *context, 1280 angle::EntryPoint entryPoint, 1281 GLuint attribIndex, 1282 GLuint bindingIndex) 1283 { 1284 if (context->getClientVersion() < ES_3_1) 1285 { 1286 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); 1287 return false; 1288 } 1289 1290 // [OpenGL ES 3.1] Section 10.3.1 page 243: 1291 // An INVALID_OPERATION error is generated if the default vertex array object is bound. 1292 if (context->getState().getVertexArrayId().value == 0) 1293 { 1294 context->validationError(entryPoint, GL_INVALID_OPERATION, kDefaultVertexArray); 1295 return false; 1296 } 1297 1298 const Caps &caps = context->getCaps(); 1299 if (attribIndex >= static_cast<GLuint>(caps.maxVertexAttributes)) 1300 { 1301 context->validationError(entryPoint, GL_INVALID_VALUE, kIndexExceedsMaxVertexAttribute); 1302 return false; 1303 } 1304 1305 if (bindingIndex >= static_cast<GLuint>(caps.maxVertexAttribBindings)) 1306 { 1307 context->validationError(entryPoint, GL_INVALID_VALUE, kExceedsMaxVertexAttribBindings); 1308 return false; 1309 } 1310 1311 return true; 1312 } 1313 1314 bool ValidateGetProgramResourceName(const Context *context, 1315 angle::EntryPoint entryPoint, 1316 ShaderProgramID program, 1317 GLenum programInterface, 1318 GLuint index, 1319 GLsizei bufSize, 1320 const GLsizei *length, 1321 const GLchar *name) 1322 { 1323 if (context->getClientVersion() < ES_3_1) 1324 { 1325 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); 1326 return false; 1327 } 1328 1329 Program *programObject = GetValidProgram(context, entryPoint, program); 1330 if (programObject == nullptr) 1331 { 1332 return false; 1333 } 1334 1335 if (!ValidateNamedProgramInterface(programInterface)) 1336 { 1337 context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidProgramInterface); 1338 return false; 1339 } 1340 1341 if (!ValidateProgramResourceIndex(programObject, programInterface, index)) 1342 { 1343 context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidProgramResourceIndex); 1344 return false; 1345 } 1346 1347 if (bufSize < 0) 1348 { 1349 context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeBufferSize); 1350 return false; 1351 } 1352 1353 return true; 1354 } 1355 1356 bool ValidateDispatchCompute(const Context *context, 1357 angle::EntryPoint entryPoint, 1358 GLuint numGroupsX, 1359 GLuint numGroupsY, 1360 GLuint numGroupsZ) 1361 { 1362 if (context->getClientVersion() < ES_3_1) 1363 { 1364 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); 1365 return false; 1366 } 1367 1368 const State &state = context->getState(); 1369 const ProgramExecutable *executable = state.getProgramExecutable(); 1370 1371 if (executable == nullptr || !executable->hasLinkedShaderStage(ShaderType::Compute)) 1372 { 1373 context->validationError(entryPoint, GL_INVALID_OPERATION, 1374 kNoActiveProgramWithComputeShader); 1375 return false; 1376 } 1377 1378 const Caps &caps = context->getCaps(); 1379 if (numGroupsX > static_cast<GLuint>(caps.maxComputeWorkGroupCount[0])) 1380 { 1381 context->validationError(entryPoint, GL_INVALID_VALUE, kExceedsComputeWorkGroupCountX); 1382 return false; 1383 } 1384 if (numGroupsY > static_cast<GLuint>(caps.maxComputeWorkGroupCount[1])) 1385 { 1386 context->validationError(entryPoint, GL_INVALID_VALUE, kExceedsComputeWorkGroupCountY); 1387 return false; 1388 } 1389 if (numGroupsZ > static_cast<GLuint>(caps.maxComputeWorkGroupCount[2])) 1390 { 1391 context->validationError(entryPoint, GL_INVALID_VALUE, kExceedsComputeWorkGroupCountZ); 1392 return false; 1393 } 1394 1395 return true; 1396 } 1397 1398 bool ValidateDispatchComputeIndirect(const Context *context, 1399 angle::EntryPoint entryPoint, 1400 GLintptr indirect) 1401 { 1402 if (context->getClientVersion() < ES_3_1) 1403 { 1404 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); 1405 return false; 1406 } 1407 1408 const State &state = context->getState(); 1409 const ProgramExecutable *executable = state.getProgramExecutable(); 1410 1411 if (executable == nullptr || !executable->hasLinkedShaderStage(ShaderType::Compute)) 1412 { 1413 context->validationError(entryPoint, GL_INVALID_OPERATION, 1414 kNoActiveProgramWithComputeShader); 1415 return false; 1416 } 1417 1418 if (indirect < 0) 1419 { 1420 context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeOffset); 1421 return false; 1422 } 1423 1424 if ((indirect & (sizeof(GLuint) - 1)) != 0) 1425 { 1426 context->validationError(entryPoint, GL_INVALID_VALUE, kOffsetMustBeMultipleOfUint); 1427 return false; 1428 } 1429 1430 Buffer *dispatchIndirectBuffer = state.getTargetBuffer(BufferBinding::DispatchIndirect); 1431 if (!dispatchIndirectBuffer) 1432 { 1433 context->validationError(entryPoint, GL_INVALID_OPERATION, kDispatchIndirectBufferNotBound); 1434 return false; 1435 } 1436 1437 CheckedNumeric<GLuint64> checkedOffset(static_cast<GLuint64>(indirect)); 1438 auto checkedSum = checkedOffset + static_cast<GLuint64>(3 * sizeof(GLuint)); 1439 if (!checkedSum.IsValid() || 1440 checkedSum.ValueOrDie() > static_cast<GLuint64>(dispatchIndirectBuffer->getSize())) 1441 { 1442 context->validationError(entryPoint, GL_INVALID_OPERATION, kInsufficientBufferSize); 1443 return false; 1444 } 1445 1446 return true; 1447 } 1448 1449 bool ValidateBindImageTexture(const Context *context, 1450 angle::EntryPoint entryPoint, 1451 GLuint unit, 1452 TextureID texture, 1453 GLint level, 1454 GLboolean layered, 1455 GLint layer, 1456 GLenum access, 1457 GLenum format) 1458 { 1459 if (context->getClientVersion() < ES_3_1) 1460 { 1461 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); 1462 return false; 1463 } 1464 1465 GLuint maxImageUnits = static_cast<GLuint>(context->getCaps().maxImageUnits); 1466 if (unit >= maxImageUnits) 1467 { 1468 context->validationError(entryPoint, GL_INVALID_VALUE, kExceedsMaxImageUnits); 1469 return false; 1470 } 1471 1472 if (level < 0) 1473 { 1474 context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeLevel); 1475 return false; 1476 } 1477 1478 if (layer < 0) 1479 { 1480 context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeLayer); 1481 return false; 1482 } 1483 1484 if (access != GL_READ_ONLY && access != GL_WRITE_ONLY && access != GL_READ_WRITE) 1485 { 1486 context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidImageAccess); 1487 return false; 1488 } 1489 1490 switch (format) 1491 { 1492 case GL_RGBA32F: 1493 case GL_RGBA16F: 1494 case GL_R32F: 1495 case GL_RGBA32UI: 1496 case GL_RGBA16UI: 1497 case GL_RGBA8UI: 1498 case GL_R32UI: 1499 case GL_RGBA32I: 1500 case GL_RGBA16I: 1501 case GL_RGBA8I: 1502 case GL_R32I: 1503 case GL_RGBA8: 1504 case GL_RGBA8_SNORM: 1505 break; 1506 default: 1507 context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidImageFormat); 1508 return false; 1509 } 1510 1511 if (texture.value != 0) 1512 { 1513 Texture *tex = context->getTexture(texture); 1514 1515 if (tex == nullptr) 1516 { 1517 context->validationError(entryPoint, GL_INVALID_VALUE, kMissingTextureName); 1518 return false; 1519 } 1520 1521 if (!tex->getImmutableFormat() && tex->getType() != gl::TextureType::Buffer) 1522 { 1523 context->validationError(entryPoint, GL_INVALID_OPERATION, 1524 kTextureIsNeitherImmutableNorTextureBuffer); 1525 return false; 1526 } 1527 } 1528 1529 return true; 1530 } 1531 1532 bool ValidateGetProgramResourceLocation(const Context *context, 1533 angle::EntryPoint entryPoint, 1534 ShaderProgramID program, 1535 GLenum programInterface, 1536 const GLchar *name) 1537 { 1538 if (context->getClientVersion() < ES_3_1) 1539 { 1540 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); 1541 return false; 1542 } 1543 1544 Program *programObject = GetValidProgram(context, entryPoint, program); 1545 if (programObject == nullptr) 1546 { 1547 return false; 1548 } 1549 1550 if (!programObject->isLinked()) 1551 { 1552 context->validationError(entryPoint, GL_INVALID_OPERATION, kProgramNotLinked); 1553 return false; 1554 } 1555 1556 if (!ValidateLocationProgramInterface(programInterface)) 1557 { 1558 context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidProgramInterface); 1559 return false; 1560 } 1561 return true; 1562 } 1563 1564 bool ValidateGetProgramResourceiv(const Context *context, 1565 angle::EntryPoint entryPoint, 1566 ShaderProgramID program, 1567 GLenum programInterface, 1568 GLuint index, 1569 GLsizei propCount, 1570 const GLenum *props, 1571 GLsizei bufSize, 1572 const GLsizei *length, 1573 const GLint *params) 1574 { 1575 if (context->getClientVersion() < ES_3_1) 1576 { 1577 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); 1578 return false; 1579 } 1580 1581 Program *programObject = GetValidProgram(context, entryPoint, program); 1582 if (programObject == nullptr) 1583 { 1584 return false; 1585 } 1586 if (!ValidateProgramInterface(programInterface)) 1587 { 1588 context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidProgramInterface); 1589 return false; 1590 } 1591 if (propCount <= 0) 1592 { 1593 context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidPropCount); 1594 return false; 1595 } 1596 if (bufSize < 0) 1597 { 1598 context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeBufSize); 1599 return false; 1600 } 1601 if (!ValidateProgramResourceIndex(programObject, programInterface, index)) 1602 { 1603 context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidProgramResourceIndex); 1604 return false; 1605 } 1606 for (GLsizei i = 0; i < propCount; i++) 1607 { 1608 if (!ValidateProgramResourceProperty(context, entryPoint, props[i])) 1609 { 1610 context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidProgramResourceProperty); 1611 return false; 1612 } 1613 if (!ValidateProgramResourcePropertyByInterface(props[i], programInterface)) 1614 { 1615 context->validationError(entryPoint, GL_INVALID_OPERATION, 1616 kInvalidPropertyForProgramInterface); 1617 return false; 1618 } 1619 } 1620 return true; 1621 } 1622 1623 bool ValidateGetProgramInterfaceiv(const Context *context, 1624 angle::EntryPoint entryPoint, 1625 ShaderProgramID program, 1626 GLenum programInterface, 1627 GLenum pname, 1628 const GLint *params) 1629 { 1630 if (context->getClientVersion() < ES_3_1) 1631 { 1632 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); 1633 return false; 1634 } 1635 1636 Program *programObject = GetValidProgram(context, entryPoint, program); 1637 if (programObject == nullptr) 1638 { 1639 return false; 1640 } 1641 1642 if (!ValidateProgramInterface(programInterface)) 1643 { 1644 context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidProgramInterface); 1645 return false; 1646 } 1647 1648 switch (pname) 1649 { 1650 case GL_ACTIVE_RESOURCES: 1651 case GL_MAX_NAME_LENGTH: 1652 case GL_MAX_NUM_ACTIVE_VARIABLES: 1653 break; 1654 1655 default: 1656 context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPname); 1657 return false; 1658 } 1659 1660 if (pname == GL_MAX_NAME_LENGTH && programInterface == GL_ATOMIC_COUNTER_BUFFER) 1661 { 1662 context->validationError(entryPoint, GL_INVALID_OPERATION, kAtomicCounterResourceName); 1663 return false; 1664 } 1665 1666 if (pname == GL_MAX_NUM_ACTIVE_VARIABLES) 1667 { 1668 switch (programInterface) 1669 { 1670 case GL_ATOMIC_COUNTER_BUFFER: 1671 case GL_SHADER_STORAGE_BLOCK: 1672 case GL_UNIFORM_BLOCK: 1673 break; 1674 1675 default: 1676 context->validationError(entryPoint, GL_INVALID_OPERATION, 1677 kMaxActiveVariablesInterface); 1678 return false; 1679 } 1680 } 1681 1682 return true; 1683 } 1684 1685 bool ValidateGetProgramInterfaceivRobustANGLE(const Context *context, 1686 angle::EntryPoint entryPoint, 1687 ShaderProgramID program, 1688 GLenum programInterface, 1689 GLenum pname, 1690 GLsizei bufSize, 1691 const GLsizei *length, 1692 const GLint *params) 1693 { 1694 UNIMPLEMENTED(); 1695 return false; 1696 } 1697 1698 bool ValidateGenProgramPipelinesBase(const Context *context, 1699 angle::EntryPoint entryPoint, 1700 GLsizei n, 1701 const ProgramPipelineID *pipelines) 1702 { 1703 return ValidateGenOrDelete(context, entryPoint, n); 1704 } 1705 1706 bool ValidateDeleteProgramPipelinesBase(const Context *context, 1707 angle::EntryPoint entryPoint, 1708 GLsizei n, 1709 const ProgramPipelineID *pipelines) 1710 { 1711 return ValidateGenOrDelete(context, entryPoint, n); 1712 } 1713 1714 bool ValidateBindProgramPipelineBase(const Context *context, 1715 angle::EntryPoint entryPoint, 1716 ProgramPipelineID pipeline) 1717 { 1718 if (!context->isProgramPipelineGenerated({pipeline})) 1719 { 1720 context->validationError(entryPoint, GL_INVALID_OPERATION, kObjectNotGenerated); 1721 return false; 1722 } 1723 1724 return true; 1725 } 1726 1727 bool ValidateIsProgramPipelineBase(const Context *context, 1728 angle::EntryPoint entryPoint, 1729 ProgramPipelineID pipeline) 1730 { 1731 return true; 1732 } 1733 1734 bool ValidateUseProgramStagesBase(const Context *context, 1735 angle::EntryPoint entryPoint, 1736 ProgramPipelineID pipeline, 1737 GLbitfield stages, 1738 ShaderProgramID programId) 1739 { 1740 // GL_INVALID_VALUE is generated if shaders contains set bits that are not recognized, and is 1741 // not the reserved value GL_ALL_SHADER_BITS. 1742 GLbitfield knownShaderBits = 1743 GL_VERTEX_SHADER_BIT | GL_FRAGMENT_SHADER_BIT | GL_COMPUTE_SHADER_BIT; 1744 1745 if (context->getClientVersion() >= ES_3_2 || context->getExtensions().geometryShaderAny()) 1746 { 1747 knownShaderBits |= GL_GEOMETRY_SHADER_BIT; 1748 } 1749 1750 if (context->getClientVersion() >= ES_3_2 || context->getExtensions().tessellationShaderEXT) 1751 { 1752 knownShaderBits |= GL_TESS_CONTROL_SHADER_BIT; 1753 knownShaderBits |= GL_TESS_EVALUATION_SHADER_BIT; 1754 } 1755 1756 if ((stages & ~knownShaderBits) && (stages != GL_ALL_SHADER_BITS)) 1757 { 1758 context->validationError(entryPoint, GL_INVALID_VALUE, kUnrecognizedShaderStageBit); 1759 return false; 1760 } 1761 1762 // GL_INVALID_OPERATION is generated if pipeline is not a name previously returned from a call 1763 // to glGenProgramPipelines or if such a name has been deleted by a call to 1764 // glDeleteProgramPipelines. 1765 if (!context->isProgramPipelineGenerated({pipeline})) 1766 { 1767 context->validationError(entryPoint, GL_INVALID_OPERATION, kObjectNotGenerated); 1768 return false; 1769 } 1770 1771 // If program is zero, or refers to a program object with no valid shader executable for a given 1772 // stage, it is as if the pipeline object has no programmable stage configured for the indicated 1773 // shader stages. 1774 if (programId.value == 0) 1775 { 1776 return true; 1777 } 1778 1779 Program *program = context->getProgramNoResolveLink(programId); 1780 if (!program) 1781 { 1782 context->validationError(entryPoint, GL_INVALID_VALUE, kProgramDoesNotExist); 1783 return false; 1784 } 1785 1786 // GL_INVALID_OPERATION is generated if program refers to a program object that was not linked 1787 // with its GL_PROGRAM_SEPARABLE status set. 1788 // resolveLink() may not have been called if glCreateShaderProgramv() was not used and 1789 // glDetachShader() was not called. 1790 program->resolveLink(context); 1791 if (!program->isSeparable()) 1792 { 1793 context->validationError(entryPoint, GL_INVALID_OPERATION, kProgramNotSeparable); 1794 return false; 1795 } 1796 1797 // GL_INVALID_OPERATION is generated if program refers to a program object that has not been 1798 // successfully linked. 1799 if (!program->isLinked()) 1800 { 1801 context->validationError(entryPoint, GL_INVALID_OPERATION, kProgramNotLinked); 1802 return false; 1803 } 1804 1805 return true; 1806 } 1807 1808 bool ValidateActiveShaderProgramBase(const Context *context, 1809 angle::EntryPoint entryPoint, 1810 ProgramPipelineID pipeline, 1811 ShaderProgramID programId) 1812 { 1813 // An INVALID_OPERATION error is generated if pipeline is not a name returned from a previous 1814 // call to GenProgramPipelines or if such a name has since been deleted by 1815 // DeleteProgramPipelines. 1816 if (!context->isProgramPipelineGenerated({pipeline})) 1817 { 1818 context->validationError(entryPoint, GL_INVALID_OPERATION, kObjectNotGenerated); 1819 return false; 1820 } 1821 1822 // An INVALID_VALUE error is generated if program is not zero and is not the name of either a 1823 // program or shader object. 1824 if ((programId.value != 0) && !context->isProgram(programId) && !context->isShader(programId)) 1825 { 1826 context->validationError(entryPoint, GL_INVALID_VALUE, kProgramDoesNotExist); 1827 return false; 1828 } 1829 1830 // An INVALID_OPERATION error is generated if program is the name of a shader object. 1831 if (context->isShader(programId)) 1832 { 1833 context->validationError(entryPoint, GL_INVALID_OPERATION, kExpectedProgramName); 1834 return false; 1835 } 1836 1837 // An INVALID_OPERATION error is generated if program is not zero and has not been linked, or 1838 // was last linked unsuccessfully. The active program is not modified. 1839 Program *program = context->getProgramNoResolveLink(programId); 1840 if ((programId.value != 0) && !program->isLinked()) 1841 { 1842 context->validationError(entryPoint, GL_INVALID_OPERATION, kProgramNotLinked); 1843 return false; 1844 } 1845 1846 return true; 1847 } 1848 1849 bool ValidateCreateShaderProgramvBase(const Context *context, 1850 angle::EntryPoint entryPoint, 1851 ShaderType type, 1852 GLsizei count, 1853 const GLchar *const *strings) 1854 { 1855 switch (type) 1856 { 1857 case ShaderType::InvalidEnum: 1858 context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidShaderType); 1859 return false; 1860 case ShaderType::Vertex: 1861 case ShaderType::Fragment: 1862 case ShaderType::Compute: 1863 break; 1864 case ShaderType::Geometry: 1865 if (!context->getExtensions().geometryShaderAny() && 1866 context->getClientVersion() < ES_3_2) 1867 { 1868 context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidShaderType); 1869 return false; 1870 } 1871 break; 1872 case ShaderType::TessControl: 1873 case ShaderType::TessEvaluation: 1874 if (!context->getExtensions().tessellationShaderEXT && 1875 context->getClientVersion() < ES_3_2) 1876 { 1877 context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidShaderType); 1878 return false; 1879 } 1880 break; 1881 default: 1882 UNREACHABLE(); 1883 } 1884 1885 // GL_INVALID_VALUE is generated if count is negative. 1886 if (count < 0) 1887 { 1888 context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeCount); 1889 return false; 1890 } 1891 1892 return true; 1893 } 1894 1895 bool ValidateCreateShaderProgramvBase(const Context *context, 1896 angle::EntryPoint entryPoint, 1897 ShaderType type, 1898 GLsizei count, 1899 const GLchar **strings) 1900 { 1901 const GLchar *const *tmpStrings = strings; 1902 return ValidateCreateShaderProgramvBase(context, entryPoint, type, count, tmpStrings); 1903 } 1904 1905 bool ValidateGetProgramPipelineivBase(const Context *context, 1906 angle::EntryPoint entryPoint, 1907 ProgramPipelineID pipeline, 1908 GLenum pname, 1909 const GLint *params) 1910 { 1911 // An INVALID_OPERATION error is generated if pipeline is not a name returned from a previous 1912 // call to GenProgramPipelines or if such a name has since been deleted by 1913 // DeleteProgramPipelines. 1914 if ((pipeline.value == 0) || (!context->isProgramPipelineGenerated(pipeline))) 1915 { 1916 context->validationError(entryPoint, GL_INVALID_OPERATION, kProgramPipelineDoesNotExist); 1917 return false; 1918 } 1919 1920 // An INVALID_ENUM error is generated if pname is not ACTIVE_PROGRAM, 1921 // INFO_LOG_LENGTH, VALIDATE_STATUS, or one of the type arguments in 1922 // table 7.1. 1923 switch (pname) 1924 { 1925 case GL_ACTIVE_PROGRAM: 1926 case GL_INFO_LOG_LENGTH: 1927 case GL_VALIDATE_STATUS: 1928 case GL_VERTEX_SHADER: 1929 case GL_FRAGMENT_SHADER: 1930 case GL_COMPUTE_SHADER: 1931 break; 1932 case GL_GEOMETRY_SHADER: 1933 return context->getExtensions().geometryShaderAny() || 1934 context->getClientVersion() >= ES_3_2; 1935 case GL_TESS_CONTROL_SHADER: 1936 case GL_TESS_EVALUATION_SHADER: 1937 return context->getExtensions().tessellationShaderEXT || 1938 context->getClientVersion() >= ES_3_2; 1939 1940 default: 1941 context->validationError(entryPoint, GL_INVALID_ENUM, kInvalidPname); 1942 return false; 1943 } 1944 1945 return true; 1946 } 1947 1948 bool ValidateValidateProgramPipelineBase(const Context *context, 1949 angle::EntryPoint entryPoint, 1950 ProgramPipelineID pipeline) 1951 { 1952 if (pipeline.value == 0) 1953 { 1954 return false; 1955 } 1956 1957 if (!context->isProgramPipelineGenerated(pipeline)) 1958 { 1959 context->validationError(entryPoint, GL_INVALID_OPERATION, kProgramPipelineDoesNotExist); 1960 return false; 1961 } 1962 1963 return true; 1964 } 1965 1966 bool ValidateGetProgramPipelineInfoLogBase(const Context *context, 1967 angle::EntryPoint entryPoint, 1968 ProgramPipelineID pipeline, 1969 GLsizei bufSize, 1970 const GLsizei *length, 1971 const GLchar *infoLog) 1972 { 1973 if (bufSize < 0) 1974 { 1975 context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeBufferSize); 1976 return false; 1977 } 1978 1979 if (!context->isProgramPipelineGenerated(pipeline)) 1980 { 1981 context->validationError(entryPoint, GL_INVALID_VALUE, kProgramPipelineDoesNotExist); 1982 return false; 1983 } 1984 1985 return true; 1986 } 1987 1988 bool ValidateActiveShaderProgram(const Context *context, 1989 angle::EntryPoint entryPoint, 1990 ProgramPipelineID pipelinePacked, 1991 ShaderProgramID programPacked) 1992 { 1993 if (context->getClientVersion() < ES_3_1) 1994 { 1995 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); 1996 return false; 1997 } 1998 1999 return ValidateActiveShaderProgramBase(context, entryPoint, pipelinePacked, programPacked); 2000 } 2001 2002 bool ValidateBindProgramPipeline(const Context *context, 2003 angle::EntryPoint entryPoint, 2004 ProgramPipelineID pipelinePacked) 2005 { 2006 if (context->getClientVersion() < ES_3_1) 2007 { 2008 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); 2009 return false; 2010 } 2011 2012 return ValidateBindProgramPipelineBase(context, entryPoint, pipelinePacked); 2013 } 2014 2015 bool ValidateCreateShaderProgramv(const Context *context, 2016 angle::EntryPoint entryPoint, 2017 ShaderType typePacked, 2018 GLsizei count, 2019 const GLchar *const *strings) 2020 { 2021 if (context->getClientVersion() < ES_3_1) 2022 { 2023 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); 2024 return false; 2025 } 2026 2027 return ValidateCreateShaderProgramvBase(context, entryPoint, typePacked, count, strings); 2028 } 2029 2030 bool ValidateDeleteProgramPipelines(const Context *context, 2031 angle::EntryPoint entryPoint, 2032 GLsizei n, 2033 const ProgramPipelineID *pipelinesPacked) 2034 { 2035 if (context->getClientVersion() < ES_3_1) 2036 { 2037 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); 2038 return false; 2039 } 2040 2041 return ValidateDeleteProgramPipelinesBase(context, entryPoint, n, pipelinesPacked); 2042 } 2043 2044 bool ValidateGenProgramPipelines(const Context *context, 2045 angle::EntryPoint entryPoint, 2046 GLsizei n, 2047 const ProgramPipelineID *pipelinesPacked) 2048 { 2049 if (context->getClientVersion() < ES_3_1) 2050 { 2051 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); 2052 return false; 2053 } 2054 2055 return ValidateGenProgramPipelinesBase(context, entryPoint, n, pipelinesPacked); 2056 } 2057 2058 bool ValidateGetProgramPipelineInfoLog(const Context *context, 2059 angle::EntryPoint entryPoint, 2060 ProgramPipelineID pipelinePacked, 2061 GLsizei bufSize, 2062 const GLsizei *length, 2063 const GLchar *infoLog) 2064 { 2065 if (context->getClientVersion() < ES_3_1) 2066 { 2067 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); 2068 return false; 2069 } 2070 2071 return ValidateGetProgramPipelineInfoLogBase(context, entryPoint, pipelinePacked, bufSize, 2072 length, infoLog); 2073 } 2074 2075 bool ValidateGetProgramPipelineiv(const Context *context, 2076 angle::EntryPoint entryPoint, 2077 ProgramPipelineID pipelinePacked, 2078 GLenum pname, 2079 const GLint *params) 2080 { 2081 if (context->getClientVersion() < ES_3_1) 2082 { 2083 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); 2084 return false; 2085 } 2086 2087 return ValidateGetProgramPipelineivBase(context, entryPoint, pipelinePacked, pname, params); 2088 } 2089 2090 bool ValidateIsProgramPipeline(const Context *context, 2091 angle::EntryPoint entryPoint, 2092 ProgramPipelineID pipelinePacked) 2093 { 2094 if (context->getClientVersion() < ES_3_1) 2095 { 2096 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); 2097 return false; 2098 } 2099 2100 return ValidateIsProgramPipelineBase(context, entryPoint, pipelinePacked); 2101 } 2102 2103 bool ValidateProgramUniform1f(const Context *context, 2104 angle::EntryPoint entryPoint, 2105 ShaderProgramID programPacked, 2106 UniformLocation locationPacked, 2107 GLfloat v0) 2108 { 2109 if (context->getClientVersion() < ES_3_1) 2110 { 2111 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); 2112 return false; 2113 } 2114 2115 return ValidateProgramUniform1fBase(context, entryPoint, programPacked, locationPacked, v0); 2116 } 2117 2118 bool ValidateProgramUniform1fv(const Context *context, 2119 angle::EntryPoint entryPoint, 2120 ShaderProgramID programPacked, 2121 UniformLocation locationPacked, 2122 GLsizei count, 2123 const GLfloat *value) 2124 { 2125 if (context->getClientVersion() < ES_3_1) 2126 { 2127 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); 2128 return false; 2129 } 2130 2131 return ValidateProgramUniform1fvBase(context, entryPoint, programPacked, locationPacked, count, 2132 value); 2133 } 2134 2135 bool ValidateProgramUniform1i(const Context *context, 2136 angle::EntryPoint entryPoint, 2137 ShaderProgramID programPacked, 2138 UniformLocation locationPacked, 2139 GLint v0) 2140 { 2141 if (context->getClientVersion() < ES_3_1) 2142 { 2143 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); 2144 return false; 2145 } 2146 2147 return ValidateProgramUniform1iBase(context, entryPoint, programPacked, locationPacked, v0); 2148 } 2149 2150 bool ValidateProgramUniform1iv(const Context *context, 2151 angle::EntryPoint entryPoint, 2152 ShaderProgramID programPacked, 2153 UniformLocation locationPacked, 2154 GLsizei count, 2155 const GLint *value) 2156 { 2157 if (context->getClientVersion() < ES_3_1) 2158 { 2159 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); 2160 return false; 2161 } 2162 2163 return ValidateProgramUniform1ivBase(context, entryPoint, programPacked, locationPacked, count, 2164 value); 2165 } 2166 2167 bool ValidateProgramUniform1ui(const Context *context, 2168 angle::EntryPoint entryPoint, 2169 ShaderProgramID programPacked, 2170 UniformLocation locationPacked, 2171 GLuint v0) 2172 { 2173 if (context->getClientVersion() < ES_3_1) 2174 { 2175 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); 2176 return false; 2177 } 2178 2179 return ValidateProgramUniform1uiBase(context, entryPoint, programPacked, locationPacked, v0); 2180 } 2181 2182 bool ValidateProgramUniform1uiv(const Context *context, 2183 angle::EntryPoint entryPoint, 2184 ShaderProgramID programPacked, 2185 UniformLocation locationPacked, 2186 GLsizei count, 2187 const GLuint *value) 2188 { 2189 if (context->getClientVersion() < ES_3_1) 2190 { 2191 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); 2192 return false; 2193 } 2194 2195 return ValidateProgramUniform1uivBase(context, entryPoint, programPacked, locationPacked, count, 2196 value); 2197 } 2198 2199 bool ValidateProgramUniform2f(const Context *context, 2200 angle::EntryPoint entryPoint, 2201 ShaderProgramID programPacked, 2202 UniformLocation locationPacked, 2203 GLfloat v0, 2204 GLfloat v1) 2205 { 2206 if (context->getClientVersion() < ES_3_1) 2207 { 2208 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); 2209 return false; 2210 } 2211 2212 return ValidateProgramUniform2fBase(context, entryPoint, programPacked, locationPacked, v0, v1); 2213 } 2214 2215 bool ValidateProgramUniform2fv(const Context *context, 2216 angle::EntryPoint entryPoint, 2217 ShaderProgramID programPacked, 2218 UniformLocation locationPacked, 2219 GLsizei count, 2220 const GLfloat *value) 2221 { 2222 if (context->getClientVersion() < ES_3_1) 2223 { 2224 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); 2225 return false; 2226 } 2227 2228 return ValidateProgramUniform2fvBase(context, entryPoint, programPacked, locationPacked, count, 2229 value); 2230 } 2231 2232 bool ValidateProgramUniform2i(const Context *context, 2233 angle::EntryPoint entryPoint, 2234 ShaderProgramID programPacked, 2235 UniformLocation locationPacked, 2236 GLint v0, 2237 GLint v1) 2238 { 2239 if (context->getClientVersion() < ES_3_1) 2240 { 2241 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); 2242 return false; 2243 } 2244 2245 return ValidateProgramUniform2iBase(context, entryPoint, programPacked, locationPacked, v0, v1); 2246 } 2247 2248 bool ValidateProgramUniform2iv(const Context *context, 2249 angle::EntryPoint entryPoint, 2250 ShaderProgramID programPacked, 2251 UniformLocation locationPacked, 2252 GLsizei count, 2253 const GLint *value) 2254 { 2255 if (context->getClientVersion() < ES_3_1) 2256 { 2257 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); 2258 return false; 2259 } 2260 2261 return ValidateProgramUniform2ivBase(context, entryPoint, programPacked, locationPacked, count, 2262 value); 2263 } 2264 2265 bool ValidateProgramUniform2ui(const Context *context, 2266 angle::EntryPoint entryPoint, 2267 ShaderProgramID programPacked, 2268 UniformLocation locationPacked, 2269 GLuint v0, 2270 GLuint v1) 2271 { 2272 if (context->getClientVersion() < ES_3_1) 2273 { 2274 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); 2275 return false; 2276 } 2277 2278 return ValidateProgramUniform2uiBase(context, entryPoint, programPacked, locationPacked, v0, 2279 v1); 2280 } 2281 2282 bool ValidateProgramUniform2uiv(const Context *context, 2283 angle::EntryPoint entryPoint, 2284 ShaderProgramID programPacked, 2285 UniformLocation locationPacked, 2286 GLsizei count, 2287 const GLuint *value) 2288 { 2289 if (context->getClientVersion() < ES_3_1) 2290 { 2291 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); 2292 return false; 2293 } 2294 2295 return ValidateProgramUniform2uivBase(context, entryPoint, programPacked, locationPacked, count, 2296 value); 2297 } 2298 2299 bool ValidateProgramUniform3f(const Context *context, 2300 angle::EntryPoint entryPoint, 2301 ShaderProgramID programPacked, 2302 UniformLocation locationPacked, 2303 GLfloat v0, 2304 GLfloat v1, 2305 GLfloat v2) 2306 { 2307 if (context->getClientVersion() < ES_3_1) 2308 { 2309 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); 2310 return false; 2311 } 2312 2313 return ValidateProgramUniform3fBase(context, entryPoint, programPacked, locationPacked, v0, v1, 2314 v2); 2315 } 2316 2317 bool ValidateProgramUniform3fv(const Context *context, 2318 angle::EntryPoint entryPoint, 2319 ShaderProgramID programPacked, 2320 UniformLocation locationPacked, 2321 GLsizei count, 2322 const GLfloat *value) 2323 { 2324 if (context->getClientVersion() < ES_3_1) 2325 { 2326 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); 2327 return false; 2328 } 2329 2330 return ValidateProgramUniform3fvBase(context, entryPoint, programPacked, locationPacked, count, 2331 value); 2332 } 2333 2334 bool ValidateProgramUniform3i(const Context *context, 2335 angle::EntryPoint entryPoint, 2336 ShaderProgramID programPacked, 2337 UniformLocation locationPacked, 2338 GLint v0, 2339 GLint v1, 2340 GLint v2) 2341 { 2342 if (context->getClientVersion() < ES_3_1) 2343 { 2344 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); 2345 return false; 2346 } 2347 2348 return ValidateProgramUniform3iBase(context, entryPoint, programPacked, locationPacked, v0, v1, 2349 v2); 2350 } 2351 2352 bool ValidateProgramUniform3iv(const Context *context, 2353 angle::EntryPoint entryPoint, 2354 ShaderProgramID programPacked, 2355 UniformLocation locationPacked, 2356 GLsizei count, 2357 const GLint *value) 2358 { 2359 if (context->getClientVersion() < ES_3_1) 2360 { 2361 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); 2362 return false; 2363 } 2364 2365 return ValidateProgramUniform3ivBase(context, entryPoint, programPacked, locationPacked, count, 2366 value); 2367 } 2368 2369 bool ValidateProgramUniform3ui(const Context *context, 2370 angle::EntryPoint entryPoint, 2371 ShaderProgramID programPacked, 2372 UniformLocation locationPacked, 2373 GLuint v0, 2374 GLuint v1, 2375 GLuint v2) 2376 { 2377 if (context->getClientVersion() < ES_3_1) 2378 { 2379 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); 2380 return false; 2381 } 2382 2383 return ValidateProgramUniform3uiBase(context, entryPoint, programPacked, locationPacked, v0, v1, 2384 v2); 2385 } 2386 2387 bool ValidateProgramUniform3uiv(const Context *context, 2388 angle::EntryPoint entryPoint, 2389 ShaderProgramID programPacked, 2390 UniformLocation locationPacked, 2391 GLsizei count, 2392 const GLuint *value) 2393 { 2394 if (context->getClientVersion() < ES_3_1) 2395 { 2396 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); 2397 return false; 2398 } 2399 2400 return ValidateProgramUniform3uivBase(context, entryPoint, programPacked, locationPacked, count, 2401 value); 2402 } 2403 2404 bool ValidateProgramUniform4f(const Context *context, 2405 angle::EntryPoint entryPoint, 2406 ShaderProgramID programPacked, 2407 UniformLocation locationPacked, 2408 GLfloat v0, 2409 GLfloat v1, 2410 GLfloat v2, 2411 GLfloat v3) 2412 { 2413 if (context->getClientVersion() < ES_3_1) 2414 { 2415 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); 2416 return false; 2417 } 2418 2419 return ValidateProgramUniform4fBase(context, entryPoint, programPacked, locationPacked, v0, v1, 2420 v2, v3); 2421 } 2422 2423 bool ValidateProgramUniform4fv(const Context *context, 2424 angle::EntryPoint entryPoint, 2425 ShaderProgramID programPacked, 2426 UniformLocation locationPacked, 2427 GLsizei count, 2428 const GLfloat *value) 2429 { 2430 if (context->getClientVersion() < ES_3_1) 2431 { 2432 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); 2433 return false; 2434 } 2435 2436 return ValidateProgramUniform4fvBase(context, entryPoint, programPacked, locationPacked, count, 2437 value); 2438 } 2439 2440 bool ValidateProgramUniform4i(const Context *context, 2441 angle::EntryPoint entryPoint, 2442 ShaderProgramID programPacked, 2443 UniformLocation locationPacked, 2444 GLint v0, 2445 GLint v1, 2446 GLint v2, 2447 GLint v3) 2448 { 2449 if (context->getClientVersion() < ES_3_1) 2450 { 2451 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); 2452 return false; 2453 } 2454 2455 return ValidateProgramUniform4iBase(context, entryPoint, programPacked, locationPacked, v0, v1, 2456 v2, v3); 2457 } 2458 2459 bool ValidateProgramUniform4iv(const Context *context, 2460 angle::EntryPoint entryPoint, 2461 ShaderProgramID programPacked, 2462 UniformLocation locationPacked, 2463 GLsizei count, 2464 const GLint *value) 2465 { 2466 if (context->getClientVersion() < ES_3_1) 2467 { 2468 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); 2469 return false; 2470 } 2471 2472 return ValidateProgramUniform4ivBase(context, entryPoint, programPacked, locationPacked, count, 2473 value); 2474 } 2475 2476 bool ValidateProgramUniform4ui(const Context *context, 2477 angle::EntryPoint entryPoint, 2478 ShaderProgramID programPacked, 2479 UniformLocation locationPacked, 2480 GLuint v0, 2481 GLuint v1, 2482 GLuint v2, 2483 GLuint v3) 2484 { 2485 if (context->getClientVersion() < ES_3_1) 2486 { 2487 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); 2488 return false; 2489 } 2490 2491 return ValidateProgramUniform4uiBase(context, entryPoint, programPacked, locationPacked, v0, v1, 2492 v2, v3); 2493 } 2494 2495 bool ValidateProgramUniform4uiv(const Context *context, 2496 angle::EntryPoint entryPoint, 2497 ShaderProgramID programPacked, 2498 UniformLocation locationPacked, 2499 GLsizei count, 2500 const GLuint *value) 2501 { 2502 if (context->getClientVersion() < ES_3_1) 2503 { 2504 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); 2505 return false; 2506 } 2507 2508 return ValidateProgramUniform4uivBase(context, entryPoint, programPacked, locationPacked, count, 2509 value); 2510 } 2511 2512 bool ValidateProgramUniformMatrix2fv(const Context *context, 2513 angle::EntryPoint entryPoint, 2514 ShaderProgramID programPacked, 2515 UniformLocation locationPacked, 2516 GLsizei count, 2517 GLboolean transpose, 2518 const GLfloat *value) 2519 { 2520 if (context->getClientVersion() < ES_3_1) 2521 { 2522 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); 2523 return false; 2524 } 2525 2526 return ValidateProgramUniformMatrix2fvBase(context, entryPoint, programPacked, locationPacked, 2527 count, transpose, value); 2528 } 2529 2530 bool ValidateProgramUniformMatrix2x3fv(const Context *context, 2531 angle::EntryPoint entryPoint, 2532 ShaderProgramID programPacked, 2533 UniformLocation locationPacked, 2534 GLsizei count, 2535 GLboolean transpose, 2536 const GLfloat *value) 2537 { 2538 if (context->getClientVersion() < ES_3_1) 2539 { 2540 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); 2541 return false; 2542 } 2543 2544 return ValidateProgramUniformMatrix2x3fvBase(context, entryPoint, programPacked, locationPacked, 2545 count, transpose, value); 2546 } 2547 2548 bool ValidateProgramUniformMatrix2x4fv(const Context *context, 2549 angle::EntryPoint entryPoint, 2550 ShaderProgramID programPacked, 2551 UniformLocation locationPacked, 2552 GLsizei count, 2553 GLboolean transpose, 2554 const GLfloat *value) 2555 { 2556 if (context->getClientVersion() < ES_3_1) 2557 { 2558 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); 2559 return false; 2560 } 2561 2562 return ValidateProgramUniformMatrix2x4fvBase(context, entryPoint, programPacked, locationPacked, 2563 count, transpose, value); 2564 } 2565 2566 bool ValidateProgramUniformMatrix3fv(const Context *context, 2567 angle::EntryPoint entryPoint, 2568 ShaderProgramID programPacked, 2569 UniformLocation locationPacked, 2570 GLsizei count, 2571 GLboolean transpose, 2572 const GLfloat *value) 2573 { 2574 if (context->getClientVersion() < ES_3_1) 2575 { 2576 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); 2577 return false; 2578 } 2579 2580 return ValidateProgramUniformMatrix3fvBase(context, entryPoint, programPacked, locationPacked, 2581 count, transpose, value); 2582 } 2583 2584 bool ValidateProgramUniformMatrix3x2fv(const Context *context, 2585 angle::EntryPoint entryPoint, 2586 ShaderProgramID programPacked, 2587 UniformLocation locationPacked, 2588 GLsizei count, 2589 GLboolean transpose, 2590 const GLfloat *value) 2591 { 2592 if (context->getClientVersion() < ES_3_1) 2593 { 2594 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); 2595 return false; 2596 } 2597 2598 return ValidateProgramUniformMatrix3x2fvBase(context, entryPoint, programPacked, locationPacked, 2599 count, transpose, value); 2600 } 2601 2602 bool ValidateProgramUniformMatrix3x4fv(const Context *context, 2603 angle::EntryPoint entryPoint, 2604 ShaderProgramID programPacked, 2605 UniformLocation locationPacked, 2606 GLsizei count, 2607 GLboolean transpose, 2608 const GLfloat *value) 2609 { 2610 if (context->getClientVersion() < ES_3_1) 2611 { 2612 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); 2613 return false; 2614 } 2615 2616 return ValidateProgramUniformMatrix3x4fvBase(context, entryPoint, programPacked, locationPacked, 2617 count, transpose, value); 2618 } 2619 2620 bool ValidateProgramUniformMatrix4fv(const Context *context, 2621 angle::EntryPoint entryPoint, 2622 ShaderProgramID programPacked, 2623 UniformLocation locationPacked, 2624 GLsizei count, 2625 GLboolean transpose, 2626 const GLfloat *value) 2627 { 2628 if (context->getClientVersion() < ES_3_1) 2629 { 2630 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); 2631 return false; 2632 } 2633 2634 return ValidateProgramUniformMatrix4fvBase(context, entryPoint, programPacked, locationPacked, 2635 count, transpose, value); 2636 } 2637 2638 bool ValidateProgramUniformMatrix4x2fv(const Context *context, 2639 angle::EntryPoint entryPoint, 2640 ShaderProgramID programPacked, 2641 UniformLocation locationPacked, 2642 GLsizei count, 2643 GLboolean transpose, 2644 const GLfloat *value) 2645 { 2646 if (context->getClientVersion() < ES_3_1) 2647 { 2648 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); 2649 return false; 2650 } 2651 2652 return ValidateProgramUniformMatrix4x2fvBase(context, entryPoint, programPacked, locationPacked, 2653 count, transpose, value); 2654 } 2655 2656 bool ValidateProgramUniformMatrix4x3fv(const Context *context, 2657 angle::EntryPoint entryPoint, 2658 ShaderProgramID programPacked, 2659 UniformLocation locationPacked, 2660 GLsizei count, 2661 GLboolean transpose, 2662 const GLfloat *value) 2663 { 2664 if (context->getClientVersion() < ES_3_1) 2665 { 2666 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); 2667 return false; 2668 } 2669 2670 return ValidateProgramUniformMatrix4x3fvBase(context, entryPoint, programPacked, locationPacked, 2671 count, transpose, value); 2672 } 2673 2674 bool ValidateUseProgramStages(const Context *context, 2675 angle::EntryPoint entryPoint, 2676 ProgramPipelineID pipelinePacked, 2677 GLbitfield stages, 2678 ShaderProgramID programPacked) 2679 { 2680 if (context->getClientVersion() < ES_3_1) 2681 { 2682 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); 2683 return false; 2684 } 2685 2686 return ValidateUseProgramStagesBase(context, entryPoint, pipelinePacked, stages, programPacked); 2687 } 2688 2689 bool ValidateValidateProgramPipeline(const Context *context, 2690 angle::EntryPoint entryPoint, 2691 ProgramPipelineID pipelinePacked) 2692 { 2693 if (context->getClientVersion() < ES_3_1) 2694 { 2695 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); 2696 return false; 2697 } 2698 2699 return ValidateValidateProgramPipelineBase(context, entryPoint, pipelinePacked); 2700 } 2701 2702 bool ValidateMemoryBarrier(const Context *context, 2703 angle::EntryPoint entryPoint, 2704 GLbitfield barriers) 2705 { 2706 if (context->getClientVersion() < ES_3_1) 2707 { 2708 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); 2709 return false; 2710 } 2711 2712 if (barriers == GL_ALL_BARRIER_BITS) 2713 { 2714 return true; 2715 } 2716 2717 GLbitfield supported_barrier_bits = 2718 GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT | GL_ELEMENT_ARRAY_BARRIER_BIT | GL_UNIFORM_BARRIER_BIT | 2719 GL_TEXTURE_FETCH_BARRIER_BIT | GL_SHADER_IMAGE_ACCESS_BARRIER_BIT | GL_COMMAND_BARRIER_BIT | 2720 GL_PIXEL_BUFFER_BARRIER_BIT | GL_TEXTURE_UPDATE_BARRIER_BIT | GL_BUFFER_UPDATE_BARRIER_BIT | 2721 GL_FRAMEBUFFER_BARRIER_BIT | GL_TRANSFORM_FEEDBACK_BARRIER_BIT | 2722 GL_ATOMIC_COUNTER_BARRIER_BIT | GL_SHADER_STORAGE_BARRIER_BIT; 2723 2724 if (context->getExtensions().bufferStorageEXT) 2725 { 2726 supported_barrier_bits |= GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT_EXT; 2727 } 2728 2729 if (barriers == 0 || (barriers & ~supported_barrier_bits) != 0) 2730 { 2731 context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidMemoryBarrierBit); 2732 return false; 2733 } 2734 2735 return true; 2736 } 2737 2738 bool ValidateMemoryBarrierByRegion(const Context *context, 2739 angle::EntryPoint entryPoint, 2740 GLbitfield barriers) 2741 { 2742 if (context->getClientVersion() < ES_3_1) 2743 { 2744 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); 2745 return false; 2746 } 2747 2748 if (barriers == GL_ALL_BARRIER_BITS) 2749 { 2750 return true; 2751 } 2752 2753 GLbitfield supported_barrier_bits = GL_ATOMIC_COUNTER_BARRIER_BIT | GL_FRAMEBUFFER_BARRIER_BIT | 2754 GL_SHADER_IMAGE_ACCESS_BARRIER_BIT | 2755 GL_SHADER_STORAGE_BARRIER_BIT | 2756 GL_TEXTURE_FETCH_BARRIER_BIT | GL_UNIFORM_BARRIER_BIT; 2757 if (barriers == 0 || (barriers & ~supported_barrier_bits) != 0) 2758 { 2759 context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidMemoryBarrierBit); 2760 return false; 2761 } 2762 2763 return true; 2764 } 2765 2766 bool ValidateSampleMaski(const Context *context, 2767 angle::EntryPoint entryPoint, 2768 GLuint maskNumber, 2769 GLbitfield mask) 2770 { 2771 if (context->getClientVersion() < ES_3_1) 2772 { 2773 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); 2774 return false; 2775 } 2776 2777 return ValidateSampleMaskiBase(context, entryPoint, maskNumber, mask); 2778 } 2779 2780 bool ValidateMinSampleShadingOES(const Context *context, 2781 angle::EntryPoint entryPoint, 2782 GLfloat value) 2783 { 2784 if (!context->getExtensions().sampleShadingOES) 2785 { 2786 context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); 2787 return false; 2788 } 2789 2790 return true; 2791 } 2792 2793 bool ValidateFramebufferTextureCommon(const Context *context, 2794 angle::EntryPoint entryPoint, 2795 GLenum target, 2796 GLenum attachment, 2797 TextureID texture, 2798 GLint level) 2799 { 2800 if (texture.value != 0) 2801 { 2802 Texture *tex = context->getTexture(texture); 2803 2804 // [EXT_geometry_shader] Section 9.2.8 "Attaching Texture Images to a Framebuffer" 2805 // An INVALID_VALUE error is generated if <texture> is not the name of a texture object. 2806 // We put this validation before ValidateFramebufferTextureBase because it is an 2807 // INVALID_OPERATION error for both FramebufferTexture2D and FramebufferTextureLayer: 2808 // [OpenGL ES 3.1] Chapter 9.2.8 (FramebufferTexture2D) 2809 // An INVALID_OPERATION error is generated if texture is not zero, and does not name an 2810 // existing texture object of type matching textarget. 2811 // [OpenGL ES 3.1 Chapter 9.2.8 (FramebufferTextureLayer) 2812 // An INVALID_OPERATION error is generated if texture is non-zero and is not the name of a 2813 // three-dimensional or two-dimensional array texture. 2814 if (tex == nullptr) 2815 { 2816 context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidTextureName); 2817 return false; 2818 } 2819 2820 if (!ValidMipLevel(context, tex->getType(), level)) 2821 { 2822 context->validationError(entryPoint, GL_INVALID_VALUE, kInvalidMipLevel); 2823 return false; 2824 } 2825 2826 // GLES spec 3.1, Section 9.2.8 "Attaching Texture Images to a Framebuffer" 2827 // If textarget is TEXTURE_2D_MULTISAMPLE, then level must be zero. 2828 if (tex->getType() == TextureType::_2DMultisample && level != 0) 2829 { 2830 context->validationError(entryPoint, GL_INVALID_VALUE, kLevelNotZero); 2831 return false; 2832 } 2833 2834 // [OES_texture_storage_multisample_2d_array] Section 9.2.2 "Attaching Images to Framebuffer 2835 // Objects" 2836 // If texture is a two-dimensional multisample array texture, then level must be zero. 2837 if (context->getExtensions().textureStorageMultisample2dArrayOES && 2838 tex->getType() == TextureType::_2DMultisampleArray && level != 0) 2839 { 2840 context->validationError(entryPoint, GL_INVALID_VALUE, kLevelNotZero); 2841 return false; 2842 } 2843 } 2844 2845 if (!ValidateFramebufferTextureBase(context, entryPoint, target, attachment, texture, level)) 2846 { 2847 return false; 2848 } 2849 2850 return true; 2851 } 2852 2853 bool ValidateFramebufferTextureEXT(const Context *context, 2854 angle::EntryPoint entryPoint, 2855 GLenum target, 2856 GLenum attachment, 2857 TextureID texture, 2858 GLint level) 2859 { 2860 if (!context->getExtensions().geometryShaderEXT) 2861 { 2862 context->validationError(entryPoint, GL_INVALID_OPERATION, 2863 kGeometryShaderExtensionNotEnabled); 2864 return false; 2865 } 2866 2867 return ValidateFramebufferTextureCommon(context, entryPoint, target, attachment, texture, 2868 level); 2869 } 2870 2871 bool ValidateFramebufferTextureOES(const Context *context, 2872 angle::EntryPoint entryPoint, 2873 GLenum target, 2874 GLenum attachment, 2875 TextureID texture, 2876 GLint level) 2877 { 2878 if (!context->getExtensions().geometryShaderOES) 2879 { 2880 context->validationError(entryPoint, GL_INVALID_OPERATION, 2881 kGeometryShaderExtensionNotEnabled); 2882 return false; 2883 } 2884 2885 return ValidateFramebufferTextureCommon(context, entryPoint, target, attachment, texture, 2886 level); 2887 } 2888 2889 // GL_OES_texture_storage_multisample_2d_array 2890 bool ValidateTexStorage3DMultisampleOES(const Context *context, 2891 angle::EntryPoint entryPoint, 2892 TextureType target, 2893 GLsizei samples, 2894 GLenum sizedinternalformat, 2895 GLsizei width, 2896 GLsizei height, 2897 GLsizei depth, 2898 GLboolean fixedsamplelocations) 2899 { 2900 if (!context->getExtensions().textureStorageMultisample2dArrayOES) 2901 { 2902 context->validationError(entryPoint, GL_INVALID_ENUM, kMultisampleArrayExtensionRequired); 2903 return false; 2904 } 2905 2906 if (target != TextureType::_2DMultisampleArray) 2907 { 2908 context->validationError(entryPoint, GL_INVALID_ENUM, 2909 kTargetMustBeTexture2DMultisampleArrayOES); 2910 return false; 2911 } 2912 2913 if (width < 1 || height < 1 || depth < 1) 2914 { 2915 context->validationError(entryPoint, GL_INVALID_VALUE, kNegativeSize); 2916 return false; 2917 } 2918 2919 if (depth > context->getCaps().maxArrayTextureLayers) 2920 { 2921 context->validationError(entryPoint, GL_INVALID_VALUE, kTextureDepthOutOfRange); 2922 return false; 2923 } 2924 2925 return ValidateTexStorageMultisample(context, entryPoint, target, samples, sizedinternalformat, 2926 width, height); 2927 } 2928 2929 bool ValidateTexStorageMem3DMultisampleEXT(const Context *context, 2930 angle::EntryPoint entryPoint, 2931 TextureType target, 2932 GLsizei samples, 2933 GLenum internalFormat, 2934 GLsizei width, 2935 GLsizei height, 2936 GLsizei depth, 2937 GLboolean fixedSampleLocations, 2938 MemoryObjectID memory, 2939 GLuint64 offset) 2940 { 2941 if (!context->getExtensions().memoryObjectEXT) 2942 { 2943 context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); 2944 return false; 2945 } 2946 2947 UNIMPLEMENTED(); 2948 return false; 2949 } 2950 2951 bool ValidateGetProgramResourceLocationIndexEXT(const Context *context, 2952 angle::EntryPoint entryPoint, 2953 ShaderProgramID program, 2954 GLenum programInterface, 2955 const char *name) 2956 { 2957 if (!context->getExtensions().blendFuncExtendedEXT) 2958 { 2959 context->validationError(entryPoint, GL_INVALID_OPERATION, kExtensionNotEnabled); 2960 return false; 2961 } 2962 if (context->getClientVersion() < ES_3_1) 2963 { 2964 context->validationError(entryPoint, GL_INVALID_OPERATION, kES31Required); 2965 return false; 2966 } 2967 if (programInterface != GL_PROGRAM_OUTPUT) 2968 { 2969 context->validationError(entryPoint, GL_INVALID_ENUM, kProgramInterfaceMustBeProgramOutput); 2970 return false; 2971 } 2972 Program *programObject = GetValidProgram(context, entryPoint, program); 2973 if (!programObject) 2974 { 2975 return false; 2976 } 2977 if (!programObject->isLinked()) 2978 { 2979 context->validationError(entryPoint, GL_INVALID_OPERATION, kProgramNotLinked); 2980 return false; 2981 } 2982 return true; 2983 } 2984 2985 // GL_OES_texture_buffer 2986 bool ValidateTexBufferOES(const Context *context, 2987 angle::EntryPoint entryPoint, 2988 TextureType target, 2989 GLenum internalformat, 2990 BufferID bufferPacked) 2991 { 2992 if (!context->getExtensions().textureBufferOES) 2993 { 2994 context->validationError(entryPoint, GL_INVALID_OPERATION, 2995 kTextureBufferExtensionNotAvailable); 2996 return false; 2997 } 2998 2999 return ValidateTexBufferBase(context, entryPoint, target, internalformat, bufferPacked); 3000 } 3001 3002 bool ValidateTexBufferRangeOES(const Context *context, 3003 angle::EntryPoint entryPoint, 3004 TextureType target, 3005 GLenum internalformat, 3006 BufferID bufferPacked, 3007 GLintptr offset, 3008 GLsizeiptr size) 3009 { 3010 if (!context->getExtensions().textureBufferOES) 3011 { 3012 context->validationError(entryPoint, GL_INVALID_OPERATION, 3013 kTextureBufferExtensionNotAvailable); 3014 return false; 3015 } 3016 3017 return ValidateTexBufferRangeBase(context, entryPoint, target, internalformat, bufferPacked, 3018 offset, size); 3019 } 3020 3021 // GL_EXT_texture_buffer 3022 bool ValidateTexBufferEXT(const Context *context, 3023 angle::EntryPoint entryPoint, 3024 TextureType target, 3025 GLenum internalformat, 3026 BufferID bufferPacked) 3027 { 3028 if (!context->getExtensions().textureBufferEXT) 3029 { 3030 context->validationError(entryPoint, GL_INVALID_OPERATION, 3031 kTextureBufferExtensionNotAvailable); 3032 return false; 3033 } 3034 3035 return ValidateTexBufferBase(context, entryPoint, target, internalformat, bufferPacked); 3036 } 3037 3038 bool ValidateTexBufferRangeEXT(const Context *context, 3039 angle::EntryPoint entryPoint, 3040 TextureType target, 3041 GLenum internalformat, 3042 BufferID bufferPacked, 3043 GLintptr offset, 3044 GLsizeiptr size) 3045 { 3046 if (!context->getExtensions().textureBufferEXT) 3047 { 3048 context->validationError(entryPoint, GL_INVALID_OPERATION, 3049 kTextureBufferExtensionNotAvailable); 3050 return false; 3051 } 3052 3053 return ValidateTexBufferRangeBase(context, entryPoint, target, internalformat, bufferPacked, 3054 offset, size); 3055 } 3056 3057 bool ValidateTexBufferBase(const Context *context, 3058 angle::EntryPoint entryPoint, 3059 TextureType target, 3060 GLenum internalformat, 3061 BufferID bufferPacked) 3062 { 3063 if (target != TextureType::Buffer) 3064 { 3065 context->validationError(entryPoint, GL_INVALID_ENUM, kTextureBufferTarget); 3066 return false; 3067 } 3068 3069 switch (internalformat) 3070 { 3071 case GL_R8: 3072 case GL_R16F: 3073 case GL_R32F: 3074 case GL_R8I: 3075 case GL_R16I: 3076 case GL_R32I: 3077 case GL_R8UI: 3078 case GL_R16UI: 3079 case GL_R32UI: 3080 case GL_RG8: 3081 case GL_RG16F: 3082 case GL_RG32F: 3083 case GL_RG8I: 3084 case GL_RG16I: 3085 case GL_RG32I: 3086 case GL_RG8UI: 3087 case GL_RG16UI: 3088 case GL_RG32UI: 3089 case GL_RGB32F: 3090 case GL_RGB32I: 3091 case GL_RGB32UI: 3092 case GL_RGBA8: 3093 case GL_RGBA16F: 3094 case GL_RGBA32F: 3095 case GL_RGBA8I: 3096 case GL_RGBA16I: 3097 case GL_RGBA32I: 3098 case GL_RGBA8UI: 3099 case GL_RGBA16UI: 3100 case GL_RGBA32UI: 3101 break; 3102 3103 default: 3104 context->validationError(entryPoint, GL_INVALID_ENUM, kTextureBufferInternalFormat); 3105 return false; 3106 } 3107 3108 if (bufferPacked.value != 0) 3109 { 3110 if (!context->isBufferGenerated(bufferPacked)) 3111 { 3112 context->validationError(entryPoint, GL_INVALID_OPERATION, kTextureBufferInvalidBuffer); 3113 return false; 3114 } 3115 } 3116 3117 return true; 3118 } 3119 3120 bool ValidateTexBufferRangeBase(const Context *context, 3121 angle::EntryPoint entryPoint, 3122 TextureType target, 3123 GLenum internalformat, 3124 BufferID bufferPacked, 3125 GLintptr offset, 3126 GLsizeiptr size) 3127 { 3128 const Caps &caps = context->getCaps(); 3129 3130 if (offset < 0 || (offset % caps.textureBufferOffsetAlignment) != 0) 3131 { 3132 context->validationError(entryPoint, GL_INVALID_VALUE, kTextureBufferOffsetAlignment); 3133 return false; 3134 } 3135 if (size <= 0) 3136 { 3137 context->validationError(entryPoint, GL_INVALID_VALUE, kTextureBufferSize); 3138 return false; 3139 } 3140 const Buffer *buffer = context->getBuffer(bufferPacked); 3141 3142 if (!buffer) 3143 { 3144 context->validationError(entryPoint, GL_INVALID_OPERATION, kBufferNotBound); 3145 return false; 3146 } 3147 3148 if (offset + size > buffer->getSize()) 3149 { 3150 context->validationError(entryPoint, GL_INVALID_VALUE, kTextureBufferSizeOffset); 3151 return false; 3152 } 3153 3154 return ValidateTexBufferBase(context, entryPoint, target, internalformat, bufferPacked); 3155 } 3156 3157 } // namespace gl