1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 // libGLESv2.cpp: Implements the exported OpenGL ES 2.0 functions. 15 16 #include "main.h" 17 #include "mathutil.h" 18 #include "utilities.h" 19 #include "Buffer.h" 20 #include "Context.h" 21 #include "Fence.h" 22 #include "Framebuffer.h" 23 #include "Program.h" 24 #include "Renderbuffer.h" 25 #include "Shader.h" 26 #include "Texture.h" 27 #include "Query.h" 28 #include "TransformFeedback.h" 29 #include "VertexArray.h" 30 #include "common/debug.h" 31 #include "Common/Version.h" 32 33 #include <GLES2/gl2.h> 34 #include <GLES2/gl2ext.h> 35 #include <GLES3/gl3.h> 36 37 #include <algorithm> 38 #include <limits> 39 40 #ifdef __ANDROID__ 41 #include <cutils/log.h> 42 #endif 43 44 namespace es2 45 { 46 47 static bool validImageSize(GLint level, GLsizei width, GLsizei height) 48 { 49 if(level < 0 || level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS || width < 0 || height < 0) 50 { 51 return false; 52 } 53 54 return true; 55 } 56 57 void ActiveTexture(GLenum texture) 58 { 59 TRACE("(GLenum texture = 0x%X)", texture); 60 61 es2::Context *context = es2::getContext(); 62 63 if(context) 64 { 65 if(texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + es2::MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1) 66 { 67 return error(GL_INVALID_ENUM); 68 } 69 70 context->setActiveSampler(texture - GL_TEXTURE0); 71 } 72 } 73 74 void AttachShader(GLuint program, GLuint shader) 75 { 76 TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader); 77 78 es2::Context *context = es2::getContext(); 79 80 if(context) 81 { 82 es2::Program *programObject = context->getProgram(program); 83 es2::Shader *shaderObject = context->getShader(shader); 84 85 if(!programObject) 86 { 87 if(context->getShader(program)) 88 { 89 return error(GL_INVALID_OPERATION); 90 } 91 else 92 { 93 return error(GL_INVALID_VALUE); 94 } 95 } 96 97 if(!shaderObject) 98 { 99 if(context->getProgram(shader)) 100 { 101 return error(GL_INVALID_OPERATION); 102 } 103 else 104 { 105 return error(GL_INVALID_VALUE); 106 } 107 } 108 109 if(!programObject->attachShader(shaderObject)) 110 { 111 return error(GL_INVALID_OPERATION); 112 } 113 } 114 } 115 116 void BeginQueryEXT(GLenum target, GLuint name) 117 { 118 TRACE("(GLenum target = 0x%X, GLuint name = %d)", target, name); 119 120 switch(target) 121 { 122 case GL_ANY_SAMPLES_PASSED_EXT: 123 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT: 124 break; 125 default: 126 return error(GL_INVALID_ENUM); 127 } 128 129 if(name == 0) 130 { 131 return error(GL_INVALID_OPERATION); 132 } 133 134 es2::Context *context = es2::getContext(); 135 136 if(context) 137 { 138 context->beginQuery(target, name); 139 } 140 } 141 142 void BindAttribLocation(GLuint program, GLuint index, const GLchar* name) 143 { 144 TRACE("(GLuint program = %d, GLuint index = %d, const GLchar* name = %s)", program, index, name); 145 146 if(index >= es2::MAX_VERTEX_ATTRIBS) 147 { 148 return error(GL_INVALID_VALUE); 149 } 150 151 es2::Context *context = es2::getContext(); 152 153 if(context) 154 { 155 es2::Program *programObject = context->getProgram(program); 156 157 if(!programObject) 158 { 159 if(context->getShader(program)) 160 { 161 return error(GL_INVALID_OPERATION); 162 } 163 else 164 { 165 return error(GL_INVALID_VALUE); 166 } 167 } 168 169 if(strncmp(name, "gl_", 3) == 0) 170 { 171 return error(GL_INVALID_OPERATION); 172 } 173 174 programObject->bindAttributeLocation(index, name); 175 } 176 } 177 178 void BindBuffer(GLenum target, GLuint buffer) 179 { 180 TRACE("(GLenum target = 0x%X, GLuint buffer = %d)", target, buffer); 181 182 es2::Context *context = es2::getContext(); 183 184 if(context) 185 { 186 GLint clientVersion = egl::getClientVersion(); 187 188 switch(target) 189 { 190 case GL_ARRAY_BUFFER: 191 context->bindArrayBuffer(buffer); 192 return; 193 case GL_ELEMENT_ARRAY_BUFFER: 194 context->bindElementArrayBuffer(buffer); 195 return; 196 case GL_COPY_READ_BUFFER: 197 if(clientVersion >= 3) 198 { 199 context->bindCopyReadBuffer(buffer); 200 return; 201 } 202 else return error(GL_INVALID_ENUM); 203 case GL_COPY_WRITE_BUFFER: 204 if(clientVersion >= 3) 205 { 206 context->bindCopyWriteBuffer(buffer); 207 return; 208 } 209 else return error(GL_INVALID_ENUM); 210 case GL_PIXEL_PACK_BUFFER: 211 if(clientVersion >= 3) 212 { 213 context->bindPixelPackBuffer(buffer); 214 return; 215 } 216 else return error(GL_INVALID_ENUM); 217 case GL_PIXEL_UNPACK_BUFFER: 218 if(clientVersion >= 3) 219 { 220 context->bindPixelUnpackBuffer(buffer); 221 return; 222 } 223 else return error(GL_INVALID_ENUM); 224 case GL_TRANSFORM_FEEDBACK_BUFFER: 225 if(clientVersion >= 3) 226 { 227 context->bindTransformFeedbackBuffer(buffer); 228 return; 229 } 230 else return error(GL_INVALID_ENUM); 231 case GL_UNIFORM_BUFFER: 232 if(clientVersion >= 3) 233 { 234 context->bindGenericUniformBuffer(buffer); 235 return; 236 } 237 else return error(GL_INVALID_ENUM); 238 default: 239 return error(GL_INVALID_ENUM); 240 } 241 } 242 } 243 244 void BindFramebuffer(GLenum target, GLuint framebuffer) 245 { 246 TRACE("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer); 247 248 if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER && target != GL_READ_FRAMEBUFFER) 249 { 250 return error(GL_INVALID_ENUM); 251 } 252 253 es2::Context *context = es2::getContext(); 254 255 if(context) 256 { 257 if(target == GL_READ_FRAMEBUFFER || target == GL_FRAMEBUFFER) 258 { 259 context->bindReadFramebuffer(framebuffer); 260 } 261 262 if(target == GL_DRAW_FRAMEBUFFER || target == GL_FRAMEBUFFER) 263 { 264 context->bindDrawFramebuffer(framebuffer); 265 } 266 } 267 } 268 269 void BindRenderbuffer(GLenum target, GLuint renderbuffer) 270 { 271 TRACE("(GLenum target = 0x%X, GLuint renderbuffer = %d)", target, renderbuffer); 272 273 if(target != GL_RENDERBUFFER) 274 { 275 return error(GL_INVALID_ENUM); 276 } 277 278 es2::Context *context = es2::getContext(); 279 280 if(context) 281 { 282 // [OpenGL ES 2.0.25] Section 4.4.3 page 110 283 // [OpenGL ES 3.0.4] Section 4.4.2 page 204 284 // If renderbuffer is not zero, then the resulting renderbuffer object 285 // is a new state vector, initialized with a zero-sized memory buffer. 286 context->bindRenderbuffer(renderbuffer); 287 } 288 } 289 290 void BindTexture(GLenum target, GLuint texture) 291 { 292 TRACE("(GLenum target = 0x%X, GLuint texture = %d)", target, texture); 293 294 es2::Context *context = es2::getContext(); 295 296 if(context) 297 { 298 es2::Texture *textureObject = context->getTexture(texture); 299 300 if(textureObject && textureObject->getTarget() != target && texture != 0) 301 { 302 return error(GL_INVALID_OPERATION); 303 } 304 305 GLint clientVersion = context->getClientVersion(); 306 307 switch(target) 308 { 309 case GL_TEXTURE_2D: 310 context->bindTexture(TEXTURE_2D, texture); 311 break; 312 case GL_TEXTURE_CUBE_MAP: 313 context->bindTexture(TEXTURE_CUBE, texture); 314 break; 315 case GL_TEXTURE_EXTERNAL_OES: 316 context->bindTexture(TEXTURE_EXTERNAL, texture); 317 break; 318 case GL_TEXTURE_2D_ARRAY: 319 if(clientVersion < 3) 320 { 321 return error(GL_INVALID_ENUM); 322 } 323 context->bindTexture(TEXTURE_2D_ARRAY, texture); 324 break; 325 case GL_TEXTURE_3D: 326 context->bindTexture(TEXTURE_3D, texture); 327 break; 328 case GL_TEXTURE_RECTANGLE_ARB: 329 context->bindTexture(TEXTURE_2D_RECT, texture); 330 break; 331 default: 332 return error(GL_INVALID_ENUM); 333 } 334 } 335 } 336 337 void BlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) 338 { 339 TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)", 340 red, green, blue, alpha); 341 342 es2::Context* context = es2::getContext(); 343 344 if(context) 345 { 346 context->setBlendColor(es2::clamp01(red), es2::clamp01(green), es2::clamp01(blue), es2::clamp01(alpha)); 347 } 348 } 349 350 void BlendEquation(GLenum mode) 351 { 352 glBlendEquationSeparate(mode, mode); 353 } 354 355 void BlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha) 356 { 357 TRACE("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha); 358 359 switch(modeRGB) 360 { 361 case GL_FUNC_ADD: 362 case GL_FUNC_SUBTRACT: 363 case GL_FUNC_REVERSE_SUBTRACT: 364 case GL_MIN_EXT: 365 case GL_MAX_EXT: 366 break; 367 default: 368 return error(GL_INVALID_ENUM); 369 } 370 371 switch(modeAlpha) 372 { 373 case GL_FUNC_ADD: 374 case GL_FUNC_SUBTRACT: 375 case GL_FUNC_REVERSE_SUBTRACT: 376 case GL_MIN_EXT: 377 case GL_MAX_EXT: 378 break; 379 default: 380 return error(GL_INVALID_ENUM); 381 } 382 383 es2::Context *context = es2::getContext(); 384 385 if(context) 386 { 387 context->setBlendEquation(modeRGB, modeAlpha); 388 } 389 } 390 391 void BlendFunc(GLenum sfactor, GLenum dfactor) 392 { 393 glBlendFuncSeparate(sfactor, dfactor, sfactor, dfactor); 394 } 395 396 void BlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) 397 { 398 TRACE("(GLenum srcRGB = 0x%X, GLenum dstRGB = 0x%X, GLenum srcAlpha = 0x%X, GLenum dstAlpha = 0x%X)", 399 srcRGB, dstRGB, srcAlpha, dstAlpha); 400 401 GLint clientVersion = egl::getClientVersion(); 402 403 switch(srcRGB) 404 { 405 case GL_ZERO: 406 case GL_ONE: 407 case GL_SRC_COLOR: 408 case GL_ONE_MINUS_SRC_COLOR: 409 case GL_DST_COLOR: 410 case GL_ONE_MINUS_DST_COLOR: 411 case GL_SRC_ALPHA: 412 case GL_ONE_MINUS_SRC_ALPHA: 413 case GL_DST_ALPHA: 414 case GL_ONE_MINUS_DST_ALPHA: 415 case GL_CONSTANT_COLOR: 416 case GL_ONE_MINUS_CONSTANT_COLOR: 417 case GL_CONSTANT_ALPHA: 418 case GL_ONE_MINUS_CONSTANT_ALPHA: 419 case GL_SRC_ALPHA_SATURATE: 420 break; 421 default: 422 return error(GL_INVALID_ENUM); 423 } 424 425 switch(dstRGB) 426 { 427 case GL_ZERO: 428 case GL_ONE: 429 case GL_SRC_COLOR: 430 case GL_ONE_MINUS_SRC_COLOR: 431 case GL_DST_COLOR: 432 case GL_ONE_MINUS_DST_COLOR: 433 case GL_SRC_ALPHA: 434 case GL_ONE_MINUS_SRC_ALPHA: 435 case GL_DST_ALPHA: 436 case GL_ONE_MINUS_DST_ALPHA: 437 case GL_CONSTANT_COLOR: 438 case GL_ONE_MINUS_CONSTANT_COLOR: 439 case GL_CONSTANT_ALPHA: 440 case GL_ONE_MINUS_CONSTANT_ALPHA: 441 break; 442 case GL_SRC_ALPHA_SATURATE: 443 if(clientVersion < 3) 444 { 445 return error(GL_INVALID_ENUM); 446 } 447 break; 448 default: 449 return error(GL_INVALID_ENUM); 450 } 451 452 switch(srcAlpha) 453 { 454 case GL_ZERO: 455 case GL_ONE: 456 case GL_SRC_COLOR: 457 case GL_ONE_MINUS_SRC_COLOR: 458 case GL_DST_COLOR: 459 case GL_ONE_MINUS_DST_COLOR: 460 case GL_SRC_ALPHA: 461 case GL_ONE_MINUS_SRC_ALPHA: 462 case GL_DST_ALPHA: 463 case GL_ONE_MINUS_DST_ALPHA: 464 case GL_CONSTANT_COLOR: 465 case GL_ONE_MINUS_CONSTANT_COLOR: 466 case GL_CONSTANT_ALPHA: 467 case GL_ONE_MINUS_CONSTANT_ALPHA: 468 case GL_SRC_ALPHA_SATURATE: 469 break; 470 default: 471 return error(GL_INVALID_ENUM); 472 } 473 474 switch(dstAlpha) 475 { 476 case GL_ZERO: 477 case GL_ONE: 478 case GL_SRC_COLOR: 479 case GL_ONE_MINUS_SRC_COLOR: 480 case GL_DST_COLOR: 481 case GL_ONE_MINUS_DST_COLOR: 482 case GL_SRC_ALPHA: 483 case GL_ONE_MINUS_SRC_ALPHA: 484 case GL_DST_ALPHA: 485 case GL_ONE_MINUS_DST_ALPHA: 486 case GL_CONSTANT_COLOR: 487 case GL_ONE_MINUS_CONSTANT_COLOR: 488 case GL_CONSTANT_ALPHA: 489 case GL_ONE_MINUS_CONSTANT_ALPHA: 490 break; 491 case GL_SRC_ALPHA_SATURATE: 492 if(clientVersion < 3) 493 { 494 return error(GL_INVALID_ENUM); 495 } 496 break; 497 default: 498 return error(GL_INVALID_ENUM); 499 } 500 501 es2::Context *context = es2::getContext(); 502 503 if(context) 504 { 505 context->setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha); 506 } 507 } 508 509 void BufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage) 510 { 511 size = static_cast<GLint>(size); // Work around issues with some 64-bit applications 512 513 TRACE("(GLenum target = 0x%X, GLsizeiptr size = %d, const GLvoid* data = %p, GLenum usage = %d)", 514 target, size, data, usage); 515 516 if(size < 0) 517 { 518 return error(GL_INVALID_VALUE); 519 } 520 521 GLint clientVersion = egl::getClientVersion(); 522 523 switch(usage) 524 { 525 case GL_STREAM_DRAW: 526 case GL_STATIC_DRAW: 527 case GL_DYNAMIC_DRAW: 528 break; 529 case GL_STREAM_READ: 530 case GL_STREAM_COPY: 531 case GL_STATIC_READ: 532 case GL_STATIC_COPY: 533 case GL_DYNAMIC_READ: 534 case GL_DYNAMIC_COPY: 535 if(clientVersion < 3) 536 { 537 return error(GL_INVALID_ENUM); 538 } 539 break; 540 default: 541 return error(GL_INVALID_ENUM); 542 } 543 544 es2::Context *context = es2::getContext(); 545 546 if(context) 547 { 548 es2::Buffer *buffer = nullptr; 549 if(!context->getBuffer(target, &buffer)) 550 { 551 return error(GL_INVALID_ENUM); 552 } 553 554 if(!buffer) 555 { 556 // A null buffer means that "0" is bound to the requested buffer target 557 return error(GL_INVALID_OPERATION); 558 } 559 560 buffer->bufferData(data, size, usage); 561 } 562 } 563 564 void BufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data) 565 { 566 size = static_cast<GLint>(size); // Work around issues with some 64-bit applications 567 offset = static_cast<GLint>(offset); 568 569 TRACE("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr size = %d, const GLvoid* data = %p)", 570 target, offset, size, data); 571 572 if(size < 0 || offset < 0) 573 { 574 return error(GL_INVALID_VALUE); 575 } 576 577 es2::Context *context = es2::getContext(); 578 579 if(context) 580 { 581 es2::Buffer *buffer = nullptr; 582 if(!context->getBuffer(target, &buffer)) 583 { 584 return error(GL_INVALID_ENUM); 585 } 586 587 if(!buffer) 588 { 589 // A null buffer means that "0" is bound to the requested buffer target 590 return error(GL_INVALID_OPERATION); 591 } 592 593 if(buffer->isMapped()) 594 { 595 // It is an invalid operation to update an already mapped buffer 596 return error(GL_INVALID_OPERATION); 597 } 598 599 if((size_t)size + offset > buffer->size()) 600 { 601 return error(GL_INVALID_VALUE); 602 } 603 604 buffer->bufferSubData(data, size, offset); 605 } 606 } 607 608 GLenum CheckFramebufferStatus(GLenum target) 609 { 610 TRACE("(GLenum target = 0x%X)", target); 611 612 if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER && target != GL_READ_FRAMEBUFFER) 613 { 614 return error(GL_INVALID_ENUM, 0); 615 } 616 617 es2::Context *context = es2::getContext(); 618 619 if(context) 620 { 621 es2::Framebuffer *framebuffer = nullptr; 622 if(target == GL_READ_FRAMEBUFFER) 623 { 624 framebuffer = context->getReadFramebuffer(); 625 } 626 else 627 { 628 framebuffer = context->getDrawFramebuffer(); 629 } 630 631 if(!framebuffer) 632 { 633 return GL_FRAMEBUFFER_UNDEFINED_OES; 634 } 635 636 return framebuffer->completeness(); 637 } 638 639 return 0; 640 } 641 642 void Clear(GLbitfield mask) 643 { 644 TRACE("(GLbitfield mask = %X)", mask); 645 646 if((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0) 647 { 648 return error(GL_INVALID_VALUE); 649 } 650 651 es2::Context *context = es2::getContext(); 652 653 if(context) 654 { 655 context->clear(mask); 656 } 657 } 658 659 void ClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) 660 { 661 TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)", 662 red, green, blue, alpha); 663 664 es2::Context *context = es2::getContext(); 665 666 if(context) 667 { 668 context->setClearColor(red, green, blue, alpha); 669 } 670 } 671 672 void ClearDepthf(GLclampf depth) 673 { 674 TRACE("(GLclampf depth = %f)", depth); 675 676 es2::Context *context = es2::getContext(); 677 678 if(context) 679 { 680 context->setClearDepth(depth); 681 } 682 } 683 684 void ClearStencil(GLint s) 685 { 686 TRACE("(GLint s = %d)", s); 687 688 es2::Context *context = es2::getContext(); 689 690 if(context) 691 { 692 context->setClearStencil(s); 693 } 694 } 695 696 void ColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) 697 { 698 TRACE("(GLboolean red = %d, GLboolean green = %d, GLboolean blue = %d, GLboolean alpha = %d)", 699 red, green, blue, alpha); 700 701 es2::Context *context = es2::getContext(); 702 703 if(context) 704 { 705 context->setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE); 706 } 707 } 708 709 void CompileShader(GLuint shader) 710 { 711 TRACE("(GLuint shader = %d)", shader); 712 713 es2::Context *context = es2::getContext(); 714 715 if(context) 716 { 717 es2::Shader *shaderObject = context->getShader(shader); 718 719 if(!shaderObject) 720 { 721 if(context->getProgram(shader)) 722 { 723 return error(GL_INVALID_OPERATION); 724 } 725 else 726 { 727 return error(GL_INVALID_VALUE); 728 } 729 } 730 731 shaderObject->compile(); 732 } 733 } 734 735 void CompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, 736 GLint border, GLsizei imageSize, const GLvoid* data) 737 { 738 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, " 739 "GLsizei height = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = %p)", 740 target, level, internalformat, width, height, border, imageSize, data); 741 742 if(!validImageSize(level, width, height) || border != 0 || imageSize < 0) 743 { 744 return error(GL_INVALID_VALUE); 745 } 746 747 if(!IsCompressed(internalformat, egl::getClientVersion())) 748 { 749 return error(GL_INVALID_ENUM); 750 } 751 752 if(border != 0) 753 { 754 return error(GL_INVALID_VALUE); 755 } 756 757 es2::Context *context = es2::getContext(); 758 759 if(context) 760 { 761 if(level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS) 762 { 763 return error(GL_INVALID_VALUE); 764 } 765 766 switch(target) 767 { 768 case GL_TEXTURE_2D: 769 if(width > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) || 770 height > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level)) 771 { 772 return error(GL_INVALID_VALUE); 773 } 774 break; 775 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 776 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 777 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 778 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 779 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 780 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 781 if(width != height) 782 { 783 return error(GL_INVALID_VALUE); 784 } 785 786 if(width > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level) || 787 height > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level)) 788 { 789 return error(GL_INVALID_VALUE); 790 } 791 break; 792 case GL_TEXTURE_RECTANGLE_ARB: // Rectangle textures cannot be compressed 793 default: 794 return error(GL_INVALID_ENUM); 795 } 796 797 if(imageSize != gl::ComputeCompressedSize(width, height, internalformat)) 798 { 799 return error(GL_INVALID_VALUE); 800 } 801 802 GLenum validationError = context->getPixels(&data, GL_UNSIGNED_BYTE, imageSize); 803 if(validationError != GL_NO_ERROR) 804 { 805 return error(validationError); 806 } 807 808 if(target == GL_TEXTURE_2D || target == GL_TEXTURE_RECTANGLE_ARB) 809 { 810 es2::Texture2D *texture = context->getTexture2D(target); 811 812 if(!texture) 813 { 814 return error(GL_INVALID_OPERATION); 815 } 816 817 texture->setCompressedImage(level, internalformat, width, height, imageSize, data); 818 } 819 else if(es2::IsCubemapTextureTarget(target)) 820 { 821 es2::TextureCubeMap *texture = context->getTextureCubeMap(); 822 823 if(!texture) 824 { 825 return error(GL_INVALID_OPERATION); 826 } 827 828 texture->setCompressedImage(target, level, internalformat, width, height, imageSize, data); 829 } 830 else UNREACHABLE(target); 831 } 832 } 833 834 void CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, 835 GLenum format, GLsizei imageSize, const GLvoid* data) 836 { 837 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, " 838 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, " 839 "GLsizei imageSize = %d, const GLvoid* data = %p)", 840 target, level, xoffset, yoffset, width, height, format, imageSize, data); 841 842 if(!es2::IsTextureTarget(target)) 843 { 844 return error(GL_INVALID_ENUM); 845 } 846 847 if(level < 0 || level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS) 848 { 849 return error(GL_INVALID_VALUE); 850 } 851 852 if(xoffset < 0 || yoffset < 0 || !validImageSize(level, width, height) || imageSize < 0) 853 { 854 return error(GL_INVALID_VALUE); 855 } 856 857 if(imageSize != gl::ComputeCompressedSize(width, height, format)) 858 { 859 return error(GL_INVALID_VALUE); 860 } 861 862 es2::Context *context = es2::getContext(); 863 864 if(context) 865 { 866 if(xoffset % 4 != 0 || yoffset % 4 != 0) 867 { 868 // We wait to check the offsets until this point, because the multiple-of-four restriction does not exist unless DXT1 textures are supported 869 return error(GL_INVALID_OPERATION); 870 } 871 872 GLenum validationError = context->getPixels(&data, GL_UNSIGNED_BYTE, imageSize); 873 if(validationError != GL_NO_ERROR) 874 { 875 return error(validationError); 876 } 877 878 if(target == GL_TEXTURE_2D || target == GL_TEXTURE_RECTANGLE_ARB) 879 { 880 es2::Texture2D *texture = context->getTexture2D(target); 881 882 GLenum validationError = ValidateSubImageParams(true, false, target, level, xoffset, yoffset, width, height, format, GL_NONE, texture, context->getClientVersion()); 883 if(validationError != GL_NO_ERROR) 884 { 885 return error(validationError); 886 } 887 888 texture->subImageCompressed(level, xoffset, yoffset, width, height, format, imageSize, data); 889 } 890 else if(es2::IsCubemapTextureTarget(target)) 891 { 892 es2::TextureCubeMap *texture = context->getTextureCubeMap(); 893 894 GLenum validationError = ValidateSubImageParams(true, false, target, level, xoffset, yoffset, width, height, format, GL_NONE, texture, context->getClientVersion()); 895 if(validationError != GL_NO_ERROR) 896 { 897 return error(validationError); 898 } 899 900 texture->subImageCompressed(target, level, xoffset, yoffset, width, height, format, imageSize, data); 901 } 902 else UNREACHABLE(target); 903 } 904 } 905 906 void CopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) 907 { 908 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, " 909 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)", 910 target, level, internalformat, x, y, width, height, border); 911 912 if(!validImageSize(level, width, height)) 913 { 914 return error(GL_INVALID_VALUE); 915 } 916 917 if(border != 0) 918 { 919 return error(GL_INVALID_VALUE); 920 } 921 922 es2::Context *context = es2::getContext(); 923 924 if(context) 925 { 926 switch(target) 927 { 928 case GL_TEXTURE_RECTANGLE_ARB: 929 if(level != 0) 930 { 931 return error(GL_INVALID_VALUE); 932 } 933 // Fall through to GL_TEXTURE_2D case. 934 case GL_TEXTURE_2D: 935 if(width > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) || 936 height > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level)) 937 { 938 return error(GL_INVALID_VALUE); 939 } 940 break; 941 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 942 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 943 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 944 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 945 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 946 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 947 if(width != height) 948 { 949 return error(GL_INVALID_VALUE); 950 } 951 952 if(width > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level) || 953 height > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level)) 954 { 955 return error(GL_INVALID_VALUE); 956 } 957 break; 958 default: 959 return error(GL_INVALID_ENUM); 960 } 961 962 es2::Framebuffer *framebuffer = context->getReadFramebuffer(); 963 964 if(!framebuffer || (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)) 965 { 966 return error(GL_INVALID_FRAMEBUFFER_OPERATION); 967 } 968 969 es2::Renderbuffer *source = framebuffer->getReadColorbuffer(); 970 971 if(context->getReadFramebufferName() != 0 && (!source || source->getSamples() > 1)) 972 { 973 return error(GL_INVALID_OPERATION); 974 } 975 976 GLenum colorbufferFormat = source->getFormat(); 977 978 // Determine the sized internal format. 979 if(gl::IsUnsizedInternalFormat(internalformat)) 980 { 981 if(gl::GetBaseInternalFormat(colorbufferFormat) == internalformat) 982 { 983 internalformat = colorbufferFormat; 984 } 985 else if(GetColorComponentType(colorbufferFormat) == GL_UNSIGNED_NORMALIZED && GetRedSize(colorbufferFormat) <= 8) 986 { 987 // TODO: Convert to the smallest format that fits all components. 988 // e.g. Copying RGBA4 to RGB should result in RGB565, not RGB8. 989 990 internalformat = gl::GetSizedInternalFormat(internalformat, GL_UNSIGNED_BYTE); 991 } 992 else if(GetColorComponentType(colorbufferFormat) == GL_INT) 993 { 994 internalformat = gl::GetSizedInternalFormat(internalformat, GL_INT); 995 } 996 else if(GetColorComponentType(colorbufferFormat) == GL_UNSIGNED_INT) 997 { 998 internalformat = gl::GetSizedInternalFormat(internalformat, GL_UNSIGNED_INT); 999 } 1000 else if(GetColorComponentType(colorbufferFormat) == GL_FLOAT && GetRedSize(colorbufferFormat) == 16) // GL_EXT_color_buffer_half_float 1001 { 1002 internalformat = gl::GetSizedInternalFormat(internalformat, GL_HALF_FLOAT_OES); 1003 } 1004 else 1005 { 1006 UNIMPLEMENTED(); 1007 1008 return error(GL_INVALID_OPERATION); 1009 } 1010 } 1011 1012 if(!ValidateCopyFormats(internalformat, colorbufferFormat)) 1013 { 1014 return; 1015 } 1016 1017 if(target == GL_TEXTURE_2D || target == GL_TEXTURE_RECTANGLE_ARB) 1018 { 1019 es2::Texture2D *texture = context->getTexture2D(target); 1020 1021 if(!texture) 1022 { 1023 return error(GL_INVALID_OPERATION); 1024 } 1025 1026 texture->copyImage(level, internalformat, x, y, width, height, source); 1027 } 1028 else if(es2::IsCubemapTextureTarget(target)) 1029 { 1030 es2::TextureCubeMap *texture = context->getTextureCubeMap(); 1031 1032 if(!texture) 1033 { 1034 return error(GL_INVALID_OPERATION); 1035 } 1036 1037 texture->copyImage(target, level, internalformat, x, y, width, height, source); 1038 } 1039 else UNREACHABLE(target); 1040 } 1041 } 1042 1043 void CopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) 1044 { 1045 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, " 1046 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", 1047 target, level, xoffset, yoffset, x, y, width, height); 1048 1049 if(!es2::IsTextureTarget(target)) 1050 { 1051 return error(GL_INVALID_ENUM); 1052 } 1053 1054 if(level < 0 || level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS) 1055 { 1056 return error(GL_INVALID_VALUE); 1057 } 1058 1059 if(xoffset < 0 || yoffset < 0 || width < 0 || height < 0) 1060 { 1061 return error(GL_INVALID_VALUE); 1062 } 1063 1064 if(std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height) 1065 { 1066 return error(GL_INVALID_VALUE); 1067 } 1068 1069 es2::Context *context = es2::getContext(); 1070 1071 if(context) 1072 { 1073 es2::Framebuffer *framebuffer = context->getReadFramebuffer(); 1074 1075 if(!framebuffer || (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)) 1076 { 1077 return error(GL_INVALID_FRAMEBUFFER_OPERATION); 1078 } 1079 1080 es2::Renderbuffer *source = framebuffer->getReadColorbuffer(); 1081 1082 if(context->getReadFramebufferName() != 0 && (!source || source->getSamples() > 1)) 1083 { 1084 return error(GL_INVALID_OPERATION); 1085 } 1086 1087 es2::Texture *texture = nullptr; 1088 1089 if(target == GL_TEXTURE_2D || target == GL_TEXTURE_RECTANGLE_ARB) 1090 { 1091 texture = context->getTexture2D(target); 1092 } 1093 else if(es2::IsCubemapTextureTarget(target)) 1094 { 1095 texture = context->getTextureCubeMap(); 1096 } 1097 else UNREACHABLE(target); 1098 1099 GLenum validationError = ValidateSubImageParams(false, true, target, level, xoffset, yoffset, width, height, GL_NONE, GL_NONE, texture, context->getClientVersion()); 1100 if(validationError != GL_NO_ERROR) 1101 { 1102 return error(validationError); 1103 } 1104 1105 texture->copySubImage(target, level, xoffset, yoffset, 0, x, y, width, height, source); 1106 } 1107 } 1108 1109 GLuint CreateProgram(void) 1110 { 1111 TRACE("()"); 1112 1113 es2::Context *context = es2::getContext(); 1114 1115 if(context) 1116 { 1117 return context->createProgram(); 1118 } 1119 1120 return 0; 1121 } 1122 1123 GLuint CreateShader(GLenum type) 1124 { 1125 TRACE("(GLenum type = 0x%X)", type); 1126 1127 es2::Context *context = es2::getContext(); 1128 1129 if(context) 1130 { 1131 switch(type) 1132 { 1133 case GL_FRAGMENT_SHADER: 1134 case GL_VERTEX_SHADER: 1135 return context->createShader(type); 1136 default: 1137 return error(GL_INVALID_ENUM, 0); 1138 } 1139 } 1140 1141 return 0; 1142 } 1143 1144 void CullFace(GLenum mode) 1145 { 1146 TRACE("(GLenum mode = 0x%X)", mode); 1147 1148 switch(mode) 1149 { 1150 case GL_FRONT: 1151 case GL_BACK: 1152 case GL_FRONT_AND_BACK: 1153 { 1154 es2::Context *context = es2::getContext(); 1155 1156 if(context) 1157 { 1158 context->setCullMode(mode); 1159 } 1160 } 1161 break; 1162 default: 1163 return error(GL_INVALID_ENUM); 1164 } 1165 } 1166 1167 void DeleteBuffers(GLsizei n, const GLuint* buffers) 1168 { 1169 TRACE("(GLsizei n = %d, const GLuint* buffers = %p)", n, buffers); 1170 1171 if(n < 0) 1172 { 1173 return error(GL_INVALID_VALUE); 1174 } 1175 1176 es2::Context *context = es2::getContext(); 1177 1178 if(context) 1179 { 1180 for(int i = 0; i < n; i++) 1181 { 1182 context->deleteBuffer(buffers[i]); 1183 } 1184 } 1185 } 1186 1187 void DeleteFencesNV(GLsizei n, const GLuint* fences) 1188 { 1189 TRACE("(GLsizei n = %d, const GLuint* fences = %p)", n, fences); 1190 1191 if(n < 0) 1192 { 1193 return error(GL_INVALID_VALUE); 1194 } 1195 1196 es2::Context *context = es2::getContext(); 1197 1198 if(context) 1199 { 1200 for(int i = 0; i < n; i++) 1201 { 1202 context->deleteFence(fences[i]); 1203 } 1204 } 1205 } 1206 1207 void DeleteFramebuffers(GLsizei n, const GLuint* framebuffers) 1208 { 1209 TRACE("(GLsizei n = %d, const GLuint* framebuffers = %p)", n, framebuffers); 1210 1211 if(n < 0) 1212 { 1213 return error(GL_INVALID_VALUE); 1214 } 1215 1216 es2::Context *context = es2::getContext(); 1217 1218 if(context) 1219 { 1220 for(int i = 0; i < n; i++) 1221 { 1222 if(framebuffers[i] != 0) 1223 { 1224 context->deleteFramebuffer(framebuffers[i]); 1225 } 1226 } 1227 } 1228 } 1229 1230 void DeleteProgram(GLuint program) 1231 { 1232 TRACE("(GLuint program = %d)", program); 1233 1234 if(program == 0) 1235 { 1236 return; 1237 } 1238 1239 es2::Context *context = es2::getContext(); 1240 1241 if(context) 1242 { 1243 if(!context->getProgram(program)) 1244 { 1245 if(context->getShader(program)) 1246 { 1247 return error(GL_INVALID_OPERATION); 1248 } 1249 else 1250 { 1251 return error(GL_INVALID_VALUE); 1252 } 1253 } 1254 1255 context->deleteProgram(program); 1256 } 1257 } 1258 1259 void DeleteQueriesEXT(GLsizei n, const GLuint *ids) 1260 { 1261 TRACE("(GLsizei n = %d, const GLuint *ids = %p)", n, ids); 1262 1263 if(n < 0) 1264 { 1265 return error(GL_INVALID_VALUE); 1266 } 1267 1268 es2::Context *context = es2::getContext(); 1269 1270 if(context) 1271 { 1272 for(int i = 0; i < n; i++) 1273 { 1274 context->deleteQuery(ids[i]); 1275 } 1276 } 1277 } 1278 1279 void DeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers) 1280 { 1281 TRACE("(GLsizei n = %d, const GLuint* renderbuffers = %p)", n, renderbuffers); 1282 1283 if(n < 0) 1284 { 1285 return error(GL_INVALID_VALUE); 1286 } 1287 1288 es2::Context *context = es2::getContext(); 1289 1290 if(context) 1291 { 1292 for(int i = 0; i < n; i++) 1293 { 1294 context->deleteRenderbuffer(renderbuffers[i]); 1295 } 1296 } 1297 } 1298 1299 void DeleteShader(GLuint shader) 1300 { 1301 TRACE("(GLuint shader = %d)", shader); 1302 1303 if(shader == 0) 1304 { 1305 return; 1306 } 1307 1308 es2::Context *context = es2::getContext(); 1309 1310 if(context) 1311 { 1312 if(!context->getShader(shader)) 1313 { 1314 if(context->getProgram(shader)) 1315 { 1316 return error(GL_INVALID_OPERATION); 1317 } 1318 else 1319 { 1320 return error(GL_INVALID_VALUE); 1321 } 1322 } 1323 1324 context->deleteShader(shader); 1325 } 1326 } 1327 1328 void DeleteTextures(GLsizei n, const GLuint* textures) 1329 { 1330 TRACE("(GLsizei n = %d, const GLuint* textures = %p)", n, textures); 1331 1332 if(n < 0) 1333 { 1334 return error(GL_INVALID_VALUE); 1335 } 1336 1337 es2::Context *context = es2::getContext(); 1338 1339 if(context) 1340 { 1341 for(int i = 0; i < n; i++) 1342 { 1343 if(textures[i] != 0) 1344 { 1345 context->deleteTexture(textures[i]); 1346 } 1347 } 1348 } 1349 } 1350 1351 void DepthFunc(GLenum func) 1352 { 1353 TRACE("(GLenum func = 0x%X)", func); 1354 1355 switch(func) 1356 { 1357 case GL_NEVER: 1358 case GL_ALWAYS: 1359 case GL_LESS: 1360 case GL_LEQUAL: 1361 case GL_EQUAL: 1362 case GL_GREATER: 1363 case GL_GEQUAL: 1364 case GL_NOTEQUAL: 1365 break; 1366 default: 1367 return error(GL_INVALID_ENUM); 1368 } 1369 1370 es2::Context *context = es2::getContext(); 1371 1372 if(context) 1373 { 1374 context->setDepthFunc(func); 1375 } 1376 } 1377 1378 void DepthMask(GLboolean flag) 1379 { 1380 TRACE("(GLboolean flag = %d)", flag); 1381 1382 es2::Context *context = es2::getContext(); 1383 1384 if(context) 1385 { 1386 context->setDepthMask(flag != GL_FALSE); 1387 } 1388 } 1389 1390 void DepthRangef(GLclampf zNear, GLclampf zFar) 1391 { 1392 TRACE("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar); 1393 1394 es2::Context *context = es2::getContext(); 1395 1396 if(context) 1397 { 1398 context->setDepthRange(zNear, zFar); 1399 } 1400 } 1401 1402 void DetachShader(GLuint program, GLuint shader) 1403 { 1404 TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader); 1405 1406 es2::Context *context = es2::getContext(); 1407 1408 if(context) 1409 { 1410 1411 es2::Program *programObject = context->getProgram(program); 1412 es2::Shader *shaderObject = context->getShader(shader); 1413 1414 if(!programObject) 1415 { 1416 es2::Shader *shaderByProgramHandle; 1417 shaderByProgramHandle = context->getShader(program); 1418 if(!shaderByProgramHandle) 1419 { 1420 return error(GL_INVALID_VALUE); 1421 } 1422 else 1423 { 1424 return error(GL_INVALID_OPERATION); 1425 } 1426 } 1427 1428 if(!shaderObject) 1429 { 1430 es2::Program *programByShaderHandle = context->getProgram(shader); 1431 if(!programByShaderHandle) 1432 { 1433 return error(GL_INVALID_VALUE); 1434 } 1435 else 1436 { 1437 return error(GL_INVALID_OPERATION); 1438 } 1439 } 1440 1441 if(!programObject->detachShader(shaderObject)) 1442 { 1443 return error(GL_INVALID_OPERATION); 1444 } 1445 } 1446 } 1447 1448 void Disable(GLenum cap) 1449 { 1450 TRACE("(GLenum cap = 0x%X)", cap); 1451 1452 es2::Context *context = es2::getContext(); 1453 1454 if(context) 1455 { 1456 switch(cap) 1457 { 1458 case GL_CULL_FACE: context->setCullFaceEnabled(false); break; 1459 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFillEnabled(false); break; 1460 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverageEnabled(false); break; 1461 case GL_SAMPLE_COVERAGE: context->setSampleCoverageEnabled(false); break; 1462 case GL_SCISSOR_TEST: context->setScissorTestEnabled(false); break; 1463 case GL_STENCIL_TEST: context->setStencilTestEnabled(false); break; 1464 case GL_DEPTH_TEST: context->setDepthTestEnabled(false); break; 1465 case GL_BLEND: context->setBlendEnabled(false); break; 1466 case GL_DITHER: context->setDitherEnabled(false); break; 1467 case GL_PRIMITIVE_RESTART_FIXED_INDEX: context->setPrimitiveRestartFixedIndexEnabled(false); break; 1468 case GL_RASTERIZER_DISCARD: context->setRasterizerDiscardEnabled(false); break; 1469 default: 1470 return error(GL_INVALID_ENUM); 1471 } 1472 } 1473 } 1474 1475 void DisableVertexAttribArray(GLuint index) 1476 { 1477 TRACE("(GLuint index = %d)", index); 1478 1479 if(index >= es2::MAX_VERTEX_ATTRIBS) 1480 { 1481 return error(GL_INVALID_VALUE); 1482 } 1483 1484 es2::Context *context = es2::getContext(); 1485 1486 if(context) 1487 { 1488 context->setVertexAttribArrayEnabled(index, false); 1489 } 1490 } 1491 1492 void DrawArrays(GLenum mode, GLint first, GLsizei count) 1493 { 1494 TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count); 1495 1496 switch(mode) 1497 { 1498 case GL_POINTS: 1499 case GL_LINES: 1500 case GL_LINE_LOOP: 1501 case GL_LINE_STRIP: 1502 case GL_TRIANGLES: 1503 case GL_TRIANGLE_FAN: 1504 case GL_TRIANGLE_STRIP: 1505 break; 1506 default: 1507 return error(GL_INVALID_ENUM); 1508 } 1509 1510 if(count < 0 || first < 0) 1511 { 1512 return error(GL_INVALID_VALUE); 1513 } 1514 1515 es2::Context *context = es2::getContext(); 1516 1517 if(context) 1518 { 1519 es2::TransformFeedback* transformFeedback = context->getTransformFeedback(); 1520 if(transformFeedback && transformFeedback->isActive() && (mode != transformFeedback->primitiveMode())) 1521 { 1522 return error(GL_INVALID_OPERATION); 1523 } 1524 1525 context->drawArrays(mode, first, count); 1526 } 1527 } 1528 1529 void DrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices) 1530 { 1531 TRACE("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = %p)", 1532 mode, count, type, indices); 1533 1534 switch(mode) 1535 { 1536 case GL_POINTS: 1537 case GL_LINES: 1538 case GL_LINE_LOOP: 1539 case GL_LINE_STRIP: 1540 case GL_TRIANGLES: 1541 case GL_TRIANGLE_FAN: 1542 case GL_TRIANGLE_STRIP: 1543 break; 1544 default: 1545 return error(GL_INVALID_ENUM); 1546 } 1547 1548 if(count < 0) 1549 { 1550 return error(GL_INVALID_VALUE); 1551 } 1552 1553 es2::Context *context = es2::getContext(); 1554 1555 if(context) 1556 { 1557 es2::TransformFeedback* transformFeedback = context->getTransformFeedback(); 1558 if(transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused()) 1559 { 1560 return error(GL_INVALID_OPERATION); 1561 } 1562 1563 switch(type) 1564 { 1565 case GL_UNSIGNED_BYTE: 1566 case GL_UNSIGNED_SHORT: 1567 case GL_UNSIGNED_INT: 1568 break; 1569 default: 1570 return error(GL_INVALID_ENUM); 1571 } 1572 1573 context->drawElements(mode, 0, MAX_ELEMENT_INDEX, count, type, indices); 1574 } 1575 } 1576 1577 void DrawArraysInstancedEXT(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount) 1578 { 1579 TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d, GLsizei instanceCount = %d)", 1580 mode, first, count, instanceCount); 1581 1582 switch(mode) 1583 { 1584 case GL_POINTS: 1585 case GL_LINES: 1586 case GL_LINE_LOOP: 1587 case GL_LINE_STRIP: 1588 case GL_TRIANGLES: 1589 case GL_TRIANGLE_FAN: 1590 case GL_TRIANGLE_STRIP: 1591 break; 1592 default: 1593 return error(GL_INVALID_ENUM); 1594 } 1595 1596 if(count < 0 || instanceCount < 0) 1597 { 1598 return error(GL_INVALID_VALUE); 1599 } 1600 1601 es2::Context *context = es2::getContext(); 1602 1603 if(context) 1604 { 1605 es2::TransformFeedback* transformFeedback = context->getTransformFeedback(); 1606 if(transformFeedback && transformFeedback->isActive() && (mode != transformFeedback->primitiveMode())) 1607 { 1608 return error(GL_INVALID_OPERATION); 1609 } 1610 1611 context->drawArrays(mode, first, count, instanceCount); 1612 } 1613 } 1614 1615 void DrawElementsInstancedEXT(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instanceCount) 1616 { 1617 TRACE("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const void *indices = %p, GLsizei instanceCount = %d)", 1618 mode, count, type, indices, instanceCount); 1619 1620 switch(mode) 1621 { 1622 case GL_POINTS: 1623 case GL_LINES: 1624 case GL_LINE_LOOP: 1625 case GL_LINE_STRIP: 1626 case GL_TRIANGLES: 1627 case GL_TRIANGLE_FAN: 1628 case GL_TRIANGLE_STRIP: 1629 break; 1630 default: 1631 return error(GL_INVALID_ENUM); 1632 } 1633 1634 switch(type) 1635 { 1636 case GL_UNSIGNED_BYTE: 1637 case GL_UNSIGNED_SHORT: 1638 case GL_UNSIGNED_INT: 1639 break; 1640 default: 1641 return error(GL_INVALID_ENUM); 1642 } 1643 1644 if(count < 0 || instanceCount < 0) 1645 { 1646 return error(GL_INVALID_VALUE); 1647 } 1648 1649 es2::Context *context = es2::getContext(); 1650 1651 if(context) 1652 { 1653 es2::TransformFeedback* transformFeedback = context->getTransformFeedback(); 1654 if(transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused()) 1655 { 1656 return error(GL_INVALID_OPERATION); 1657 } 1658 1659 context->drawElements(mode, 0, MAX_ELEMENT_INDEX, count, type, indices, instanceCount); 1660 } 1661 } 1662 1663 void VertexAttribDivisorEXT(GLuint index, GLuint divisor) 1664 { 1665 TRACE("(GLuint index = %d, GLuint divisor = %d)", index, divisor); 1666 1667 es2::Context *context = es2::getContext(); 1668 1669 if(context) 1670 { 1671 if(index >= es2::MAX_VERTEX_ATTRIBS) 1672 { 1673 return error(GL_INVALID_VALUE); 1674 } 1675 1676 context->setVertexAttribDivisor(index, divisor); 1677 } 1678 } 1679 1680 void DrawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount) 1681 { 1682 TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d, GLsizei instanceCount = %d)", 1683 mode, first, count, instanceCount); 1684 1685 switch(mode) 1686 { 1687 case GL_POINTS: 1688 case GL_LINES: 1689 case GL_LINE_LOOP: 1690 case GL_LINE_STRIP: 1691 case GL_TRIANGLES: 1692 case GL_TRIANGLE_FAN: 1693 case GL_TRIANGLE_STRIP: 1694 break; 1695 default: 1696 return error(GL_INVALID_ENUM); 1697 } 1698 1699 if(count < 0 || instanceCount < 0) 1700 { 1701 return error(GL_INVALID_VALUE); 1702 } 1703 1704 es2::Context *context = es2::getContext(); 1705 1706 if(context) 1707 { 1708 if(!context->hasZeroDivisor()) 1709 { 1710 return error(GL_INVALID_OPERATION); 1711 } 1712 1713 es2::TransformFeedback* transformFeedback = context->getTransformFeedback(); 1714 if(transformFeedback && transformFeedback->isActive() && (mode != transformFeedback->primitiveMode())) 1715 { 1716 return error(GL_INVALID_OPERATION); 1717 } 1718 1719 context->drawArrays(mode, first, count, instanceCount); 1720 } 1721 } 1722 1723 void DrawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instanceCount) 1724 { 1725 TRACE("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const void *indices = %p, GLsizei instanceCount = %d)", 1726 mode, count, type, indices, instanceCount); 1727 1728 switch(mode) 1729 { 1730 case GL_POINTS: 1731 case GL_LINES: 1732 case GL_LINE_LOOP: 1733 case GL_LINE_STRIP: 1734 case GL_TRIANGLES: 1735 case GL_TRIANGLE_FAN: 1736 case GL_TRIANGLE_STRIP: 1737 break; 1738 default: 1739 return error(GL_INVALID_ENUM); 1740 } 1741 1742 switch(type) 1743 { 1744 case GL_UNSIGNED_BYTE: 1745 case GL_UNSIGNED_SHORT: 1746 case GL_UNSIGNED_INT: 1747 break; 1748 default: 1749 return error(GL_INVALID_ENUM); 1750 } 1751 1752 if(count < 0 || instanceCount < 0) 1753 { 1754 return error(GL_INVALID_VALUE); 1755 } 1756 1757 es2::Context *context = es2::getContext(); 1758 1759 if(context) 1760 { 1761 if(!context->hasZeroDivisor()) 1762 { 1763 return error(GL_INVALID_OPERATION); 1764 } 1765 1766 es2::TransformFeedback* transformFeedback = context->getTransformFeedback(); 1767 if(transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused()) 1768 { 1769 return error(GL_INVALID_OPERATION); 1770 } 1771 1772 context->drawElements(mode, 0, MAX_ELEMENT_INDEX, count, type, indices, instanceCount); 1773 } 1774 } 1775 1776 void VertexAttribDivisorANGLE(GLuint index, GLuint divisor) 1777 { 1778 TRACE("(GLuint index = %d, GLuint divisor = %d)", index, divisor); 1779 1780 es2::Context *context = es2::getContext(); 1781 1782 if(context) 1783 { 1784 if(index >= MAX_VERTEX_ATTRIBS) 1785 { 1786 return error(GL_INVALID_VALUE); 1787 } 1788 1789 context->setVertexAttribDivisor(index, divisor); 1790 } 1791 } 1792 1793 void Enable(GLenum cap) 1794 { 1795 TRACE("(GLenum cap = 0x%X)", cap); 1796 1797 es2::Context *context = es2::getContext(); 1798 1799 if(context) 1800 { 1801 switch(cap) 1802 { 1803 case GL_CULL_FACE: context->setCullFaceEnabled(true); break; 1804 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFillEnabled(true); break; 1805 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverageEnabled(true); break; 1806 case GL_SAMPLE_COVERAGE: context->setSampleCoverageEnabled(true); break; 1807 case GL_SCISSOR_TEST: context->setScissorTestEnabled(true); break; 1808 case GL_STENCIL_TEST: context->setStencilTestEnabled(true); break; 1809 case GL_DEPTH_TEST: context->setDepthTestEnabled(true); break; 1810 case GL_BLEND: context->setBlendEnabled(true); break; 1811 case GL_DITHER: context->setDitherEnabled(true); break; 1812 case GL_PRIMITIVE_RESTART_FIXED_INDEX: context->setPrimitiveRestartFixedIndexEnabled(true); break; 1813 case GL_RASTERIZER_DISCARD: context->setRasterizerDiscardEnabled(true); break; 1814 default: 1815 return error(GL_INVALID_ENUM); 1816 } 1817 } 1818 } 1819 1820 void EnableVertexAttribArray(GLuint index) 1821 { 1822 TRACE("(GLuint index = %d)", index); 1823 1824 if(index >= es2::MAX_VERTEX_ATTRIBS) 1825 { 1826 return error(GL_INVALID_VALUE); 1827 } 1828 1829 es2::Context *context = es2::getContext(); 1830 1831 if(context) 1832 { 1833 context->setVertexAttribArrayEnabled(index, true); 1834 } 1835 } 1836 1837 void EndQueryEXT(GLenum target) 1838 { 1839 TRACE("GLenum target = 0x%X)", target); 1840 1841 switch(target) 1842 { 1843 case GL_ANY_SAMPLES_PASSED_EXT: 1844 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT: 1845 break; 1846 default: 1847 return error(GL_INVALID_ENUM); 1848 } 1849 1850 es2::Context *context = es2::getContext(); 1851 1852 if(context) 1853 { 1854 context->endQuery(target); 1855 } 1856 } 1857 1858 void FinishFenceNV(GLuint fence) 1859 { 1860 TRACE("(GLuint fence = %d)", fence); 1861 1862 es2::Context *context = es2::getContext(); 1863 1864 if(context) 1865 { 1866 es2::Fence *fenceObject = context->getFence(fence); 1867 1868 if(!fenceObject) 1869 { 1870 return error(GL_INVALID_OPERATION); 1871 } 1872 1873 fenceObject->finishFence(); 1874 } 1875 } 1876 1877 void Finish(void) 1878 { 1879 TRACE("()"); 1880 1881 es2::Context *context = es2::getContext(); 1882 1883 if(context) 1884 { 1885 context->finish(); 1886 } 1887 } 1888 1889 void Flush(void) 1890 { 1891 TRACE("()"); 1892 1893 es2::Context *context = es2::getContext(); 1894 1895 if(context) 1896 { 1897 context->flush(); 1898 } 1899 } 1900 1901 void FramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) 1902 { 1903 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, " 1904 "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer); 1905 1906 if((target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER && target != GL_READ_FRAMEBUFFER) || 1907 (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0)) 1908 { 1909 return error(GL_INVALID_ENUM); 1910 } 1911 1912 es2::Context *context = es2::getContext(); 1913 1914 if(context) 1915 { 1916 es2::Framebuffer *framebuffer = nullptr; 1917 GLuint framebufferName = 0; 1918 if(target == GL_READ_FRAMEBUFFER) 1919 { 1920 framebuffer = context->getReadFramebuffer(); 1921 framebufferName = context->getReadFramebufferName(); 1922 } 1923 else 1924 { 1925 framebuffer = context->getDrawFramebuffer(); 1926 framebufferName = context->getDrawFramebufferName(); 1927 } 1928 1929 if(!framebuffer || framebufferName == 0) 1930 { 1931 return error(GL_INVALID_OPERATION); 1932 } 1933 1934 // [OpenGL ES 2.0.25] Section 4.4.3 page 112 1935 // [OpenGL ES 3.0.2] Section 4.4.2 page 201 1936 // 'renderbuffer' must be either zero or the name of an existing renderbuffer object of 1937 // type 'renderbuffertarget', otherwise an INVALID_OPERATION error is generated. 1938 if(renderbuffer != 0) 1939 { 1940 if(!context->getRenderbuffer(renderbuffer)) 1941 { 1942 return error(GL_INVALID_OPERATION); 1943 } 1944 } 1945 1946 GLint clientVersion = context->getClientVersion(); 1947 1948 switch(attachment) 1949 { 1950 case GL_COLOR_ATTACHMENT0: 1951 case GL_COLOR_ATTACHMENT1: 1952 case GL_COLOR_ATTACHMENT2: 1953 case GL_COLOR_ATTACHMENT3: 1954 case GL_COLOR_ATTACHMENT4: 1955 case GL_COLOR_ATTACHMENT5: 1956 case GL_COLOR_ATTACHMENT6: 1957 case GL_COLOR_ATTACHMENT7: 1958 case GL_COLOR_ATTACHMENT8: 1959 case GL_COLOR_ATTACHMENT9: 1960 case GL_COLOR_ATTACHMENT10: 1961 case GL_COLOR_ATTACHMENT11: 1962 case GL_COLOR_ATTACHMENT12: 1963 case GL_COLOR_ATTACHMENT13: 1964 case GL_COLOR_ATTACHMENT14: 1965 case GL_COLOR_ATTACHMENT15: 1966 case GL_COLOR_ATTACHMENT16: 1967 case GL_COLOR_ATTACHMENT17: 1968 case GL_COLOR_ATTACHMENT18: 1969 case GL_COLOR_ATTACHMENT19: 1970 case GL_COLOR_ATTACHMENT20: 1971 case GL_COLOR_ATTACHMENT21: 1972 case GL_COLOR_ATTACHMENT22: 1973 case GL_COLOR_ATTACHMENT23: 1974 case GL_COLOR_ATTACHMENT24: 1975 case GL_COLOR_ATTACHMENT25: 1976 case GL_COLOR_ATTACHMENT26: 1977 case GL_COLOR_ATTACHMENT27: 1978 case GL_COLOR_ATTACHMENT28: 1979 case GL_COLOR_ATTACHMENT29: 1980 case GL_COLOR_ATTACHMENT30: 1981 case GL_COLOR_ATTACHMENT31: 1982 if((attachment - GL_COLOR_ATTACHMENT0) >= MAX_COLOR_ATTACHMENTS) 1983 { 1984 return error(GL_INVALID_ENUM); 1985 } 1986 framebuffer->setColorbuffer(GL_RENDERBUFFER, renderbuffer, attachment - GL_COLOR_ATTACHMENT0); 1987 break; 1988 case GL_DEPTH_ATTACHMENT: 1989 framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer); 1990 break; 1991 case GL_STENCIL_ATTACHMENT: 1992 framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer); 1993 break; 1994 case GL_DEPTH_STENCIL_ATTACHMENT: 1995 if(clientVersion >= 3) 1996 { 1997 framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer); 1998 framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer); 1999 break; 2000 } 2001 else return error(GL_INVALID_ENUM); 2002 default: 2003 return error(GL_INVALID_ENUM); 2004 } 2005 } 2006 } 2007 2008 void FramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) 2009 { 2010 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, " 2011 "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level); 2012 2013 if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER && target != GL_READ_FRAMEBUFFER) 2014 { 2015 return error(GL_INVALID_ENUM); 2016 } 2017 2018 es2::Context *context = es2::getContext(); 2019 2020 if(context) 2021 { 2022 GLint clientVersion = context->getClientVersion(); 2023 2024 if(texture == 0) 2025 { 2026 textarget = GL_NONE; 2027 } 2028 else 2029 { 2030 es2::Texture *tex = context->getTexture(texture); 2031 2032 if(!tex) 2033 { 2034 return error(GL_INVALID_OPERATION); 2035 } 2036 2037 switch(textarget) 2038 { 2039 case GL_TEXTURE_2D: 2040 if(tex->getTarget() != GL_TEXTURE_2D) 2041 { 2042 return error(GL_INVALID_OPERATION); 2043 } 2044 break; 2045 case GL_TEXTURE_RECTANGLE_ARB: 2046 if(tex->getTarget() != GL_TEXTURE_RECTANGLE_ARB) 2047 { 2048 return error(GL_INVALID_OPERATION); 2049 } 2050 break; 2051 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 2052 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 2053 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 2054 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 2055 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 2056 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 2057 if(tex->getTarget() != GL_TEXTURE_CUBE_MAP) 2058 { 2059 return error(GL_INVALID_OPERATION); 2060 } 2061 break; 2062 default: 2063 return error(GL_INVALID_ENUM); 2064 } 2065 2066 if((level != 0) && ((clientVersion < 3) || (textarget == GL_TEXTURE_RECTANGLE_ARB))) 2067 { 2068 return error(GL_INVALID_VALUE); 2069 } 2070 2071 if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)) 2072 { 2073 return error(GL_INVALID_VALUE); 2074 } 2075 2076 if(tex->isCompressed(textarget, level)) 2077 { 2078 return error(GL_INVALID_OPERATION); 2079 } 2080 } 2081 2082 es2::Framebuffer *framebuffer = nullptr; 2083 GLuint framebufferName = 0; 2084 if(target == GL_READ_FRAMEBUFFER) 2085 { 2086 framebuffer = context->getReadFramebuffer(); 2087 framebufferName = context->getReadFramebufferName(); 2088 } 2089 else 2090 { 2091 framebuffer = context->getDrawFramebuffer(); 2092 framebufferName = context->getDrawFramebufferName(); 2093 } 2094 2095 if(framebufferName == 0 || !framebuffer) 2096 { 2097 return error(GL_INVALID_OPERATION); 2098 } 2099 2100 switch(attachment) 2101 { 2102 case GL_COLOR_ATTACHMENT0: 2103 case GL_COLOR_ATTACHMENT1: 2104 case GL_COLOR_ATTACHMENT2: 2105 case GL_COLOR_ATTACHMENT3: 2106 case GL_COLOR_ATTACHMENT4: 2107 case GL_COLOR_ATTACHMENT5: 2108 case GL_COLOR_ATTACHMENT6: 2109 case GL_COLOR_ATTACHMENT7: 2110 case GL_COLOR_ATTACHMENT8: 2111 case GL_COLOR_ATTACHMENT9: 2112 case GL_COLOR_ATTACHMENT10: 2113 case GL_COLOR_ATTACHMENT11: 2114 case GL_COLOR_ATTACHMENT12: 2115 case GL_COLOR_ATTACHMENT13: 2116 case GL_COLOR_ATTACHMENT14: 2117 case GL_COLOR_ATTACHMENT15: 2118 case GL_COLOR_ATTACHMENT16: 2119 case GL_COLOR_ATTACHMENT17: 2120 case GL_COLOR_ATTACHMENT18: 2121 case GL_COLOR_ATTACHMENT19: 2122 case GL_COLOR_ATTACHMENT20: 2123 case GL_COLOR_ATTACHMENT21: 2124 case GL_COLOR_ATTACHMENT22: 2125 case GL_COLOR_ATTACHMENT23: 2126 case GL_COLOR_ATTACHMENT24: 2127 case GL_COLOR_ATTACHMENT25: 2128 case GL_COLOR_ATTACHMENT26: 2129 case GL_COLOR_ATTACHMENT27: 2130 case GL_COLOR_ATTACHMENT28: 2131 case GL_COLOR_ATTACHMENT29: 2132 case GL_COLOR_ATTACHMENT30: 2133 case GL_COLOR_ATTACHMENT31: 2134 if((attachment - GL_COLOR_ATTACHMENT0) >= MAX_COLOR_ATTACHMENTS) 2135 { 2136 return error(GL_INVALID_ENUM); 2137 } 2138 framebuffer->setColorbuffer(textarget, texture, attachment - GL_COLOR_ATTACHMENT0, level); 2139 break; 2140 case GL_DEPTH_ATTACHMENT: framebuffer->setDepthbuffer(textarget, texture, level); break; 2141 case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture, level); break; 2142 case GL_DEPTH_STENCIL_ATTACHMENT: 2143 if(clientVersion >= 3) 2144 { 2145 framebuffer->setDepthbuffer(textarget, texture, level); 2146 framebuffer->setStencilbuffer(textarget, texture, level); 2147 break; 2148 } 2149 else return error(GL_INVALID_ENUM); 2150 default: 2151 return error(GL_INVALID_ENUM); 2152 } 2153 } 2154 } 2155 2156 void FrontFace(GLenum mode) 2157 { 2158 TRACE("(GLenum mode = 0x%X)", mode); 2159 2160 switch(mode) 2161 { 2162 case GL_CW: 2163 case GL_CCW: 2164 { 2165 es2::Context *context = es2::getContext(); 2166 2167 if(context) 2168 { 2169 context->setFrontFace(mode); 2170 } 2171 } 2172 break; 2173 default: 2174 return error(GL_INVALID_ENUM); 2175 } 2176 } 2177 2178 void GenBuffers(GLsizei n, GLuint* buffers) 2179 { 2180 TRACE("(GLsizei n = %d, GLuint* buffers = %p)", n, buffers); 2181 2182 if(n < 0) 2183 { 2184 return error(GL_INVALID_VALUE); 2185 } 2186 2187 es2::Context *context = es2::getContext(); 2188 2189 if(context) 2190 { 2191 for(int i = 0; i < n; i++) 2192 { 2193 buffers[i] = context->createBuffer(); 2194 } 2195 } 2196 } 2197 2198 void GenerateMipmap(GLenum target) 2199 { 2200 TRACE("(GLenum target = 0x%X)", target); 2201 2202 es2::Context *context = es2::getContext(); 2203 2204 if(context) 2205 { 2206 es2::Texture *texture = nullptr; 2207 2208 GLint clientVersion = context->getClientVersion(); 2209 2210 switch(target) 2211 { 2212 case GL_TEXTURE_2D: 2213 texture = context->getTexture2D(); 2214 break; 2215 case GL_TEXTURE_CUBE_MAP: 2216 { 2217 TextureCubeMap *cube = context->getTextureCubeMap(); 2218 texture = cube; 2219 2220 if(!cube->isCubeComplete()) 2221 { 2222 return error(GL_INVALID_OPERATION); 2223 } 2224 } 2225 break; 2226 case GL_TEXTURE_2D_ARRAY: 2227 if(clientVersion < 3) 2228 { 2229 return error(GL_INVALID_ENUM); 2230 } 2231 else 2232 { 2233 texture = context->getTexture2DArray(); 2234 } 2235 break; 2236 case GL_TEXTURE_3D: 2237 texture = context->getTexture3D(); 2238 break; 2239 case GL_TEXTURE_RECTANGLE_ARB: 2240 texture = context->getTexture2DRect(); 2241 break; 2242 default: 2243 return error(GL_INVALID_ENUM); 2244 } 2245 2246 if(!IsMipmappable(texture->getFormat(target, texture->getBaseLevel()), clientVersion)) 2247 { 2248 return error(GL_INVALID_OPERATION); 2249 } 2250 2251 texture->generateMipmaps(); 2252 } 2253 } 2254 2255 void GenFencesNV(GLsizei n, GLuint* fences) 2256 { 2257 TRACE("(GLsizei n = %d, GLuint* fences = %p)", n, fences); 2258 2259 if(n < 0) 2260 { 2261 return error(GL_INVALID_VALUE); 2262 } 2263 2264 es2::Context *context = es2::getContext(); 2265 2266 if(context) 2267 { 2268 for(int i = 0; i < n; i++) 2269 { 2270 fences[i] = context->createFence(); 2271 } 2272 } 2273 } 2274 2275 void GenFramebuffers(GLsizei n, GLuint* framebuffers) 2276 { 2277 TRACE("(GLsizei n = %d, GLuint* framebuffers = %p)", n, framebuffers); 2278 2279 if(n < 0) 2280 { 2281 return error(GL_INVALID_VALUE); 2282 } 2283 2284 es2::Context *context = es2::getContext(); 2285 2286 if(context) 2287 { 2288 for(int i = 0; i < n; i++) 2289 { 2290 framebuffers[i] = context->createFramebuffer(); 2291 } 2292 } 2293 } 2294 2295 void GenQueriesEXT(GLsizei n, GLuint* ids) 2296 { 2297 TRACE("(GLsizei n = %d, GLuint* ids = %p)", n, ids); 2298 2299 if(n < 0) 2300 { 2301 return error(GL_INVALID_VALUE); 2302 } 2303 2304 es2::Context *context = es2::getContext(); 2305 2306 if(context) 2307 { 2308 for(int i = 0; i < n; i++) 2309 { 2310 ids[i] = context->createQuery(); 2311 } 2312 } 2313 } 2314 2315 void GenRenderbuffers(GLsizei n, GLuint* renderbuffers) 2316 { 2317 TRACE("(GLsizei n = %d, GLuint* renderbuffers = %p)", n, renderbuffers); 2318 2319 if(n < 0) 2320 { 2321 return error(GL_INVALID_VALUE); 2322 } 2323 2324 es2::Context *context = es2::getContext(); 2325 2326 if(context) 2327 { 2328 for(int i = 0; i < n; i++) 2329 { 2330 renderbuffers[i] = context->createRenderbuffer(); 2331 } 2332 } 2333 } 2334 2335 void GenTextures(GLsizei n, GLuint* textures) 2336 { 2337 TRACE("(GLsizei n = %d, GLuint* textures = %p)", n, textures); 2338 2339 if(n < 0) 2340 { 2341 return error(GL_INVALID_VALUE); 2342 } 2343 2344 es2::Context *context = es2::getContext(); 2345 2346 if(context) 2347 { 2348 for(int i = 0; i < n; i++) 2349 { 2350 textures[i] = context->createTexture(); 2351 } 2352 } 2353 } 2354 2355 void GetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) 2356 { 2357 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei *length = %p, " 2358 "GLint *size = %p, GLenum *type = %p, GLchar *name = %p)", 2359 program, index, bufsize, length, size, type, name); 2360 2361 if(bufsize < 0) 2362 { 2363 return error(GL_INVALID_VALUE); 2364 } 2365 2366 es2::Context *context = es2::getContext(); 2367 2368 if(context) 2369 { 2370 es2::Program *programObject = context->getProgram(program); 2371 2372 if(!programObject) 2373 { 2374 if(context->getShader(program)) 2375 { 2376 return error(GL_INVALID_OPERATION); 2377 } 2378 else 2379 { 2380 return error(GL_INVALID_VALUE); 2381 } 2382 } 2383 2384 if(index >= programObject->getActiveAttributeCount()) 2385 { 2386 return error(GL_INVALID_VALUE); 2387 } 2388 2389 programObject->getActiveAttribute(index, bufsize, length, size, type, name); 2390 } 2391 } 2392 2393 void GetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name) 2394 { 2395 TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, " 2396 "GLsizei* length = %p, GLint* size = %p, GLenum* type = %p, GLchar* name = %s)", 2397 program, index, bufsize, length, size, type, name); 2398 2399 if(bufsize < 0) 2400 { 2401 return error(GL_INVALID_VALUE); 2402 } 2403 2404 es2::Context *context = es2::getContext(); 2405 2406 if(context) 2407 { 2408 es2::Program *programObject = context->getProgram(program); 2409 2410 if(!programObject) 2411 { 2412 if(context->getShader(program)) 2413 { 2414 return error(GL_INVALID_OPERATION); 2415 } 2416 else 2417 { 2418 return error(GL_INVALID_VALUE); 2419 } 2420 } 2421 2422 if(index >= programObject->getActiveUniformCount()) 2423 { 2424 return error(GL_INVALID_VALUE); 2425 } 2426 2427 programObject->getActiveUniform(index, bufsize, length, size, type, name); 2428 } 2429 } 2430 2431 void GetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders) 2432 { 2433 TRACE("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = %p, GLuint* shaders = %p)", 2434 program, maxcount, count, shaders); 2435 2436 if(maxcount < 0) 2437 { 2438 return error(GL_INVALID_VALUE); 2439 } 2440 2441 es2::Context *context = es2::getContext(); 2442 2443 if(context) 2444 { 2445 es2::Program *programObject = context->getProgram(program); 2446 2447 if(!programObject) 2448 { 2449 if(context->getShader(program)) 2450 { 2451 return error(GL_INVALID_OPERATION); 2452 } 2453 else 2454 { 2455 return error(GL_INVALID_VALUE); 2456 } 2457 } 2458 2459 return programObject->getAttachedShaders(maxcount, count, shaders); 2460 } 2461 } 2462 2463 int GetAttribLocation(GLuint program, const GLchar* name) 2464 { 2465 TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name); 2466 2467 es2::Context *context = es2::getContext(); 2468 2469 if(context) 2470 { 2471 2472 es2::Program *programObject = context->getProgram(program); 2473 2474 if(!programObject) 2475 { 2476 if(context->getShader(program)) 2477 { 2478 return error(GL_INVALID_OPERATION, -1); 2479 } 2480 else 2481 { 2482 return error(GL_INVALID_VALUE, -1); 2483 } 2484 } 2485 2486 if(!programObject->isLinked()) 2487 { 2488 return error(GL_INVALID_OPERATION, -1); 2489 } 2490 2491 return programObject->getAttributeLocation(name); 2492 } 2493 2494 return -1; 2495 } 2496 2497 void GetBooleanv(GLenum pname, GLboolean* params) 2498 { 2499 TRACE("(GLenum pname = 0x%X, GLboolean* params = %p)", pname, params); 2500 2501 es2::Context *context = es2::getContext(); 2502 2503 if(context) 2504 { 2505 if(!(context->getBooleanv(pname, params))) 2506 { 2507 GLenum nativeType; 2508 unsigned int numParams = 0; 2509 if(!context->getQueryParameterInfo(pname, &nativeType, &numParams)) 2510 return error(GL_INVALID_ENUM); 2511 2512 if(numParams == 0) 2513 return; // it is known that the pname is valid, but there are no parameters to return 2514 2515 if(nativeType == GL_FLOAT) 2516 { 2517 GLfloat *floatParams = nullptr; 2518 floatParams = new GLfloat[numParams]; 2519 2520 context->getFloatv(pname, floatParams); 2521 2522 for(unsigned int i = 0; i < numParams; ++i) 2523 { 2524 if(floatParams[i] == 0.0f) 2525 params[i] = GL_FALSE; 2526 else 2527 params[i] = GL_TRUE; 2528 } 2529 2530 delete [] floatParams; 2531 } 2532 else if(nativeType == GL_INT) 2533 { 2534 GLint *intParams = nullptr; 2535 intParams = new GLint[numParams]; 2536 2537 context->getIntegerv(pname, intParams); 2538 2539 for(unsigned int i = 0; i < numParams; ++i) 2540 { 2541 if(intParams[i] == 0) 2542 params[i] = GL_FALSE; 2543 else 2544 params[i] = GL_TRUE; 2545 } 2546 2547 delete [] intParams; 2548 } 2549 } 2550 } 2551 } 2552 2553 void GetBufferParameteriv(GLenum target, GLenum pname, GLint* params) 2554 { 2555 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", target, pname, params); 2556 2557 es2::Context *context = es2::getContext(); 2558 2559 if(context) 2560 { 2561 es2::Buffer *buffer; 2562 if(!context->getBuffer(target, &buffer)) 2563 { 2564 return error(GL_INVALID_ENUM); 2565 } 2566 2567 if(!buffer) 2568 { 2569 // A null buffer means that "0" is bound to the requested buffer target 2570 return error(GL_INVALID_OPERATION); 2571 } 2572 2573 GLint clientVersion = context->getClientVersion(); 2574 2575 switch(pname) 2576 { 2577 case GL_BUFFER_USAGE: 2578 *params = buffer->usage(); 2579 break; 2580 case GL_BUFFER_SIZE: 2581 *params = (GLint)buffer->size(); 2582 break; 2583 case GL_BUFFER_ACCESS_FLAGS: 2584 if(clientVersion >= 3) 2585 { 2586 *params = buffer->access(); 2587 break; 2588 } 2589 else return error(GL_INVALID_ENUM); 2590 case GL_BUFFER_MAPPED: 2591 if(clientVersion >= 3) 2592 { 2593 *params = buffer->isMapped(); 2594 break; 2595 } 2596 else return error(GL_INVALID_ENUM); 2597 case GL_BUFFER_MAP_LENGTH: 2598 if(clientVersion >= 3) 2599 { 2600 *params = (GLint)buffer->length(); 2601 break; 2602 } 2603 else return error(GL_INVALID_ENUM); 2604 case GL_BUFFER_MAP_OFFSET: 2605 if(clientVersion >= 3) 2606 { 2607 *params = (GLint)buffer->offset(); 2608 break; 2609 } 2610 else return error(GL_INVALID_ENUM); 2611 default: 2612 return error(GL_INVALID_ENUM); 2613 } 2614 } 2615 } 2616 2617 GLenum GetError(void) 2618 { 2619 TRACE("()"); 2620 2621 es2::Context *context = es2::getContext(); 2622 2623 if(context) 2624 { 2625 return context->getError(); 2626 } 2627 2628 return GL_NO_ERROR; 2629 } 2630 2631 void GetFenceivNV(GLuint fence, GLenum pname, GLint *params) 2632 { 2633 TRACE("(GLuint fence = %d, GLenum pname = 0x%X, GLint *params = %p)", fence, pname, params); 2634 2635 es2::Context *context = es2::getContext(); 2636 2637 if(context) 2638 { 2639 es2::Fence *fenceObject = context->getFence(fence); 2640 2641 if(!fenceObject) 2642 { 2643 return error(GL_INVALID_OPERATION); 2644 } 2645 2646 fenceObject->getFenceiv(pname, params); 2647 } 2648 } 2649 2650 void GetFloatv(GLenum pname, GLfloat* params) 2651 { 2652 TRACE("(GLenum pname = 0x%X, GLfloat* params = %p)", pname, params); 2653 2654 es2::Context *context = es2::getContext(); 2655 2656 if(context) 2657 { 2658 if(!(context->getFloatv(pname, params))) 2659 { 2660 GLenum nativeType; 2661 unsigned int numParams = 0; 2662 if(!context->getQueryParameterInfo(pname, &nativeType, &numParams)) 2663 return error(GL_INVALID_ENUM); 2664 2665 if(numParams == 0) 2666 return; // it is known that the pname is valid, but that there are no parameters to return. 2667 2668 if(nativeType == GL_BOOL) 2669 { 2670 GLboolean *boolParams = nullptr; 2671 boolParams = new GLboolean[numParams]; 2672 2673 context->getBooleanv(pname, boolParams); 2674 2675 for(unsigned int i = 0; i < numParams; ++i) 2676 { 2677 if(boolParams[i] == GL_FALSE) 2678 params[i] = 0.0f; 2679 else 2680 params[i] = 1.0f; 2681 } 2682 2683 delete [] boolParams; 2684 } 2685 else if(nativeType == GL_INT) 2686 { 2687 GLint *intParams = nullptr; 2688 intParams = new GLint[numParams]; 2689 2690 context->getIntegerv(pname, intParams); 2691 2692 for(unsigned int i = 0; i < numParams; ++i) 2693 { 2694 params[i] = (GLfloat)intParams[i]; 2695 } 2696 2697 delete [] intParams; 2698 } 2699 } 2700 } 2701 } 2702 2703 void GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params) 2704 { 2705 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", 2706 target, attachment, pname, params); 2707 2708 es2::Context *context = es2::getContext(); 2709 2710 if(context) 2711 { 2712 if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER && target != GL_READ_FRAMEBUFFER) 2713 { 2714 return error(GL_INVALID_ENUM); 2715 } 2716 2717 GLuint framebufferName = 0; 2718 2719 if(target == GL_READ_FRAMEBUFFER) 2720 { 2721 framebufferName = context->getReadFramebufferName(); 2722 } 2723 else 2724 { 2725 framebufferName = context->getDrawFramebufferName(); 2726 } 2727 2728 GLint clientVersion = context->getClientVersion(); 2729 2730 if(framebufferName == 0) // Default framebuffer. 2731 { 2732 if(clientVersion < 3) 2733 { 2734 return error(GL_INVALID_OPERATION); 2735 } 2736 } 2737 2738 switch(attachment) 2739 { 2740 case GL_BACK: 2741 case GL_DEPTH: 2742 case GL_STENCIL: 2743 if(clientVersion < 3) 2744 { 2745 return error(GL_INVALID_ENUM); 2746 } 2747 2748 if(framebufferName != 0) 2749 { 2750 return error(GL_INVALID_OPERATION); 2751 } 2752 break; 2753 case GL_DEPTH_ATTACHMENT: 2754 case GL_STENCIL_ATTACHMENT: 2755 if(framebufferName == 0) 2756 { 2757 return error(GL_INVALID_OPERATION); 2758 } 2759 break; 2760 case GL_DEPTH_STENCIL_ATTACHMENT: 2761 if(clientVersion < 3) 2762 { 2763 return error(GL_INVALID_ENUM); 2764 } 2765 2766 if(framebufferName == 0) 2767 { 2768 return error(GL_INVALID_OPERATION); 2769 } 2770 break; 2771 default: 2772 if((unsigned int)(attachment - GL_COLOR_ATTACHMENT0) < MAX_COLOR_ATTACHMENTS) 2773 { 2774 if(framebufferName == 0) 2775 { 2776 return error(GL_INVALID_OPERATION); 2777 } 2778 } 2779 else return error(GL_INVALID_ENUM); 2780 } 2781 2782 es2::Framebuffer *framebuffer = context->getFramebuffer(framebufferName); 2783 2784 if(!framebuffer) 2785 { 2786 return error(GL_INVALID_OPERATION); 2787 } 2788 2789 GLenum attachmentType; 2790 GLuint attachmentHandle; 2791 GLint attachmentLayer; 2792 Renderbuffer *renderbuffer = nullptr; 2793 switch(attachment) 2794 { 2795 case GL_BACK: 2796 attachmentType = framebuffer->getColorbufferType(0); 2797 attachmentHandle = framebuffer->getColorbufferName(0); 2798 attachmentLayer = framebuffer->getColorbufferLayer(0); 2799 renderbuffer = framebuffer->getColorbuffer(0); 2800 break; 2801 case GL_DEPTH: 2802 case GL_DEPTH_ATTACHMENT: 2803 attachmentType = framebuffer->getDepthbufferType(); 2804 attachmentHandle = framebuffer->getDepthbufferName(); 2805 attachmentLayer = framebuffer->getDepthbufferLayer(); 2806 renderbuffer = framebuffer->getDepthbuffer(); 2807 break; 2808 case GL_STENCIL: 2809 case GL_STENCIL_ATTACHMENT: 2810 attachmentType = framebuffer->getStencilbufferType(); 2811 attachmentHandle = framebuffer->getStencilbufferName(); 2812 attachmentLayer = framebuffer->getStencilbufferLayer(); 2813 renderbuffer = framebuffer->getStencilbuffer(); 2814 break; 2815 case GL_DEPTH_STENCIL_ATTACHMENT: 2816 attachmentType = framebuffer->getDepthbufferType(); 2817 attachmentHandle = framebuffer->getDepthbufferName(); 2818 attachmentLayer = framebuffer->getDepthbufferLayer(); 2819 renderbuffer = framebuffer->getDepthbuffer(); 2820 2821 if(attachmentHandle != framebuffer->getStencilbufferName()) 2822 { 2823 // Different attachments to DEPTH and STENCIL, query fails 2824 return error(GL_INVALID_OPERATION); 2825 } 2826 break; 2827 default: 2828 ASSERT((unsigned int)(attachment - GL_COLOR_ATTACHMENT0) < MAX_COLOR_ATTACHMENTS); 2829 attachmentType = framebuffer->getColorbufferType(attachment - GL_COLOR_ATTACHMENT0); 2830 attachmentHandle = framebuffer->getColorbufferName(attachment - GL_COLOR_ATTACHMENT0); 2831 attachmentLayer = framebuffer->getColorbufferLayer(attachment - GL_COLOR_ATTACHMENT0); 2832 renderbuffer = framebuffer->getColorbuffer(attachment - GL_COLOR_ATTACHMENT0); 2833 break; 2834 } 2835 2836 GLenum attachmentObjectType = GL_NONE; // Type category 2837 if(framebufferName == 0) 2838 { 2839 attachmentObjectType = GL_FRAMEBUFFER_DEFAULT; 2840 } 2841 else if(attachmentType == GL_NONE || Framebuffer::IsRenderbuffer(attachmentType)) 2842 { 2843 attachmentObjectType = attachmentType; 2844 } 2845 else if(es2::IsTextureTarget(attachmentType)) 2846 { 2847 attachmentObjectType = GL_TEXTURE; 2848 } 2849 else UNREACHABLE(attachmentType); 2850 2851 if(attachmentObjectType != GL_NONE) 2852 { 2853 switch(pname) 2854 { 2855 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE: 2856 *params = attachmentObjectType; 2857 break; 2858 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: 2859 if(attachmentObjectType == GL_RENDERBUFFER || attachmentObjectType == GL_TEXTURE) 2860 { 2861 *params = attachmentHandle; 2862 } 2863 else 2864 { 2865 return error(GL_INVALID_ENUM); 2866 } 2867 break; 2868 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL: 2869 if(attachmentObjectType == GL_TEXTURE) 2870 { 2871 *params = clientVersion < 3 ? 0 : renderbuffer->getLevel(); // glFramebufferTexture2D does not allow level to be set to anything else in GL ES 2.0 2872 } 2873 else 2874 { 2875 return error(GL_INVALID_ENUM); 2876 } 2877 break; 2878 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE: 2879 if(attachmentObjectType == GL_TEXTURE) 2880 { 2881 if(es2::IsCubemapTextureTarget(attachmentType)) 2882 { 2883 *params = attachmentType; 2884 } 2885 else 2886 { 2887 *params = 0; 2888 } 2889 } 2890 else 2891 { 2892 return error(GL_INVALID_ENUM); 2893 } 2894 break; 2895 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER: 2896 if(clientVersion >= 3) 2897 { 2898 *params = attachmentLayer; 2899 } 2900 else return error(GL_INVALID_ENUM); 2901 break; 2902 case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE: 2903 if(clientVersion >= 3) 2904 { 2905 *params = renderbuffer->getRedSize(); 2906 } 2907 else return error(GL_INVALID_ENUM); 2908 break; 2909 case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE: 2910 if(clientVersion >= 3) 2911 { 2912 *params = renderbuffer->getGreenSize(); 2913 } 2914 else return error(GL_INVALID_ENUM); 2915 break; 2916 case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE: 2917 if(clientVersion >= 3) 2918 { 2919 *params = renderbuffer->getBlueSize(); 2920 } 2921 else return error(GL_INVALID_ENUM); 2922 break; 2923 case GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE: 2924 if(clientVersion >= 3) 2925 { 2926 *params = renderbuffer->getAlphaSize(); 2927 } 2928 else return error(GL_INVALID_ENUM); 2929 break; 2930 case GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE: 2931 if(clientVersion >= 3) 2932 { 2933 *params = renderbuffer->getDepthSize(); 2934 } 2935 else return error(GL_INVALID_ENUM); 2936 break; 2937 case GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE: 2938 if(clientVersion >= 3) 2939 { 2940 *params = renderbuffer->getStencilSize(); 2941 } 2942 else return error(GL_INVALID_ENUM); 2943 break; 2944 case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE: 2945 // case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT: // GL_EXT_color_buffer_half_float 2946 if(attachment == GL_DEPTH_STENCIL_ATTACHMENT) 2947 { 2948 return error(GL_INVALID_OPERATION); 2949 } 2950 2951 *params = GetComponentType(renderbuffer->getFormat(), attachment); 2952 break; 2953 case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING: 2954 if(clientVersion >= 3) 2955 { 2956 *params = GetColorEncoding(renderbuffer->getFormat()); 2957 } 2958 else return error(GL_INVALID_ENUM); 2959 break; 2960 default: 2961 return error(GL_INVALID_ENUM); 2962 } 2963 } 2964 else 2965 { 2966 // ES 2.0.25 spec pg 127 states that if the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 2967 // is NONE, then querying any other pname will generate INVALID_ENUM. 2968 2969 // ES 3.0.2 spec pg 235 states that if the attachment type is none, 2970 // GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME will return zero and be an 2971 // INVALID_OPERATION for all other pnames 2972 2973 switch(pname) 2974 { 2975 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE: 2976 *params = GL_NONE; 2977 break; 2978 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: 2979 if(clientVersion < 3) 2980 { 2981 return error(GL_INVALID_ENUM); 2982 } 2983 *params = 0; 2984 break; 2985 default: 2986 if(clientVersion < 3) 2987 { 2988 return error(GL_INVALID_ENUM); 2989 } 2990 else 2991 { 2992 return error(GL_INVALID_OPERATION); 2993 } 2994 } 2995 } 2996 } 2997 } 2998 2999 GLenum GetGraphicsResetStatusEXT(void) 3000 { 3001 TRACE("()"); 3002 3003 return GL_NO_ERROR; 3004 } 3005 3006 void GetIntegerv(GLenum pname, GLint* params) 3007 { 3008 TRACE("(GLenum pname = 0x%X, GLint* params = %p)", pname, params); 3009 3010 es2::Context *context = es2::getContext(); 3011 3012 if(!context) 3013 { 3014 // Not strictly an error, but probably unintended or attempting to rely on non-compliant behavior 3015 #ifdef __ANDROID__ 3016 ALOGI("expected_badness glGetIntegerv() called without current context."); 3017 #else 3018 ERR("glGetIntegerv() called without current context."); 3019 #endif 3020 3021 // This is not spec compliant! When there is no current GL context, functions should 3022 // have no side effects. Google Maps queries these values before creating a context, 3023 // so we need this as a bug-compatible workaround. 3024 switch(pname) 3025 { 3026 case GL_MAX_TEXTURE_SIZE: *params = es2::IMPLEMENTATION_MAX_TEXTURE_SIZE; return; 3027 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = es2::MAX_VERTEX_TEXTURE_IMAGE_UNITS; return; 3028 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = es2::MAX_COMBINED_TEXTURE_IMAGE_UNITS; return; 3029 case GL_STENCIL_BITS: *params = 8; return; 3030 case GL_ALIASED_LINE_WIDTH_RANGE: 3031 params[0] = (GLint)es2::ALIASED_LINE_WIDTH_RANGE_MIN; 3032 params[1] = (GLint)es2::ALIASED_LINE_WIDTH_RANGE_MAX; 3033 return; 3034 } 3035 } 3036 3037 if(context) 3038 { 3039 if(!(context->getIntegerv(pname, params))) 3040 { 3041 GLenum nativeType; 3042 unsigned int numParams = 0; 3043 if(!context->getQueryParameterInfo(pname, &nativeType, &numParams)) 3044 return error(GL_INVALID_ENUM); 3045 3046 if(numParams == 0) 3047 return; // it is known that pname is valid, but there are no parameters to return 3048 3049 if(nativeType == GL_BOOL) 3050 { 3051 GLboolean *boolParams = nullptr; 3052 boolParams = new GLboolean[numParams]; 3053 3054 context->getBooleanv(pname, boolParams); 3055 3056 for(unsigned int i = 0; i < numParams; ++i) 3057 { 3058 params[i] = (boolParams[i] == GL_FALSE) ? 0 : 1; 3059 } 3060 3061 delete [] boolParams; 3062 } 3063 else if(nativeType == GL_FLOAT) 3064 { 3065 GLfloat *floatParams = nullptr; 3066 floatParams = new GLfloat[numParams]; 3067 3068 context->getFloatv(pname, floatParams); 3069 3070 for(unsigned int i = 0; i < numParams; ++i) 3071 { 3072 if(pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE || pname == GL_BLEND_COLOR) 3073 { 3074 params[i] = convert_float_fixed(floatParams[i]); 3075 } 3076 else 3077 { 3078 params[i] = (GLint)(floatParams[i] > 0.0f ? floor(floatParams[i] + 0.5) : ceil(floatParams[i] - 0.5)); 3079 } 3080 } 3081 3082 delete [] floatParams; 3083 } 3084 } 3085 } 3086 } 3087 3088 void GetProgramiv(GLuint program, GLenum pname, GLint* params) 3089 { 3090 TRACE("(GLuint program = %d, GLenum pname = 0x%X, GLint* params = %p)", program, pname, params); 3091 3092 es2::Context *context = es2::getContext(); 3093 3094 if(context) 3095 { 3096 es2::Program *programObject = context->getProgram(program); 3097 3098 if(!programObject) 3099 { 3100 if(context->getShader(program)) 3101 { 3102 return error(GL_INVALID_OPERATION); 3103 } 3104 else 3105 { 3106 return error(GL_INVALID_VALUE); 3107 } 3108 } 3109 3110 GLint clientVersion = egl::getClientVersion(); 3111 3112 switch(pname) 3113 { 3114 case GL_DELETE_STATUS: 3115 *params = programObject->isFlaggedForDeletion(); 3116 return; 3117 case GL_LINK_STATUS: 3118 *params = programObject->isLinked(); 3119 return; 3120 case GL_VALIDATE_STATUS: 3121 *params = programObject->isValidated(); 3122 return; 3123 case GL_INFO_LOG_LENGTH: 3124 *params = (GLint)programObject->getInfoLogLength(); 3125 return; 3126 case GL_ATTACHED_SHADERS: 3127 *params = programObject->getAttachedShadersCount(); 3128 return; 3129 case GL_ACTIVE_ATTRIBUTES: 3130 *params = (GLint)programObject->getActiveAttributeCount(); 3131 return; 3132 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH: 3133 *params = programObject->getActiveAttributeMaxLength(); 3134 return; 3135 case GL_ACTIVE_UNIFORMS: 3136 *params = (GLint)programObject->getActiveUniformCount(); 3137 return; 3138 case GL_ACTIVE_UNIFORM_MAX_LENGTH: 3139 *params = programObject->getActiveUniformMaxLength(); 3140 return; 3141 case GL_ACTIVE_UNIFORM_BLOCKS: 3142 if(clientVersion >= 3) 3143 { 3144 *params = (GLint)programObject->getActiveUniformBlockCount(); 3145 return; 3146 } 3147 else return error(GL_INVALID_ENUM); 3148 case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH: 3149 if(clientVersion >= 3) 3150 { 3151 *params = programObject->getActiveUniformBlockMaxLength(); 3152 return; 3153 } 3154 else return error(GL_INVALID_ENUM); 3155 case GL_TRANSFORM_FEEDBACK_BUFFER_MODE: 3156 if(clientVersion >= 3) 3157 { 3158 *params = programObject->getTransformFeedbackBufferMode(); 3159 return; 3160 } 3161 else return error(GL_INVALID_ENUM); 3162 case GL_TRANSFORM_FEEDBACK_VARYINGS: 3163 if(clientVersion >= 3) 3164 { 3165 *params = programObject->getTransformFeedbackVaryingCount(); 3166 return; 3167 } 3168 else return error(GL_INVALID_ENUM); 3169 case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH: 3170 if(clientVersion >= 3) 3171 { 3172 *params = programObject->getTransformFeedbackVaryingMaxLength(); 3173 return; 3174 } 3175 else return error(GL_INVALID_ENUM); 3176 case GL_PROGRAM_BINARY_RETRIEVABLE_HINT: 3177 if(clientVersion >= 3) 3178 { 3179 *params = programObject->getBinaryRetrievableHint(); 3180 return; 3181 } 3182 else return error(GL_INVALID_ENUM); 3183 case GL_PROGRAM_BINARY_LENGTH: 3184 if(clientVersion >= 3) 3185 { 3186 *params = programObject->getBinaryLength(); 3187 return; 3188 } 3189 else return error(GL_INVALID_ENUM); 3190 default: 3191 return error(GL_INVALID_ENUM); 3192 } 3193 } 3194 } 3195 3196 void GetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog) 3197 { 3198 TRACE("(GLuint program = %d, GLsizei bufsize = %d, GLsizei* length = %p, GLchar* infolog = %p)", 3199 program, bufsize, length, infolog); 3200 3201 if(bufsize < 0) 3202 { 3203 return error(GL_INVALID_VALUE); 3204 } 3205 3206 es2::Context *context = es2::getContext(); 3207 3208 if(context) 3209 { 3210 es2::Program *programObject = context->getProgram(program); 3211 3212 if(!programObject) 3213 { 3214 if(context->getShader(program)) 3215 { 3216 return error(GL_INVALID_OPERATION); 3217 } 3218 else 3219 { 3220 return error(GL_INVALID_VALUE); 3221 } 3222 } 3223 3224 programObject->getInfoLog(bufsize, length, infolog); 3225 } 3226 } 3227 3228 void GetQueryivEXT(GLenum target, GLenum pname, GLint *params) 3229 { 3230 TRACE("GLenum target = 0x%X, GLenum pname = 0x%X, GLint *params = %p)", target, pname, params); 3231 3232 switch(pname) 3233 { 3234 case GL_CURRENT_QUERY_EXT: 3235 break; 3236 default: 3237 return error(GL_INVALID_ENUM); 3238 } 3239 3240 es2::Context *context = es2::getContext(); 3241 3242 if(context) 3243 { 3244 params[0] = context->getActiveQuery(target); 3245 } 3246 } 3247 3248 void GetQueryObjectuivEXT(GLuint name, GLenum pname, GLuint *params) 3249 { 3250 TRACE("(GLuint name = %d, GLenum pname = 0x%X, GLuint *params = %p)", name, pname, params); 3251 3252 switch(pname) 3253 { 3254 case GL_QUERY_RESULT_EXT: 3255 case GL_QUERY_RESULT_AVAILABLE_EXT: 3256 break; 3257 default: 3258 return error(GL_INVALID_ENUM); 3259 } 3260 3261 es2::Context *context = es2::getContext(); 3262 3263 if(context) 3264 { 3265 es2::Query *queryObject = context->getQuery(name); 3266 3267 if(!queryObject) 3268 { 3269 return error(GL_INVALID_OPERATION); 3270 } 3271 3272 if(context->getActiveQuery(queryObject->getType()) == name) 3273 { 3274 return error(GL_INVALID_OPERATION); 3275 } 3276 3277 switch(pname) 3278 { 3279 case GL_QUERY_RESULT_EXT: 3280 params[0] = queryObject->getResult(); 3281 break; 3282 case GL_QUERY_RESULT_AVAILABLE_EXT: 3283 params[0] = queryObject->isResultAvailable(); 3284 break; 3285 default: 3286 ASSERT(false); 3287 } 3288 } 3289 } 3290 3291 void GetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params) 3292 { 3293 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", target, pname, params); 3294 3295 es2::Context *context = es2::getContext(); 3296 3297 if(context) 3298 { 3299 if(target != GL_RENDERBUFFER) 3300 { 3301 return error(GL_INVALID_ENUM); 3302 } 3303 3304 if(context->getRenderbufferName() == 0) 3305 { 3306 return error(GL_INVALID_OPERATION); 3307 } 3308 3309 es2::Renderbuffer *renderbuffer = context->getRenderbuffer(context->getRenderbufferName()); 3310 3311 switch(pname) 3312 { 3313 case GL_RENDERBUFFER_WIDTH: *params = renderbuffer->getWidth(); break; 3314 case GL_RENDERBUFFER_HEIGHT: *params = renderbuffer->getHeight(); break; 3315 case GL_RENDERBUFFER_INTERNAL_FORMAT: 3316 { 3317 GLint internalformat = renderbuffer->getFormat(); 3318 *params = (internalformat == GL_NONE) ? GL_RGBA4 : internalformat; 3319 } 3320 break; 3321 case GL_RENDERBUFFER_RED_SIZE: *params = renderbuffer->getRedSize(); break; 3322 case GL_RENDERBUFFER_GREEN_SIZE: *params = renderbuffer->getGreenSize(); break; 3323 case GL_RENDERBUFFER_BLUE_SIZE: *params = renderbuffer->getBlueSize(); break; 3324 case GL_RENDERBUFFER_ALPHA_SIZE: *params = renderbuffer->getAlphaSize(); break; 3325 case GL_RENDERBUFFER_DEPTH_SIZE: *params = renderbuffer->getDepthSize(); break; 3326 case GL_RENDERBUFFER_STENCIL_SIZE: *params = renderbuffer->getStencilSize(); break; 3327 case GL_RENDERBUFFER_SAMPLES: *params = renderbuffer->getSamples(); break; 3328 default: 3329 return error(GL_INVALID_ENUM); 3330 } 3331 } 3332 } 3333 3334 void GetShaderiv(GLuint shader, GLenum pname, GLint* params) 3335 { 3336 TRACE("(GLuint shader = %d, GLenum pname = %d, GLint* params = %p)", shader, pname, params); 3337 3338 es2::Context *context = es2::getContext(); 3339 3340 if(context) 3341 { 3342 es2::Shader *shaderObject = context->getShader(shader); 3343 3344 if(!shaderObject) 3345 { 3346 if(context->getProgram(shader)) 3347 { 3348 return error(GL_INVALID_OPERATION); 3349 } 3350 else 3351 { 3352 return error(GL_INVALID_VALUE); 3353 } 3354 } 3355 3356 switch(pname) 3357 { 3358 case GL_SHADER_TYPE: 3359 *params = shaderObject->getType(); 3360 return; 3361 case GL_DELETE_STATUS: 3362 *params = shaderObject->isFlaggedForDeletion(); 3363 return; 3364 case GL_COMPILE_STATUS: 3365 *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE; 3366 return; 3367 case GL_INFO_LOG_LENGTH: 3368 *params = (GLint)shaderObject->getInfoLogLength(); 3369 return; 3370 case GL_SHADER_SOURCE_LENGTH: 3371 *params = (GLint)shaderObject->getSourceLength(); 3372 return; 3373 default: 3374 return error(GL_INVALID_ENUM); 3375 } 3376 } 3377 } 3378 3379 void GetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog) 3380 { 3381 TRACE("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = %p, GLchar* infolog = %p)", 3382 shader, bufsize, length, infolog); 3383 3384 if(bufsize < 0) 3385 { 3386 return error(GL_INVALID_VALUE); 3387 } 3388 3389 es2::Context *context = es2::getContext(); 3390 3391 if(context) 3392 { 3393 es2::Shader *shaderObject = context->getShader(shader); 3394 3395 if(!shaderObject) 3396 { 3397 if(context->getProgram(shader)) 3398 { 3399 return error(GL_INVALID_OPERATION); 3400 } 3401 else 3402 { 3403 return error(GL_INVALID_VALUE); 3404 } 3405 } 3406 3407 shaderObject->getInfoLog(bufsize, length, infolog); 3408 } 3409 } 3410 3411 void GetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) 3412 { 3413 TRACE("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = %p, GLint* precision = %p)", 3414 shadertype, precisiontype, range, precision); 3415 3416 switch(shadertype) 3417 { 3418 case GL_VERTEX_SHADER: 3419 case GL_FRAGMENT_SHADER: 3420 break; 3421 default: 3422 return error(GL_INVALID_ENUM); 3423 } 3424 3425 switch(precisiontype) 3426 { 3427 case GL_LOW_FLOAT: 3428 case GL_MEDIUM_FLOAT: 3429 case GL_HIGH_FLOAT: 3430 // IEEE 754 single-precision 3431 range[0] = 127; 3432 range[1] = 127; 3433 *precision = 23; 3434 break; 3435 case GL_LOW_INT: 3436 case GL_MEDIUM_INT: 3437 case GL_HIGH_INT: 3438 // Full integer precision is supported 3439 range[0] = 31; 3440 range[1] = 30; 3441 *precision = 0; 3442 break; 3443 default: 3444 return error(GL_INVALID_ENUM); 3445 } 3446 } 3447 3448 void GetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source) 3449 { 3450 TRACE("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = %p, GLchar* source = %p)", 3451 shader, bufsize, length, source); 3452 3453 if(bufsize < 0) 3454 { 3455 return error(GL_INVALID_VALUE); 3456 } 3457 3458 es2::Context *context = es2::getContext(); 3459 3460 if(context) 3461 { 3462 es2::Shader *shaderObject = context->getShader(shader); 3463 3464 if(!shaderObject) 3465 { 3466 if(context->getProgram(shader)) 3467 { 3468 return error(GL_INVALID_OPERATION); 3469 } 3470 else 3471 { 3472 return error(GL_INVALID_VALUE); 3473 } 3474 } 3475 3476 shaderObject->getSource(bufsize, length, source); 3477 } 3478 } 3479 3480 const GLubyte* GetString(GLenum name) 3481 { 3482 TRACE("(GLenum name = 0x%X)", name); 3483 3484 switch(name) 3485 { 3486 case GL_VENDOR: 3487 return (GLubyte*)"Google Inc."; 3488 case GL_RENDERER: 3489 return (GLubyte*)"Google SwiftShader"; 3490 case GL_VERSION: 3491 { 3492 es2::Context *context = es2::getContext(); 3493 return (context && (context->getClientVersion() >= 3)) ? 3494 (GLubyte*)"OpenGL ES 3.0 SwiftShader " VERSION_STRING : 3495 (GLubyte*)"OpenGL ES 2.0 SwiftShader " VERSION_STRING; 3496 } 3497 case GL_SHADING_LANGUAGE_VERSION: 3498 { 3499 es2::Context *context = es2::getContext(); 3500 return (context && (context->getClientVersion() >= 3)) ? 3501 (GLubyte*)"OpenGL ES GLSL ES 3.00 SwiftShader " VERSION_STRING : 3502 (GLubyte*)"OpenGL ES GLSL ES 1.00 SwiftShader " VERSION_STRING; 3503 } 3504 case GL_EXTENSIONS: 3505 { 3506 es2::Context *context = es2::getContext(); 3507 return context ? context->getExtensions(GL_INVALID_INDEX) : (GLubyte*)nullptr; 3508 } 3509 default: 3510 return error(GL_INVALID_ENUM, (GLubyte*)nullptr); 3511 } 3512 } 3513 3514 void GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params) 3515 { 3516 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat* params = %p)", target, pname, params); 3517 3518 es2::Context *context = es2::getContext(); 3519 3520 if(context) 3521 { 3522 es2::Texture *texture; 3523 3524 GLint clientVersion = context->getClientVersion(); 3525 3526 switch(target) 3527 { 3528 case GL_TEXTURE_2D: 3529 texture = context->getTexture2D(); 3530 break; 3531 case GL_TEXTURE_CUBE_MAP: 3532 texture = context->getTextureCubeMap(); 3533 break; 3534 case GL_TEXTURE_EXTERNAL_OES: 3535 texture = context->getTextureExternal(); 3536 break; 3537 case GL_TEXTURE_2D_ARRAY: 3538 if(clientVersion < 3) 3539 { 3540 return error(GL_INVALID_ENUM); 3541 } 3542 else 3543 { 3544 texture = context->getTexture2DArray(); 3545 } 3546 break; 3547 case GL_TEXTURE_3D: 3548 texture = context->getTexture3D(); 3549 break; 3550 case GL_TEXTURE_RECTANGLE_ARB: 3551 texture = context->getTexture2DRect(); 3552 break; 3553 default: 3554 return error(GL_INVALID_ENUM); 3555 } 3556 3557 switch(pname) 3558 { 3559 case GL_TEXTURE_MAG_FILTER: 3560 *params = (GLfloat)texture->getMagFilter(); 3561 break; 3562 case GL_TEXTURE_MIN_FILTER: 3563 *params = (GLfloat)texture->getMinFilter(); 3564 break; 3565 case GL_TEXTURE_WRAP_S: 3566 *params = (GLfloat)texture->getWrapS(); 3567 break; 3568 case GL_TEXTURE_WRAP_T: 3569 *params = (GLfloat)texture->getWrapT(); 3570 break; 3571 case GL_TEXTURE_WRAP_R_OES: 3572 *params = (GLfloat)texture->getWrapR(); 3573 break; 3574 case GL_TEXTURE_MAX_ANISOTROPY_EXT: 3575 *params = texture->getMaxAnisotropy(); 3576 break; 3577 case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES: 3578 *params = (GLfloat)1; 3579 break; 3580 case GL_TEXTURE_BASE_LEVEL: 3581 if(clientVersion >= 3) 3582 { 3583 *params = (GLfloat)texture->getBaseLevel(); 3584 break; 3585 } 3586 else return error(GL_INVALID_ENUM); 3587 case GL_TEXTURE_COMPARE_FUNC: 3588 if(clientVersion >= 3) 3589 { 3590 *params = (GLfloat)texture->getCompareFunc(); 3591 break; 3592 } 3593 else return error(GL_INVALID_ENUM); 3594 case GL_TEXTURE_COMPARE_MODE: 3595 if(clientVersion >= 3) 3596 { 3597 *params = (GLfloat)texture->getCompareMode(); 3598 break; 3599 } 3600 else return error(GL_INVALID_ENUM); 3601 case GL_TEXTURE_IMMUTABLE_FORMAT: 3602 if(clientVersion >= 3) 3603 { 3604 *params = (GLfloat)texture->getImmutableFormat(); 3605 break; 3606 } 3607 else return error(GL_INVALID_ENUM); 3608 case GL_TEXTURE_IMMUTABLE_LEVELS: 3609 if(clientVersion >= 3) 3610 { 3611 *params = (GLfloat)texture->getImmutableLevels(); 3612 break; 3613 } 3614 else return error(GL_INVALID_ENUM); 3615 case GL_TEXTURE_MAX_LEVEL: 3616 if(clientVersion >= 3) 3617 { 3618 *params = (GLfloat)texture->getMaxLevel(); 3619 break; 3620 } 3621 else return error(GL_INVALID_ENUM); 3622 case GL_TEXTURE_MAX_LOD: 3623 if(clientVersion >= 3) 3624 { 3625 *params = texture->getMaxLOD(); 3626 break; 3627 } 3628 else return error(GL_INVALID_ENUM); 3629 case GL_TEXTURE_MIN_LOD: 3630 if(clientVersion >= 3) 3631 { 3632 *params = texture->getMinLOD(); 3633 break; 3634 } 3635 else return error(GL_INVALID_ENUM); 3636 case GL_TEXTURE_SWIZZLE_R: 3637 if(clientVersion >= 3) 3638 { 3639 *params = (GLfloat)texture->getSwizzleR(); 3640 break; 3641 } 3642 else return error(GL_INVALID_ENUM); 3643 case GL_TEXTURE_SWIZZLE_G: 3644 if(clientVersion >= 3) 3645 { 3646 *params = (GLfloat)texture->getSwizzleG(); 3647 break; 3648 } 3649 else return error(GL_INVALID_ENUM); 3650 case GL_TEXTURE_SWIZZLE_B: 3651 if(clientVersion >= 3) 3652 { 3653 *params = (GLfloat)texture->getSwizzleB(); 3654 break; 3655 } 3656 else return error(GL_INVALID_ENUM); 3657 case GL_TEXTURE_SWIZZLE_A: 3658 if(clientVersion >= 3) 3659 { 3660 *params = (GLfloat)texture->getSwizzleA(); 3661 break; 3662 } 3663 else return error(GL_INVALID_ENUM); 3664 default: 3665 return error(GL_INVALID_ENUM); 3666 } 3667 } 3668 } 3669 3670 void GetTexParameteriv(GLenum target, GLenum pname, GLint* params) 3671 { 3672 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", target, pname, params); 3673 3674 es2::Context *context = es2::getContext(); 3675 3676 if(context) 3677 { 3678 es2::Texture *texture; 3679 3680 GLint clientVersion = context->getClientVersion(); 3681 3682 switch(target) 3683 { 3684 case GL_TEXTURE_2D: 3685 texture = context->getTexture2D(); 3686 break; 3687 case GL_TEXTURE_CUBE_MAP: 3688 texture = context->getTextureCubeMap(); 3689 break; 3690 case GL_TEXTURE_EXTERNAL_OES: 3691 texture = context->getTextureExternal(); 3692 break; 3693 case GL_TEXTURE_2D_ARRAY: 3694 if(clientVersion < 3) 3695 { 3696 return error(GL_INVALID_ENUM); 3697 } 3698 else 3699 { 3700 texture = context->getTexture2DArray(); 3701 } 3702 break; 3703 case GL_TEXTURE_3D: 3704 texture = context->getTexture3D(); 3705 break; 3706 case GL_TEXTURE_RECTANGLE_ARB: 3707 texture = context->getTexture2DRect(); 3708 break; 3709 default: 3710 return error(GL_INVALID_ENUM); 3711 } 3712 3713 switch(pname) 3714 { 3715 case GL_TEXTURE_MAG_FILTER: 3716 *params = texture->getMagFilter(); 3717 break; 3718 case GL_TEXTURE_MIN_FILTER: 3719 *params = texture->getMinFilter(); 3720 break; 3721 case GL_TEXTURE_WRAP_S: 3722 *params = texture->getWrapS(); 3723 break; 3724 case GL_TEXTURE_WRAP_T: 3725 *params = texture->getWrapT(); 3726 break; 3727 case GL_TEXTURE_WRAP_R_OES: 3728 *params = texture->getWrapR(); 3729 break; 3730 case GL_TEXTURE_MAX_ANISOTROPY_EXT: 3731 *params = (GLint)texture->getMaxAnisotropy(); 3732 break; 3733 case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES: 3734 *params = 1; 3735 break; 3736 case GL_TEXTURE_BASE_LEVEL: 3737 if(clientVersion >= 3) 3738 { 3739 *params = texture->getBaseLevel(); 3740 break; 3741 } 3742 else return error(GL_INVALID_ENUM); 3743 case GL_TEXTURE_COMPARE_FUNC: 3744 if(clientVersion >= 3) 3745 { 3746 *params = (GLint)texture->getCompareFunc(); 3747 break; 3748 } 3749 else return error(GL_INVALID_ENUM); 3750 case GL_TEXTURE_COMPARE_MODE: 3751 if(clientVersion >= 3) 3752 { 3753 *params = (GLint)texture->getCompareMode(); 3754 break; 3755 } 3756 else return error(GL_INVALID_ENUM); 3757 case GL_TEXTURE_IMMUTABLE_FORMAT: 3758 if(clientVersion >= 3) 3759 { 3760 *params = (GLint)texture->getImmutableFormat(); 3761 break; 3762 } 3763 else return error(GL_INVALID_ENUM); 3764 case GL_TEXTURE_IMMUTABLE_LEVELS: 3765 if(clientVersion >= 3) 3766 { 3767 *params = (GLint)texture->getImmutableLevels(); 3768 break; 3769 } 3770 else return error(GL_INVALID_ENUM); 3771 case GL_TEXTURE_MAX_LEVEL: 3772 if(clientVersion >= 3) 3773 { 3774 *params = texture->getMaxLevel(); 3775 break; 3776 } 3777 else return error(GL_INVALID_ENUM); 3778 case GL_TEXTURE_MAX_LOD: 3779 if(clientVersion >= 3) 3780 { 3781 *params = (GLint)roundf(texture->getMaxLOD()); 3782 break; 3783 } 3784 else return error(GL_INVALID_ENUM); 3785 case GL_TEXTURE_MIN_LOD: 3786 if(clientVersion >= 3) 3787 { 3788 *params = (GLint)roundf(texture->getMinLOD()); 3789 break; 3790 } 3791 else return error(GL_INVALID_ENUM); 3792 case GL_TEXTURE_SWIZZLE_R: 3793 if(clientVersion >= 3) 3794 { 3795 *params = (GLint)texture->getSwizzleR(); 3796 break; 3797 } 3798 else return error(GL_INVALID_ENUM); 3799 case GL_TEXTURE_SWIZZLE_G: 3800 if(clientVersion >= 3) 3801 { 3802 *params = (GLint)texture->getSwizzleG(); 3803 break; 3804 } 3805 else return error(GL_INVALID_ENUM); 3806 case GL_TEXTURE_SWIZZLE_B: 3807 if(clientVersion >= 3) 3808 { 3809 *params = (GLint)texture->getSwizzleB(); 3810 break; 3811 } 3812 else return error(GL_INVALID_ENUM); 3813 case GL_TEXTURE_SWIZZLE_A: 3814 if(clientVersion >= 3) 3815 { 3816 *params = (GLint)texture->getSwizzleA(); 3817 break; 3818 } 3819 else return error(GL_INVALID_ENUM); 3820 default: 3821 return error(GL_INVALID_ENUM); 3822 } 3823 } 3824 } 3825 3826 void GetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSize, GLfloat* params) 3827 { 3828 TRACE("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLfloat* params = %p)", 3829 program, location, bufSize, params); 3830 3831 if(bufSize < 0) 3832 { 3833 return error(GL_INVALID_VALUE); 3834 } 3835 3836 es2::Context *context = es2::getContext(); 3837 3838 if(context) 3839 { 3840 es2::Program *programObject = context->getProgram(program); 3841 3842 if(!programObject) 3843 { 3844 if(context->getShader(program)) 3845 { 3846 return error(GL_INVALID_OPERATION); 3847 } 3848 else 3849 { 3850 return error(GL_INVALID_VALUE); 3851 } 3852 } 3853 3854 if(!programObject->isLinked()) 3855 { 3856 return error(GL_INVALID_OPERATION); 3857 } 3858 3859 if(!programObject->getUniformfv(location, &bufSize, params)) 3860 { 3861 return error(GL_INVALID_OPERATION); 3862 } 3863 } 3864 } 3865 3866 void GetUniformfv(GLuint program, GLint location, GLfloat* params) 3867 { 3868 TRACE("(GLuint program = %d, GLint location = %d, GLfloat* params = %p)", program, location, params); 3869 3870 es2::Context *context = es2::getContext(); 3871 3872 if(context) 3873 { 3874 es2::Program *programObject = context->getProgram(program); 3875 3876 if(!programObject) 3877 { 3878 if(context->getShader(program)) 3879 { 3880 return error(GL_INVALID_OPERATION); 3881 } 3882 else 3883 { 3884 return error(GL_INVALID_VALUE); 3885 } 3886 } 3887 3888 if(!programObject->isLinked()) 3889 { 3890 return error(GL_INVALID_OPERATION); 3891 } 3892 3893 if(!programObject->getUniformfv(location, nullptr, params)) 3894 { 3895 return error(GL_INVALID_OPERATION); 3896 } 3897 } 3898 } 3899 3900 void GetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint* params) 3901 { 3902 TRACE("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLint* params = %p)", 3903 program, location, bufSize, params); 3904 3905 if(bufSize < 0) 3906 { 3907 return error(GL_INVALID_VALUE); 3908 } 3909 3910 es2::Context *context = es2::getContext(); 3911 3912 if(context) 3913 { 3914 es2::Program *programObject = context->getProgram(program); 3915 3916 if(!programObject) 3917 { 3918 if(context->getShader(program)) 3919 { 3920 return error(GL_INVALID_OPERATION); 3921 } 3922 else 3923 { 3924 return error(GL_INVALID_VALUE); 3925 } 3926 } 3927 3928 if(!programObject->isLinked()) 3929 { 3930 return error(GL_INVALID_OPERATION); 3931 } 3932 3933 if(!programObject->getUniformiv(location, &bufSize, params)) 3934 { 3935 return error(GL_INVALID_OPERATION); 3936 } 3937 } 3938 } 3939 3940 void GetUniformiv(GLuint program, GLint location, GLint* params) 3941 { 3942 TRACE("(GLuint program = %d, GLint location = %d, GLint* params = %p)", program, location, params); 3943 3944 es2::Context *context = es2::getContext(); 3945 3946 if(context) 3947 { 3948 es2::Program *programObject = context->getProgram(program); 3949 3950 if(!programObject) 3951 { 3952 if(context->getShader(program)) 3953 { 3954 return error(GL_INVALID_OPERATION); 3955 } 3956 else 3957 { 3958 return error(GL_INVALID_VALUE); 3959 } 3960 } 3961 3962 if(!programObject->isLinked()) 3963 { 3964 return error(GL_INVALID_OPERATION); 3965 } 3966 3967 if(!programObject->getUniformiv(location, nullptr, params)) 3968 { 3969 return error(GL_INVALID_OPERATION); 3970 } 3971 } 3972 } 3973 3974 int GetUniformLocation(GLuint program, const GLchar* name) 3975 { 3976 TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name); 3977 3978 es2::Context *context = es2::getContext(); 3979 3980 if(strstr(name, "gl_") == name) 3981 { 3982 return -1; 3983 } 3984 3985 if(context) 3986 { 3987 es2::Program *programObject = context->getProgram(program); 3988 3989 if(!programObject) 3990 { 3991 if(context->getShader(program)) 3992 { 3993 return error(GL_INVALID_OPERATION, -1); 3994 } 3995 else 3996 { 3997 return error(GL_INVALID_VALUE, -1); 3998 } 3999 } 4000 4001 if(!programObject->isLinked()) 4002 { 4003 return error(GL_INVALID_OPERATION, -1); 4004 } 4005 4006 return programObject->getUniformLocation(name); 4007 } 4008 4009 return -1; 4010 } 4011 4012 void GetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params) 4013 { 4014 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = %p)", index, pname, params); 4015 4016 es2::Context *context = es2::getContext(); 4017 4018 if(context) 4019 { 4020 if(index >= es2::MAX_VERTEX_ATTRIBS) 4021 { 4022 return error(GL_INVALID_VALUE); 4023 } 4024 4025 const es2::VertexAttribute &attribState = context->getVertexAttribState(index); 4026 4027 GLint clientVersion = context->getClientVersion(); 4028 4029 switch(pname) 4030 { 4031 case GL_VERTEX_ATTRIB_ARRAY_ENABLED: 4032 *params = (GLfloat)(attribState.mArrayEnabled ? GL_TRUE : GL_FALSE); 4033 break; 4034 case GL_VERTEX_ATTRIB_ARRAY_SIZE: 4035 *params = (GLfloat)attribState.mSize; 4036 break; 4037 case GL_VERTEX_ATTRIB_ARRAY_STRIDE: 4038 *params = (GLfloat)attribState.mStride; 4039 break; 4040 case GL_VERTEX_ATTRIB_ARRAY_TYPE: 4041 *params = (GLfloat)attribState.mType; 4042 break; 4043 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED: 4044 *params = (GLfloat)(attribState.mNormalized ? GL_TRUE : GL_FALSE); 4045 break; 4046 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: 4047 *params = (GLfloat)attribState.mBoundBuffer.name(); 4048 break; 4049 case GL_CURRENT_VERTEX_ATTRIB: 4050 { 4051 const VertexAttribute& attrib = context->getCurrentVertexAttributes()[index]; 4052 for(int i = 0; i < 4; ++i) 4053 { 4054 params[i] = attrib.getCurrentValueF(i); 4055 } 4056 } 4057 break; 4058 case GL_VERTEX_ATTRIB_ARRAY_INTEGER: 4059 if(clientVersion >= 3) 4060 { 4061 *params = (GLfloat)(attribState.mPureInteger ? GL_TRUE : GL_FALSE); 4062 break; 4063 } 4064 else return error(GL_INVALID_ENUM); 4065 default: return error(GL_INVALID_ENUM); 4066 } 4067 } 4068 } 4069 4070 void GetVertexAttribiv(GLuint index, GLenum pname, GLint* params) 4071 { 4072 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = %p)", index, pname, params); 4073 4074 es2::Context *context = es2::getContext(); 4075 4076 if(context) 4077 { 4078 if(index >= es2::MAX_VERTEX_ATTRIBS) 4079 { 4080 return error(GL_INVALID_VALUE); 4081 } 4082 4083 const es2::VertexAttribute &attribState = context->getVertexAttribState(index); 4084 4085 GLint clientVersion = context->getClientVersion(); 4086 4087 switch(pname) 4088 { 4089 case GL_VERTEX_ATTRIB_ARRAY_ENABLED: 4090 *params = (attribState.mArrayEnabled ? GL_TRUE : GL_FALSE); 4091 break; 4092 case GL_VERTEX_ATTRIB_ARRAY_SIZE: 4093 *params = attribState.mSize; 4094 break; 4095 case GL_VERTEX_ATTRIB_ARRAY_STRIDE: 4096 *params = attribState.mStride; 4097 break; 4098 case GL_VERTEX_ATTRIB_ARRAY_TYPE: 4099 *params = attribState.mType; 4100 break; 4101 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED: 4102 *params = (attribState.mNormalized ? GL_TRUE : GL_FALSE); 4103 break; 4104 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: 4105 *params = attribState.mBoundBuffer.name(); 4106 break; 4107 case GL_CURRENT_VERTEX_ATTRIB: 4108 { 4109 const VertexAttribute& attrib = context->getCurrentVertexAttributes()[index]; 4110 for(int i = 0; i < 4; ++i) 4111 { 4112 float currentValue = attrib.getCurrentValueF(i); 4113 params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f)); 4114 } 4115 } 4116 break; 4117 case GL_VERTEX_ATTRIB_ARRAY_INTEGER: 4118 if(clientVersion >= 3) 4119 { 4120 *params = (attribState.mPureInteger ? GL_TRUE : GL_FALSE); 4121 break; 4122 } 4123 else return error(GL_INVALID_ENUM); 4124 default: return error(GL_INVALID_ENUM); 4125 } 4126 } 4127 } 4128 4129 void GetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer) 4130 { 4131 TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = %p)", index, pname, pointer); 4132 4133 es2::Context *context = es2::getContext(); 4134 4135 if(context) 4136 { 4137 if(index >= es2::MAX_VERTEX_ATTRIBS) 4138 { 4139 return error(GL_INVALID_VALUE); 4140 } 4141 4142 if(pname != GL_VERTEX_ATTRIB_ARRAY_POINTER) 4143 { 4144 return error(GL_INVALID_ENUM); 4145 } 4146 4147 *pointer = const_cast<GLvoid*>(context->getVertexAttribPointer(index)); 4148 } 4149 } 4150 4151 void Hint(GLenum target, GLenum mode) 4152 { 4153 TRACE("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode); 4154 4155 switch(mode) 4156 { 4157 case GL_FASTEST: 4158 case GL_NICEST: 4159 case GL_DONT_CARE: 4160 break; 4161 default: 4162 return error(GL_INVALID_ENUM); 4163 } 4164 4165 es2::Context *context = es2::getContext(); 4166 4167 if(context) 4168 { 4169 switch(target) 4170 { 4171 case GL_GENERATE_MIPMAP_HINT: 4172 context->setGenerateMipmapHint(mode); 4173 break; 4174 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: 4175 context->setFragmentShaderDerivativeHint(mode); 4176 break; 4177 case GL_TEXTURE_FILTERING_HINT_CHROMIUM: 4178 context->setTextureFilteringHint(mode); 4179 break; 4180 default: 4181 return error(GL_INVALID_ENUM); 4182 } 4183 } 4184 } 4185 4186 GLboolean IsBuffer(GLuint buffer) 4187 { 4188 TRACE("(GLuint buffer = %d)", buffer); 4189 4190 es2::Context *context = es2::getContext(); 4191 4192 if(context && buffer) 4193 { 4194 es2::Buffer *bufferObject = context->getBuffer(buffer); 4195 4196 if(bufferObject) 4197 { 4198 return GL_TRUE; 4199 } 4200 } 4201 4202 return GL_FALSE; 4203 } 4204 4205 GLboolean IsEnabled(GLenum cap) 4206 { 4207 TRACE("(GLenum cap = 0x%X)", cap); 4208 4209 es2::Context *context = es2::getContext(); 4210 4211 if(context) 4212 { 4213 GLint clientVersion = context->getClientVersion(); 4214 4215 switch(cap) 4216 { 4217 case GL_CULL_FACE: return context->isCullFaceEnabled(); 4218 case GL_POLYGON_OFFSET_FILL: return context->isPolygonOffsetFillEnabled(); 4219 case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled(); 4220 case GL_SAMPLE_COVERAGE: return context->isSampleCoverageEnabled(); 4221 case GL_SCISSOR_TEST: return context->isScissorTestEnabled(); 4222 case GL_STENCIL_TEST: return context->isStencilTestEnabled(); 4223 case GL_DEPTH_TEST: return context->isDepthTestEnabled(); 4224 case GL_BLEND: return context->isBlendEnabled(); 4225 case GL_DITHER: return context->isDitherEnabled(); 4226 case GL_PRIMITIVE_RESTART_FIXED_INDEX: 4227 if(clientVersion >= 3) 4228 { 4229 return context->isPrimitiveRestartFixedIndexEnabled(); 4230 } 4231 else return error(GL_INVALID_ENUM, false); 4232 case GL_RASTERIZER_DISCARD: 4233 if(clientVersion >= 3) 4234 { 4235 return context->isRasterizerDiscardEnabled(); 4236 } 4237 else return error(GL_INVALID_ENUM, false); 4238 default: 4239 return error(GL_INVALID_ENUM, false); 4240 } 4241 } 4242 4243 return false; 4244 } 4245 4246 GLboolean IsFenceNV(GLuint fence) 4247 { 4248 TRACE("(GLuint fence = %d)", fence); 4249 4250 es2::Context *context = es2::getContext(); 4251 4252 if(context) 4253 { 4254 es2::Fence *fenceObject = context->getFence(fence); 4255 4256 if(!fenceObject) 4257 { 4258 return GL_FALSE; 4259 } 4260 4261 return fenceObject->isFence(); 4262 } 4263 4264 return GL_FALSE; 4265 } 4266 4267 GLboolean IsFramebuffer(GLuint framebuffer) 4268 { 4269 TRACE("(GLuint framebuffer = %d)", framebuffer); 4270 4271 es2::Context *context = es2::getContext(); 4272 4273 if(context && framebuffer) 4274 { 4275 es2::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer); 4276 4277 if(framebufferObject) 4278 { 4279 return GL_TRUE; 4280 } 4281 } 4282 4283 return GL_FALSE; 4284 } 4285 4286 GLboolean IsProgram(GLuint program) 4287 { 4288 TRACE("(GLuint program = %d)", program); 4289 4290 es2::Context *context = es2::getContext(); 4291 4292 if(context && program) 4293 { 4294 es2::Program *programObject = context->getProgram(program); 4295 4296 if(programObject) 4297 { 4298 return GL_TRUE; 4299 } 4300 } 4301 4302 return GL_FALSE; 4303 } 4304 4305 GLboolean IsQueryEXT(GLuint name) 4306 { 4307 TRACE("(GLuint name = %d)", name); 4308 4309 if(name == 0) 4310 { 4311 return GL_FALSE; 4312 } 4313 4314 es2::Context *context = es2::getContext(); 4315 4316 if(context) 4317 { 4318 es2::Query *queryObject = context->getQuery(name); 4319 4320 if(queryObject) 4321 { 4322 return GL_TRUE; 4323 } 4324 } 4325 4326 return GL_FALSE; 4327 } 4328 4329 GLboolean IsRenderbuffer(GLuint renderbuffer) 4330 { 4331 TRACE("(GLuint renderbuffer = %d)", renderbuffer); 4332 4333 es2::Context *context = es2::getContext(); 4334 4335 if(context && renderbuffer) 4336 { 4337 es2::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer); 4338 4339 if(renderbufferObject) 4340 { 4341 return GL_TRUE; 4342 } 4343 } 4344 4345 return GL_FALSE; 4346 } 4347 4348 GLboolean IsShader(GLuint shader) 4349 { 4350 TRACE("(GLuint shader = %d)", shader); 4351 4352 es2::Context *context = es2::getContext(); 4353 4354 if(context && shader) 4355 { 4356 es2::Shader *shaderObject = context->getShader(shader); 4357 4358 if(shaderObject) 4359 { 4360 return GL_TRUE; 4361 } 4362 } 4363 4364 return GL_FALSE; 4365 } 4366 4367 GLboolean IsTexture(GLuint texture) 4368 { 4369 TRACE("(GLuint texture = %d)", texture); 4370 4371 es2::Context *context = es2::getContext(); 4372 4373 if(context && texture) 4374 { 4375 es2::Texture *textureObject = context->getTexture(texture); 4376 4377 if(textureObject) 4378 { 4379 return GL_TRUE; 4380 } 4381 } 4382 4383 return GL_FALSE; 4384 } 4385 4386 void LineWidth(GLfloat width) 4387 { 4388 TRACE("(GLfloat width = %f)", width); 4389 4390 if(width <= 0.0f) 4391 { 4392 return error(GL_INVALID_VALUE); 4393 } 4394 4395 es2::Context *context = es2::getContext(); 4396 4397 if(context) 4398 { 4399 context->setLineWidth(width); 4400 } 4401 } 4402 4403 void LinkProgram(GLuint program) 4404 { 4405 TRACE("(GLuint program = %d)", program); 4406 4407 es2::Context *context = es2::getContext(); 4408 4409 if(context) 4410 { 4411 es2::Program *programObject = context->getProgram(program); 4412 4413 if(!programObject) 4414 { 4415 if(context->getShader(program)) 4416 { 4417 return error(GL_INVALID_OPERATION); 4418 } 4419 else 4420 { 4421 return error(GL_INVALID_VALUE); 4422 } 4423 } 4424 4425 if(programObject == context->getCurrentProgram()) 4426 { 4427 es2::TransformFeedback* transformFeedback = context->getTransformFeedback(); 4428 if(transformFeedback && transformFeedback->isActive()) 4429 { 4430 return error(GL_INVALID_OPERATION); 4431 } 4432 } 4433 4434 programObject->link(); 4435 } 4436 } 4437 4438 void PixelStorei(GLenum pname, GLint param) 4439 { 4440 TRACE("(GLenum pname = 0x%X, GLint param = %d)", pname, param); 4441 4442 es2::Context *context = es2::getContext(); 4443 4444 if(context) 4445 { 4446 GLint clientVersion = context->getClientVersion(); 4447 4448 switch(pname) 4449 { 4450 case GL_UNPACK_ALIGNMENT: 4451 if(param != 1 && param != 2 && param != 4 && param != 8) 4452 { 4453 return error(GL_INVALID_VALUE); 4454 } 4455 context->setUnpackAlignment(param); 4456 break; 4457 case GL_PACK_ALIGNMENT: 4458 if(param != 1 && param != 2 && param != 4 && param != 8) 4459 { 4460 return error(GL_INVALID_VALUE); 4461 } 4462 context->setPackAlignment(param); 4463 break; 4464 case GL_PACK_ROW_LENGTH: 4465 if(clientVersion >= 3) 4466 { 4467 if(param < 0) 4468 { 4469 return error(GL_INVALID_VALUE); 4470 } 4471 context->setPackRowLength(param); 4472 break; 4473 } 4474 else return error(GL_INVALID_ENUM); 4475 case GL_PACK_SKIP_PIXELS: 4476 if(clientVersion >= 3) 4477 { 4478 if(param < 0) 4479 { 4480 return error(GL_INVALID_VALUE); 4481 } 4482 context->setPackSkipPixels(param); 4483 break; 4484 } 4485 else return error(GL_INVALID_ENUM); 4486 case GL_PACK_SKIP_ROWS: 4487 if(clientVersion >= 3) 4488 { 4489 if(param < 0) 4490 { 4491 return error(GL_INVALID_VALUE); 4492 } 4493 context->setPackSkipRows(param); 4494 break; 4495 } 4496 else return error(GL_INVALID_ENUM); 4497 case GL_UNPACK_ROW_LENGTH: 4498 if(clientVersion >= 3) 4499 { 4500 if(param < 0) 4501 { 4502 return error(GL_INVALID_VALUE); 4503 } 4504 context->setUnpackRowLength(param); 4505 break; 4506 } 4507 else return error(GL_INVALID_ENUM); 4508 case GL_UNPACK_IMAGE_HEIGHT: 4509 if(clientVersion >= 3) 4510 { 4511 if(param < 0) 4512 { 4513 return error(GL_INVALID_VALUE); 4514 } 4515 context->setUnpackImageHeight(param); 4516 break; 4517 } 4518 else return error(GL_INVALID_ENUM); 4519 case GL_UNPACK_SKIP_PIXELS: 4520 if(clientVersion >= 3) 4521 { 4522 if(param < 0) 4523 { 4524 return error(GL_INVALID_VALUE); 4525 } 4526 context->setUnpackSkipPixels(param); 4527 break; 4528 } 4529 else return error(GL_INVALID_ENUM); 4530 case GL_UNPACK_SKIP_ROWS: 4531 if(clientVersion >= 3) 4532 { 4533 if(param < 0) 4534 { 4535 return error(GL_INVALID_VALUE); 4536 } 4537 context->setUnpackSkipRows(param); 4538 break; 4539 } 4540 else return error(GL_INVALID_ENUM); 4541 case GL_UNPACK_SKIP_IMAGES: 4542 if(clientVersion >= 3) { 4543 if(param < 0) 4544 { 4545 return error(GL_INVALID_VALUE); 4546 } 4547 context->setUnpackSkipImages(param); 4548 break; 4549 } 4550 else return error(GL_INVALID_ENUM); 4551 default: 4552 return error(GL_INVALID_ENUM); 4553 } 4554 } 4555 } 4556 4557 void PolygonOffset(GLfloat factor, GLfloat units) 4558 { 4559 TRACE("(GLfloat factor = %f, GLfloat units = %f)", factor, units); 4560 4561 es2::Context *context = es2::getContext(); 4562 4563 if(context) 4564 { 4565 context->setPolygonOffsetParams(factor, units); 4566 } 4567 } 4568 4569 void ReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height, 4570 GLenum format, GLenum type, GLsizei bufSize, GLvoid *data) 4571 { 4572 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, " 4573 "GLenum format = 0x%X, GLenum type = 0x%X, GLsizei bufSize = 0x%d, GLvoid *data = %p)", 4574 x, y, width, height, format, type, bufSize, data); 4575 4576 if(width < 0 || height < 0 || bufSize < 0) 4577 { 4578 return error(GL_INVALID_VALUE); 4579 } 4580 4581 es2::Context *context = es2::getContext(); 4582 4583 if(context) 4584 { 4585 context->readPixels(x, y, width, height, format, type, &bufSize, data); 4586 } 4587 } 4588 4589 void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels) 4590 { 4591 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, " 4592 "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = %p)", 4593 x, y, width, height, format, type, pixels); 4594 4595 if(width < 0 || height < 0) 4596 { 4597 return error(GL_INVALID_VALUE); 4598 } 4599 4600 es2::Context *context = es2::getContext(); 4601 4602 if(context) 4603 { 4604 context->readPixels(x, y, width, height, format, type, nullptr, pixels); 4605 } 4606 } 4607 4608 void ReleaseShaderCompiler(void) 4609 { 4610 TRACE("()"); 4611 4612 es2::Shader::releaseCompiler(); 4613 } 4614 4615 void RenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) 4616 { 4617 TRACE("(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)", 4618 target, samples, internalformat, width, height); 4619 4620 switch(target) 4621 { 4622 case GL_RENDERBUFFER: 4623 break; 4624 default: 4625 return error(GL_INVALID_ENUM); 4626 } 4627 4628 if(width < 0 || height < 0 || samples < 0 || 4629 width > es2::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE || 4630 height > es2::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE) 4631 { 4632 return error(GL_INVALID_VALUE); 4633 } 4634 4635 if(samples > es2::IMPLEMENTATION_MAX_SAMPLES || 4636 (IsNonNormalizedInteger(internalformat) && samples > 0)) 4637 { 4638 return error(GL_INVALID_OPERATION); 4639 } 4640 4641 es2::Context *context = es2::getContext(); 4642 4643 if(context) 4644 { 4645 GLuint handle = context->getRenderbufferName(); 4646 if(handle == 0) 4647 { 4648 return error(GL_INVALID_OPERATION); 4649 } 4650 4651 GLint clientVersion = context->getClientVersion(); 4652 4653 if(IsColorRenderable(internalformat, clientVersion)) 4654 { 4655 context->setRenderbufferStorage(new es2::Colorbuffer(width, height, internalformat, samples)); 4656 } 4657 else if(IsDepthRenderable(internalformat, clientVersion) && IsStencilRenderable(internalformat, clientVersion)) 4658 { 4659 context->setRenderbufferStorage(new es2::DepthStencilbuffer(width, height, internalformat, samples)); 4660 } 4661 else if(IsDepthRenderable(internalformat, clientVersion)) 4662 { 4663 context->setRenderbufferStorage(new es2::Depthbuffer(width, height, internalformat, samples)); 4664 } 4665 else if(IsStencilRenderable(internalformat, clientVersion)) 4666 { 4667 context->setRenderbufferStorage(new es2::Stencilbuffer(width, height, samples)); 4668 } 4669 else error(GL_INVALID_ENUM); 4670 } 4671 } 4672 4673 void RenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) 4674 { 4675 RenderbufferStorageMultisample(target, samples, internalformat, width, height); 4676 } 4677 4678 void RenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height) 4679 { 4680 RenderbufferStorageMultisample(target, 0, internalformat, width, height); 4681 } 4682 4683 void SampleCoverage(GLclampf value, GLboolean invert) 4684 { 4685 TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert); 4686 4687 es2::Context* context = es2::getContext(); 4688 4689 if(context) 4690 { 4691 context->setSampleCoverageParams(es2::clamp01(value), invert == GL_TRUE); 4692 } 4693 } 4694 4695 void SetFenceNV(GLuint fence, GLenum condition) 4696 { 4697 TRACE("(GLuint fence = %d, GLenum condition = 0x%X)", fence, condition); 4698 4699 if(condition != GL_ALL_COMPLETED_NV) 4700 { 4701 return error(GL_INVALID_ENUM); 4702 } 4703 4704 es2::Context *context = es2::getContext(); 4705 4706 if(context) 4707 { 4708 es2::Fence *fenceObject = context->getFence(fence); 4709 4710 if(!fenceObject) 4711 { 4712 return error(GL_INVALID_OPERATION); 4713 } 4714 4715 fenceObject->setFence(condition); 4716 } 4717 } 4718 4719 void Scissor(GLint x, GLint y, GLsizei width, GLsizei height) 4720 { 4721 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height); 4722 4723 if(width < 0 || height < 0) 4724 { 4725 return error(GL_INVALID_VALUE); 4726 } 4727 4728 es2::Context* context = es2::getContext(); 4729 4730 if(context) 4731 { 4732 context->setScissorParams(x, y, width, height); 4733 } 4734 } 4735 4736 void ShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length) 4737 { 4738 TRACE("(GLsizei n = %d, const GLuint* shaders = %p, GLenum binaryformat = 0x%X, " 4739 "const GLvoid* binary = %p, GLsizei length = %d)", 4740 n, shaders, binaryformat, binary, length); 4741 4742 // No binary shader formats are supported. 4743 return error(GL_INVALID_ENUM); 4744 } 4745 4746 void ShaderSource(GLuint shader, GLsizei count, const GLchar *const *string, const GLint *length) 4747 { 4748 TRACE("(GLuint shader = %d, GLsizei count = %d, const GLchar** string = %p, const GLint* length = %p)", 4749 shader, count, string, length); 4750 4751 if(count < 0) 4752 { 4753 return error(GL_INVALID_VALUE); 4754 } 4755 4756 es2::Context *context = es2::getContext(); 4757 4758 if(context) 4759 { 4760 es2::Shader *shaderObject = context->getShader(shader); 4761 4762 if(!shaderObject) 4763 { 4764 if(context->getProgram(shader)) 4765 { 4766 return error(GL_INVALID_OPERATION); 4767 } 4768 else 4769 { 4770 return error(GL_INVALID_VALUE); 4771 } 4772 } 4773 4774 shaderObject->setSource(count, string, length); 4775 } 4776 } 4777 4778 void StencilFunc(GLenum func, GLint ref, GLuint mask) 4779 { 4780 glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask); 4781 } 4782 4783 void StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask) 4784 { 4785 TRACE("(GLenum face = 0x%X, GLenum func = 0x%X, GLint ref = %d, GLuint mask = %d)", face, func, ref, mask); 4786 4787 switch(face) 4788 { 4789 case GL_FRONT: 4790 case GL_BACK: 4791 case GL_FRONT_AND_BACK: 4792 break; 4793 default: 4794 return error(GL_INVALID_ENUM); 4795 } 4796 4797 switch(func) 4798 { 4799 case GL_NEVER: 4800 case GL_ALWAYS: 4801 case GL_LESS: 4802 case GL_LEQUAL: 4803 case GL_EQUAL: 4804 case GL_GEQUAL: 4805 case GL_GREATER: 4806 case GL_NOTEQUAL: 4807 break; 4808 default: 4809 return error(GL_INVALID_ENUM); 4810 } 4811 4812 es2::Context *context = es2::getContext(); 4813 4814 if(context) 4815 { 4816 if(face == GL_FRONT || face == GL_FRONT_AND_BACK) 4817 { 4818 context->setStencilParams(func, ref, mask); 4819 } 4820 4821 if(face == GL_BACK || face == GL_FRONT_AND_BACK) 4822 { 4823 context->setStencilBackParams(func, ref, mask); 4824 } 4825 } 4826 } 4827 4828 void StencilMask(GLuint mask) 4829 { 4830 glStencilMaskSeparate(GL_FRONT_AND_BACK, mask); 4831 } 4832 4833 void StencilMaskSeparate(GLenum face, GLuint mask) 4834 { 4835 TRACE("(GLenum face = 0x%X, GLuint mask = %d)", face, mask); 4836 4837 switch(face) 4838 { 4839 case GL_FRONT: 4840 case GL_BACK: 4841 case GL_FRONT_AND_BACK: 4842 break; 4843 default: 4844 return error(GL_INVALID_ENUM); 4845 } 4846 4847 es2::Context *context = es2::getContext(); 4848 4849 if(context) 4850 { 4851 if(face == GL_FRONT || face == GL_FRONT_AND_BACK) 4852 { 4853 context->setStencilWritemask(mask); 4854 } 4855 4856 if(face == GL_BACK || face == GL_FRONT_AND_BACK) 4857 { 4858 context->setStencilBackWritemask(mask); 4859 } 4860 } 4861 } 4862 4863 void StencilOp(GLenum fail, GLenum zfail, GLenum zpass) 4864 { 4865 glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass); 4866 } 4867 4868 void StencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass) 4869 { 4870 TRACE("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)", 4871 face, fail, zfail, zpass); 4872 4873 switch(face) 4874 { 4875 case GL_FRONT: 4876 case GL_BACK: 4877 case GL_FRONT_AND_BACK: 4878 break; 4879 default: 4880 return error(GL_INVALID_ENUM); 4881 } 4882 4883 switch(fail) 4884 { 4885 case GL_ZERO: 4886 case GL_KEEP: 4887 case GL_REPLACE: 4888 case GL_INCR: 4889 case GL_DECR: 4890 case GL_INVERT: 4891 case GL_INCR_WRAP: 4892 case GL_DECR_WRAP: 4893 break; 4894 default: 4895 return error(GL_INVALID_ENUM); 4896 } 4897 4898 switch(zfail) 4899 { 4900 case GL_ZERO: 4901 case GL_KEEP: 4902 case GL_REPLACE: 4903 case GL_INCR: 4904 case GL_DECR: 4905 case GL_INVERT: 4906 case GL_INCR_WRAP: 4907 case GL_DECR_WRAP: 4908 break; 4909 default: 4910 return error(GL_INVALID_ENUM); 4911 } 4912 4913 switch(zpass) 4914 { 4915 case GL_ZERO: 4916 case GL_KEEP: 4917 case GL_REPLACE: 4918 case GL_INCR: 4919 case GL_DECR: 4920 case GL_INVERT: 4921 case GL_INCR_WRAP: 4922 case GL_DECR_WRAP: 4923 break; 4924 default: 4925 return error(GL_INVALID_ENUM); 4926 } 4927 4928 es2::Context *context = es2::getContext(); 4929 4930 if(context) 4931 { 4932 if(face == GL_FRONT || face == GL_FRONT_AND_BACK) 4933 { 4934 context->setStencilOperations(fail, zfail, zpass); 4935 } 4936 4937 if(face == GL_BACK || face == GL_FRONT_AND_BACK) 4938 { 4939 context->setStencilBackOperations(fail, zfail, zpass); 4940 } 4941 } 4942 } 4943 4944 GLboolean TestFenceNV(GLuint fence) 4945 { 4946 TRACE("(GLuint fence = %d)", fence); 4947 4948 es2::Context *context = es2::getContext(); 4949 4950 if(context) 4951 { 4952 es2::Fence *fenceObject = context->getFence(fence); 4953 4954 if(!fenceObject) 4955 { 4956 return error(GL_INVALID_OPERATION, GL_TRUE); 4957 } 4958 4959 return fenceObject->testFence(); 4960 } 4961 4962 return GL_TRUE; 4963 } 4964 4965 void TexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, 4966 GLint border, GLenum format, GLenum type, const GLvoid* data) 4967 { 4968 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, GLsizei height = %d, " 4969 "GLint border = %d, GLenum format = 0x%X, GLenum type = 0x%X, const GLvoid* data = %p)", 4970 target, level, internalformat, width, height, border, format, type, data); 4971 4972 if(!validImageSize(level, width, height)) 4973 { 4974 return error(GL_INVALID_VALUE); 4975 } 4976 4977 es2::Context *context = es2::getContext(); 4978 4979 if(context) 4980 { 4981 // Core OpenGL ES 2.0 requires format and internalformat to be equal (checked below), 4982 // but GL_APPLE_texture_format_BGRA8888 allows (only) GL_BGRA_EXT / GL_RGBA, while 4983 // GL_EXT_texture_format_BGRA8888 also allows GL_BGRA_EXT / GL_BGRA_EXT. 4984 if(format == GL_BGRA_EXT && internalformat == GL_RGBA) 4985 { 4986 internalformat = GL_BGRA_EXT; 4987 } 4988 4989 GLint clientVersion = context->getClientVersion(); 4990 if(clientVersion < 3) 4991 { 4992 if((internalformat != (GLint)format) && 4993 !((type == GL_FLOAT) && (format == GL_RGBA) && (internalformat == GL_RGBA32F))) // CHROMIUM_color_buffer_float_rgba 4994 { 4995 return error(GL_INVALID_OPERATION); 4996 } 4997 } 4998 4999 GLenum validationError = ValidateTextureFormatType(format, type, internalformat, target, clientVersion); 5000 if(validationError != GL_NO_ERROR) 5001 { 5002 return error(validationError); 5003 } 5004 5005 if(border != 0) 5006 { 5007 return error(GL_INVALID_VALUE); 5008 } 5009 5010 switch(target) 5011 { 5012 case GL_TEXTURE_RECTANGLE_ARB: 5013 if(level != 0) 5014 { 5015 return error(GL_INVALID_VALUE); // Defining level other than 0 is not allowed 5016 } 5017 // Fall through to GL_TEXTURE_2D case. 5018 case GL_TEXTURE_2D: 5019 if(width > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) || 5020 height > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level)) 5021 { 5022 return error(GL_INVALID_VALUE); 5023 } 5024 break; 5025 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 5026 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 5027 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 5028 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 5029 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 5030 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 5031 if(width != height) 5032 { 5033 return error(GL_INVALID_VALUE); 5034 } 5035 5036 if(width > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level) || 5037 height > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level)) 5038 { 5039 return error(GL_INVALID_VALUE); 5040 } 5041 break; 5042 default: 5043 return error(GL_INVALID_ENUM); 5044 } 5045 5046 validationError = context->getPixels(&data, type, context->getRequiredBufferSize(width, height, 1, format, type)); 5047 if(validationError != GL_NO_ERROR) 5048 { 5049 return error(validationError); 5050 } 5051 5052 GLint sizedInternalFormat = gl::GetSizedInternalFormat(internalformat, type); 5053 5054 if(target == GL_TEXTURE_2D || target == GL_TEXTURE_RECTANGLE_ARB) 5055 { 5056 es2::Texture2D *texture = context->getTexture2D(target); 5057 5058 if(!texture) 5059 { 5060 return error(GL_INVALID_OPERATION); 5061 } 5062 5063 texture->setImage(level, width, height, sizedInternalFormat, format, type, context->getUnpackParameters(), data); 5064 } 5065 else 5066 { 5067 es2::TextureCubeMap *texture = context->getTextureCubeMap(); 5068 5069 if(!texture) 5070 { 5071 return error(GL_INVALID_OPERATION); 5072 } 5073 5074 texture->setImage(target, level, width, height, sizedInternalFormat, format, type, context->getUnpackParameters(), data); 5075 } 5076 } 5077 } 5078 5079 void TexParameterf(GLenum target, GLenum pname, GLfloat param) 5080 { 5081 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", target, pname, param); 5082 5083 es2::Context *context = es2::getContext(); 5084 5085 if(context) 5086 { 5087 es2::Texture *texture; 5088 5089 GLint clientVersion = context->getClientVersion(); 5090 5091 switch(target) 5092 { 5093 case GL_TEXTURE_2D: 5094 texture = context->getTexture2D(); 5095 break; 5096 case GL_TEXTURE_2D_ARRAY: 5097 if(clientVersion < 3) 5098 { 5099 return error(GL_INVALID_ENUM); 5100 } 5101 else 5102 { 5103 texture = context->getTexture2DArray(); 5104 } 5105 break; 5106 case GL_TEXTURE_3D: 5107 texture = context->getTexture3D(); 5108 break; 5109 case GL_TEXTURE_CUBE_MAP: 5110 texture = context->getTextureCubeMap(); 5111 break; 5112 case GL_TEXTURE_EXTERNAL_OES: 5113 texture = context->getTextureExternal(); 5114 break; 5115 case GL_TEXTURE_RECTANGLE_ARB: 5116 texture = context->getTexture2DRect(); 5117 break; 5118 default: 5119 return error(GL_INVALID_ENUM); 5120 } 5121 5122 switch(pname) 5123 { 5124 case GL_TEXTURE_WRAP_S: 5125 if(!texture->setWrapS((GLenum)param)) 5126 { 5127 return error(GL_INVALID_ENUM); 5128 } 5129 break; 5130 case GL_TEXTURE_WRAP_T: 5131 if(!texture->setWrapT((GLenum)param)) 5132 { 5133 return error(GL_INVALID_ENUM); 5134 } 5135 break; 5136 case GL_TEXTURE_WRAP_R_OES: 5137 if(!texture->setWrapR((GLenum)param)) 5138 { 5139 return error(GL_INVALID_ENUM); 5140 } 5141 break; 5142 case GL_TEXTURE_MIN_FILTER: 5143 if(!texture->setMinFilter((GLenum)param)) 5144 { 5145 return error(GL_INVALID_ENUM); 5146 } 5147 break; 5148 case GL_TEXTURE_MAG_FILTER: 5149 if(!texture->setMagFilter((GLenum)param)) 5150 { 5151 return error(GL_INVALID_ENUM); 5152 } 5153 break; 5154 case GL_TEXTURE_MAX_ANISOTROPY_EXT: 5155 if(!texture->setMaxAnisotropy(param)) 5156 { 5157 return error(GL_INVALID_VALUE); 5158 } 5159 break; 5160 case GL_TEXTURE_BASE_LEVEL: 5161 if(clientVersion < 3 || !texture->setBaseLevel((GLint)(roundf(param)))) 5162 { 5163 return error(GL_INVALID_VALUE); 5164 } 5165 break; 5166 case GL_TEXTURE_COMPARE_FUNC: 5167 if(clientVersion < 3 || !texture->setCompareFunc((GLenum)param)) 5168 { 5169 return error(GL_INVALID_VALUE); 5170 } 5171 break; 5172 case GL_TEXTURE_COMPARE_MODE: 5173 if(clientVersion < 3 || !texture->setCompareMode((GLenum)param)) 5174 { 5175 return error(GL_INVALID_VALUE); 5176 } 5177 break; 5178 case GL_TEXTURE_MAX_LEVEL: 5179 if(clientVersion < 3 || !texture->setMaxLevel((GLint)(roundf(param)))) 5180 { 5181 return error(GL_INVALID_VALUE); 5182 } 5183 break; 5184 case GL_TEXTURE_MAX_LOD: 5185 if(clientVersion < 3 || !texture->setMaxLOD(param)) 5186 { 5187 return error(GL_INVALID_VALUE); 5188 } 5189 break; 5190 case GL_TEXTURE_MIN_LOD: 5191 if(clientVersion < 3 || !texture->setMinLOD(param)) 5192 { 5193 return error(GL_INVALID_VALUE); 5194 } 5195 break; 5196 case GL_TEXTURE_SWIZZLE_R: 5197 if(clientVersion < 3 || !texture->setSwizzleR((GLenum)param)) 5198 { 5199 return error(GL_INVALID_VALUE); 5200 } 5201 break; 5202 case GL_TEXTURE_SWIZZLE_G: 5203 if(clientVersion < 3 || !texture->setSwizzleG((GLenum)param)) 5204 { 5205 return error(GL_INVALID_VALUE); 5206 } 5207 break; 5208 case GL_TEXTURE_SWIZZLE_B: 5209 if(clientVersion < 3 || !texture->setSwizzleB((GLenum)param)) 5210 { 5211 return error(GL_INVALID_VALUE); 5212 } 5213 break; 5214 case GL_TEXTURE_SWIZZLE_A: 5215 if(clientVersion < 3 || !texture->setSwizzleA((GLenum)param)) 5216 { 5217 return error(GL_INVALID_VALUE); 5218 } 5219 break; 5220 default: 5221 return error(GL_INVALID_ENUM); 5222 } 5223 } 5224 } 5225 5226 void TexParameterfv(GLenum target, GLenum pname, const GLfloat* params) 5227 { 5228 glTexParameterf(target, pname, *params); 5229 } 5230 5231 void TexParameteri(GLenum target, GLenum pname, GLint param) 5232 { 5233 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param); 5234 5235 es2::Context *context = es2::getContext(); 5236 5237 if(context) 5238 { 5239 es2::Texture *texture; 5240 5241 GLint clientVersion = context->getClientVersion(); 5242 5243 switch(target) 5244 { 5245 case GL_TEXTURE_2D: 5246 texture = context->getTexture2D(); 5247 break; 5248 case GL_TEXTURE_2D_ARRAY: 5249 if(clientVersion < 3) 5250 { 5251 return error(GL_INVALID_ENUM); 5252 } 5253 else 5254 { 5255 texture = context->getTexture2DArray(); 5256 } 5257 break; 5258 case GL_TEXTURE_3D: 5259 texture = context->getTexture3D(); 5260 break; 5261 case GL_TEXTURE_CUBE_MAP: 5262 texture = context->getTextureCubeMap(); 5263 break; 5264 case GL_TEXTURE_EXTERNAL_OES: 5265 texture = context->getTextureExternal(); 5266 break; 5267 case GL_TEXTURE_RECTANGLE_ARB: 5268 texture = context->getTexture2DRect(); 5269 break; 5270 default: 5271 return error(GL_INVALID_ENUM); 5272 } 5273 5274 switch(pname) 5275 { 5276 case GL_TEXTURE_WRAP_S: 5277 if(!texture->setWrapS((GLenum)param)) 5278 { 5279 return error(GL_INVALID_ENUM); 5280 } 5281 break; 5282 case GL_TEXTURE_WRAP_T: 5283 if(!texture->setWrapT((GLenum)param)) 5284 { 5285 return error(GL_INVALID_ENUM); 5286 } 5287 break; 5288 case GL_TEXTURE_WRAP_R_OES: 5289 if(!texture->setWrapR((GLenum)param)) 5290 { 5291 return error(GL_INVALID_ENUM); 5292 } 5293 break; 5294 case GL_TEXTURE_MIN_FILTER: 5295 if(!texture->setMinFilter((GLenum)param)) 5296 { 5297 return error(GL_INVALID_ENUM); 5298 } 5299 break; 5300 case GL_TEXTURE_MAG_FILTER: 5301 if(!texture->setMagFilter((GLenum)param)) 5302 { 5303 return error(GL_INVALID_ENUM); 5304 } 5305 break; 5306 case GL_TEXTURE_MAX_ANISOTROPY_EXT: 5307 if(!texture->setMaxAnisotropy((GLfloat)param)) 5308 { 5309 return error(GL_INVALID_VALUE); 5310 } 5311 break; 5312 case GL_TEXTURE_BASE_LEVEL: 5313 if((texture->getTarget() == GL_TEXTURE_RECTANGLE_ARB) && (param != 0)) 5314 { 5315 return error(GL_INVALID_OPERATION); // Base level has to be 0 5316 } 5317 if(clientVersion < 3 || !texture->setBaseLevel(param)) 5318 { 5319 return error(GL_INVALID_VALUE); 5320 } 5321 break; 5322 case GL_TEXTURE_COMPARE_FUNC: 5323 if(clientVersion < 3 || !texture->setCompareFunc((GLenum)param)) 5324 { 5325 return error(GL_INVALID_VALUE); 5326 } 5327 break; 5328 case GL_TEXTURE_COMPARE_MODE: 5329 if(clientVersion < 3 || !texture->setCompareMode((GLenum)param)) 5330 { 5331 return error(GL_INVALID_VALUE); 5332 } 5333 break; 5334 case GL_TEXTURE_MAX_LEVEL: 5335 if(clientVersion < 3 || !texture->setMaxLevel(param)) 5336 { 5337 return error(GL_INVALID_VALUE); 5338 } 5339 break; 5340 case GL_TEXTURE_MAX_LOD: 5341 if(clientVersion < 3 || !texture->setMaxLOD((GLfloat)param)) 5342 { 5343 return error(GL_INVALID_VALUE); 5344 } 5345 break; 5346 case GL_TEXTURE_MIN_LOD: 5347 if(clientVersion < 3 || !texture->setMinLOD((GLfloat)param)) 5348 { 5349 return error(GL_INVALID_VALUE); 5350 } 5351 break; 5352 case GL_TEXTURE_SWIZZLE_R: 5353 if(clientVersion < 3 || !texture->setSwizzleR((GLenum)param)) 5354 { 5355 return error(GL_INVALID_VALUE); 5356 } 5357 break; 5358 case GL_TEXTURE_SWIZZLE_G: 5359 if(clientVersion < 3 || !texture->setSwizzleG((GLenum)param)) 5360 { 5361 return error(GL_INVALID_VALUE); 5362 } 5363 break; 5364 case GL_TEXTURE_SWIZZLE_B: 5365 if(clientVersion < 3 || !texture->setSwizzleB((GLenum)param)) 5366 { 5367 return error(GL_INVALID_VALUE); 5368 } 5369 break; 5370 case GL_TEXTURE_SWIZZLE_A: 5371 if(clientVersion < 3 || !texture->setSwizzleA((GLenum)param)) 5372 { 5373 return error(GL_INVALID_VALUE); 5374 } 5375 break; 5376 default: 5377 return error(GL_INVALID_ENUM); 5378 } 5379 } 5380 } 5381 5382 void TexParameteriv(GLenum target, GLenum pname, const GLint* params) 5383 { 5384 glTexParameteri(target, pname, *params); 5385 } 5386 5387 void TexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, 5388 GLenum format, GLenum type, const GLvoid* data) 5389 { 5390 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, " 5391 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, " 5392 "const GLvoid* data = %p)", 5393 target, level, xoffset, yoffset, width, height, format, type, data); 5394 5395 if(!es2::IsTextureTarget(target)) 5396 { 5397 return error(GL_INVALID_ENUM); 5398 } 5399 5400 if(level < 0 || level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS) 5401 { 5402 return error(GL_INVALID_VALUE); 5403 } 5404 5405 if(xoffset < 0 || yoffset < 0 || width < 0 || height < 0) 5406 { 5407 return error(GL_INVALID_VALUE); 5408 } 5409 5410 if(std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height) 5411 { 5412 return error(GL_INVALID_VALUE); 5413 } 5414 5415 es2::Context *context = es2::getContext(); 5416 5417 if(context) 5418 { 5419 if(target == GL_TEXTURE_2D || target == GL_TEXTURE_RECTANGLE_ARB) 5420 { 5421 es2::Texture2D *texture = context->getTexture2D(target); 5422 5423 GLenum validationError = ValidateSubImageParams(false, false, target, level, xoffset, yoffset, width, height, format, type, texture, context->getClientVersion()); 5424 if(validationError != GL_NO_ERROR) 5425 { 5426 return error(validationError); 5427 } 5428 5429 validationError = context->getPixels(&data, type, context->getRequiredBufferSize(width, height, 1, format, type)); 5430 if(validationError != GL_NO_ERROR) 5431 { 5432 return error(validationError); 5433 } 5434 5435 texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackParameters(), data); 5436 } 5437 else if(es2::IsCubemapTextureTarget(target)) 5438 { 5439 es2::TextureCubeMap *texture = context->getTextureCubeMap(); 5440 5441 GLenum validationError = ValidateSubImageParams(false, false, target, level, xoffset, yoffset, width, height, format, type, texture, context->getClientVersion()); 5442 if(validationError != GL_NO_ERROR) 5443 { 5444 return error(validationError); 5445 } 5446 5447 validationError = context->getPixels(&data, type, context->getRequiredBufferSize(width, height, 1, format, type)); 5448 if(validationError != GL_NO_ERROR) 5449 { 5450 return error(validationError); 5451 } 5452 5453 texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackParameters(), data); 5454 } 5455 else UNREACHABLE(target); 5456 } 5457 } 5458 5459 void Uniform1f(GLint location, GLfloat x) 5460 { 5461 glUniform1fv(location, 1, &x); 5462 } 5463 5464 void Uniform1fv(GLint location, GLsizei count, const GLfloat* v) 5465 { 5466 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v); 5467 5468 if(count < 0) 5469 { 5470 return error(GL_INVALID_VALUE); 5471 } 5472 5473 es2::Context *context = es2::getContext(); 5474 5475 if(context) 5476 { 5477 es2::Program *program = context->getCurrentProgram(); 5478 5479 if(!program) 5480 { 5481 return error(GL_INVALID_OPERATION); 5482 } 5483 5484 if(location == -1) 5485 { 5486 return; 5487 } 5488 5489 if(!program->setUniform1fv(location, count, v)) 5490 { 5491 return error(GL_INVALID_OPERATION); 5492 } 5493 } 5494 } 5495 5496 void Uniform1i(GLint location, GLint x) 5497 { 5498 glUniform1iv(location, 1, &x); 5499 } 5500 5501 void Uniform1iv(GLint location, GLsizei count, const GLint* v) 5502 { 5503 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v); 5504 5505 if(count < 0) 5506 { 5507 return error(GL_INVALID_VALUE); 5508 } 5509 5510 es2::Context *context = es2::getContext(); 5511 5512 if(context) 5513 { 5514 es2::Program *program = context->getCurrentProgram(); 5515 5516 if(!program) 5517 { 5518 return error(GL_INVALID_OPERATION); 5519 } 5520 5521 if(location == -1) 5522 { 5523 return; 5524 } 5525 5526 if(!program->setUniform1iv(location, count, v)) 5527 { 5528 return error(GL_INVALID_OPERATION); 5529 } 5530 } 5531 } 5532 5533 void Uniform2f(GLint location, GLfloat x, GLfloat y) 5534 { 5535 GLfloat xy[2] = {x, y}; 5536 5537 glUniform2fv(location, 1, (GLfloat*)&xy); 5538 } 5539 5540 void Uniform2fv(GLint location, GLsizei count, const GLfloat* v) 5541 { 5542 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v); 5543 5544 if(count < 0) 5545 { 5546 return error(GL_INVALID_VALUE); 5547 } 5548 5549 es2::Context *context = es2::getContext(); 5550 5551 if(context) 5552 { 5553 es2::Program *program = context->getCurrentProgram(); 5554 5555 if(!program) 5556 { 5557 return error(GL_INVALID_OPERATION); 5558 } 5559 5560 if(location == -1) 5561 { 5562 return; 5563 } 5564 5565 if(!program->setUniform2fv(location, count, v)) 5566 { 5567 return error(GL_INVALID_OPERATION); 5568 } 5569 } 5570 } 5571 5572 void Uniform2i(GLint location, GLint x, GLint y) 5573 { 5574 GLint xy[4] = {x, y}; 5575 5576 glUniform2iv(location, 1, (GLint*)&xy); 5577 } 5578 5579 void Uniform2iv(GLint location, GLsizei count, const GLint* v) 5580 { 5581 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v); 5582 5583 if(count < 0) 5584 { 5585 return error(GL_INVALID_VALUE); 5586 } 5587 5588 es2::Context *context = es2::getContext(); 5589 5590 if(context) 5591 { 5592 es2::Program *program = context->getCurrentProgram(); 5593 5594 if(!program) 5595 { 5596 return error(GL_INVALID_OPERATION); 5597 } 5598 5599 if(location == -1) 5600 { 5601 return; 5602 } 5603 5604 if(!program->setUniform2iv(location, count, v)) 5605 { 5606 return error(GL_INVALID_OPERATION); 5607 } 5608 } 5609 } 5610 5611 void Uniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z) 5612 { 5613 GLfloat xyz[3] = {x, y, z}; 5614 5615 glUniform3fv(location, 1, (GLfloat*)&xyz); 5616 } 5617 5618 void Uniform3fv(GLint location, GLsizei count, const GLfloat* v) 5619 { 5620 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v); 5621 5622 if(count < 0) 5623 { 5624 return error(GL_INVALID_VALUE); 5625 } 5626 5627 es2::Context *context = es2::getContext(); 5628 5629 if(context) 5630 { 5631 es2::Program *program = context->getCurrentProgram(); 5632 5633 if(!program) 5634 { 5635 return error(GL_INVALID_OPERATION); 5636 } 5637 5638 if(location == -1) 5639 { 5640 return; 5641 } 5642 5643 if(!program->setUniform3fv(location, count, v)) 5644 { 5645 return error(GL_INVALID_OPERATION); 5646 } 5647 } 5648 } 5649 5650 void Uniform3i(GLint location, GLint x, GLint y, GLint z) 5651 { 5652 GLint xyz[3] = {x, y, z}; 5653 5654 glUniform3iv(location, 1, (GLint*)&xyz); 5655 } 5656 5657 void Uniform3iv(GLint location, GLsizei count, const GLint* v) 5658 { 5659 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v); 5660 5661 if(count < 0) 5662 { 5663 return error(GL_INVALID_VALUE); 5664 } 5665 5666 es2::Context *context = es2::getContext(); 5667 5668 if(context) 5669 { 5670 es2::Program *program = context->getCurrentProgram(); 5671 5672 if(!program) 5673 { 5674 return error(GL_INVALID_OPERATION); 5675 } 5676 5677 if(location == -1) 5678 { 5679 return; 5680 } 5681 5682 if(!program->setUniform3iv(location, count, v)) 5683 { 5684 return error(GL_INVALID_OPERATION); 5685 } 5686 } 5687 } 5688 5689 void Uniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w) 5690 { 5691 GLfloat xyzw[4] = {x, y, z, w}; 5692 5693 glUniform4fv(location, 1, (GLfloat*)&xyzw); 5694 } 5695 5696 void Uniform4fv(GLint location, GLsizei count, const GLfloat* v) 5697 { 5698 TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v); 5699 5700 if(count < 0) 5701 { 5702 return error(GL_INVALID_VALUE); 5703 } 5704 5705 es2::Context *context = es2::getContext(); 5706 5707 if(context) 5708 { 5709 es2::Program *program = context->getCurrentProgram(); 5710 5711 if(!program) 5712 { 5713 return error(GL_INVALID_OPERATION); 5714 } 5715 5716 if(location == -1) 5717 { 5718 return; 5719 } 5720 5721 if(!program->setUniform4fv(location, count, v)) 5722 { 5723 return error(GL_INVALID_OPERATION); 5724 } 5725 } 5726 } 5727 5728 void Uniform4i(GLint location, GLint x, GLint y, GLint z, GLint w) 5729 { 5730 GLint xyzw[4] = {x, y, z, w}; 5731 5732 glUniform4iv(location, 1, (GLint*)&xyzw); 5733 } 5734 5735 void Uniform4iv(GLint location, GLsizei count, const GLint* v) 5736 { 5737 TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v); 5738 5739 if(count < 0) 5740 { 5741 return error(GL_INVALID_VALUE); 5742 } 5743 5744 es2::Context *context = es2::getContext(); 5745 5746 if(context) 5747 { 5748 es2::Program *program = context->getCurrentProgram(); 5749 5750 if(!program) 5751 { 5752 return error(GL_INVALID_OPERATION); 5753 } 5754 5755 if(location == -1) 5756 { 5757 return; 5758 } 5759 5760 if(!program->setUniform4iv(location, count, v)) 5761 { 5762 return error(GL_INVALID_OPERATION); 5763 } 5764 } 5765 } 5766 5767 void UniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) 5768 { 5769 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = %p)", 5770 location, count, transpose, value); 5771 5772 if(count < 0) 5773 { 5774 return error(GL_INVALID_VALUE); 5775 } 5776 5777 es2::Context *context = es2::getContext(); 5778 5779 if(context) 5780 { 5781 if(context->getClientVersion() < 3 && transpose != GL_FALSE) 5782 { 5783 return error(GL_INVALID_VALUE); 5784 } 5785 5786 es2::Program *program = context->getCurrentProgram(); 5787 5788 if(!program) 5789 { 5790 return error(GL_INVALID_OPERATION); 5791 } 5792 5793 if(location == -1) 5794 { 5795 return; 5796 } 5797 5798 if(!program->setUniformMatrix2fv(location, count, transpose, value)) 5799 { 5800 return error(GL_INVALID_OPERATION); 5801 } 5802 } 5803 } 5804 5805 void UniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) 5806 { 5807 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = %p)", 5808 location, count, transpose, value); 5809 5810 if(count < 0) 5811 { 5812 return error(GL_INVALID_VALUE); 5813 } 5814 5815 es2::Context *context = es2::getContext(); 5816 5817 if(context) 5818 { 5819 if(context->getClientVersion() < 3 && transpose != GL_FALSE) 5820 { 5821 return error(GL_INVALID_VALUE); 5822 } 5823 5824 es2::Program *program = context->getCurrentProgram(); 5825 5826 if(!program) 5827 { 5828 return error(GL_INVALID_OPERATION); 5829 } 5830 5831 if(location == -1) 5832 { 5833 return; 5834 } 5835 5836 if(!program->setUniformMatrix3fv(location, count, transpose, value)) 5837 { 5838 return error(GL_INVALID_OPERATION); 5839 } 5840 } 5841 } 5842 5843 void UniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) 5844 { 5845 TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = %p)", 5846 location, count, transpose, value); 5847 5848 if(count < 0) 5849 { 5850 return error(GL_INVALID_VALUE); 5851 } 5852 5853 es2::Context *context = es2::getContext(); 5854 5855 if(context) 5856 { 5857 if(context->getClientVersion() < 3 && transpose != GL_FALSE) 5858 { 5859 return error(GL_INVALID_VALUE); 5860 } 5861 5862 es2::Program *program = context->getCurrentProgram(); 5863 5864 if(!program) 5865 { 5866 return error(GL_INVALID_OPERATION); 5867 } 5868 5869 if(location == -1) 5870 { 5871 return; 5872 } 5873 5874 if(!program->setUniformMatrix4fv(location, count, transpose, value)) 5875 { 5876 return error(GL_INVALID_OPERATION); 5877 } 5878 } 5879 } 5880 5881 void UseProgram(GLuint program) 5882 { 5883 TRACE("(GLuint program = %d)", program); 5884 5885 es2::Context *context = es2::getContext(); 5886 5887 if(context) 5888 { 5889 es2::TransformFeedback* transformFeedback = context->getTransformFeedback(); 5890 if(transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused()) 5891 { 5892 return error(GL_INVALID_OPERATION); 5893 } 5894 5895 es2::Program *programObject = context->getProgram(program); 5896 5897 if(!programObject && program != 0) 5898 { 5899 if(context->getShader(program)) 5900 { 5901 return error(GL_INVALID_OPERATION); 5902 } 5903 else 5904 { 5905 return error(GL_INVALID_VALUE); 5906 } 5907 } 5908 5909 if(program != 0 && !programObject->isLinked()) 5910 { 5911 return error(GL_INVALID_OPERATION); 5912 } 5913 5914 context->useProgram(program); 5915 } 5916 } 5917 5918 void ValidateProgram(GLuint program) 5919 { 5920 TRACE("(GLuint program = %d)", program); 5921 5922 es2::Context *context = es2::getContext(); 5923 5924 if(context) 5925 { 5926 es2::Program *programObject = context->getProgram(program); 5927 5928 if(!programObject) 5929 { 5930 if(context->getShader(program)) 5931 { 5932 return error(GL_INVALID_OPERATION); 5933 } 5934 else 5935 { 5936 return error(GL_INVALID_VALUE); 5937 } 5938 } 5939 5940 programObject->validate(context->getDevice()); 5941 } 5942 } 5943 5944 void VertexAttrib1f(GLuint index, GLfloat x) 5945 { 5946 TRACE("(GLuint index = %d, GLfloat x = %f)", index, x); 5947 5948 if(index >= es2::MAX_VERTEX_ATTRIBS) 5949 { 5950 return error(GL_INVALID_VALUE); 5951 } 5952 5953 es2::Context *context = es2::getContext(); 5954 5955 if(context) 5956 { 5957 GLfloat vals[4] = { x, 0, 0, 1 }; 5958 context->setVertexAttrib(index, vals); 5959 } 5960 } 5961 5962 void VertexAttrib1fv(GLuint index, const GLfloat* values) 5963 { 5964 TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values); 5965 5966 if(index >= es2::MAX_VERTEX_ATTRIBS) 5967 { 5968 return error(GL_INVALID_VALUE); 5969 } 5970 5971 es2::Context *context = es2::getContext(); 5972 5973 if(context) 5974 { 5975 GLfloat vals[4] = { values[0], 0, 0, 1 }; 5976 context->setVertexAttrib(index, vals); 5977 } 5978 } 5979 5980 void VertexAttrib2f(GLuint index, GLfloat x, GLfloat y) 5981 { 5982 TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y); 5983 5984 if(index >= es2::MAX_VERTEX_ATTRIBS) 5985 { 5986 return error(GL_INVALID_VALUE); 5987 } 5988 5989 es2::Context *context = es2::getContext(); 5990 5991 if(context) 5992 { 5993 GLfloat vals[4] = { x, y, 0, 1 }; 5994 context->setVertexAttrib(index, vals); 5995 } 5996 } 5997 5998 void VertexAttrib2fv(GLuint index, const GLfloat* values) 5999 { 6000 TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values); 6001 6002 if(index >= es2::MAX_VERTEX_ATTRIBS) 6003 { 6004 return error(GL_INVALID_VALUE); 6005 } 6006 6007 es2::Context *context = es2::getContext(); 6008 6009 if(context) 6010 { 6011 GLfloat vals[4] = { values[0], values[1], 0, 1 }; 6012 context->setVertexAttrib(index, vals); 6013 } 6014 } 6015 6016 void VertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z) 6017 { 6018 TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", index, x, y, z); 6019 6020 if(index >= es2::MAX_VERTEX_ATTRIBS) 6021 { 6022 return error(GL_INVALID_VALUE); 6023 } 6024 6025 es2::Context *context = es2::getContext(); 6026 6027 if(context) 6028 { 6029 GLfloat vals[4] = { x, y, z, 1 }; 6030 context->setVertexAttrib(index, vals); 6031 } 6032 } 6033 6034 void VertexAttrib3fv(GLuint index, const GLfloat* values) 6035 { 6036 TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values); 6037 6038 if(index >= es2::MAX_VERTEX_ATTRIBS) 6039 { 6040 return error(GL_INVALID_VALUE); 6041 } 6042 6043 es2::Context *context = es2::getContext(); 6044 6045 if(context) 6046 { 6047 GLfloat vals[4] = { values[0], values[1], values[2], 1 }; 6048 context->setVertexAttrib(index, vals); 6049 } 6050 } 6051 6052 void VertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) 6053 { 6054 TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f, GLfloat w = %f)", index, x, y, z, w); 6055 6056 if(index >= es2::MAX_VERTEX_ATTRIBS) 6057 { 6058 return error(GL_INVALID_VALUE); 6059 } 6060 6061 es2::Context *context = es2::getContext(); 6062 6063 if(context) 6064 { 6065 GLfloat vals[4] = { x, y, z, w }; 6066 context->setVertexAttrib(index, vals); 6067 } 6068 } 6069 6070 void VertexAttrib4fv(GLuint index, const GLfloat* values) 6071 { 6072 TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values); 6073 6074 if(index >= es2::MAX_VERTEX_ATTRIBS) 6075 { 6076 return error(GL_INVALID_VALUE); 6077 } 6078 6079 es2::Context *context = es2::getContext(); 6080 6081 if(context) 6082 { 6083 context->setVertexAttrib(index, values); 6084 } 6085 } 6086 6087 void VertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr) 6088 { 6089 TRACE("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, " 6090 "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = %p)", 6091 index, size, type, normalized, stride, ptr); 6092 6093 if(index >= es2::MAX_VERTEX_ATTRIBS) 6094 { 6095 return error(GL_INVALID_VALUE); 6096 } 6097 6098 if(size < 1 || size > 4) 6099 { 6100 return error(GL_INVALID_VALUE); 6101 } 6102 6103 GLint clientVersion = egl::getClientVersion(); 6104 6105 switch(type) 6106 { 6107 case GL_BYTE: 6108 case GL_UNSIGNED_BYTE: 6109 case GL_SHORT: 6110 case GL_UNSIGNED_SHORT: 6111 case GL_FIXED: 6112 case GL_FLOAT: 6113 case GL_HALF_FLOAT_OES: // GL_OES_vertex_half_float 6114 case GL_HALF_FLOAT: 6115 break; 6116 case GL_INT_2_10_10_10_REV: 6117 case GL_UNSIGNED_INT_2_10_10_10_REV: 6118 if(clientVersion >= 3) 6119 { 6120 if(size != 4) 6121 { 6122 return error(GL_INVALID_OPERATION); 6123 } 6124 break; 6125 } 6126 else return error(GL_INVALID_ENUM); 6127 case GL_INT: 6128 case GL_UNSIGNED_INT: 6129 if(clientVersion >= 3) 6130 { 6131 break; 6132 } 6133 else return error(GL_INVALID_ENUM); 6134 default: 6135 return error(GL_INVALID_ENUM); 6136 } 6137 6138 if(stride < 0) 6139 { 6140 return error(GL_INVALID_VALUE); 6141 } 6142 6143 es2::Context *context = es2::getContext(); 6144 6145 if(context) 6146 { 6147 es2::VertexArray* vertexArray = context->getCurrentVertexArray(); 6148 if((context->getArrayBufferName() == 0) && vertexArray && (vertexArray->name != 0) && ptr) 6149 { 6150 // GL_INVALID_OPERATION is generated if a non-zero vertex array object is bound, zero is bound 6151 // to the GL_ARRAY_BUFFER buffer object binding point and the pointer argument is not NULL. 6152 return error(GL_INVALID_OPERATION); 6153 } 6154 6155 context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), false, stride, ptr); 6156 } 6157 } 6158 6159 void Viewport(GLint x, GLint y, GLsizei width, GLsizei height) 6160 { 6161 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height); 6162 6163 if(width < 0 || height < 0) 6164 { 6165 return error(GL_INVALID_VALUE); 6166 } 6167 6168 es2::Context *context = es2::getContext(); 6169 6170 if(context) 6171 { 6172 context->setViewportParams(x, y, width, height); 6173 } 6174 } 6175 6176 static void BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter, bool allowPartialDepthStencilBlit) 6177 { 6178 TRACE("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, " 6179 "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, " 6180 "GLbitfield mask = 0x%X, GLenum filter = 0x%X)", 6181 srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter); 6182 6183 switch(filter) 6184 { 6185 case GL_NEAREST: 6186 break; 6187 default: 6188 return error(GL_INVALID_ENUM); 6189 } 6190 6191 if((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0) 6192 { 6193 return error(GL_INVALID_VALUE); 6194 } 6195 6196 es2::Context *context = es2::getContext(); 6197 6198 if(context) 6199 { 6200 if(context->getReadFramebufferName() == context->getDrawFramebufferName()) 6201 { 6202 ERR("Blits with the same source and destination framebuffer are not supported by this implementation."); 6203 return error(GL_INVALID_OPERATION); 6204 } 6205 6206 context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, false, allowPartialDepthStencilBlit); 6207 } 6208 } 6209 6210 void BlitFramebufferNV(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) 6211 { 6212 BlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter, true); 6213 } 6214 6215 void BlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, 6216 GLbitfield mask, GLenum filter) 6217 { 6218 if(srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0) 6219 { 6220 ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation"); 6221 return error(GL_INVALID_OPERATION); 6222 } 6223 6224 BlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter, false); 6225 } 6226 6227 void TexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, 6228 GLint border, GLenum format, GLenum type, const GLvoid* data) 6229 { 6230 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, " 6231 "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, " 6232 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* data = %p)", 6233 target, level, internalformat, width, height, depth, border, format, type, data); 6234 6235 switch(target) 6236 { 6237 case GL_TEXTURE_3D: 6238 switch(format) 6239 { 6240 case GL_DEPTH_COMPONENT: 6241 case GL_DEPTH_STENCIL_OES: 6242 return error(GL_INVALID_OPERATION); 6243 default: 6244 break; 6245 } 6246 break; 6247 default: 6248 return error(GL_INVALID_ENUM); 6249 } 6250 6251 if(internalformat != format) 6252 { 6253 return error(GL_INVALID_OPERATION); 6254 } 6255 6256 GLenum validationError = ValidateTextureFormatType(format, type, internalformat, target, egl::getClientVersion()); 6257 if(validationError != GL_NO_ERROR) 6258 { 6259 return error(validationError); 6260 } 6261 6262 if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)) 6263 { 6264 return error(GL_INVALID_VALUE); 6265 } 6266 6267 const GLsizei maxSize3D = es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level; 6268 if((width < 0) || (height < 0) || (depth < 0) || (width > maxSize3D) || (height > maxSize3D) || (depth > maxSize3D)) 6269 { 6270 return error(GL_INVALID_VALUE); 6271 } 6272 6273 if(border != 0) 6274 { 6275 return error(GL_INVALID_VALUE); 6276 } 6277 6278 es2::Context *context = es2::getContext(); 6279 6280 if(context) 6281 { 6282 es2::Texture3D *texture = context->getTexture3D(); 6283 6284 if(!texture) 6285 { 6286 return error(GL_INVALID_OPERATION); 6287 } 6288 6289 GLenum validationError = context->getPixels(&data, type, context->getRequiredBufferSize(width, height, depth, format, type)); 6290 if(validationError != GL_NO_ERROR) 6291 { 6292 return error(validationError); 6293 } 6294 6295 GLint sizedInternalFormat = gl::GetSizedInternalFormat(internalformat, type); 6296 texture->setImage(level, width, height, depth, sizedInternalFormat, format, type, context->getUnpackParameters(), data); 6297 } 6298 } 6299 6300 void TexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *data) 6301 { 6302 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, " 6303 "GLint zoffset = %d, GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, " 6304 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* data = %p)", 6305 target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, data); 6306 6307 switch(target) 6308 { 6309 case GL_TEXTURE_3D: 6310 break; 6311 default: 6312 return error(GL_INVALID_ENUM); 6313 } 6314 6315 if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)) 6316 { 6317 return error(GL_INVALID_VALUE); 6318 } 6319 6320 if((width < 0) || (height < 0) || (depth < 0)) 6321 { 6322 return error(GL_INVALID_VALUE); 6323 } 6324 6325 es2::Context *context = es2::getContext(); 6326 6327 if(context) 6328 { 6329 es2::Texture3D *texture = context->getTexture3D(); 6330 6331 GLenum validationError = ValidateSubImageParams(false, false, target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, texture, context->getClientVersion()); 6332 if(validationError != GL_NO_ERROR) 6333 { 6334 return error(validationError); 6335 } 6336 6337 validationError = context->getPixels(&data, type, context->getRequiredBufferSize(width, height, depth, format, type)); 6338 if(validationError != GL_NO_ERROR) 6339 { 6340 return error(validationError); 6341 } 6342 6343 texture->subImage(level, xoffset, yoffset, zoffset, width, height, depth, format, type, context->getUnpackParameters(), data); 6344 } 6345 } 6346 6347 void CopyTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) 6348 { 6349 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, " 6350 "GLint zoffset = %d, GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", 6351 target, level, xoffset, yoffset, zoffset, x, y, width, height); 6352 6353 switch(target) 6354 { 6355 case GL_TEXTURE_3D: 6356 break; 6357 default: 6358 return error(GL_INVALID_ENUM); 6359 } 6360 6361 if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)) 6362 { 6363 return error(GL_INVALID_VALUE); 6364 } 6365 6366 es2::Context *context = es2::getContext(); 6367 6368 if(context) 6369 { 6370 es2::Framebuffer *framebuffer = context->getReadFramebuffer(); 6371 6372 if(!framebuffer || (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)) 6373 { 6374 return error(GL_INVALID_FRAMEBUFFER_OPERATION); 6375 } 6376 6377 es2::Renderbuffer *source = framebuffer->getReadColorbuffer(); 6378 6379 if(context->getReadFramebufferName() != 0 && (!source || source->getSamples() > 1)) 6380 { 6381 return error(GL_INVALID_OPERATION); 6382 } 6383 6384 es2::Texture3D *texture = context->getTexture3D(); 6385 6386 GLenum validationError = ValidateSubImageParams(false, true, target, level, xoffset, yoffset, zoffset, width, height, 1, GL_NONE, GL_NONE, texture, context->getClientVersion()); 6387 if(validationError != GL_NO_ERROR) 6388 { 6389 return error(validationError); 6390 } 6391 6392 texture->copySubImage(target, level, xoffset, yoffset, zoffset, x, y, width, height, source); 6393 } 6394 } 6395 6396 void CompressedTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data) 6397 { 6398 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, " 6399 "GLsizei height = %d, GLsizei depth = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = %p)", 6400 target, level, internalformat, width, height, depth, border, imageSize, data); 6401 6402 switch(target) 6403 { 6404 case GL_TEXTURE_3D: 6405 break; 6406 default: 6407 return error(GL_INVALID_ENUM); 6408 } 6409 6410 if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)) 6411 { 6412 return error(GL_INVALID_VALUE); 6413 } 6414 6415 const GLsizei maxSize3D = es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level; 6416 if((width < 0) || (height < 0) || (depth < 0) || (width > maxSize3D) || (height > maxSize3D) || (depth > maxSize3D) ||(border != 0) || (imageSize < 0)) 6417 { 6418 return error(GL_INVALID_VALUE); 6419 } 6420 6421 if(!IsCompressed(internalformat, egl::getClientVersion())) 6422 { 6423 return error(GL_INVALID_ENUM); 6424 } 6425 6426 if(imageSize != gl::ComputeCompressedSize(width, height, internalformat) * depth) 6427 { 6428 return error(GL_INVALID_VALUE); 6429 } 6430 6431 es2::Context *context = es2::getContext(); 6432 6433 if(context) 6434 { 6435 es2::Texture3D *texture = context->getTexture3D(); 6436 6437 if(!texture) 6438 { 6439 return error(GL_INVALID_OPERATION); 6440 } 6441 6442 GLenum validationError = context->getPixels(&data, GL_UNSIGNED_BYTE, imageSize); 6443 6444 if(validationError != GL_NO_ERROR) 6445 { 6446 return error(validationError); 6447 } 6448 6449 texture->setCompressedImage(level, internalformat, width, height, depth, imageSize, data); 6450 } 6451 } 6452 6453 void CompressedTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data) 6454 { 6455 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, " 6456 "GLint zoffset = %d, GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, " 6457 "GLenum format = 0x%X, GLsizei imageSize = %d, const void *data = %p)", 6458 target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data); 6459 6460 switch(target) 6461 { 6462 case GL_TEXTURE_3D: 6463 break; 6464 default: 6465 return error(GL_INVALID_ENUM); 6466 } 6467 6468 if(level < 0 || level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS) 6469 { 6470 return error(GL_INVALID_VALUE); 6471 } 6472 6473 if(xoffset < 0 || yoffset < 0 || zoffset < 0 || !validImageSize(level, width, height) || depth < 0 || imageSize < 0) 6474 { 6475 return error(GL_INVALID_VALUE); 6476 } 6477 6478 if(!IsCompressed(format, egl::getClientVersion())) 6479 { 6480 return error(GL_INVALID_ENUM); 6481 } 6482 6483 if(imageSize != gl::ComputeCompressedSize(width, height, format) * depth) 6484 { 6485 return error(GL_INVALID_VALUE); 6486 } 6487 6488 es2::Context *context = es2::getContext(); 6489 6490 if(context) 6491 { 6492 es2::Texture3D *texture = context->getTexture3D(); 6493 6494 if(!texture) 6495 { 6496 return error(GL_INVALID_OPERATION); 6497 } 6498 6499 GLenum validationError = context->getPixels(&data, GL_UNSIGNED_BYTE, imageSize); 6500 if(validationError != GL_NO_ERROR) 6501 { 6502 return error(validationError); 6503 } 6504 6505 texture->subImageCompressed(level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data); 6506 } 6507 } 6508 6509 void FramebufferTexture3DOES(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset) 6510 { 6511 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, " 6512 "GLuint texture = %d, GLint level = %d, GLint zoffset = %d)", target, attachment, textarget, texture, level, zoffset); 6513 6514 if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER && target != GL_READ_FRAMEBUFFER) 6515 { 6516 return error(GL_INVALID_ENUM); 6517 } 6518 6519 es2::Context *context = es2::getContext(); 6520 6521 if(context) 6522 { 6523 if(texture == 0) 6524 { 6525 textarget = GL_NONE; 6526 } 6527 else 6528 { 6529 es2::Texture *tex = context->getTexture(texture); 6530 6531 if(!tex) 6532 { 6533 return error(GL_INVALID_OPERATION); 6534 } 6535 6536 if(tex->isCompressed(textarget, level)) 6537 { 6538 return error(GL_INVALID_OPERATION); 6539 } 6540 6541 switch(textarget) 6542 { 6543 case GL_TEXTURE_3D: 6544 if(tex->getTarget() != GL_TEXTURE_3D) 6545 { 6546 return error(GL_INVALID_OPERATION); 6547 } 6548 break; 6549 default: 6550 return error(GL_INVALID_ENUM); 6551 } 6552 6553 if(level != 0) 6554 { 6555 return error(GL_INVALID_VALUE); 6556 } 6557 } 6558 6559 es2::Framebuffer *framebuffer = nullptr; 6560 GLuint framebufferName = 0; 6561 if(target == GL_READ_FRAMEBUFFER) 6562 { 6563 framebuffer = context->getReadFramebuffer(); 6564 framebufferName = context->getReadFramebufferName(); 6565 } 6566 else 6567 { 6568 framebuffer = context->getDrawFramebuffer(); 6569 framebufferName = context->getDrawFramebufferName(); 6570 } 6571 6572 if(framebufferName == 0 || !framebuffer) 6573 { 6574 return error(GL_INVALID_OPERATION); 6575 } 6576 6577 GLint clientVersion = context->getClientVersion(); 6578 6579 switch(attachment) 6580 { 6581 case GL_COLOR_ATTACHMENT1: 6582 case GL_COLOR_ATTACHMENT2: 6583 case GL_COLOR_ATTACHMENT3: 6584 case GL_COLOR_ATTACHMENT4: 6585 case GL_COLOR_ATTACHMENT5: 6586 case GL_COLOR_ATTACHMENT6: 6587 case GL_COLOR_ATTACHMENT7: 6588 case GL_COLOR_ATTACHMENT8: 6589 case GL_COLOR_ATTACHMENT9: 6590 case GL_COLOR_ATTACHMENT10: 6591 case GL_COLOR_ATTACHMENT11: 6592 case GL_COLOR_ATTACHMENT12: 6593 case GL_COLOR_ATTACHMENT13: 6594 case GL_COLOR_ATTACHMENT14: 6595 case GL_COLOR_ATTACHMENT15: 6596 case GL_COLOR_ATTACHMENT16: 6597 case GL_COLOR_ATTACHMENT17: 6598 case GL_COLOR_ATTACHMENT18: 6599 case GL_COLOR_ATTACHMENT19: 6600 case GL_COLOR_ATTACHMENT20: 6601 case GL_COLOR_ATTACHMENT21: 6602 case GL_COLOR_ATTACHMENT22: 6603 case GL_COLOR_ATTACHMENT23: 6604 case GL_COLOR_ATTACHMENT24: 6605 case GL_COLOR_ATTACHMENT25: 6606 case GL_COLOR_ATTACHMENT26: 6607 case GL_COLOR_ATTACHMENT27: 6608 case GL_COLOR_ATTACHMENT28: 6609 case GL_COLOR_ATTACHMENT29: 6610 case GL_COLOR_ATTACHMENT30: 6611 case GL_COLOR_ATTACHMENT31: 6612 if(clientVersion < 3) 6613 { 6614 return error(GL_INVALID_ENUM); 6615 } 6616 // fall through 6617 case GL_COLOR_ATTACHMENT0: 6618 if((attachment - GL_COLOR_ATTACHMENT0) >= MAX_COLOR_ATTACHMENTS) 6619 { 6620 return error(GL_INVALID_ENUM); 6621 } 6622 framebuffer->setColorbuffer(textarget, texture, attachment - GL_COLOR_ATTACHMENT0); 6623 break; 6624 case GL_DEPTH_ATTACHMENT: framebuffer->setDepthbuffer(textarget, texture); break; 6625 case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture); break; 6626 default: 6627 return error(GL_INVALID_ENUM); 6628 } 6629 } 6630 } 6631 6632 void EGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image) 6633 { 6634 if(egl::getClientVersion() == 1) 6635 { 6636 return libGLES_CM->glEGLImageTargetTexture2DOES(target, image); 6637 } 6638 6639 TRACE("(GLenum target = 0x%X, GLeglImageOES image = %p)", target, image); 6640 6641 switch(target) 6642 { 6643 case GL_TEXTURE_2D: 6644 case GL_TEXTURE_RECTANGLE_ARB: 6645 case GL_TEXTURE_EXTERNAL_OES: 6646 break; 6647 default: 6648 return error(GL_INVALID_ENUM); 6649 } 6650 6651 es2::Context *context = es2::getContext(); 6652 6653 if(context) 6654 { 6655 es2::Texture2D *texture = context->getTexture2D(target); 6656 6657 if(!texture) 6658 { 6659 return error(GL_INVALID_OPERATION); 6660 } 6661 6662 egl::Image *eglImage = context->getSharedImage(image); 6663 6664 if(!eglImage) 6665 { 6666 return error(GL_INVALID_OPERATION); 6667 } 6668 6669 texture->setSharedImage(eglImage); 6670 } 6671 } 6672 6673 void EGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image) 6674 { 6675 TRACE("(GLenum target = 0x%X, GLeglImageOES image = %p)", target, image); 6676 6677 UNIMPLEMENTED(); 6678 } 6679 6680 GLboolean IsRenderbufferOES(GLuint renderbuffer) 6681 { 6682 return IsRenderbuffer(renderbuffer); 6683 } 6684 6685 void BindRenderbufferOES(GLenum target, GLuint renderbuffer) 6686 { 6687 BindRenderbuffer(target, renderbuffer); 6688 } 6689 6690 void DeleteRenderbuffersOES(GLsizei n, const GLuint* renderbuffers) 6691 { 6692 DeleteRenderbuffers(n, renderbuffers); 6693 } 6694 6695 void GenRenderbuffersOES(GLsizei n, GLuint* renderbuffers) 6696 { 6697 GenRenderbuffers(n, renderbuffers); 6698 } 6699 6700 void RenderbufferStorageOES(GLenum target, GLenum internalformat, GLsizei width, GLsizei height) 6701 { 6702 RenderbufferStorage(target, internalformat, width, height); 6703 } 6704 6705 void GetRenderbufferParameterivOES(GLenum target, GLenum pname, GLint* params) 6706 { 6707 GetRenderbufferParameteriv(target, pname, params); 6708 } 6709 6710 GLboolean IsFramebufferOES(GLuint framebuffer) 6711 { 6712 return IsFramebuffer(framebuffer); 6713 } 6714 6715 void BindFramebufferOES(GLenum target, GLuint framebuffer) 6716 { 6717 BindFramebuffer(target, framebuffer); 6718 } 6719 6720 void DeleteFramebuffersOES(GLsizei n, const GLuint* framebuffers) 6721 { 6722 DeleteFramebuffers(n, framebuffers); 6723 } 6724 6725 void GenFramebuffersOES(GLsizei n, GLuint* framebuffers) 6726 { 6727 GenFramebuffers(n, framebuffers); 6728 } 6729 6730 GLenum CheckFramebufferStatusOES(GLenum target) 6731 { 6732 return CheckFramebufferStatus(target); 6733 } 6734 6735 void FramebufferRenderbufferOES(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) 6736 { 6737 FramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer); 6738 } 6739 6740 void FramebufferTexture2DOES(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) 6741 { 6742 FramebufferTexture2D(target, attachment, textarget, texture, level); 6743 } 6744 6745 void GetFramebufferAttachmentParameterivOES(GLenum target, GLenum attachment, GLenum pname, GLint* params) 6746 { 6747 GetFramebufferAttachmentParameteriv(target, attachment, pname, params); 6748 } 6749 6750 void GenerateMipmapOES(GLenum target) 6751 { 6752 GenerateMipmap(target); 6753 } 6754 6755 void DrawBuffersEXT(GLsizei n, const GLenum *bufs) 6756 { 6757 TRACE("(GLsizei n = %d, const GLenum *bufs = %p)", n, bufs); 6758 6759 if(n < 0 || n > MAX_DRAW_BUFFERS) 6760 { 6761 return error(GL_INVALID_VALUE); 6762 } 6763 6764 es2::Context *context = es2::getContext(); 6765 6766 if(context) 6767 { 6768 GLuint drawFramebufferName = context->getDrawFramebufferName(); 6769 6770 if((drawFramebufferName == 0) && (n != 1)) 6771 { 6772 return error(GL_INVALID_OPERATION); 6773 } 6774 6775 for(unsigned int i = 0; i < (unsigned)n; i++) 6776 { 6777 switch(bufs[i]) 6778 { 6779 case GL_BACK: 6780 if(drawFramebufferName != 0) 6781 { 6782 return error(GL_INVALID_OPERATION); 6783 } 6784 break; 6785 case GL_NONE: 6786 break; 6787 case GL_COLOR_ATTACHMENT0_EXT: 6788 case GL_COLOR_ATTACHMENT1_EXT: 6789 case GL_COLOR_ATTACHMENT2_EXT: 6790 case GL_COLOR_ATTACHMENT3_EXT: 6791 case GL_COLOR_ATTACHMENT4_EXT: 6792 case GL_COLOR_ATTACHMENT5_EXT: 6793 case GL_COLOR_ATTACHMENT6_EXT: 6794 case GL_COLOR_ATTACHMENT7_EXT: 6795 case GL_COLOR_ATTACHMENT8_EXT: 6796 case GL_COLOR_ATTACHMENT9_EXT: 6797 case GL_COLOR_ATTACHMENT10_EXT: 6798 case GL_COLOR_ATTACHMENT11_EXT: 6799 case GL_COLOR_ATTACHMENT12_EXT: 6800 case GL_COLOR_ATTACHMENT13_EXT: 6801 case GL_COLOR_ATTACHMENT14_EXT: 6802 case GL_COLOR_ATTACHMENT15_EXT: 6803 { 6804 GLuint index = (bufs[i] - GL_COLOR_ATTACHMENT0_EXT); 6805 6806 if(index >= MAX_COLOR_ATTACHMENTS) 6807 { 6808 return error(GL_INVALID_OPERATION); 6809 } 6810 6811 if(index != i) 6812 { 6813 return error(GL_INVALID_OPERATION); 6814 } 6815 6816 if(drawFramebufferName == 0) 6817 { 6818 return error(GL_INVALID_OPERATION); 6819 } 6820 } 6821 break; 6822 default: 6823 return error(GL_INVALID_ENUM); 6824 } 6825 } 6826 6827 context->setFramebufferDrawBuffers(n, bufs); 6828 } 6829 } 6830 6831 } 6832 6833 extern "C" NO_SANITIZE_FUNCTION __eglMustCastToProperFunctionPointerType es2GetProcAddress(const char *procname) 6834 { 6835 struct Function 6836 { 6837 const char *name; 6838 __eglMustCastToProperFunctionPointerType address; 6839 }; 6840 6841 struct CompareFunctor 6842 { 6843 bool operator()(const Function &a, const Function &b) const 6844 { 6845 return strcmp(a.name, b.name) < 0; 6846 } 6847 }; 6848 6849 // This array must be kept sorted with respect to strcmp(), so that binary search works correctly. 6850 // The Unix command "LC_COLLATE=C sort" will generate the correct order. 6851 static const Function glFunctions[] = 6852 { 6853 #define FUNCTION(name) {#name, (__eglMustCastToProperFunctionPointerType)name} 6854 6855 FUNCTION(glActiveTexture), 6856 FUNCTION(glAttachShader), 6857 FUNCTION(glBeginQuery), 6858 FUNCTION(glBeginQueryEXT), 6859 FUNCTION(glBeginTransformFeedback), 6860 FUNCTION(glBindAttribLocation), 6861 FUNCTION(glBindBuffer), 6862 FUNCTION(glBindBufferBase), 6863 FUNCTION(glBindBufferRange), 6864 FUNCTION(glBindFramebuffer), 6865 FUNCTION(glBindFramebufferOES), 6866 FUNCTION(glBindRenderbuffer), 6867 FUNCTION(glBindRenderbufferOES), 6868 FUNCTION(glBindSampler), 6869 FUNCTION(glBindTexture), 6870 FUNCTION(glBindTransformFeedback), 6871 FUNCTION(glBindVertexArray), 6872 FUNCTION(glBlendColor), 6873 FUNCTION(glBlendEquation), 6874 FUNCTION(glBlendEquationSeparate), 6875 FUNCTION(glBlendFunc), 6876 FUNCTION(glBlendFuncSeparate), 6877 FUNCTION(glBlitFramebuffer), 6878 FUNCTION(glBlitFramebufferANGLE), 6879 FUNCTION(glBufferData), 6880 FUNCTION(glBufferSubData), 6881 FUNCTION(glCheckFramebufferStatus), 6882 FUNCTION(glCheckFramebufferStatusOES), 6883 FUNCTION(glClear), 6884 FUNCTION(glClearBufferfi), 6885 FUNCTION(glClearBufferfv), 6886 FUNCTION(glClearBufferiv), 6887 FUNCTION(glClearBufferuiv), 6888 FUNCTION(glClearColor), 6889 FUNCTION(glClearDepthf), 6890 FUNCTION(glClearStencil), 6891 FUNCTION(glClientWaitSync), 6892 FUNCTION(glColorMask), 6893 FUNCTION(glCompileShader), 6894 FUNCTION(glCompressedTexImage2D), 6895 FUNCTION(glCompressedTexImage3D), 6896 FUNCTION(glCompressedTexSubImage2D), 6897 FUNCTION(glCompressedTexSubImage3D), 6898 FUNCTION(glCopyBufferSubData), 6899 FUNCTION(glCopyTexImage2D), 6900 FUNCTION(glCopyTexSubImage2D), 6901 FUNCTION(glCopyTexSubImage3D), 6902 FUNCTION(glCreateProgram), 6903 FUNCTION(glCreateShader), 6904 FUNCTION(glCullFace), 6905 FUNCTION(glDeleteBuffers), 6906 FUNCTION(glDeleteFencesNV), 6907 FUNCTION(glDeleteFramebuffers), 6908 FUNCTION(glDeleteFramebuffersOES), 6909 FUNCTION(glDeleteProgram), 6910 FUNCTION(glDeleteQueries), 6911 FUNCTION(glDeleteQueriesEXT), 6912 FUNCTION(glDeleteRenderbuffers), 6913 FUNCTION(glDeleteRenderbuffersOES), 6914 FUNCTION(glDeleteSamplers), 6915 FUNCTION(glDeleteShader), 6916 FUNCTION(glDeleteSync), 6917 FUNCTION(glDeleteTextures), 6918 FUNCTION(glDeleteTransformFeedbacks), 6919 FUNCTION(glDeleteVertexArrays), 6920 FUNCTION(glDepthFunc), 6921 FUNCTION(glDepthMask), 6922 FUNCTION(glDepthRangef), 6923 FUNCTION(glDetachShader), 6924 FUNCTION(glDisable), 6925 FUNCTION(glDisableVertexAttribArray), 6926 FUNCTION(glDrawArrays), 6927 FUNCTION(glDrawArraysInstanced), 6928 FUNCTION(glDrawBuffers), 6929 FUNCTION(glDrawBuffersEXT), 6930 FUNCTION(glDrawElements), 6931 FUNCTION(glDrawElementsInstanced), 6932 FUNCTION(glDrawRangeElements), 6933 FUNCTION(glEGLImageTargetRenderbufferStorageOES), 6934 FUNCTION(glEGLImageTargetTexture2DOES), 6935 FUNCTION(glEnable), 6936 FUNCTION(glEnableVertexAttribArray), 6937 FUNCTION(glEndQuery), 6938 FUNCTION(glEndQueryEXT), 6939 FUNCTION(glEndTransformFeedback), 6940 FUNCTION(glFenceSync), 6941 FUNCTION(glFinish), 6942 FUNCTION(glFinishFenceNV), 6943 FUNCTION(glFlush), 6944 FUNCTION(glFlushMappedBufferRange), 6945 FUNCTION(glFramebufferRenderbuffer), 6946 FUNCTION(glFramebufferRenderbufferOES), 6947 FUNCTION(glFramebufferTexture2D), 6948 FUNCTION(glFramebufferTexture2DOES), 6949 FUNCTION(glFramebufferTextureLayer), 6950 FUNCTION(glFrontFace), 6951 FUNCTION(glGenBuffers), 6952 FUNCTION(glGenFencesNV), 6953 FUNCTION(glGenFramebuffers), 6954 FUNCTION(glGenFramebuffersOES), 6955 FUNCTION(glGenQueries), 6956 FUNCTION(glGenQueriesEXT), 6957 FUNCTION(glGenRenderbuffers), 6958 FUNCTION(glGenRenderbuffersOES), 6959 FUNCTION(glGenSamplers), 6960 FUNCTION(glGenTextures), 6961 FUNCTION(glGenTransformFeedbacks), 6962 FUNCTION(glGenVertexArrays), 6963 FUNCTION(glGenerateMipmap), 6964 FUNCTION(glGenerateMipmapOES), 6965 FUNCTION(glGetActiveAttrib), 6966 FUNCTION(glGetActiveUniform), 6967 FUNCTION(glGetActiveUniformBlockName), 6968 FUNCTION(glGetActiveUniformBlockiv), 6969 FUNCTION(glGetActiveUniformsiv), 6970 FUNCTION(glGetAttachedShaders), 6971 FUNCTION(glGetAttribLocation), 6972 FUNCTION(glGetBooleanv), 6973 FUNCTION(glGetBufferParameteri64v), 6974 FUNCTION(glGetBufferParameteriv), 6975 FUNCTION(glGetBufferPointerv), 6976 FUNCTION(glGetError), 6977 FUNCTION(glGetFenceivNV), 6978 FUNCTION(glGetFloatv), 6979 FUNCTION(glGetFragDataLocation), 6980 FUNCTION(glGetFramebufferAttachmentParameteriv), 6981 FUNCTION(glGetFramebufferAttachmentParameterivOES), 6982 FUNCTION(glGetGraphicsResetStatusEXT), 6983 FUNCTION(glGetInteger64i_v), 6984 FUNCTION(glGetInteger64v), 6985 FUNCTION(glGetIntegeri_v), 6986 FUNCTION(glGetIntegerv), 6987 FUNCTION(glGetInternalformativ), 6988 FUNCTION(glGetProgramBinary), 6989 FUNCTION(glGetProgramInfoLog), 6990 FUNCTION(glGetProgramiv), 6991 FUNCTION(glGetQueryObjectuiv), 6992 FUNCTION(glGetQueryObjectuivEXT), 6993 FUNCTION(glGetQueryiv), 6994 FUNCTION(glGetQueryivEXT), 6995 FUNCTION(glGetRenderbufferParameteriv), 6996 FUNCTION(glGetRenderbufferParameterivOES), 6997 FUNCTION(glGetSamplerParameterfv), 6998 FUNCTION(glGetSamplerParameteriv), 6999 FUNCTION(glGetShaderInfoLog), 7000 FUNCTION(glGetShaderPrecisionFormat), 7001 FUNCTION(glGetShaderSource), 7002 FUNCTION(glGetShaderiv), 7003 FUNCTION(glGetString), 7004 FUNCTION(glGetStringi), 7005 FUNCTION(glGetSynciv), 7006 FUNCTION(glGetTexParameterfv), 7007 FUNCTION(glGetTexParameteriv), 7008 FUNCTION(glGetTransformFeedbackVarying), 7009 FUNCTION(glGetUniformBlockIndex), 7010 FUNCTION(glGetUniformIndices), 7011 FUNCTION(glGetUniformLocation), 7012 FUNCTION(glGetUniformfv), 7013 FUNCTION(glGetUniformiv), 7014 FUNCTION(glGetUniformuiv), 7015 FUNCTION(glGetVertexAttribIiv), 7016 FUNCTION(glGetVertexAttribIuiv), 7017 FUNCTION(glGetVertexAttribPointerv), 7018 FUNCTION(glGetVertexAttribfv), 7019 FUNCTION(glGetVertexAttribiv), 7020 FUNCTION(glGetnUniformfvEXT), 7021 FUNCTION(glGetnUniformivEXT), 7022 FUNCTION(glHint), 7023 FUNCTION(glInvalidateFramebuffer), 7024 FUNCTION(glInvalidateSubFramebuffer), 7025 FUNCTION(glIsBuffer), 7026 FUNCTION(glIsEnabled), 7027 FUNCTION(glIsFenceNV), 7028 FUNCTION(glIsFramebuffer), 7029 FUNCTION(glIsFramebufferOES), 7030 FUNCTION(glIsProgram), 7031 FUNCTION(glIsQuery), 7032 FUNCTION(glIsQueryEXT), 7033 FUNCTION(glIsRenderbuffer), 7034 FUNCTION(glIsRenderbufferOES), 7035 FUNCTION(glIsSampler), 7036 FUNCTION(glIsShader), 7037 FUNCTION(glIsSync), 7038 FUNCTION(glIsTexture), 7039 FUNCTION(glIsTransformFeedback), 7040 FUNCTION(glIsVertexArray), 7041 FUNCTION(glLineWidth), 7042 FUNCTION(glLinkProgram), 7043 FUNCTION(glMapBufferRange), 7044 FUNCTION(glPauseTransformFeedback), 7045 FUNCTION(glPixelStorei), 7046 FUNCTION(glPolygonOffset), 7047 FUNCTION(glProgramBinary), 7048 FUNCTION(glProgramParameteri), 7049 FUNCTION(glReadBuffer), 7050 FUNCTION(glReadPixels), 7051 FUNCTION(glReadnPixelsEXT), 7052 FUNCTION(glReleaseShaderCompiler), 7053 FUNCTION(glRenderbufferStorage), 7054 FUNCTION(glRenderbufferStorageMultisample), 7055 FUNCTION(glRenderbufferStorageMultisampleANGLE), 7056 FUNCTION(glRenderbufferStorageOES), 7057 FUNCTION(glResumeTransformFeedback), 7058 FUNCTION(glSampleCoverage), 7059 FUNCTION(glSamplerParameterf), 7060 FUNCTION(glSamplerParameterfv), 7061 FUNCTION(glSamplerParameteri), 7062 FUNCTION(glSamplerParameteriv), 7063 FUNCTION(glScissor), 7064 FUNCTION(glSetFenceNV), 7065 FUNCTION(glShaderBinary), 7066 FUNCTION(glShaderSource), 7067 FUNCTION(glStencilFunc), 7068 FUNCTION(glStencilFuncSeparate), 7069 FUNCTION(glStencilMask), 7070 FUNCTION(glStencilMaskSeparate), 7071 FUNCTION(glStencilOp), 7072 FUNCTION(glStencilOpSeparate), 7073 FUNCTION(glTestFenceNV), 7074 FUNCTION(glTexImage2D), 7075 FUNCTION(glTexImage3D), 7076 FUNCTION(glTexImage3DOES), 7077 FUNCTION(glTexParameterf), 7078 FUNCTION(glTexParameterfv), 7079 FUNCTION(glTexParameteri), 7080 FUNCTION(glTexParameteriv), 7081 FUNCTION(glTexStorage2D), 7082 FUNCTION(glTexStorage3D), 7083 FUNCTION(glTexSubImage2D), 7084 FUNCTION(glTexSubImage3D), 7085 FUNCTION(glTransformFeedbackVaryings), 7086 FUNCTION(glUniform1f), 7087 FUNCTION(glUniform1fv), 7088 FUNCTION(glUniform1i), 7089 FUNCTION(glUniform1iv), 7090 FUNCTION(glUniform1ui), 7091 FUNCTION(glUniform1uiv), 7092 FUNCTION(glUniform2f), 7093 FUNCTION(glUniform2fv), 7094 FUNCTION(glUniform2i), 7095 FUNCTION(glUniform2iv), 7096 FUNCTION(glUniform2ui), 7097 FUNCTION(glUniform2uiv), 7098 FUNCTION(glUniform3f), 7099 FUNCTION(glUniform3fv), 7100 FUNCTION(glUniform3i), 7101 FUNCTION(glUniform3iv), 7102 FUNCTION(glUniform3ui), 7103 FUNCTION(glUniform3uiv), 7104 FUNCTION(glUniform4f), 7105 FUNCTION(glUniform4fv), 7106 FUNCTION(glUniform4i), 7107 FUNCTION(glUniform4iv), 7108 FUNCTION(glUniform4ui), 7109 FUNCTION(glUniform4uiv), 7110 FUNCTION(glUniformBlockBinding), 7111 FUNCTION(glUniformMatrix2fv), 7112 FUNCTION(glUniformMatrix2x3fv), 7113 FUNCTION(glUniformMatrix2x4fv), 7114 FUNCTION(glUniformMatrix3fv), 7115 FUNCTION(glUniformMatrix3x2fv), 7116 FUNCTION(glUniformMatrix3x4fv), 7117 FUNCTION(glUniformMatrix4fv), 7118 FUNCTION(glUniformMatrix4x2fv), 7119 FUNCTION(glUniformMatrix4x3fv), 7120 FUNCTION(glUnmapBuffer), 7121 FUNCTION(glUseProgram), 7122 FUNCTION(glValidateProgram), 7123 FUNCTION(glVertexAttrib1f), 7124 FUNCTION(glVertexAttrib1fv), 7125 FUNCTION(glVertexAttrib2f), 7126 FUNCTION(glVertexAttrib2fv), 7127 FUNCTION(glVertexAttrib3f), 7128 FUNCTION(glVertexAttrib3fv), 7129 FUNCTION(glVertexAttrib4f), 7130 FUNCTION(glVertexAttrib4fv), 7131 FUNCTION(glVertexAttribDivisor), 7132 FUNCTION(glVertexAttribI4i), 7133 FUNCTION(glVertexAttribI4iv), 7134 FUNCTION(glVertexAttribI4ui), 7135 FUNCTION(glVertexAttribI4uiv), 7136 FUNCTION(glVertexAttribIPointer), 7137 FUNCTION(glVertexAttribPointer), 7138 FUNCTION(glViewport), 7139 FUNCTION(glWaitSync), 7140 7141 #undef FUNCTION 7142 }; 7143 7144 static const size_t numFunctions = sizeof glFunctions / sizeof(Function); 7145 static const Function *const glFunctionsEnd = glFunctions + numFunctions; 7146 7147 Function needle; 7148 needle.name = procname; 7149 7150 if(procname && strncmp("gl", procname, 2) == 0) 7151 { 7152 const Function *result = std::lower_bound(glFunctions, glFunctionsEnd, needle, CompareFunctor()); 7153 if(result != glFunctionsEnd && strcmp(procname, result->name) == 0) 7154 { 7155 return (__eglMustCastToProperFunctionPointerType)result->address; 7156 } 7157 } 7158 7159 return nullptr; 7160 } 7161