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