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 15 // libGLES_CM.cpp: Implements the exported OpenGL ES 1.1 functions. 16 17 #include "main.h" 18 #include "mathutil.h" 19 #include "utilities.h" 20 #include "Buffer.h" 21 #include "Context.h" 22 #include "Framebuffer.h" 23 #include "Renderbuffer.h" 24 #include "Texture.h" 25 #include "common/debug.h" 26 #include "Common/SharedLibrary.hpp" 27 #include "Common/Version.h" 28 29 #include <EGL/egl.h> 30 #include <EGL/eglext.h> 31 32 #include <GLES/gl.h> 33 #include <GLES/glext.h> 34 35 #include <limits> 36 37 namespace es1 38 { 39 40 static bool validImageSize(GLint level, GLsizei width, GLsizei height) 41 { 42 if(level < 0 || level >= es1::IMPLEMENTATION_MAX_TEXTURE_LEVELS || width < 0 || height < 0) 43 { 44 return false; 45 } 46 47 return true; 48 } 49 50 static bool validateSubImageParams(bool compressed, GLsizei width, GLsizei height, GLint xoffset, GLint yoffset, GLenum target, GLint level, GLenum format, es1::Texture *texture) 51 { 52 if(!texture) 53 { 54 return error(GL_INVALID_OPERATION, false); 55 } 56 57 if(compressed != texture->isCompressed(target, level)) 58 { 59 return error(GL_INVALID_OPERATION, false); 60 } 61 62 if(format != GL_NONE_OES && format != texture->getFormat(target, level)) 63 { 64 return error(GL_INVALID_OPERATION, false); 65 } 66 67 if(compressed) 68 { 69 if((width % 4 != 0 && width != texture->getWidth(target, 0)) || 70 (height % 4 != 0 && height != texture->getHeight(target, 0))) 71 { 72 return error(GL_INVALID_OPERATION, false); 73 } 74 } 75 76 if(xoffset + width > texture->getWidth(target, level) || 77 yoffset + height > texture->getHeight(target, level)) 78 { 79 return error(GL_INVALID_VALUE, false); 80 } 81 82 return true; 83 } 84 85 void ActiveTexture(GLenum texture) 86 { 87 TRACE("(GLenum texture = 0x%X)", texture); 88 89 es1::Context *context = es1::getContext(); 90 91 if(context) 92 { 93 if(texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + es1::MAX_TEXTURE_UNITS - 1) 94 { 95 return error(GL_INVALID_ENUM); 96 } 97 98 context->setActiveSampler(texture - GL_TEXTURE0); 99 } 100 } 101 102 void AlphaFunc(GLenum func, GLclampf ref) 103 { 104 TRACE("(GLenum func = 0x%X, GLclampf ref = %f)", func, ref); 105 106 switch(func) 107 { 108 case GL_NEVER: 109 case GL_ALWAYS: 110 case GL_LESS: 111 case GL_LEQUAL: 112 case GL_EQUAL: 113 case GL_GEQUAL: 114 case GL_GREATER: 115 case GL_NOTEQUAL: 116 break; 117 default: 118 return error(GL_INVALID_ENUM); 119 } 120 121 es1::Context *context = es1::getContext(); 122 123 if(context) 124 { 125 context->setAlphaFunc(func, clamp01(ref)); 126 } 127 } 128 129 void AlphaFuncx(GLenum func, GLclampx ref) 130 { 131 AlphaFunc(func, (float)ref / 0x10000); 132 } 133 134 void BindBuffer(GLenum target, GLuint buffer) 135 { 136 TRACE("(GLenum target = 0x%X, GLuint buffer = %d)", target, buffer); 137 138 es1::Context *context = es1::getContext(); 139 140 if(context) 141 { 142 switch(target) 143 { 144 case GL_ARRAY_BUFFER: 145 context->bindArrayBuffer(buffer); 146 return; 147 case GL_ELEMENT_ARRAY_BUFFER: 148 context->bindElementArrayBuffer(buffer); 149 return; 150 default: 151 return error(GL_INVALID_ENUM); 152 } 153 } 154 } 155 156 void BindFramebuffer(GLenum target, GLuint framebuffer) 157 { 158 TRACE("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer); 159 160 if(target != GL_FRAMEBUFFER_OES) 161 { 162 return error(GL_INVALID_ENUM); 163 } 164 165 es1::Context *context = es1::getContext(); 166 167 if(context) 168 { 169 context->bindFramebuffer(framebuffer); 170 } 171 } 172 173 void BindFramebufferOES(GLenum target, GLuint framebuffer) 174 { 175 TRACE("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer); 176 177 if(target != GL_FRAMEBUFFER_OES) 178 { 179 return error(GL_INVALID_ENUM); 180 } 181 182 es1::Context *context = es1::getContext(); 183 184 if(context) 185 { 186 context->bindFramebuffer(framebuffer); 187 } 188 } 189 190 void BindRenderbufferOES(GLenum target, GLuint renderbuffer) 191 { 192 TRACE("(GLenum target = 0x%X, GLuint renderbuffer = %d)", target, renderbuffer); 193 194 if(target != GL_RENDERBUFFER_OES) 195 { 196 return error(GL_INVALID_ENUM); 197 } 198 199 es1::Context *context = es1::getContext(); 200 201 if(context) 202 { 203 if(renderbuffer != 0 && !context->getRenderbuffer(renderbuffer)) 204 { 205 // [OpenGL ES 2.0.25] Section 4.4.3 page 112 206 // [OpenGL ES 3.0.2] Section 4.4.2 page 201 207 // 'renderbuffer' must be either zero or the name of an existing renderbuffer object of 208 // type 'renderbuffertarget', otherwise an INVALID_OPERATION error is generated. 209 return error(GL_INVALID_OPERATION); 210 } 211 212 context->bindRenderbuffer(renderbuffer); 213 } 214 } 215 216 void BindTexture(GLenum target, GLuint texture) 217 { 218 TRACE("(GLenum target = 0x%X, GLuint texture = %d)", target, texture); 219 220 es1::Context *context = es1::getContext(); 221 222 if(context) 223 { 224 es1::Texture *textureObject = context->getTexture(texture); 225 226 if(textureObject && textureObject->getTarget() != target && texture != 0) 227 { 228 return error(GL_INVALID_OPERATION); 229 } 230 231 switch(target) 232 { 233 case GL_TEXTURE_2D: 234 context->bindTexture2D(texture); 235 return; 236 case GL_TEXTURE_EXTERNAL_OES: 237 context->bindTextureExternal(texture); 238 return; 239 default: 240 return error(GL_INVALID_ENUM); 241 } 242 } 243 } 244 245 void BlendEquationSeparateOES(GLenum modeRGB, GLenum modeAlpha); 246 247 void BlendEquationOES(GLenum mode) 248 { 249 BlendEquationSeparateOES(mode, mode); 250 } 251 252 void BlendEquationSeparateOES(GLenum modeRGB, GLenum modeAlpha) 253 { 254 TRACE("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha); 255 256 switch(modeRGB) 257 { 258 case GL_FUNC_ADD_OES: 259 case GL_FUNC_SUBTRACT_OES: 260 case GL_FUNC_REVERSE_SUBTRACT_OES: 261 case GL_MIN_EXT: 262 case GL_MAX_EXT: 263 break; 264 default: 265 return error(GL_INVALID_ENUM); 266 } 267 268 switch(modeAlpha) 269 { 270 case GL_FUNC_ADD_OES: 271 case GL_FUNC_SUBTRACT_OES: 272 case GL_FUNC_REVERSE_SUBTRACT_OES: 273 case GL_MIN_EXT: 274 case GL_MAX_EXT: 275 break; 276 default: 277 return error(GL_INVALID_ENUM); 278 } 279 280 es1::Context *context = es1::getContext(); 281 282 if(context) 283 { 284 context->setBlendEquation(modeRGB, modeAlpha); 285 } 286 } 287 288 void BlendFuncSeparateOES(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); 289 290 void BlendFunc(GLenum sfactor, GLenum dfactor) 291 { 292 BlendFuncSeparateOES(sfactor, dfactor, sfactor, dfactor); 293 } 294 295 void BlendFuncSeparateOES(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) 296 { 297 TRACE("(GLenum srcRGB = 0x%X, GLenum dstRGB = 0x%X, GLenum srcAlpha = 0x%X, GLenum dstAlpha = 0x%X)", 298 srcRGB, dstRGB, srcAlpha, dstAlpha); 299 300 switch(srcRGB) 301 { 302 case GL_ZERO: 303 case GL_ONE: 304 case GL_SRC_COLOR: 305 case GL_ONE_MINUS_SRC_COLOR: 306 case GL_DST_COLOR: 307 case GL_ONE_MINUS_DST_COLOR: 308 case GL_SRC_ALPHA: 309 case GL_ONE_MINUS_SRC_ALPHA: 310 case GL_DST_ALPHA: 311 case GL_ONE_MINUS_DST_ALPHA: 312 case GL_SRC_ALPHA_SATURATE: 313 break; 314 default: 315 return error(GL_INVALID_ENUM); 316 } 317 318 switch(dstRGB) 319 { 320 case GL_ZERO: 321 case GL_ONE: 322 case GL_SRC_COLOR: 323 case GL_ONE_MINUS_SRC_COLOR: 324 case GL_DST_COLOR: 325 case GL_ONE_MINUS_DST_COLOR: 326 case GL_SRC_ALPHA: 327 case GL_ONE_MINUS_SRC_ALPHA: 328 case GL_DST_ALPHA: 329 case GL_ONE_MINUS_DST_ALPHA: 330 break; 331 default: 332 return error(GL_INVALID_ENUM); 333 } 334 335 switch(srcAlpha) 336 { 337 case GL_ZERO: 338 case GL_ONE: 339 case GL_SRC_COLOR: 340 case GL_ONE_MINUS_SRC_COLOR: 341 case GL_DST_COLOR: 342 case GL_ONE_MINUS_DST_COLOR: 343 case GL_SRC_ALPHA: 344 case GL_ONE_MINUS_SRC_ALPHA: 345 case GL_DST_ALPHA: 346 case GL_ONE_MINUS_DST_ALPHA: 347 case GL_SRC_ALPHA_SATURATE: 348 break; 349 default: 350 return error(GL_INVALID_ENUM); 351 } 352 353 switch(dstAlpha) 354 { 355 case GL_ZERO: 356 case GL_ONE: 357 case GL_SRC_COLOR: 358 case GL_ONE_MINUS_SRC_COLOR: 359 case GL_DST_COLOR: 360 case GL_ONE_MINUS_DST_COLOR: 361 case GL_SRC_ALPHA: 362 case GL_ONE_MINUS_SRC_ALPHA: 363 case GL_DST_ALPHA: 364 case GL_ONE_MINUS_DST_ALPHA: 365 break; 366 default: 367 return error(GL_INVALID_ENUM); 368 } 369 370 es1::Context *context = es1::getContext(); 371 372 if(context) 373 { 374 context->setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha); 375 } 376 } 377 378 void BufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage) 379 { 380 size = static_cast<GLint>(size); // Work around issues with some 64-bit applications 381 382 TRACE("(GLenum target = 0x%X, GLsizeiptr size = %d, const GLvoid* data = %p, GLenum usage = %d)", 383 target, size, data, usage); 384 385 if(size < 0) 386 { 387 return error(GL_INVALID_VALUE); 388 } 389 390 switch(usage) 391 { 392 case GL_STATIC_DRAW: 393 case GL_DYNAMIC_DRAW: 394 break; 395 default: 396 return error(GL_INVALID_ENUM); 397 } 398 399 es1::Context *context = es1::getContext(); 400 401 if(context) 402 { 403 es1::Buffer *buffer; 404 405 switch(target) 406 { 407 case GL_ARRAY_BUFFER: 408 buffer = context->getArrayBuffer(); 409 break; 410 case GL_ELEMENT_ARRAY_BUFFER: 411 buffer = context->getElementArrayBuffer(); 412 break; 413 default: 414 return error(GL_INVALID_ENUM); 415 } 416 417 if(!buffer) 418 { 419 return error(GL_INVALID_OPERATION); 420 } 421 422 buffer->bufferData(data, size, usage); 423 } 424 } 425 426 void BufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data) 427 { 428 size = static_cast<GLint>(size); // Work around issues with some 64-bit applications 429 offset = static_cast<GLint>(offset); 430 431 TRACE("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr size = %d, const GLvoid* data = %p)", 432 target, offset, size, data); 433 434 if(size < 0 || offset < 0) 435 { 436 return error(GL_INVALID_VALUE); 437 } 438 439 if(!data) 440 { 441 return; 442 } 443 444 es1::Context *context = es1::getContext(); 445 446 if(context) 447 { 448 es1::Buffer *buffer; 449 450 switch(target) 451 { 452 case GL_ARRAY_BUFFER: 453 buffer = context->getArrayBuffer(); 454 break; 455 case GL_ELEMENT_ARRAY_BUFFER: 456 buffer = context->getElementArrayBuffer(); 457 break; 458 default: 459 return error(GL_INVALID_ENUM); 460 } 461 462 if(!buffer) 463 { 464 return error(GL_INVALID_OPERATION); 465 } 466 467 if((size_t)size + offset > buffer->size()) 468 { 469 return error(GL_INVALID_VALUE); 470 } 471 472 buffer->bufferSubData(data, size, offset); 473 } 474 } 475 476 GLenum CheckFramebufferStatusOES(GLenum target) 477 { 478 TRACE("(GLenum target = 0x%X)", target); 479 480 if(target != GL_FRAMEBUFFER_OES) 481 { 482 return error(GL_INVALID_ENUM, 0); 483 } 484 485 es1::Context *context = es1::getContext(); 486 487 if(context) 488 { 489 es1::Framebuffer *framebuffer = context->getFramebuffer(); 490 491 return framebuffer->completeness(); 492 } 493 494 return 0; 495 } 496 497 void Clear(GLbitfield mask) 498 { 499 TRACE("(GLbitfield mask = %X)", mask); 500 501 if((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0) 502 { 503 return error(GL_INVALID_VALUE); 504 } 505 506 es1::Context *context = es1::getContext(); 507 508 if(context) 509 { 510 context->clear(mask); 511 } 512 } 513 514 void ClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) 515 { 516 TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)", 517 red, green, blue, alpha); 518 519 es1::Context *context = es1::getContext(); 520 521 if(context) 522 { 523 context->setClearColor(red, green, blue, alpha); 524 } 525 } 526 527 void ClearColorx(GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha) 528 { 529 ClearColor((float)red / 0x10000, (float)green / 0x10000, (float)blue / 0x10000, (float)alpha / 0x10000); 530 } 531 532 void ClearDepthf(GLclampf depth) 533 { 534 TRACE("(GLclampf depth = %f)", depth); 535 536 es1::Context *context = es1::getContext(); 537 538 if(context) 539 { 540 context->setClearDepth(depth); 541 } 542 } 543 544 void ClearDepthx(GLclampx depth) 545 { 546 ClearDepthf((float)depth / 0x10000); 547 } 548 549 void ClearStencil(GLint s) 550 { 551 TRACE("(GLint s = %d)", s); 552 553 es1::Context *context = es1::getContext(); 554 555 if(context) 556 { 557 context->setClearStencil(s); 558 } 559 } 560 561 void ClientActiveTexture(GLenum texture) 562 { 563 TRACE("(GLenum texture = 0x%X)", texture); 564 565 switch(texture) 566 { 567 case GL_TEXTURE0: 568 case GL_TEXTURE1: 569 break; 570 default: 571 return error(GL_INVALID_ENUM); 572 } 573 574 es1::Context *context = es1::getContext(); 575 576 if(context) 577 { 578 context->clientActiveTexture(texture); 579 } 580 } 581 582 void ClipPlanef(GLenum plane, const GLfloat *equation) 583 { 584 TRACE("(GLenum plane = 0x%X, const GLfloat *equation)", plane); 585 586 int index = plane - GL_CLIP_PLANE0; 587 588 if(index < 0 || index >= MAX_CLIP_PLANES) 589 { 590 return error(GL_INVALID_ENUM); 591 } 592 593 es1::Context *context = es1::getContext(); 594 595 if(context) 596 { 597 context->setClipPlane(index, equation); 598 } 599 } 600 601 void ClipPlanex(GLenum plane, const GLfixed *equation) 602 { 603 GLfloat equationf[4] = 604 { 605 (float)equation[0] / 0x10000, 606 (float)equation[1] / 0x10000, 607 (float)equation[2] / 0x10000, 608 (float)equation[3] / 0x10000, 609 }; 610 611 ClipPlanef(plane, equationf); 612 } 613 614 void Color4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) 615 { 616 TRACE("(GLfloat red = %f, GLfloat green = %f, GLfloat blue = %f, GLfloat alpha = %f)", red, green, blue, alpha); 617 618 es1::Context *context = es1::getContext(); 619 620 if(context) 621 { 622 context->setVertexAttrib(sw::Color0, red, green, blue, alpha); 623 } 624 } 625 626 void Color4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha) 627 { 628 Color4f((float)red / 0xFF, (float)green / 0xFF, (float)blue / 0xFF, (float)alpha / 0xFF); 629 } 630 631 void Color4x(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha) 632 { 633 Color4f((float)red / 0x10000, (float)green / 0x10000, (float)blue / 0x10000, (float)alpha / 0x10000); 634 } 635 636 void ColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) 637 { 638 TRACE("(GLboolean red = %d, GLboolean green = %d, GLboolean blue = %d, GLboolean alpha = %d)", 639 red, green, blue, alpha); 640 641 es1::Context *context = es1::getContext(); 642 643 if(context) 644 { 645 context->setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE); 646 } 647 } 648 649 void VertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr) 650 { 651 TRACE("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, " 652 "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = %p)", 653 index, size, type, normalized, stride, ptr); 654 655 if(index >= es1::MAX_VERTEX_ATTRIBS) 656 { 657 return error(GL_INVALID_VALUE); 658 } 659 660 if(size < 1 || size > 4) 661 { 662 return error(GL_INVALID_VALUE); 663 } 664 665 switch(type) 666 { 667 case GL_BYTE: 668 case GL_UNSIGNED_BYTE: 669 case GL_SHORT: 670 case GL_UNSIGNED_SHORT: 671 case GL_FIXED: 672 case GL_FLOAT: 673 break; 674 default: 675 return error(GL_INVALID_ENUM); 676 } 677 678 if(stride < 0) 679 { 680 return error(GL_INVALID_VALUE); 681 } 682 683 es1::Context *context = es1::getContext(); 684 685 if(context) 686 { 687 context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr); 688 } 689 } 690 691 void ColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) 692 { 693 TRACE("(GLint size = %d, GLenum type = 0x%X, GLsizei stride = %d, const GLvoid *pointer = %p)", size, type, stride, pointer); 694 695 if(size != 4) 696 { 697 return error(GL_INVALID_VALUE); 698 } 699 700 VertexAttribPointer(sw::Color0, size, type, true, stride, pointer); 701 } 702 703 void CompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, 704 GLint border, GLsizei imageSize, const GLvoid* data) 705 { 706 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, " 707 "GLsizei height = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = %p)", 708 target, level, internalformat, width, height, border, imageSize, data); 709 710 if(level < 0 || level >= es1::IMPLEMENTATION_MAX_TEXTURE_LEVELS) 711 { 712 return error(GL_INVALID_VALUE); 713 } 714 715 if(!validImageSize(level, width, height) || imageSize < 0) 716 { 717 return error(GL_INVALID_VALUE); 718 } 719 720 switch(internalformat) 721 { 722 case GL_ETC1_RGB8_OES: 723 break; 724 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: 725 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: 726 if(!S3TC_SUPPORT) 727 { 728 return error(GL_INVALID_ENUM); 729 } 730 break; 731 case GL_DEPTH_COMPONENT16_OES: 732 case GL_DEPTH_COMPONENT32_OES: 733 case GL_DEPTH_STENCIL_OES: 734 case GL_DEPTH24_STENCIL8_OES: 735 return error(GL_INVALID_OPERATION); 736 default: 737 return error(GL_INVALID_ENUM); 738 } 739 740 if(border != 0) 741 { 742 return error(GL_INVALID_VALUE); 743 } 744 745 es1::Context *context = es1::getContext(); 746 747 if(context) 748 { 749 switch(target) 750 { 751 case GL_TEXTURE_2D: 752 if(width > (es1::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) || 753 height > (es1::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level)) 754 { 755 return error(GL_INVALID_VALUE); 756 } 757 break; 758 default: 759 return error(GL_INVALID_ENUM); 760 } 761 762 if(imageSize != egl::ComputeCompressedSize(width, height, internalformat)) 763 { 764 return error(GL_INVALID_VALUE); 765 } 766 767 if(target == GL_TEXTURE_2D) 768 { 769 es1::Texture2D *texture = context->getTexture2D(); 770 771 if(!texture) 772 { 773 return error(GL_INVALID_OPERATION); 774 } 775 776 texture->setCompressedImage(level, internalformat, width, height, imageSize, data); 777 } 778 else UNREACHABLE(target); 779 } 780 } 781 782 void CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, 783 GLenum format, GLsizei imageSize, const GLvoid* data) 784 { 785 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, " 786 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, " 787 "GLsizei imageSize = %d, const GLvoid* data = %p)", 788 target, level, xoffset, yoffset, width, height, format, imageSize, data); 789 790 if(!es1::IsTextureTarget(target)) 791 { 792 return error(GL_INVALID_ENUM); 793 } 794 795 if(level < 0 || level >= es1::IMPLEMENTATION_MAX_TEXTURE_LEVELS) 796 { 797 return error(GL_INVALID_VALUE); 798 } 799 800 if(xoffset < 0 || yoffset < 0 || !validImageSize(level, width, height) || imageSize < 0) 801 { 802 return error(GL_INVALID_VALUE); 803 } 804 805 switch(format) 806 { 807 case GL_ETC1_RGB8_OES: 808 break; 809 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: 810 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: 811 if(!S3TC_SUPPORT) 812 { 813 return error(GL_INVALID_ENUM); 814 } 815 break; 816 default: 817 return error(GL_INVALID_ENUM); 818 } 819 820 if(width == 0 || height == 0 || !data) 821 { 822 return; 823 } 824 825 es1::Context *context = es1::getContext(); 826 827 if(context) 828 { 829 if(imageSize != egl::ComputeCompressedSize(width, height, format)) 830 { 831 return error(GL_INVALID_VALUE); 832 } 833 834 if(xoffset % 4 != 0 || yoffset % 4 != 0) 835 { 836 // We wait to check the offsets until this point, because the multiple-of-four restriction does not exist unless DXT1 textures are supported 837 return error(GL_INVALID_OPERATION); 838 } 839 840 if(target == GL_TEXTURE_2D) 841 { 842 es1::Texture2D *texture = context->getTexture2D(); 843 844 if(validateSubImageParams(true, width, height, xoffset, yoffset, target, level, format, texture)) 845 { 846 texture->subImageCompressed(level, xoffset, yoffset, width, height, format, imageSize, data); 847 } 848 } 849 else UNREACHABLE(target); 850 } 851 } 852 853 void CopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) 854 { 855 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, " 856 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)", 857 target, level, internalformat, x, y, width, height, border); 858 859 if(!validImageSize(level, width, height)) 860 { 861 return error(GL_INVALID_VALUE); 862 } 863 864 if(border != 0) 865 { 866 return error(GL_INVALID_VALUE); 867 } 868 869 es1::Context *context = es1::getContext(); 870 871 if(context) 872 { 873 switch(target) 874 { 875 case GL_TEXTURE_2D: 876 if(width > (es1::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) || 877 height > (es1::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level)) 878 { 879 return error(GL_INVALID_VALUE); 880 } 881 break; 882 default: 883 return error(GL_INVALID_ENUM); 884 } 885 886 es1::Framebuffer *framebuffer = context->getFramebuffer(); 887 888 if(framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE_OES) 889 { 890 return error(GL_INVALID_FRAMEBUFFER_OPERATION_OES); 891 } 892 893 if(context->getFramebufferName() != 0 && framebuffer->getColorbuffer()->getSamples() > 1) 894 { 895 return error(GL_INVALID_OPERATION); 896 } 897 898 es1::Renderbuffer *source = framebuffer->getColorbuffer(); 899 GLenum colorbufferFormat = source->getFormat(); 900 901 // [OpenGL ES 2.0.24] table 3.9 902 switch(internalformat) 903 { 904 case GL_ALPHA: 905 if(colorbufferFormat != GL_ALPHA && 906 colorbufferFormat != GL_RGBA && 907 colorbufferFormat != GL_RGBA4_OES && 908 colorbufferFormat != GL_RGB5_A1_OES && 909 colorbufferFormat != GL_RGBA8_OES) 910 { 911 return error(GL_INVALID_OPERATION); 912 } 913 break; 914 case GL_LUMINANCE: 915 case GL_RGB: 916 if(colorbufferFormat != GL_RGB && 917 colorbufferFormat != GL_RGB565_OES && 918 colorbufferFormat != GL_RGB8_OES && 919 colorbufferFormat != GL_RGBA && 920 colorbufferFormat != GL_RGBA4_OES && 921 colorbufferFormat != GL_RGB5_A1_OES && 922 colorbufferFormat != GL_RGBA8_OES) 923 { 924 return error(GL_INVALID_OPERATION); 925 } 926 break; 927 case GL_LUMINANCE_ALPHA: 928 case GL_RGBA: 929 if(colorbufferFormat != GL_RGBA && 930 colorbufferFormat != GL_RGBA4_OES && 931 colorbufferFormat != GL_RGB5_A1_OES && 932 colorbufferFormat != GL_RGBA8_OES) 933 { 934 return error(GL_INVALID_OPERATION); 935 } 936 break; 937 case GL_ETC1_RGB8_OES: 938 return error(GL_INVALID_OPERATION); 939 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: 940 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: 941 if(S3TC_SUPPORT) 942 { 943 return error(GL_INVALID_OPERATION); 944 } 945 else 946 { 947 return error(GL_INVALID_ENUM); 948 } 949 default: 950 return error(GL_INVALID_ENUM); 951 } 952 953 if(target == GL_TEXTURE_2D) 954 { 955 es1::Texture2D *texture = context->getTexture2D(); 956 957 if(!texture) 958 { 959 return error(GL_INVALID_OPERATION); 960 } 961 962 texture->copyImage(level, internalformat, x, y, width, height, framebuffer); 963 } 964 else UNREACHABLE(target); 965 } 966 } 967 968 void CopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) 969 { 970 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, " 971 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", 972 target, level, xoffset, yoffset, x, y, width, height); 973 974 if(!es1::IsTextureTarget(target)) 975 { 976 return error(GL_INVALID_ENUM); 977 } 978 979 if(level < 0 || level >= es1::IMPLEMENTATION_MAX_TEXTURE_LEVELS) 980 { 981 return error(GL_INVALID_VALUE); 982 } 983 984 if(xoffset < 0 || yoffset < 0 || width < 0 || height < 0) 985 { 986 return error(GL_INVALID_VALUE); 987 } 988 989 if(std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height) 990 { 991 return error(GL_INVALID_VALUE); 992 } 993 994 if(width == 0 || height == 0) 995 { 996 return; 997 } 998 999 es1::Context *context = es1::getContext(); 1000 1001 if(context) 1002 { 1003 1004 es1::Framebuffer *framebuffer = context->getFramebuffer(); 1005 1006 if(framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE_OES) 1007 { 1008 return error(GL_INVALID_FRAMEBUFFER_OPERATION_OES); 1009 } 1010 1011 es1::Renderbuffer *source = framebuffer->getColorbuffer(); 1012 1013 if(context->getFramebufferName() != 0 && (!source || source->getSamples() > 1)) 1014 { 1015 return error(GL_INVALID_OPERATION); 1016 } 1017 1018 es1::Texture *texture = nullptr; 1019 1020 if(target == GL_TEXTURE_2D) 1021 { 1022 texture = context->getTexture2D(); 1023 } 1024 else UNREACHABLE(target); 1025 1026 if(!validateSubImageParams(false, width, height, xoffset, yoffset, target, level, GL_NONE_OES, texture)) 1027 { 1028 return; 1029 } 1030 1031 texture->copySubImage(target, level, xoffset, yoffset, x, y, width, height, framebuffer); 1032 } 1033 } 1034 1035 void CullFace(GLenum mode) 1036 { 1037 TRACE("(GLenum mode = 0x%X)", mode); 1038 1039 switch(mode) 1040 { 1041 case GL_FRONT: 1042 case GL_BACK: 1043 case GL_FRONT_AND_BACK: 1044 { 1045 es1::Context *context = es1::getContext(); 1046 1047 if(context) 1048 { 1049 context->setCullMode(mode); 1050 } 1051 } 1052 break; 1053 default: 1054 return error(GL_INVALID_ENUM); 1055 } 1056 } 1057 1058 void DeleteBuffers(GLsizei n, const GLuint* buffers) 1059 { 1060 TRACE("(GLsizei n = %d, const GLuint* buffers = %p)", n, buffers); 1061 1062 if(n < 0) 1063 { 1064 return error(GL_INVALID_VALUE); 1065 } 1066 1067 es1::Context *context = es1::getContext(); 1068 1069 if(context) 1070 { 1071 for(int i = 0; i < n; i++) 1072 { 1073 context->deleteBuffer(buffers[i]); 1074 } 1075 } 1076 } 1077 1078 void DeleteFramebuffersOES(GLsizei n, const GLuint* framebuffers) 1079 { 1080 TRACE("(GLsizei n = %d, const GLuint* framebuffers = %p)", n, framebuffers); 1081 1082 if(n < 0) 1083 { 1084 return error(GL_INVALID_VALUE); 1085 } 1086 1087 es1::Context *context = es1::getContext(); 1088 1089 if(context) 1090 { 1091 for(int i = 0; i < n; i++) 1092 { 1093 if(framebuffers[i] != 0) 1094 { 1095 context->deleteFramebuffer(framebuffers[i]); 1096 } 1097 } 1098 } 1099 } 1100 1101 void DeleteRenderbuffersOES(GLsizei n, const GLuint* renderbuffers) 1102 { 1103 TRACE("(GLsizei n = %d, const GLuint* renderbuffers = %p)", n, renderbuffers); 1104 1105 if(n < 0) 1106 { 1107 return error(GL_INVALID_VALUE); 1108 } 1109 1110 es1::Context *context = es1::getContext(); 1111 1112 if(context) 1113 { 1114 for(int i = 0; i < n; i++) 1115 { 1116 context->deleteRenderbuffer(renderbuffers[i]); 1117 } 1118 } 1119 } 1120 1121 void DeleteTextures(GLsizei n, const GLuint* textures) 1122 { 1123 TRACE("(GLsizei n = %d, const GLuint* textures = %p)", n, textures); 1124 1125 if(n < 0) 1126 { 1127 return error(GL_INVALID_VALUE); 1128 } 1129 1130 es1::Context *context = es1::getContext(); 1131 1132 if(context) 1133 { 1134 for(int i = 0; i < n; i++) 1135 { 1136 if(textures[i] != 0) 1137 { 1138 context->deleteTexture(textures[i]); 1139 } 1140 } 1141 } 1142 } 1143 1144 void DepthFunc(GLenum func) 1145 { 1146 TRACE("(GLenum func = 0x%X)", func); 1147 1148 switch(func) 1149 { 1150 case GL_NEVER: 1151 case GL_ALWAYS: 1152 case GL_LESS: 1153 case GL_LEQUAL: 1154 case GL_EQUAL: 1155 case GL_GREATER: 1156 case GL_GEQUAL: 1157 case GL_NOTEQUAL: 1158 break; 1159 default: 1160 return error(GL_INVALID_ENUM); 1161 } 1162 1163 es1::Context *context = es1::getContext(); 1164 1165 if(context) 1166 { 1167 context->setDepthFunc(func); 1168 } 1169 } 1170 1171 void DepthMask(GLboolean flag) 1172 { 1173 TRACE("(GLboolean flag = %d)", flag); 1174 1175 es1::Context *context = es1::getContext(); 1176 1177 if(context) 1178 { 1179 context->setDepthMask(flag != GL_FALSE); 1180 } 1181 } 1182 1183 void DepthRangef(GLclampf zNear, GLclampf zFar) 1184 { 1185 TRACE("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar); 1186 1187 es1::Context *context = es1::getContext(); 1188 1189 if(context) 1190 { 1191 context->setDepthRange(zNear, zFar); 1192 } 1193 } 1194 1195 void DepthRangex(GLclampx zNear, GLclampx zFar) 1196 { 1197 DepthRangef((float)zNear / 0x10000, (float)zFar / 0x10000); 1198 } 1199 1200 void Disable(GLenum cap) 1201 { 1202 TRACE("(GLenum cap = 0x%X)", cap); 1203 1204 es1::Context *context = es1::getContext(); 1205 1206 if(context) 1207 { 1208 switch(cap) 1209 { 1210 case GL_CULL_FACE: context->setCullFaceEnabled(false); break; 1211 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFillEnabled(false); break; 1212 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverageEnabled(false); break; 1213 case GL_SAMPLE_COVERAGE: context->setSampleCoverageEnabled(false); break; 1214 case GL_SCISSOR_TEST: context->setScissorTestEnabled(false); break; 1215 case GL_STENCIL_TEST: context->setStencilTestEnabled(false); break; 1216 case GL_DEPTH_TEST: context->setDepthTestEnabled(false); break; 1217 case GL_BLEND: context->setBlendEnabled(false); break; 1218 case GL_DITHER: context->setDitherEnabled(false); break; 1219 case GL_LIGHTING: context->setLightingEnabled(false); break; 1220 case GL_LIGHT0: context->setLightEnabled(0, false); break; 1221 case GL_LIGHT1: context->setLightEnabled(1, false); break; 1222 case GL_LIGHT2: context->setLightEnabled(2, false); break; 1223 case GL_LIGHT3: context->setLightEnabled(3, false); break; 1224 case GL_LIGHT4: context->setLightEnabled(4, false); break; 1225 case GL_LIGHT5: context->setLightEnabled(5, false); break; 1226 case GL_LIGHT6: context->setLightEnabled(6, false); break; 1227 case GL_LIGHT7: context->setLightEnabled(7, false); break; 1228 case GL_FOG: context->setFogEnabled(false); break; 1229 case GL_TEXTURE_2D: context->setTexture2Denabled(false); break; 1230 case GL_TEXTURE_EXTERNAL_OES: context->setTextureExternalEnabled(false); break; 1231 case GL_ALPHA_TEST: context->setAlphaTestEnabled(false); break; 1232 case GL_COLOR_LOGIC_OP: context->setColorLogicOpEnabled(false); break; 1233 case GL_POINT_SMOOTH: context->setPointSmoothEnabled(false); break; 1234 case GL_LINE_SMOOTH: context->setLineSmoothEnabled(false); break; 1235 case GL_COLOR_MATERIAL: context->setColorMaterialEnabled(false); break; 1236 case GL_NORMALIZE: context->setNormalizeEnabled(false); break; 1237 case GL_RESCALE_NORMAL: context->setRescaleNormalEnabled(false); break; 1238 case GL_VERTEX_ARRAY: context->setVertexArrayEnabled(false); break; 1239 case GL_NORMAL_ARRAY: context->setNormalArrayEnabled(false); break; 1240 case GL_COLOR_ARRAY: context->setColorArrayEnabled(false); break; 1241 case GL_POINT_SIZE_ARRAY_OES: context->setPointSizeArrayEnabled(false); break; 1242 case GL_TEXTURE_COORD_ARRAY: context->setTextureCoordArrayEnabled(false); break; 1243 case GL_MULTISAMPLE: context->setMultisampleEnabled(false); break; 1244 case GL_SAMPLE_ALPHA_TO_ONE: context->setSampleAlphaToOneEnabled(false); break; 1245 case GL_CLIP_PLANE0: context->setClipPlaneEnabled(0, false); break; 1246 case GL_CLIP_PLANE1: context->setClipPlaneEnabled(1, false); break; 1247 case GL_CLIP_PLANE2: context->setClipPlaneEnabled(2, false); break; 1248 case GL_CLIP_PLANE3: context->setClipPlaneEnabled(3, false); break; 1249 case GL_CLIP_PLANE4: context->setClipPlaneEnabled(4, false); break; 1250 case GL_CLIP_PLANE5: context->setClipPlaneEnabled(5, false); break; 1251 case GL_POINT_SPRITE_OES: context->setPointSpriteEnabled(false); break; 1252 default: 1253 return error(GL_INVALID_ENUM); 1254 } 1255 } 1256 } 1257 1258 void DisableClientState(GLenum array) 1259 { 1260 TRACE("(GLenum array = 0x%X)", array); 1261 1262 switch(array) 1263 { 1264 case GL_VERTEX_ARRAY: 1265 case GL_NORMAL_ARRAY: 1266 case GL_COLOR_ARRAY: 1267 case GL_POINT_SIZE_ARRAY_OES: 1268 case GL_TEXTURE_COORD_ARRAY: 1269 break; 1270 default: 1271 return error(GL_INVALID_ENUM); 1272 } 1273 1274 es1::Context *context = es1::getContext(); 1275 1276 if(context) 1277 { 1278 GLenum texture = context->getClientActiveTexture(); 1279 1280 switch(array) 1281 { 1282 case GL_VERTEX_ARRAY: context->setVertexAttribArrayEnabled(sw::Position, false); break; 1283 case GL_NORMAL_ARRAY: context->setVertexAttribArrayEnabled(sw::Normal, false); break; 1284 case GL_COLOR_ARRAY: context->setVertexAttribArrayEnabled(sw::Color0, false); break; 1285 case GL_POINT_SIZE_ARRAY_OES: context->setVertexAttribArrayEnabled(sw::PointSize, false); break; 1286 case GL_TEXTURE_COORD_ARRAY: context->setVertexAttribArrayEnabled(sw::TexCoord0 + (texture - GL_TEXTURE0), false); break; 1287 default: UNREACHABLE(array); 1288 } 1289 } 1290 } 1291 1292 void DrawArrays(GLenum mode, GLint first, GLsizei count) 1293 { 1294 TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count); 1295 1296 if(count < 0 || first < 0) 1297 { 1298 return error(GL_INVALID_VALUE); 1299 } 1300 1301 es1::Context *context = es1::getContext(); 1302 1303 if(context) 1304 { 1305 context->drawArrays(mode, first, count); 1306 } 1307 } 1308 1309 void DrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices) 1310 { 1311 TRACE("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = %p)", 1312 mode, count, type, indices); 1313 1314 if(count < 0) 1315 { 1316 return error(GL_INVALID_VALUE); 1317 } 1318 1319 es1::Context *context = es1::getContext(); 1320 1321 if(context) 1322 { 1323 switch(type) 1324 { 1325 case GL_UNSIGNED_BYTE: 1326 case GL_UNSIGNED_SHORT: 1327 case GL_UNSIGNED_INT: 1328 break; 1329 default: 1330 return error(GL_INVALID_ENUM); 1331 } 1332 1333 context->drawElements(mode, count, type, indices); 1334 } 1335 } 1336 1337 void Enable(GLenum cap) 1338 { 1339 TRACE("(GLenum cap = 0x%X)", cap); 1340 1341 es1::Context *context = es1::getContext(); 1342 1343 if(context) 1344 { 1345 switch(cap) 1346 { 1347 case GL_CULL_FACE: context->setCullFaceEnabled(true); break; 1348 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFillEnabled(true); break; 1349 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverageEnabled(true); break; 1350 case GL_SAMPLE_COVERAGE: context->setSampleCoverageEnabled(true); break; 1351 case GL_SCISSOR_TEST: context->setScissorTestEnabled(true); break; 1352 case GL_STENCIL_TEST: context->setStencilTestEnabled(true); break; 1353 case GL_DEPTH_TEST: context->setDepthTestEnabled(true); break; 1354 case GL_BLEND: context->setBlendEnabled(true); break; 1355 case GL_DITHER: context->setDitherEnabled(true); break; 1356 case GL_LIGHTING: context->setLightingEnabled(true); break; 1357 case GL_LIGHT0: context->setLightEnabled(0, true); break; 1358 case GL_LIGHT1: context->setLightEnabled(1, true); break; 1359 case GL_LIGHT2: context->setLightEnabled(2, true); break; 1360 case GL_LIGHT3: context->setLightEnabled(3, true); break; 1361 case GL_LIGHT4: context->setLightEnabled(4, true); break; 1362 case GL_LIGHT5: context->setLightEnabled(5, true); break; 1363 case GL_LIGHT6: context->setLightEnabled(6, true); break; 1364 case GL_LIGHT7: context->setLightEnabled(7, true); break; 1365 case GL_FOG: context->setFogEnabled(true); break; 1366 case GL_TEXTURE_2D: context->setTexture2Denabled(true); break; 1367 case GL_TEXTURE_EXTERNAL_OES: context->setTextureExternalEnabled(true); break; 1368 case GL_ALPHA_TEST: context->setAlphaTestEnabled(true); break; 1369 case GL_COLOR_LOGIC_OP: context->setColorLogicOpEnabled(true); break; 1370 case GL_POINT_SMOOTH: context->setPointSmoothEnabled(true); break; 1371 case GL_LINE_SMOOTH: context->setLineSmoothEnabled(true); break; 1372 case GL_COLOR_MATERIAL: context->setColorMaterialEnabled(true); break; 1373 case GL_NORMALIZE: context->setNormalizeEnabled(true); break; 1374 case GL_RESCALE_NORMAL: context->setRescaleNormalEnabled(true); break; 1375 case GL_VERTEX_ARRAY: context->setVertexArrayEnabled(true); break; 1376 case GL_NORMAL_ARRAY: context->setNormalArrayEnabled(true); break; 1377 case GL_COLOR_ARRAY: context->setColorArrayEnabled(true); break; 1378 case GL_POINT_SIZE_ARRAY_OES: context->setPointSizeArrayEnabled(true); break; 1379 case GL_TEXTURE_COORD_ARRAY: context->setTextureCoordArrayEnabled(true); break; 1380 case GL_MULTISAMPLE: context->setMultisampleEnabled(true); break; 1381 case GL_SAMPLE_ALPHA_TO_ONE: context->setSampleAlphaToOneEnabled(true); break; 1382 case GL_CLIP_PLANE0: context->setClipPlaneEnabled(0, true); break; 1383 case GL_CLIP_PLANE1: context->setClipPlaneEnabled(1, true); break; 1384 case GL_CLIP_PLANE2: context->setClipPlaneEnabled(2, true); break; 1385 case GL_CLIP_PLANE3: context->setClipPlaneEnabled(3, true); break; 1386 case GL_CLIP_PLANE4: context->setClipPlaneEnabled(4, true); break; 1387 case GL_CLIP_PLANE5: context->setClipPlaneEnabled(5, true); break; 1388 case GL_POINT_SPRITE_OES: context->setPointSpriteEnabled(true); break; 1389 default: 1390 return error(GL_INVALID_ENUM); 1391 } 1392 } 1393 } 1394 1395 void EnableClientState(GLenum array) 1396 { 1397 TRACE("(GLenum array = 0x%X)", array); 1398 1399 switch(array) 1400 { 1401 case GL_VERTEX_ARRAY: 1402 case GL_NORMAL_ARRAY: 1403 case GL_COLOR_ARRAY: 1404 case GL_POINT_SIZE_ARRAY_OES: 1405 case GL_TEXTURE_COORD_ARRAY: 1406 break; 1407 default: 1408 return error(GL_INVALID_ENUM); 1409 } 1410 1411 es1::Context *context = es1::getContext(); 1412 1413 if(context) 1414 { 1415 GLenum texture = context->getClientActiveTexture(); 1416 1417 switch(array) 1418 { 1419 case GL_VERTEX_ARRAY: context->setVertexAttribArrayEnabled(sw::Position, true); break; 1420 case GL_NORMAL_ARRAY: context->setVertexAttribArrayEnabled(sw::Normal, true); break; 1421 case GL_COLOR_ARRAY: context->setVertexAttribArrayEnabled(sw::Color0, true); break; 1422 case GL_POINT_SIZE_ARRAY_OES: context->setVertexAttribArrayEnabled(sw::PointSize, true); break; 1423 case GL_TEXTURE_COORD_ARRAY: context->setVertexAttribArrayEnabled(sw::TexCoord0 + (texture - GL_TEXTURE0), true); break; 1424 default: UNREACHABLE(array); 1425 } 1426 } 1427 } 1428 1429 void Finish(void) 1430 { 1431 TRACE("()"); 1432 1433 es1::Context *context = es1::getContext(); 1434 1435 if(context) 1436 { 1437 context->finish(); 1438 } 1439 } 1440 1441 void Flush(void) 1442 { 1443 TRACE("()"); 1444 1445 es1::Context *context = es1::getContext(); 1446 1447 if(context) 1448 { 1449 context->flush(); 1450 } 1451 } 1452 1453 void FramebufferRenderbufferOES(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) 1454 { 1455 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, " 1456 "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer); 1457 1458 if(target != GL_FRAMEBUFFER_OES || (renderbuffertarget != GL_RENDERBUFFER_OES && renderbuffer != 0)) 1459 { 1460 return error(GL_INVALID_ENUM); 1461 } 1462 1463 es1::Context *context = es1::getContext(); 1464 1465 if(context) 1466 { 1467 es1::Framebuffer *framebuffer = context->getFramebuffer(); 1468 GLuint framebufferName = context->getFramebufferName(); 1469 1470 if(!framebuffer || (framebufferName == 0 && renderbuffer != 0)) 1471 { 1472 return error(GL_INVALID_OPERATION); 1473 } 1474 1475 switch(attachment) 1476 { 1477 case GL_COLOR_ATTACHMENT0_OES: 1478 framebuffer->setColorbuffer(GL_RENDERBUFFER_OES, renderbuffer); 1479 break; 1480 case GL_DEPTH_ATTACHMENT_OES: 1481 framebuffer->setDepthbuffer(GL_RENDERBUFFER_OES, renderbuffer); 1482 break; 1483 case GL_STENCIL_ATTACHMENT_OES: 1484 framebuffer->setStencilbuffer(GL_RENDERBUFFER_OES, renderbuffer); 1485 break; 1486 default: 1487 return error(GL_INVALID_ENUM); 1488 } 1489 } 1490 } 1491 1492 void FramebufferTexture2DOES(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) 1493 { 1494 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, " 1495 "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level); 1496 1497 if(target != GL_FRAMEBUFFER_OES) 1498 { 1499 return error(GL_INVALID_ENUM); 1500 } 1501 1502 switch(attachment) 1503 { 1504 case GL_COLOR_ATTACHMENT0_OES: 1505 case GL_DEPTH_ATTACHMENT_OES: 1506 case GL_STENCIL_ATTACHMENT_OES: 1507 break; 1508 default: 1509 return error(GL_INVALID_ENUM); 1510 } 1511 1512 es1::Context *context = es1::getContext(); 1513 1514 if(context) 1515 { 1516 if(texture == 0) 1517 { 1518 textarget = GL_NONE_OES; 1519 } 1520 else 1521 { 1522 es1::Texture *tex = context->getTexture(texture); 1523 1524 if(!tex) 1525 { 1526 return error(GL_INVALID_OPERATION); 1527 } 1528 1529 if(tex->isCompressed(textarget, level)) 1530 { 1531 return error(GL_INVALID_OPERATION); 1532 } 1533 1534 switch(textarget) 1535 { 1536 case GL_TEXTURE_2D: 1537 if(tex->getTarget() != GL_TEXTURE_2D) 1538 { 1539 return error(GL_INVALID_OPERATION); 1540 } 1541 break; 1542 default: 1543 return error(GL_INVALID_ENUM); 1544 } 1545 1546 if(level != 0) 1547 { 1548 return error(GL_INVALID_VALUE); 1549 } 1550 } 1551 1552 es1::Framebuffer *framebuffer = context->getFramebuffer(); 1553 GLuint framebufferName = context->getFramebufferName(); 1554 1555 if(framebufferName == 0 || !framebuffer) 1556 { 1557 return error(GL_INVALID_OPERATION); 1558 } 1559 1560 switch(attachment) 1561 { 1562 case GL_COLOR_ATTACHMENT0_OES: framebuffer->setColorbuffer(textarget, texture); break; 1563 case GL_DEPTH_ATTACHMENT_OES: framebuffer->setDepthbuffer(textarget, texture); break; 1564 case GL_STENCIL_ATTACHMENT_OES: framebuffer->setStencilbuffer(textarget, texture); break; 1565 } 1566 } 1567 } 1568 1569 void Fogf(GLenum pname, GLfloat param) 1570 { 1571 TRACE("(GLenum pname = 0x%X, GLfloat param = %f)", pname, param); 1572 1573 es1::Context *context = es1::getContext(); 1574 1575 if(context) 1576 { 1577 switch(pname) 1578 { 1579 case GL_FOG_MODE: 1580 switch((GLenum)param) 1581 { 1582 case GL_LINEAR: 1583 case GL_EXP: 1584 case GL_EXP2: 1585 context->setFogMode((GLenum)param); 1586 break; 1587 default: 1588 return error(GL_INVALID_ENUM); 1589 } 1590 break; 1591 case GL_FOG_DENSITY: 1592 if(param < 0) 1593 { 1594 return error(GL_INVALID_VALUE); 1595 } 1596 context->setFogDensity(param); 1597 break; 1598 case GL_FOG_START: 1599 context->setFogStart(param); 1600 break; 1601 case GL_FOG_END: 1602 context->setFogEnd(param); 1603 break; 1604 case GL_FOG_COLOR: 1605 return error(GL_INVALID_ENUM); // Need four values, should call glFogfv() instead 1606 default: 1607 return error(GL_INVALID_ENUM); 1608 } 1609 } 1610 } 1611 1612 void Fogfv(GLenum pname, const GLfloat *params) 1613 { 1614 TRACE("(GLenum pname = 0x%X, const GLfloat *params)", pname); 1615 1616 es1::Context *context = es1::getContext(); 1617 1618 if(context) 1619 { 1620 switch(pname) 1621 { 1622 case GL_FOG_MODE: 1623 switch((GLenum)params[0]) 1624 { 1625 case GL_LINEAR: 1626 case GL_EXP: 1627 case GL_EXP2: 1628 context->setFogMode((GLenum)params[0]); 1629 break; 1630 default: 1631 return error(GL_INVALID_ENUM); 1632 } 1633 break; 1634 case GL_FOG_DENSITY: 1635 if(params[0] < 0) 1636 { 1637 return error(GL_INVALID_VALUE); 1638 } 1639 context->setFogDensity(params[0]); 1640 break; 1641 case GL_FOG_START: 1642 context->setFogStart(params[0]); 1643 break; 1644 case GL_FOG_END: 1645 context->setFogEnd(params[0]); 1646 break; 1647 case GL_FOG_COLOR: 1648 context->setFogColor(params[0], params[1], params[2], params[3]); 1649 break; 1650 default: 1651 return error(GL_INVALID_ENUM); 1652 } 1653 } 1654 } 1655 1656 void Fogx(GLenum pname, GLfixed param) 1657 { 1658 TRACE("(GLenum pname = 0x%X, GLfixed param = %d)", pname, param); 1659 1660 es1::Context *context = es1::getContext(); 1661 1662 if(context) 1663 { 1664 switch(pname) 1665 { 1666 case GL_FOG_MODE: 1667 switch((GLenum)param) 1668 { 1669 case GL_LINEAR: 1670 case GL_EXP: 1671 case GL_EXP2: 1672 context->setFogMode((GLenum)param); 1673 break; 1674 default: 1675 return error(GL_INVALID_ENUM); 1676 } 1677 break; 1678 case GL_FOG_DENSITY: 1679 if(param < 0) 1680 { 1681 return error(GL_INVALID_VALUE); 1682 } 1683 context->setFogDensity((float)param / 0x10000); 1684 break; 1685 case GL_FOG_START: 1686 context->setFogStart((float)param / 0x10000); 1687 break; 1688 case GL_FOG_END: 1689 context->setFogEnd((float)param / 0x10000); 1690 break; 1691 case GL_FOG_COLOR: 1692 return error(GL_INVALID_ENUM); // Need four values, should call glFogxv() instead 1693 default: 1694 return error(GL_INVALID_ENUM); 1695 } 1696 } 1697 } 1698 1699 void Fogxv(GLenum pname, const GLfixed *params) 1700 { 1701 UNIMPLEMENTED(); 1702 } 1703 1704 void FrontFace(GLenum mode) 1705 { 1706 TRACE("(GLenum mode = 0x%X)", mode); 1707 1708 switch(mode) 1709 { 1710 case GL_CW: 1711 case GL_CCW: 1712 { 1713 es1::Context *context = es1::getContext(); 1714 1715 if(context) 1716 { 1717 context->setFrontFace(mode); 1718 } 1719 } 1720 break; 1721 default: 1722 return error(GL_INVALID_ENUM); 1723 } 1724 } 1725 1726 void Frustumf(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar) 1727 { 1728 TRACE("(GLfloat left = %f, GLfloat right = %f, GLfloat bottom = %f, GLfloat top = %f, GLfloat zNear = %f, GLfloat zFar = %f)", left, right, bottom, top, zNear, zFar); 1729 1730 if(zNear <= 0.0f || zFar <= 0.0f || left == right || bottom == top || zNear == zFar) 1731 { 1732 return error(GL_INVALID_VALUE); 1733 } 1734 1735 es1::Context *context = es1::getContext(); 1736 1737 if(context) 1738 { 1739 context->frustum(left, right, bottom, top, zNear, zFar); 1740 } 1741 } 1742 1743 void Frustumx(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar) 1744 { 1745 Frustumf((float)left / 0x10000, (float)right / 0x10000, (float)bottom / 0x10000, (float)top / 0x10000, (float)zNear / 0x10000, (float)zFar / 0x10000); 1746 } 1747 1748 void GenerateMipmapOES(GLenum target) 1749 { 1750 TRACE("(GLenum target = 0x%X)", target); 1751 1752 es1::Context *context = es1::getContext(); 1753 1754 if(context) 1755 { 1756 es1::Texture *texture; 1757 1758 switch(target) 1759 { 1760 case GL_TEXTURE_2D: 1761 texture = context->getTexture2D(); 1762 break; 1763 default: 1764 return error(GL_INVALID_ENUM); 1765 } 1766 1767 if(texture->isCompressed(target, 0) || texture->isDepth(target, 0)) 1768 { 1769 return error(GL_INVALID_OPERATION); 1770 } 1771 1772 texture->generateMipmaps(); 1773 } 1774 } 1775 1776 void GenBuffers(GLsizei n, GLuint* buffers) 1777 { 1778 TRACE("(GLsizei n = %d, GLuint* buffers = %p)", n, buffers); 1779 1780 if(n < 0) 1781 { 1782 return error(GL_INVALID_VALUE); 1783 } 1784 1785 es1::Context *context = es1::getContext(); 1786 1787 if(context) 1788 { 1789 for(int i = 0; i < n; i++) 1790 { 1791 buffers[i] = context->createBuffer(); 1792 } 1793 } 1794 } 1795 1796 void GenFramebuffersOES(GLsizei n, GLuint* framebuffers) 1797 { 1798 TRACE("(GLsizei n = %d, GLuint* framebuffers = %p)", n, framebuffers); 1799 1800 if(n < 0) 1801 { 1802 return error(GL_INVALID_VALUE); 1803 } 1804 1805 es1::Context *context = es1::getContext(); 1806 1807 if(context) 1808 { 1809 for(int i = 0; i < n; i++) 1810 { 1811 framebuffers[i] = context->createFramebuffer(); 1812 } 1813 } 1814 } 1815 1816 void GenRenderbuffersOES(GLsizei n, GLuint* renderbuffers) 1817 { 1818 TRACE("(GLsizei n = %d, GLuint* renderbuffers = %p)", n, renderbuffers); 1819 1820 if(n < 0) 1821 { 1822 return error(GL_INVALID_VALUE); 1823 } 1824 1825 es1::Context *context = es1::getContext(); 1826 1827 if(context) 1828 { 1829 for(int i = 0; i < n; i++) 1830 { 1831 renderbuffers[i] = context->createRenderbuffer(); 1832 } 1833 } 1834 } 1835 1836 void GenTextures(GLsizei n, GLuint* textures) 1837 { 1838 TRACE("(GLsizei n = %d, GLuint* textures = %p)", n, textures); 1839 1840 if(n < 0) 1841 { 1842 return error(GL_INVALID_VALUE); 1843 } 1844 1845 es1::Context *context = es1::getContext(); 1846 1847 if(context) 1848 { 1849 for(int i = 0; i < n; i++) 1850 { 1851 textures[i] = context->createTexture(); 1852 } 1853 } 1854 } 1855 1856 void GetRenderbufferParameterivOES(GLenum target, GLenum pname, GLint* params) 1857 { 1858 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", target, pname, params); 1859 1860 es1::Context *context = es1::getContext(); 1861 1862 if(context) 1863 { 1864 if(target != GL_RENDERBUFFER_OES) 1865 { 1866 return error(GL_INVALID_ENUM); 1867 } 1868 1869 if(context->getRenderbufferName() == 0) 1870 { 1871 return error(GL_INVALID_OPERATION); 1872 } 1873 1874 es1::Renderbuffer *renderbuffer = context->getRenderbuffer(context->getRenderbufferName()); 1875 1876 switch(pname) 1877 { 1878 case GL_RENDERBUFFER_WIDTH_OES: *params = renderbuffer->getWidth(); break; 1879 case GL_RENDERBUFFER_HEIGHT_OES: *params = renderbuffer->getHeight(); break; 1880 case GL_RENDERBUFFER_INTERNAL_FORMAT_OES: *params = renderbuffer->getFormat(); break; 1881 case GL_RENDERBUFFER_RED_SIZE_OES: *params = renderbuffer->getRedSize(); break; 1882 case GL_RENDERBUFFER_GREEN_SIZE_OES: *params = renderbuffer->getGreenSize(); break; 1883 case GL_RENDERBUFFER_BLUE_SIZE_OES: *params = renderbuffer->getBlueSize(); break; 1884 case GL_RENDERBUFFER_ALPHA_SIZE_OES: *params = renderbuffer->getAlphaSize(); break; 1885 case GL_RENDERBUFFER_DEPTH_SIZE_OES: *params = renderbuffer->getDepthSize(); break; 1886 case GL_RENDERBUFFER_STENCIL_SIZE_OES: *params = renderbuffer->getStencilSize(); break; 1887 default: 1888 return error(GL_INVALID_ENUM); 1889 } 1890 } 1891 } 1892 1893 void GetBooleanv(GLenum pname, GLboolean* params) 1894 { 1895 TRACE("(GLenum pname = 0x%X, GLboolean* params = %p)", pname, params); 1896 1897 es1::Context *context = es1::getContext(); 1898 1899 if(context) 1900 { 1901 if(!(context->getBooleanv(pname, params))) 1902 { 1903 int numParams = context->getQueryParameterNum(pname); 1904 1905 if(numParams < 0) 1906 { 1907 return error(GL_INVALID_ENUM); 1908 } 1909 1910 if(numParams == 0) 1911 { 1912 return; 1913 } 1914 1915 if(context->isQueryParameterFloat(pname)) 1916 { 1917 GLfloat *floatParams = nullptr; 1918 floatParams = new GLfloat[numParams]; 1919 1920 context->getFloatv(pname, floatParams); 1921 1922 for(int i = 0; i < numParams; ++i) 1923 { 1924 if(floatParams[i] == 0.0f) 1925 params[i] = GL_FALSE; 1926 else 1927 params[i] = GL_TRUE; 1928 } 1929 1930 delete [] floatParams; 1931 } 1932 else if(context->isQueryParameterInt(pname)) 1933 { 1934 GLint *intParams = nullptr; 1935 intParams = new GLint[numParams]; 1936 1937 context->getIntegerv(pname, intParams); 1938 1939 for(int i = 0; i < numParams; ++i) 1940 { 1941 if(intParams[i] == 0) 1942 params[i] = GL_FALSE; 1943 else 1944 params[i] = GL_TRUE; 1945 } 1946 1947 delete [] intParams; 1948 } 1949 else UNREACHABLE(pname); 1950 } 1951 } 1952 } 1953 1954 void GetBufferParameteriv(GLenum target, GLenum pname, GLint* params) 1955 { 1956 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", target, pname, params); 1957 1958 es1::Context *context = es1::getContext(); 1959 1960 if(context) 1961 { 1962 es1::Buffer *buffer; 1963 1964 switch(target) 1965 { 1966 case GL_ARRAY_BUFFER: 1967 buffer = context->getArrayBuffer(); 1968 break; 1969 case GL_ELEMENT_ARRAY_BUFFER: 1970 buffer = context->getElementArrayBuffer(); 1971 break; 1972 default: 1973 return error(GL_INVALID_ENUM); 1974 } 1975 1976 if(!buffer) 1977 { 1978 // A null buffer means that "0" is bound to the requested buffer target 1979 return error(GL_INVALID_OPERATION); 1980 } 1981 1982 switch(pname) 1983 { 1984 case GL_BUFFER_USAGE: 1985 *params = buffer->usage(); 1986 break; 1987 case GL_BUFFER_SIZE: 1988 *params = buffer->size(); 1989 break; 1990 default: 1991 return error(GL_INVALID_ENUM); 1992 } 1993 } 1994 } 1995 1996 void GetClipPlanef(GLenum pname, GLfloat eqn[4]) 1997 { 1998 UNIMPLEMENTED(); 1999 } 2000 2001 void GetClipPlanex(GLenum pname, GLfixed eqn[4]) 2002 { 2003 UNIMPLEMENTED(); 2004 } 2005 2006 GLenum GetError(void) 2007 { 2008 TRACE("()"); 2009 2010 es1::Context *context = es1::getContext(); 2011 2012 if(context) 2013 { 2014 return context->getError(); 2015 } 2016 2017 return GL_NO_ERROR; 2018 } 2019 2020 void GetFixedv(GLenum pname, GLfixed *params) 2021 { 2022 UNIMPLEMENTED(); 2023 } 2024 2025 void GetFloatv(GLenum pname, GLfloat* params) 2026 { 2027 TRACE("(GLenum pname = 0x%X, GLfloat* params = %p)", pname, params); 2028 2029 es1::Context *context = es1::getContext(); 2030 2031 if(context) 2032 { 2033 if(!(context->getFloatv(pname, params))) 2034 { 2035 int numParams = context->getQueryParameterNum(pname); 2036 2037 if(numParams < 0) 2038 { 2039 return error(GL_INVALID_ENUM); 2040 } 2041 2042 if(numParams == 0) 2043 { 2044 return; 2045 } 2046 2047 if(context->isQueryParameterBool(pname)) 2048 { 2049 GLboolean *boolParams = nullptr; 2050 boolParams = new GLboolean[numParams]; 2051 2052 context->getBooleanv(pname, boolParams); 2053 2054 for(int i = 0; i < numParams; ++i) 2055 { 2056 if(boolParams[i] == GL_FALSE) 2057 params[i] = 0.0f; 2058 else 2059 params[i] = 1.0f; 2060 } 2061 2062 delete [] boolParams; 2063 } 2064 else if(context->isQueryParameterInt(pname)) 2065 { 2066 GLint *intParams = nullptr; 2067 intParams = new GLint[numParams]; 2068 2069 context->getIntegerv(pname, intParams); 2070 2071 for(int i = 0; i < numParams; ++i) 2072 { 2073 params[i] = (GLfloat)intParams[i]; 2074 } 2075 2076 delete [] intParams; 2077 } 2078 else UNREACHABLE(pname); 2079 } 2080 } 2081 } 2082 2083 void GetFramebufferAttachmentParameterivOES(GLenum target, GLenum attachment, GLenum pname, GLint* params) 2084 { 2085 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", 2086 target, attachment, pname, params); 2087 2088 es1::Context *context = es1::getContext(); 2089 2090 if(context) 2091 { 2092 if(target != GL_FRAMEBUFFER_OES) 2093 { 2094 return error(GL_INVALID_ENUM); 2095 } 2096 2097 if(context->getFramebufferName() == 0) 2098 { 2099 return error(GL_INVALID_OPERATION); 2100 } 2101 2102 es1::Framebuffer *framebuffer = context->getFramebuffer(); 2103 2104 GLenum attachmentType; 2105 GLuint attachmentHandle; 2106 switch(attachment) 2107 { 2108 case GL_COLOR_ATTACHMENT0_OES: 2109 attachmentType = framebuffer->getColorbufferType(); 2110 attachmentHandle = framebuffer->getColorbufferName(); 2111 break; 2112 case GL_DEPTH_ATTACHMENT_OES: 2113 attachmentType = framebuffer->getDepthbufferType(); 2114 attachmentHandle = framebuffer->getDepthbufferName(); 2115 break; 2116 case GL_STENCIL_ATTACHMENT_OES: 2117 attachmentType = framebuffer->getStencilbufferType(); 2118 attachmentHandle = framebuffer->getStencilbufferName(); 2119 break; 2120 default: 2121 return error(GL_INVALID_ENUM); 2122 } 2123 2124 GLenum attachmentObjectType; // Type category 2125 if(attachmentType == GL_NONE_OES || attachmentType == GL_RENDERBUFFER_OES) 2126 { 2127 attachmentObjectType = attachmentType; 2128 } 2129 else if(es1::IsTextureTarget(attachmentType)) 2130 { 2131 attachmentObjectType = GL_TEXTURE; 2132 } 2133 else UNREACHABLE(attachmentType); 2134 2135 switch(pname) 2136 { 2137 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_OES: 2138 *params = attachmentObjectType; 2139 break; 2140 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_OES: 2141 if(attachmentObjectType == GL_RENDERBUFFER_OES || attachmentObjectType == GL_TEXTURE) 2142 { 2143 *params = attachmentHandle; 2144 } 2145 else 2146 { 2147 return error(GL_INVALID_ENUM); 2148 } 2149 break; 2150 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_OES: 2151 if(attachmentObjectType == GL_TEXTURE) 2152 { 2153 *params = 0; // FramebufferTexture2D will not allow level to be set to anything else in GL ES 2.0 2154 } 2155 else 2156 { 2157 return error(GL_INVALID_ENUM); 2158 } 2159 break; 2160 default: 2161 return error(GL_INVALID_ENUM); 2162 } 2163 } 2164 } 2165 2166 void GetIntegerv(GLenum pname, GLint* params) 2167 { 2168 TRACE("(GLenum pname = 0x%X, GLint* params = %p)", pname, params); 2169 2170 es1::Context *context = es1::getContext(); 2171 2172 if(context) 2173 { 2174 if(!(context->getIntegerv(pname, params))) 2175 { 2176 int numParams = context->getQueryParameterNum(pname); 2177 2178 if(numParams < 0) 2179 { 2180 return error(GL_INVALID_ENUM); 2181 } 2182 2183 if(numParams == 0) 2184 { 2185 return; 2186 } 2187 2188 if(context->isQueryParameterBool(pname)) 2189 { 2190 GLboolean *boolParams = nullptr; 2191 boolParams = new GLboolean[numParams]; 2192 2193 context->getBooleanv(pname, boolParams); 2194 2195 for(int i = 0; i < numParams; ++i) 2196 { 2197 if(boolParams[i] == GL_FALSE) 2198 params[i] = 0; 2199 else 2200 params[i] = 1; 2201 } 2202 2203 delete [] boolParams; 2204 } 2205 else if(context->isQueryParameterFloat(pname)) 2206 { 2207 GLfloat *floatParams = nullptr; 2208 floatParams = new GLfloat[numParams]; 2209 2210 context->getFloatv(pname, floatParams); 2211 2212 for(int i = 0; i < numParams; ++i) 2213 { 2214 if(pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE) 2215 { 2216 params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) / 2.0f); 2217 } 2218 else 2219 { 2220 params[i] = (GLint)(floatParams[i] > 0.0f ? floor(floatParams[i] + 0.5) : ceil(floatParams[i] - 0.5)); 2221 } 2222 } 2223 2224 delete [] floatParams; 2225 } 2226 else UNREACHABLE(pname); 2227 } 2228 } 2229 } 2230 2231 void GetLightfv(GLenum light, GLenum pname, GLfloat *params) 2232 { 2233 UNIMPLEMENTED(); 2234 } 2235 2236 void GetLightxv(GLenum light, GLenum pname, GLfixed *params) 2237 { 2238 UNIMPLEMENTED(); 2239 } 2240 2241 void GetMaterialfv(GLenum face, GLenum pname, GLfloat *params) 2242 { 2243 UNIMPLEMENTED(); 2244 } 2245 2246 void GetMaterialxv(GLenum face, GLenum pname, GLfixed *params) 2247 { 2248 UNIMPLEMENTED(); 2249 } 2250 2251 void GetPointerv(GLenum pname, GLvoid **params) 2252 { 2253 TRACE("(GLenum pname = 0x%X, GLvoid **params = %p)", pname, params); 2254 2255 es1::Context *context = es1::getContext(); 2256 2257 if(context) 2258 { 2259 if(!(context->getPointerv(pname, const_cast<const GLvoid**>(params)))) 2260 { 2261 return error(GL_INVALID_ENUM); 2262 } 2263 } 2264 } 2265 2266 const GLubyte* GetString(GLenum name) 2267 { 2268 TRACE("(GLenum name = 0x%X)", name); 2269 2270 switch(name) 2271 { 2272 case GL_VENDOR: 2273 return (GLubyte*)"Google Inc."; 2274 case GL_RENDERER: 2275 return (GLubyte*)"Google SwiftShader"; 2276 case GL_VERSION: 2277 return (GLubyte*)"OpenGL ES 1.1 SwiftShader " VERSION_STRING; 2278 case GL_EXTENSIONS: 2279 // Keep list sorted in following order: 2280 // OES extensions 2281 // EXT extensions 2282 // Vendor extensions 2283 return (GLubyte*) 2284 "GL_OES_blend_equation_separate " 2285 "GL_OES_blend_func_separate " 2286 "GL_OES_blend_subtract " 2287 "GL_OES_compressed_ETC1_RGB8_texture " 2288 "GL_OES_depth_texture " 2289 "GL_OES_EGL_image " 2290 "GL_OES_EGL_image_external " 2291 "GL_OES_EGL_sync " 2292 "GL_OES_element_index_uint " 2293 "GL_OES_framebuffer_object " 2294 "GL_OES_packed_depth_stencil " 2295 "GL_OES_read_format " 2296 "GL_OES_rgb8_rgba8 " 2297 "GL_OES_stencil8 " 2298 "GL_OES_stencil_wrap " 2299 "GL_OES_texture_mirrored_repeat " 2300 "GL_OES_texture_npot " 2301 "GL_EXT_blend_minmax " 2302 "GL_EXT_read_format_bgra " 2303 #if (S3TC_SUPPORT) 2304 "GL_EXT_texture_compression_dxt1 " 2305 "GL_ANGLE_texture_compression_dxt3 " 2306 "GL_ANGLE_texture_compression_dxt5 " 2307 #endif 2308 "GL_EXT_texture_filter_anisotropic " 2309 "GL_EXT_texture_format_BGRA8888"; 2310 default: 2311 return error(GL_INVALID_ENUM, (GLubyte*)nullptr); 2312 } 2313 } 2314 2315 void GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params) 2316 { 2317 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat* params = %p)", target, pname, params); 2318 2319 es1::Context *context = es1::getContext(); 2320 2321 if(context) 2322 { 2323 es1::Texture *texture; 2324 2325 switch(target) 2326 { 2327 case GL_TEXTURE_2D: 2328 texture = context->getTexture2D(); 2329 break; 2330 case GL_TEXTURE_EXTERNAL_OES: 2331 texture = context->getTextureExternal(); 2332 break; 2333 default: 2334 return error(GL_INVALID_ENUM); 2335 } 2336 2337 switch(pname) 2338 { 2339 case GL_TEXTURE_MAG_FILTER: 2340 *params = (GLfloat)texture->getMagFilter(); 2341 break; 2342 case GL_TEXTURE_MIN_FILTER: 2343 *params = (GLfloat)texture->getMinFilter(); 2344 break; 2345 case GL_TEXTURE_WRAP_S: 2346 *params = (GLfloat)texture->getWrapS(); 2347 break; 2348 case GL_TEXTURE_WRAP_T: 2349 *params = (GLfloat)texture->getWrapT(); 2350 break; 2351 case GL_TEXTURE_MAX_ANISOTROPY_EXT: 2352 *params = texture->getMaxAnisotropy(); 2353 break; 2354 case GL_GENERATE_MIPMAP: 2355 *params = (GLfloat)texture->getGenerateMipmap(); 2356 break; 2357 case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES: 2358 *params = (GLfloat)1; 2359 break; 2360 default: 2361 return error(GL_INVALID_ENUM); 2362 } 2363 } 2364 } 2365 2366 void GetTexParameteriv(GLenum target, GLenum pname, GLint* params) 2367 { 2368 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", target, pname, params); 2369 2370 es1::Context *context = es1::getContext(); 2371 2372 if(context) 2373 { 2374 es1::Texture *texture; 2375 2376 switch(target) 2377 { 2378 case GL_TEXTURE_2D: 2379 texture = context->getTexture2D(); 2380 break; 2381 case GL_TEXTURE_EXTERNAL_OES: 2382 texture = context->getTextureExternal(); 2383 break; 2384 default: 2385 return error(GL_INVALID_ENUM); 2386 } 2387 2388 switch(pname) 2389 { 2390 case GL_TEXTURE_MAG_FILTER: 2391 *params = texture->getMagFilter(); 2392 break; 2393 case GL_TEXTURE_MIN_FILTER: 2394 *params = texture->getMinFilter(); 2395 break; 2396 case GL_TEXTURE_WRAP_S: 2397 *params = texture->getWrapS(); 2398 break; 2399 case GL_TEXTURE_WRAP_T: 2400 *params = texture->getWrapT(); 2401 break; 2402 case GL_TEXTURE_MAX_ANISOTROPY_EXT: 2403 *params = (GLint)texture->getMaxAnisotropy(); 2404 break; 2405 case GL_GENERATE_MIPMAP: 2406 *params = (GLint)texture->getGenerateMipmap(); 2407 break; 2408 case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES: 2409 *params = 1; 2410 break; 2411 default: 2412 return error(GL_INVALID_ENUM); 2413 } 2414 } 2415 } 2416 2417 void GetTexEnvfv(GLenum env, GLenum pname, GLfloat *params) 2418 { 2419 UNIMPLEMENTED(); 2420 } 2421 2422 void GetTexEnviv(GLenum env, GLenum pname, GLint *params) 2423 { 2424 UNIMPLEMENTED(); 2425 } 2426 2427 void GetTexEnvxv(GLenum env, GLenum pname, GLfixed *params) 2428 { 2429 UNIMPLEMENTED(); 2430 } 2431 2432 void GetTexParameterxv(GLenum target, GLenum pname, GLfixed *params) 2433 { 2434 UNIMPLEMENTED(); 2435 } 2436 2437 void Hint(GLenum target, GLenum mode) 2438 { 2439 TRACE("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode); 2440 2441 switch(mode) 2442 { 2443 case GL_FASTEST: 2444 case GL_NICEST: 2445 case GL_DONT_CARE: 2446 break; 2447 default: 2448 return error(GL_INVALID_ENUM); 2449 } 2450 2451 es1::Context *context = es1::getContext(); 2452 2453 if(context) 2454 { 2455 switch(target) 2456 { 2457 case GL_GENERATE_MIPMAP_HINT: 2458 context->setGenerateMipmapHint(mode); 2459 break; 2460 case GL_PERSPECTIVE_CORRECTION_HINT: 2461 context->setPerspectiveCorrectionHint(mode); 2462 break; 2463 case GL_FOG_HINT: 2464 context->setFogHint(mode); 2465 break; 2466 default: 2467 return error(GL_INVALID_ENUM); 2468 } 2469 } 2470 } 2471 2472 GLboolean IsBuffer(GLuint buffer) 2473 { 2474 TRACE("(GLuint buffer = %d)", buffer); 2475 2476 es1::Context *context = es1::getContext(); 2477 2478 if(context && buffer) 2479 { 2480 es1::Buffer *bufferObject = context->getBuffer(buffer); 2481 2482 if(bufferObject) 2483 { 2484 return GL_TRUE; 2485 } 2486 } 2487 2488 return GL_FALSE; 2489 } 2490 2491 GLboolean IsEnabled(GLenum cap) 2492 { 2493 TRACE("(GLenum cap = 0x%X)", cap); 2494 2495 es1::Context *context = es1::getContext(); 2496 2497 if(context) 2498 { 2499 switch(cap) 2500 { 2501 case GL_CULL_FACE: return context->isCullFaceEnabled(); break; 2502 case GL_POLYGON_OFFSET_FILL: return context->isPolygonOffsetFillEnabled(); break; 2503 case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled(); break; 2504 case GL_SAMPLE_COVERAGE: return context->isSampleCoverageEnabled(); break; 2505 case GL_SCISSOR_TEST: return context->isScissorTestEnabled(); break; 2506 case GL_STENCIL_TEST: return context->isStencilTestEnabled(); break; 2507 case GL_DEPTH_TEST: return context->isDepthTestEnabled(); break; 2508 case GL_BLEND: return context->isBlendEnabled(); break; 2509 case GL_DITHER: return context->isDitherEnabled(); break; 2510 case GL_LIGHTING: return context->isLightingEnabled(); break; 2511 case GL_LIGHT0: return context->isLightEnabled(0); break; 2512 case GL_LIGHT1: return context->isLightEnabled(1); break; 2513 case GL_LIGHT2: return context->isLightEnabled(2); break; 2514 case GL_LIGHT3: return context->isLightEnabled(3); break; 2515 case GL_LIGHT4: return context->isLightEnabled(4); break; 2516 case GL_LIGHT5: return context->isLightEnabled(5); break; 2517 case GL_LIGHT6: return context->isLightEnabled(6); break; 2518 case GL_LIGHT7: return context->isLightEnabled(7); break; 2519 case GL_FOG: return context->isFogEnabled(); break; 2520 case GL_TEXTURE_2D: return context->isTexture2Denabled(); break; 2521 case GL_TEXTURE_EXTERNAL_OES: return context->isTextureExternalEnabled(); break; 2522 case GL_ALPHA_TEST: return context->isAlphaTestEnabled(); break; 2523 case GL_COLOR_LOGIC_OP: return context->isColorLogicOpEnabled(); break; 2524 case GL_POINT_SMOOTH: return context->isPointSmoothEnabled(); break; 2525 case GL_LINE_SMOOTH: return context->isLineSmoothEnabled(); break; 2526 case GL_COLOR_MATERIAL: return context->isColorMaterialEnabled(); break; 2527 case GL_NORMALIZE: return context->isNormalizeEnabled(); break; 2528 case GL_RESCALE_NORMAL: return context->isRescaleNormalEnabled(); break; 2529 case GL_VERTEX_ARRAY: return context->isVertexArrayEnabled(); break; 2530 case GL_NORMAL_ARRAY: return context->isNormalArrayEnabled(); break; 2531 case GL_COLOR_ARRAY: return context->isColorArrayEnabled(); break; 2532 case GL_POINT_SIZE_ARRAY_OES: return context->isPointSizeArrayEnabled(); break; 2533 case GL_TEXTURE_COORD_ARRAY: return context->isTextureCoordArrayEnabled(); break; 2534 case GL_MULTISAMPLE: return context->isMultisampleEnabled(); break; 2535 case GL_SAMPLE_ALPHA_TO_ONE: return context->isSampleAlphaToOneEnabled(); break; 2536 case GL_CLIP_PLANE0: return context->isClipPlaneEnabled(0); break; 2537 case GL_CLIP_PLANE1: return context->isClipPlaneEnabled(1); break; 2538 case GL_CLIP_PLANE2: return context->isClipPlaneEnabled(2); break; 2539 case GL_CLIP_PLANE3: return context->isClipPlaneEnabled(3); break; 2540 case GL_CLIP_PLANE4: return context->isClipPlaneEnabled(4); break; 2541 case GL_CLIP_PLANE5: return context->isClipPlaneEnabled(5); break; 2542 case GL_POINT_SPRITE_OES: return context->isPointSpriteEnabled(); break; 2543 default: 2544 return error(GL_INVALID_ENUM, GL_FALSE); 2545 } 2546 } 2547 2548 return GL_FALSE; 2549 } 2550 2551 GLboolean IsFramebufferOES(GLuint framebuffer) 2552 { 2553 TRACE("(GLuint framebuffer = %d)", framebuffer); 2554 2555 es1::Context *context = es1::getContext(); 2556 2557 if(context && framebuffer) 2558 { 2559 es1::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer); 2560 2561 if(framebufferObject) 2562 { 2563 return GL_TRUE; 2564 } 2565 } 2566 2567 return GL_FALSE; 2568 } 2569 2570 GLboolean IsTexture(GLuint texture) 2571 { 2572 TRACE("(GLuint texture = %d)", texture); 2573 2574 es1::Context *context = es1::getContext(); 2575 2576 if(context && texture) 2577 { 2578 es1::Texture *textureObject = context->getTexture(texture); 2579 2580 if(textureObject) 2581 { 2582 return GL_TRUE; 2583 } 2584 } 2585 2586 return GL_FALSE; 2587 } 2588 2589 GLboolean IsRenderbufferOES(GLuint renderbuffer) 2590 { 2591 TRACE("(GLuint renderbuffer = %d)", renderbuffer); 2592 2593 es1::Context *context = es1::getContext(); 2594 2595 if(context && renderbuffer) 2596 { 2597 es1::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer); 2598 2599 if(renderbufferObject) 2600 { 2601 return GL_TRUE; 2602 } 2603 } 2604 2605 return GL_FALSE; 2606 } 2607 2608 void LightModelf(GLenum pname, GLfloat param) 2609 { 2610 TRACE("(GLenum pname = 0x%X, GLfloat param = %f)", pname, param); 2611 2612 es1::Context *context = es1::getContext(); 2613 2614 if(context) 2615 { 2616 switch(pname) 2617 { 2618 case GL_LIGHT_MODEL_TWO_SIDE: 2619 context->setLightModelTwoSide(param != 0.0f); 2620 break; 2621 case GL_LIGHT_MODEL_AMBIENT: 2622 return error(GL_INVALID_ENUM); // Need four values, should call glLightModelfv() instead 2623 default: 2624 return error(GL_INVALID_ENUM); 2625 } 2626 } 2627 } 2628 2629 void LightModelfv(GLenum pname, const GLfloat *params) 2630 { 2631 TRACE("(GLenum pname = 0x%X, const GLfloat *params)", pname); 2632 2633 es1::Context *context = es1::getContext(); 2634 2635 if(context) 2636 { 2637 switch(pname) 2638 { 2639 case GL_LIGHT_MODEL_AMBIENT: 2640 context->setGlobalAmbient(params[0], params[1], params[2], params[3]); 2641 break; 2642 case GL_LIGHT_MODEL_TWO_SIDE: 2643 context->setLightModelTwoSide(params[0] != 0.0f); 2644 break; 2645 default: 2646 return error(GL_INVALID_ENUM); 2647 } 2648 } 2649 } 2650 2651 void LightModelx(GLenum pname, GLfixed param) 2652 { 2653 TRACE("(GLenum pname = 0x%X, GLfixed param = %d)", pname, param); 2654 2655 es1::Context *context = es1::getContext(); 2656 2657 if(context) 2658 { 2659 switch(pname) 2660 { 2661 case GL_LIGHT_MODEL_TWO_SIDE: 2662 context->setLightModelTwoSide(param != 0); 2663 break; 2664 case GL_LIGHT_MODEL_AMBIENT: 2665 return error(GL_INVALID_ENUM); // Need four values, should call glLightModelxv() instead 2666 default: 2667 return error(GL_INVALID_ENUM); 2668 } 2669 } 2670 } 2671 2672 void LightModelxv(GLenum pname, const GLfixed *params) 2673 { 2674 TRACE("(GLenum pname = 0x%X, const GLfixed *params)", pname); 2675 2676 es1::Context *context = es1::getContext(); 2677 2678 if(context) 2679 { 2680 switch(pname) 2681 { 2682 case GL_LIGHT_MODEL_AMBIENT: 2683 context->setGlobalAmbient((float)params[0] / 0x10000, (float)params[1] / 0x10000, (float)params[2] / 0x10000, (float)params[3] / 0x10000); 2684 break; 2685 case GL_LIGHT_MODEL_TWO_SIDE: 2686 context->setLightModelTwoSide(params[0] != 0); 2687 break; 2688 default: 2689 return error(GL_INVALID_ENUM); 2690 } 2691 } 2692 } 2693 2694 void Lightf(GLenum light, GLenum pname, GLfloat param) 2695 { 2696 TRACE("(GLenum light = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", light, pname, param); 2697 2698 int index = light - GL_LIGHT0; 2699 2700 if(index < 0 || index >= es1::MAX_LIGHTS) 2701 { 2702 return error(GL_INVALID_ENUM); 2703 } 2704 2705 es1::Context *context = es1::getContext(); 2706 2707 if(context) 2708 { 2709 switch(pname) 2710 { 2711 case GL_SPOT_EXPONENT: 2712 if(param < 0.0f || param > 128.0f) 2713 { 2714 return error(GL_INVALID_VALUE); 2715 } 2716 context->setSpotLightExponent(index, param); 2717 break; 2718 case GL_SPOT_CUTOFF: 2719 if((param < 0.0f || param > 90.0f) && param != 180.0f) 2720 { 2721 return error(GL_INVALID_VALUE); 2722 } 2723 context->setSpotLightCutoff(index, param); 2724 break; 2725 case GL_CONSTANT_ATTENUATION: 2726 if(param < 0.0f) 2727 { 2728 return error(GL_INVALID_VALUE); 2729 } 2730 context->setLightAttenuationConstant(index, param); 2731 break; 2732 case GL_LINEAR_ATTENUATION: 2733 if(param < 0.0f) 2734 { 2735 return error(GL_INVALID_VALUE); 2736 } 2737 context->setLightAttenuationLinear(index, param); 2738 break; 2739 case GL_QUADRATIC_ATTENUATION: 2740 if(param < 0.0f) 2741 { 2742 return error(GL_INVALID_VALUE); 2743 } 2744 context->setLightAttenuationQuadratic(index, param); 2745 break; 2746 case GL_AMBIENT: 2747 case GL_DIFFUSE: 2748 case GL_SPECULAR: 2749 case GL_POSITION: 2750 case GL_SPOT_DIRECTION: 2751 return error(GL_INVALID_ENUM); // Need four values, should call glLightfv() instead 2752 default: 2753 return error(GL_INVALID_ENUM); 2754 } 2755 } 2756 } 2757 2758 void Lightfv(GLenum light, GLenum pname, const GLfloat *params) 2759 { 2760 TRACE("(GLenum light = 0x%X, GLenum pname = 0x%X, const GLint *params)", light, pname); 2761 2762 es1::Context *context = es1::getContext(); 2763 2764 if(context) 2765 { 2766 int index = light - GL_LIGHT0; 2767 2768 if(index < 0 || index > es1::MAX_LIGHTS) 2769 { 2770 return error(GL_INVALID_ENUM); 2771 } 2772 2773 switch(pname) 2774 { 2775 case GL_AMBIENT: context->setLightAmbient(index, params[0], params[1], params[2], params[3]); break; 2776 case GL_DIFFUSE: context->setLightDiffuse(index, params[0], params[1], params[2], params[3]); break; 2777 case GL_SPECULAR: context->setLightSpecular(index, params[0], params[1], params[2], params[3]); break; 2778 case GL_POSITION: context->setLightPosition(index, params[0], params[1], params[2], params[3]); break; 2779 case GL_SPOT_DIRECTION: context->setLightDirection(index, params[0], params[1], params[2]); break; 2780 case GL_SPOT_EXPONENT: 2781 if(params[0] < 0.0f || params[0] > 128.0f) 2782 { 2783 return error(GL_INVALID_VALUE); 2784 } 2785 context->setSpotLightExponent(index, params[0]); 2786 break; 2787 case GL_SPOT_CUTOFF: 2788 if((params[0] < 0.0f || params[0] > 90.0f) && params[0] != 180.0f) 2789 { 2790 return error(GL_INVALID_VALUE); 2791 } 2792 context->setSpotLightCutoff(index, params[0]); 2793 break; 2794 case GL_CONSTANT_ATTENUATION: 2795 if(params[0] < 0.0f) 2796 { 2797 return error(GL_INVALID_VALUE); 2798 } 2799 context->setLightAttenuationConstant(index, params[0]); 2800 break; 2801 case GL_LINEAR_ATTENUATION: 2802 if(params[0] < 0.0f) 2803 { 2804 return error(GL_INVALID_VALUE); 2805 } 2806 context->setLightAttenuationLinear(index, params[0]); 2807 break; 2808 case GL_QUADRATIC_ATTENUATION: 2809 if(params[0] < 0.0f) 2810 { 2811 return error(GL_INVALID_VALUE); 2812 } 2813 context->setLightAttenuationQuadratic(index, params[0]); 2814 break; 2815 default: 2816 return error(GL_INVALID_ENUM); 2817 } 2818 } 2819 } 2820 2821 void Lightx(GLenum light, GLenum pname, GLfixed param) 2822 { 2823 UNIMPLEMENTED(); 2824 } 2825 2826 void Lightxv(GLenum light, GLenum pname, const GLfixed *params) 2827 { 2828 UNIMPLEMENTED(); 2829 } 2830 2831 void LineWidth(GLfloat width) 2832 { 2833 TRACE("(GLfloat width = %f)", width); 2834 2835 if(width <= 0.0f) 2836 { 2837 return error(GL_INVALID_VALUE); 2838 } 2839 2840 es1::Context *context = es1::getContext(); 2841 2842 if(context) 2843 { 2844 context->setLineWidth(width); 2845 } 2846 } 2847 2848 void LineWidthx(GLfixed width) 2849 { 2850 LineWidth((float)width / 0x10000); 2851 } 2852 2853 void LoadIdentity(void) 2854 { 2855 TRACE("()"); 2856 2857 es1::Context *context = es1::getContext(); 2858 2859 if(context) 2860 { 2861 context->loadIdentity(); 2862 } 2863 } 2864 2865 void LoadMatrixf(const GLfloat *m) 2866 { 2867 TRACE("(const GLfloat *m)"); 2868 2869 es1::Context *context = es1::getContext(); 2870 2871 if(context) 2872 { 2873 context->load(m); 2874 } 2875 } 2876 2877 void LoadMatrixx(const GLfixed *m) 2878 { 2879 GLfloat matrix[16] = 2880 { 2881 (float)m[0] / 0x10000, (float)m[1] / 0x10000, (float)m[2] / 0x10000, (float)m[3] / 0x10000, 2882 (float)m[4] / 0x10000, (float)m[5] / 0x10000, (float)m[6] / 0x10000, (float)m[7] / 0x10000, 2883 (float)m[8] / 0x10000, (float)m[9] / 0x10000, (float)m[10] / 0x10000, (float)m[11] / 0x10000, 2884 (float)m[12] / 0x10000, (float)m[13] / 0x10000, (float)m[14] / 0x10000, (float)m[15] / 0x10000 2885 }; 2886 2887 LoadMatrixf(matrix); 2888 } 2889 2890 void LogicOp(GLenum opcode) 2891 { 2892 TRACE("(GLenum opcode = 0x%X)", opcode); 2893 2894 switch(opcode) 2895 { 2896 case GL_CLEAR: 2897 case GL_SET: 2898 case GL_COPY: 2899 case GL_COPY_INVERTED: 2900 case GL_NOOP: 2901 case GL_INVERT: 2902 case GL_AND: 2903 case GL_NAND: 2904 case GL_OR: 2905 case GL_NOR: 2906 case GL_XOR: 2907 case GL_EQUIV: 2908 case GL_AND_REVERSE: 2909 case GL_AND_INVERTED: 2910 case GL_OR_REVERSE: 2911 case GL_OR_INVERTED: 2912 break; 2913 default: 2914 return error(GL_INVALID_ENUM); 2915 } 2916 2917 es1::Context *context = es1::getContext(); 2918 2919 if(context) 2920 { 2921 context->setLogicalOperation(opcode); 2922 } 2923 } 2924 2925 void Materialf(GLenum face, GLenum pname, GLfloat param) 2926 { 2927 TRACE("(GLenum face = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", face, pname, param); 2928 2929 if(face != GL_FRONT_AND_BACK) 2930 { 2931 return error(GL_INVALID_ENUM); 2932 } 2933 2934 es1::Context *context = es1::getContext(); 2935 2936 if(context) 2937 { 2938 switch(pname) 2939 { 2940 case GL_SHININESS: 2941 if(param < 0.0f || param > 128.0f) 2942 { 2943 return error(GL_INVALID_VALUE); 2944 } 2945 context->setMaterialShininess(param); 2946 break; 2947 case GL_AMBIENT: 2948 case GL_DIFFUSE: 2949 case GL_AMBIENT_AND_DIFFUSE: 2950 case GL_SPECULAR: 2951 case GL_EMISSION: 2952 return error(GL_INVALID_ENUM); // Need four values, should call glMaterialfv() instead 2953 default: 2954 return error(GL_INVALID_ENUM); 2955 } 2956 } 2957 } 2958 2959 void Materialfv(GLenum face, GLenum pname, const GLfloat *params) 2960 { 2961 TRACE("(GLenum face = 0x%X, GLenum pname = 0x%X, GLfloat params)", face, pname); 2962 2963 if(face != GL_FRONT_AND_BACK) 2964 { 2965 return error(GL_INVALID_ENUM); 2966 } 2967 2968 es1::Context *context = es1::getContext(); 2969 2970 if(context) 2971 { 2972 switch(pname) 2973 { 2974 case GL_AMBIENT: 2975 context->setMaterialAmbient(params[0], params[1], params[2], params[3]); 2976 break; 2977 case GL_DIFFUSE: 2978 context->setMaterialDiffuse(params[0], params[1], params[2], params[3]); 2979 break; 2980 case GL_AMBIENT_AND_DIFFUSE: 2981 context->setMaterialAmbient(params[0], params[1], params[2], params[3]); 2982 context->setMaterialDiffuse(params[0], params[1], params[2], params[3]); 2983 break; 2984 case GL_SPECULAR: 2985 context->setMaterialSpecular(params[0], params[1], params[2], params[3]); 2986 break; 2987 case GL_EMISSION: 2988 context->setMaterialEmission(params[0], params[1], params[2], params[3]); 2989 break; 2990 case GL_SHININESS: 2991 context->setMaterialShininess(params[0]); 2992 break; 2993 default: 2994 return error(GL_INVALID_ENUM); 2995 } 2996 } 2997 } 2998 2999 void Materialx(GLenum face, GLenum pname, GLfixed param) 3000 { 3001 UNIMPLEMENTED(); 3002 } 3003 3004 void Materialxv(GLenum face, GLenum pname, const GLfixed *params) 3005 { 3006 UNIMPLEMENTED(); 3007 } 3008 3009 void MatrixMode(GLenum mode) 3010 { 3011 TRACE("(GLenum mode = 0x%X)", mode); 3012 3013 es1::Context *context = es1::getContext(); 3014 3015 if(context) 3016 { 3017 context->setMatrixMode(mode); 3018 } 3019 } 3020 3021 void MultMatrixf(const GLfloat *m) 3022 { 3023 TRACE("(const GLfloat *m)"); 3024 3025 es1::Context *context = es1::getContext(); 3026 3027 if(context) 3028 { 3029 context->multiply(m); 3030 } 3031 } 3032 3033 void MultMatrixx(const GLfixed *m) 3034 { 3035 GLfloat matrix[16] = 3036 { 3037 (float)m[0] / 0x10000, (float)m[1] / 0x10000, (float)m[2] / 0x10000, (float)m[3] / 0x10000, 3038 (float)m[4] / 0x10000, (float)m[5] / 0x10000, (float)m[6] / 0x10000, (float)m[7] / 0x10000, 3039 (float)m[8] / 0x10000, (float)m[9] / 0x10000, (float)m[10] / 0x10000, (float)m[11] / 0x10000, 3040 (float)m[12] / 0x10000, (float)m[13] / 0x10000, (float)m[14] / 0x10000, (float)m[15] / 0x10000 3041 }; 3042 3043 MultMatrixf(matrix); 3044 } 3045 3046 void MultiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q) 3047 { 3048 TRACE("(GLenum target = 0x%X, GLfloat s = %f, GLfloat t = %f, GLfloat r = %f, GLfloat q = %f)", target, s, t, r, q); 3049 3050 switch(target) 3051 { 3052 case GL_TEXTURE0: 3053 case GL_TEXTURE1: 3054 break; 3055 default: 3056 return error(GL_INVALID_ENUM); 3057 } 3058 3059 es1::Context *context = es1::getContext(); 3060 3061 if(context) 3062 { 3063 context->setVertexAttrib(sw::TexCoord0 + (target - GL_TEXTURE0), s, t, r, q); 3064 } 3065 } 3066 3067 void MultiTexCoord4x(GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q) 3068 { 3069 UNIMPLEMENTED(); 3070 } 3071 3072 void Normal3f(GLfloat nx, GLfloat ny, GLfloat nz) 3073 { 3074 TRACE("(GLfloat nx, GLfloat ny, GLfloat nz)", nx, ny, nz); 3075 3076 es1::Context *context = es1::getContext(); 3077 3078 if(context) 3079 { 3080 context->setVertexAttrib(sw::Normal, nx, ny, nz, 0); 3081 } 3082 } 3083 3084 void Normal3x(GLfixed nx, GLfixed ny, GLfixed nz) 3085 { 3086 UNIMPLEMENTED(); 3087 } 3088 3089 void NormalPointer(GLenum type, GLsizei stride, const GLvoid *pointer) 3090 { 3091 TRACE("(GLenum type = 0x%X, GLsizei stride = %d, const GLvoid *pointer = %p)", type, stride, pointer); 3092 3093 VertexAttribPointer(sw::Normal, 3, type, true, stride, pointer); 3094 } 3095 3096 void Orthof(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar) 3097 { 3098 TRACE("(GLfloat left = %f, GLfloat right = %f, GLfloat bottom = %f, GLfloat top = %f, GLfloat zNear = %f, GLfloat zFar = %f)", left, right, bottom, top, zNear, zFar); 3099 3100 if(left == right || bottom == top || zNear == zFar) 3101 { 3102 return error(GL_INVALID_VALUE); 3103 } 3104 3105 es1::Context *context = es1::getContext(); 3106 3107 if(context) 3108 { 3109 context->ortho(left, right, bottom, top, zNear, zFar); 3110 } 3111 } 3112 3113 void Orthox(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar) 3114 { 3115 Orthof((float)left / 0x10000, (float)right / 0x10000, (float)bottom / 0x10000, (float)top / 0x10000, (float)zNear / 0x10000, (float)zFar / 0x10000); 3116 } 3117 3118 void PixelStorei(GLenum pname, GLint param) 3119 { 3120 TRACE("(GLenum pname = 0x%X, GLint param = %d)", pname, param); 3121 3122 es1::Context *context = es1::getContext(); 3123 3124 if(context) 3125 { 3126 switch(pname) 3127 { 3128 case GL_UNPACK_ALIGNMENT: 3129 if(param != 1 && param != 2 && param != 4 && param != 8) 3130 { 3131 return error(GL_INVALID_VALUE); 3132 } 3133 3134 context->setUnpackAlignment(param); 3135 break; 3136 case GL_PACK_ALIGNMENT: 3137 if(param != 1 && param != 2 && param != 4 && param != 8) 3138 { 3139 return error(GL_INVALID_VALUE); 3140 } 3141 3142 context->setPackAlignment(param); 3143 break; 3144 default: 3145 return error(GL_INVALID_ENUM); 3146 } 3147 } 3148 } 3149 3150 void PointParameterf(GLenum pname, GLfloat param) 3151 { 3152 TRACE("(GLenum pname = 0x%X, GLfloat param = %f)", pname, param); 3153 3154 es1::Context *context = es1::getContext(); 3155 3156 if(context) 3157 { 3158 switch(pname) 3159 { 3160 case GL_POINT_SIZE_MIN: 3161 if(param < 0.0f) 3162 { 3163 return error(GL_INVALID_VALUE); 3164 } 3165 context->setPointSizeMin(param); 3166 break; 3167 case GL_POINT_SIZE_MAX: 3168 if(param < 0.0f) 3169 { 3170 return error(GL_INVALID_VALUE); 3171 } 3172 context->setPointSizeMax(param); 3173 break; 3174 case GL_POINT_FADE_THRESHOLD_SIZE: 3175 if(param < 0.0f) 3176 { 3177 return error(GL_INVALID_VALUE); 3178 } 3179 context->setPointFadeThresholdSize(param); 3180 break; 3181 case GL_POINT_DISTANCE_ATTENUATION: 3182 return error(GL_INVALID_ENUM); // Needs three values, should call glPointParameterfv() instead 3183 default: 3184 return error(GL_INVALID_ENUM); 3185 } 3186 } 3187 } 3188 3189 void PointParameterfv(GLenum pname, const GLfloat *params) 3190 { 3191 TRACE("(GLenum pname = 0x%X, const GLfloat *params)", pname); 3192 3193 es1::Context *context = es1::getContext(); 3194 3195 if(context) 3196 { 3197 switch(pname) 3198 { 3199 case GL_POINT_SIZE_MIN: 3200 if(params[0] < 0.0f) 3201 { 3202 return error(GL_INVALID_VALUE); 3203 } 3204 context->setPointSizeMin(params[0]); 3205 break; 3206 case GL_POINT_SIZE_MAX: 3207 if(params[0] < 0.0f) 3208 { 3209 return error(GL_INVALID_VALUE); 3210 } 3211 context->setPointSizeMax(params[0]); 3212 break; 3213 case GL_POINT_DISTANCE_ATTENUATION: 3214 context->setPointDistanceAttenuation(params[0], params[1], params[2]); 3215 break; 3216 case GL_POINT_FADE_THRESHOLD_SIZE: 3217 if(params[0] < 0.0f) 3218 { 3219 return error(GL_INVALID_VALUE); 3220 } 3221 context->setPointFadeThresholdSize(params[0]); 3222 break; 3223 default: 3224 return error(GL_INVALID_ENUM); 3225 } 3226 } 3227 } 3228 3229 void PointParameterx(GLenum pname, GLfixed param) 3230 { 3231 TRACE("(GLenum pname = 0x%X, GLfixed param = %d)", pname, param); 3232 3233 es1::Context *context = es1::getContext(); 3234 3235 if(context) 3236 { 3237 switch(pname) 3238 { 3239 case GL_POINT_SIZE_MIN: 3240 if(param < 0) 3241 { 3242 return error(GL_INVALID_VALUE); 3243 } 3244 context->setPointSizeMin((float)param / 0x10000); 3245 break; 3246 case GL_POINT_SIZE_MAX: 3247 if(param < 0) 3248 { 3249 return error(GL_INVALID_VALUE); 3250 } 3251 context->setPointSizeMax((float)param / 0x10000); 3252 break; 3253 case GL_POINT_FADE_THRESHOLD_SIZE: 3254 if(param < 0) 3255 { 3256 return error(GL_INVALID_VALUE); 3257 } 3258 context->setPointFadeThresholdSize((float)param / 0x10000); 3259 break; 3260 case GL_POINT_DISTANCE_ATTENUATION: 3261 return error(GL_INVALID_ENUM); // Needs three parameters, should call glPointParameterxv() instead 3262 default: 3263 return error(GL_INVALID_ENUM); 3264 } 3265 } 3266 } 3267 3268 void PointParameterxv(GLenum pname, const GLfixed *params) 3269 { 3270 TRACE("(GLenum pname = 0x%X, const GLfixed *params)", pname); 3271 3272 es1::Context *context = es1::getContext(); 3273 3274 if(context) 3275 { 3276 switch(pname) 3277 { 3278 case GL_POINT_SIZE_MIN: 3279 if(params[0] < 0) 3280 { 3281 return error(GL_INVALID_VALUE); 3282 } 3283 context->setPointSizeMin((float)params[0] / 0x10000); 3284 break; 3285 case GL_POINT_SIZE_MAX: 3286 if(params[0] < 0) 3287 { 3288 return error(GL_INVALID_VALUE); 3289 } 3290 context->setPointSizeMax((float)params[0] / 0x10000); 3291 break; 3292 case GL_POINT_DISTANCE_ATTENUATION: 3293 context->setPointDistanceAttenuation((float)params[0] / 0x10000, (float)params[1] / 0x10000, (float)params[2] / 0x10000); 3294 break; 3295 case GL_POINT_FADE_THRESHOLD_SIZE: 3296 if(params[0] < 0) 3297 { 3298 return error(GL_INVALID_VALUE); 3299 } 3300 context->setPointFadeThresholdSize((float)params[0] / 0x10000); 3301 break; 3302 default: 3303 return error(GL_INVALID_ENUM); 3304 } 3305 } 3306 } 3307 3308 void PointSize(GLfloat size) 3309 { 3310 TRACE("(GLfloat size = %f)", size); 3311 3312 if(size <= 0) 3313 { 3314 return error(GL_INVALID_VALUE); 3315 } 3316 3317 es1::Context *context = es1::getContext(); 3318 3319 if(context) 3320 { 3321 context->setVertexAttrib(sw::PointSize, size, size, size, size); 3322 } 3323 } 3324 3325 void PointSizePointerOES(GLenum type, GLsizei stride, const GLvoid *pointer) 3326 { 3327 TRACE("(GLenum type = 0x%X, GLsizei stride = %d, const GLvoid *pointer = %p)", type, stride, pointer); 3328 3329 switch(type) 3330 { 3331 case GL_FIXED: 3332 case GL_FLOAT: 3333 break; 3334 default: 3335 return error(GL_INVALID_ENUM); 3336 } 3337 3338 VertexAttribPointer(sw::PointSize, 1, type, true, stride, pointer); 3339 } 3340 3341 void PointSizex(GLfixed size) 3342 { 3343 PointSize((float)size / 0x10000); 3344 } 3345 3346 void PolygonOffset(GLfloat factor, GLfloat units) 3347 { 3348 TRACE("(GLfloat factor = %f, GLfloat units = %f)", factor, units); 3349 3350 es1::Context *context = es1::getContext(); 3351 3352 if(context) 3353 { 3354 context->setPolygonOffsetParams(factor, units); 3355 } 3356 } 3357 3358 void PolygonOffsetx(GLfixed factor, GLfixed units) 3359 { 3360 PolygonOffset((float)factor / 0x10000, (float)units / 0x10000); 3361 } 3362 3363 void PopMatrix(void) 3364 { 3365 TRACE("()"); 3366 3367 es1::Context *context = es1::getContext(); 3368 3369 if(context) 3370 { 3371 context->popMatrix(); 3372 } 3373 } 3374 3375 void PushMatrix(void) 3376 { 3377 TRACE("()"); 3378 3379 es1::Context *context = es1::getContext(); 3380 3381 if(context) 3382 { 3383 context->pushMatrix(); 3384 } 3385 } 3386 3387 void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels) 3388 { 3389 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, " 3390 "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = %p)", 3391 x, y, width, height, format, type, pixels); 3392 3393 if(width < 0 || height < 0) 3394 { 3395 return error(GL_INVALID_VALUE); 3396 } 3397 3398 es1::Context *context = es1::getContext(); 3399 3400 if(context) 3401 { 3402 context->readPixels(x, y, width, height, format, type, nullptr, pixels); 3403 } 3404 } 3405 3406 void RenderbufferStorageOES(GLenum target, GLenum internalformat, GLsizei width, GLsizei height) 3407 { 3408 TRACE("(GLenum target = 0x%X, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)", 3409 target, internalformat, width, height); 3410 3411 switch(target) 3412 { 3413 case GL_RENDERBUFFER_OES: 3414 break; 3415 default: 3416 return error(GL_INVALID_ENUM); 3417 } 3418 3419 if(!es1::IsColorRenderable(internalformat) && !es1::IsDepthRenderable(internalformat) && !es1::IsStencilRenderable(internalformat)) 3420 { 3421 return error(GL_INVALID_ENUM); 3422 } 3423 3424 if(width < 0 || height < 0) 3425 { 3426 return error(GL_INVALID_VALUE); 3427 } 3428 3429 es1::Context *context = es1::getContext(); 3430 3431 if(context) 3432 { 3433 if(width > es1::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE || 3434 height > es1::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE) 3435 { 3436 return error(GL_INVALID_VALUE); 3437 } 3438 3439 GLuint handle = context->getRenderbufferName(); 3440 if(handle == 0) 3441 { 3442 return error(GL_INVALID_OPERATION); 3443 } 3444 3445 switch(internalformat) 3446 { 3447 case GL_DEPTH_COMPONENT16_OES: 3448 context->setRenderbufferStorage(new es1::Depthbuffer(width, height, 0)); 3449 break; 3450 case GL_RGBA4_OES: 3451 case GL_RGB5_A1_OES: 3452 case GL_RGB565_OES: 3453 case GL_RGB8_OES: 3454 case GL_RGBA8_OES: 3455 context->setRenderbufferStorage(new es1::Colorbuffer(width, height, internalformat, 0)); 3456 break; 3457 case GL_STENCIL_INDEX8_OES: 3458 context->setRenderbufferStorage(new es1::Stencilbuffer(width, height, 0)); 3459 break; 3460 case GL_DEPTH24_STENCIL8_OES: 3461 context->setRenderbufferStorage(new es1::DepthStencilbuffer(width, height, 0)); 3462 break; 3463 default: 3464 return error(GL_INVALID_ENUM); 3465 } 3466 } 3467 } 3468 3469 void Rotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) 3470 { 3471 TRACE("(GLfloat angle = %f, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", angle, x, y, z); 3472 3473 es1::Context *context = es1::getContext(); 3474 3475 if(context) 3476 { 3477 context->rotate(angle, x, y, z); 3478 } 3479 } 3480 3481 void Rotatex(GLfixed angle, GLfixed x, GLfixed y, GLfixed z) 3482 { 3483 Rotatef((float)angle / 0x10000, (float)x / 0x10000, (float)y / 0x10000, (float)z / 0x10000); 3484 } 3485 3486 void SampleCoverage(GLclampf value, GLboolean invert) 3487 { 3488 TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert); 3489 3490 es1::Context* context = es1::getContext(); 3491 3492 if(context) 3493 { 3494 context->setSampleCoverageParams(es1::clamp01(value), invert == GL_TRUE); 3495 } 3496 } 3497 3498 void SampleCoveragex(GLclampx value, GLboolean invert) 3499 { 3500 SampleCoverage((float)value / 0x10000, invert); 3501 } 3502 3503 void Scalef(GLfloat x, GLfloat y, GLfloat z) 3504 { 3505 TRACE("(GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", x, y, z); 3506 3507 es1::Context *context = es1::getContext(); 3508 3509 if(context) 3510 { 3511 context->scale(x, y, z); 3512 } 3513 } 3514 3515 void Scalex(GLfixed x, GLfixed y, GLfixed z) 3516 { 3517 Scalef((float)x / 0x10000, (float)y / 0x10000, (float)z / 0x10000); 3518 } 3519 3520 void Scissor(GLint x, GLint y, GLsizei width, GLsizei height) 3521 { 3522 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height); 3523 3524 if(width < 0 || height < 0) 3525 { 3526 return error(GL_INVALID_VALUE); 3527 } 3528 3529 es1::Context* context = es1::getContext(); 3530 3531 if(context) 3532 { 3533 context->setScissorParams(x, y, width, height); 3534 } 3535 } 3536 3537 void ShadeModel(GLenum mode) 3538 { 3539 switch(mode) 3540 { 3541 case GL_FLAT: 3542 case GL_SMOOTH: 3543 break; 3544 default: 3545 return error(GL_INVALID_ENUM); 3546 } 3547 3548 es1::Context *context = es1::getContext(); 3549 3550 if(context) 3551 { 3552 context->setShadeModel(mode); 3553 } 3554 } 3555 3556 void StencilFunc(GLenum func, GLint ref, GLuint mask) 3557 { 3558 TRACE("(GLenum func = 0x%X, GLint ref = %d, GLuint mask = %d)", func, ref, mask); 3559 3560 switch(func) 3561 { 3562 case GL_NEVER: 3563 case GL_ALWAYS: 3564 case GL_LESS: 3565 case GL_LEQUAL: 3566 case GL_EQUAL: 3567 case GL_GEQUAL: 3568 case GL_GREATER: 3569 case GL_NOTEQUAL: 3570 break; 3571 default: 3572 return error(GL_INVALID_ENUM); 3573 } 3574 3575 es1::Context *context = es1::getContext(); 3576 3577 if(context) 3578 { 3579 context->setStencilParams(func, ref, mask); 3580 } 3581 } 3582 3583 void StencilMask(GLuint mask) 3584 { 3585 TRACE("(GLuint mask = %d)", mask); 3586 3587 es1::Context *context = es1::getContext(); 3588 3589 if(context) 3590 { 3591 context->setStencilWritemask(mask); 3592 } 3593 } 3594 3595 void StencilOp(GLenum fail, GLenum zfail, GLenum zpass) 3596 { 3597 TRACE("(GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)", fail, zfail, zpass); 3598 3599 switch(fail) 3600 { 3601 case GL_ZERO: 3602 case GL_KEEP: 3603 case GL_REPLACE: 3604 case GL_INCR: 3605 case GL_DECR: 3606 case GL_INVERT: 3607 case GL_INCR_WRAP_OES: 3608 case GL_DECR_WRAP_OES: 3609 break; 3610 default: 3611 return error(GL_INVALID_ENUM); 3612 } 3613 3614 switch(zfail) 3615 { 3616 case GL_ZERO: 3617 case GL_KEEP: 3618 case GL_REPLACE: 3619 case GL_INCR: 3620 case GL_DECR: 3621 case GL_INVERT: 3622 case GL_INCR_WRAP_OES: 3623 case GL_DECR_WRAP_OES: 3624 break; 3625 default: 3626 return error(GL_INVALID_ENUM); 3627 } 3628 3629 switch(zpass) 3630 { 3631 case GL_ZERO: 3632 case GL_KEEP: 3633 case GL_REPLACE: 3634 case GL_INCR: 3635 case GL_DECR: 3636 case GL_INVERT: 3637 case GL_INCR_WRAP_OES: 3638 case GL_DECR_WRAP_OES: 3639 break; 3640 default: 3641 return error(GL_INVALID_ENUM); 3642 } 3643 3644 es1::Context *context = es1::getContext(); 3645 3646 if(context) 3647 { 3648 context->setStencilOperations(fail, zfail, zpass); 3649 } 3650 } 3651 3652 void TexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) 3653 { 3654 TRACE("(GLint size = %d, GLenum type = 0x%X, GLsizei stride = %d, const GLvoid *pointer = %p)", size, type, stride, pointer); 3655 3656 if(size < 2 || size > 4) 3657 { 3658 return error(GL_INVALID_VALUE); 3659 } 3660 3661 es1::Context *context = es1::getContext(); 3662 3663 if(context) 3664 { 3665 GLenum texture = context->getClientActiveTexture(); 3666 VertexAttribPointer(sw::TexCoord0 + (texture - GL_TEXTURE0), size, type, false, stride, pointer); 3667 } 3668 } 3669 3670 void TexEnvi(GLenum target, GLenum pname, GLint param); 3671 3672 void TexEnvf(GLenum target, GLenum pname, GLfloat param) 3673 { 3674 TexEnvi(target, pname, (GLint)param); 3675 } 3676 3677 void TexEnvfv(GLenum target, GLenum pname, const GLfloat *params) 3678 { 3679 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, const GLfloat *params)", target, pname); 3680 3681 es1::Context *context = es1::getContext(); 3682 3683 if(context) 3684 { 3685 GLint iParam = (GLint)roundf(params[0]); 3686 3687 switch(target) 3688 { 3689 case GL_POINT_SPRITE_OES: 3690 UNIMPLEMENTED(); 3691 break; 3692 case GL_TEXTURE_ENV: 3693 switch(pname) 3694 { 3695 case GL_TEXTURE_ENV_MODE: 3696 switch(iParam) 3697 { 3698 case GL_REPLACE: 3699 case GL_MODULATE: 3700 case GL_DECAL: 3701 case GL_BLEND: 3702 case GL_ADD: 3703 case GL_COMBINE: 3704 break; 3705 default: 3706 error(GL_INVALID_ENUM); 3707 } 3708 3709 context->setTextureEnvMode(iParam); 3710 break; 3711 case GL_TEXTURE_ENV_COLOR: 3712 context->setTextureEnvColor(clamp01(params[0]), clamp01(params[1]), clamp01(params[2]), clamp01(params[3])); 3713 break; 3714 case GL_COMBINE_RGB: 3715 switch(iParam) 3716 { 3717 case GL_REPLACE: 3718 case GL_MODULATE: 3719 case GL_ADD: 3720 case GL_ADD_SIGNED: 3721 case GL_INTERPOLATE: 3722 case GL_SUBTRACT: 3723 case GL_DOT3_RGB: 3724 case GL_DOT3_RGBA: 3725 break; 3726 default: 3727 error(GL_INVALID_ENUM); 3728 } 3729 3730 context->setCombineRGB(iParam); 3731 break; 3732 case GL_COMBINE_ALPHA: 3733 switch(iParam) 3734 { 3735 case GL_REPLACE: 3736 case GL_MODULATE: 3737 case GL_ADD: 3738 case GL_ADD_SIGNED: 3739 case GL_INTERPOLATE: 3740 case GL_SUBTRACT: 3741 break; 3742 default: 3743 error(GL_INVALID_ENUM); 3744 } 3745 3746 context->setCombineAlpha(iParam); 3747 break; 3748 case GL_RGB_SCALE: 3749 if(iParam != 1 && iParam != 2 && iParam != 4) 3750 { 3751 return error(GL_INVALID_VALUE); 3752 } 3753 if(iParam != 1) UNIMPLEMENTED(); 3754 break; 3755 case GL_ALPHA_SCALE: 3756 if(iParam != 1 && iParam != 2 && iParam != 4) 3757 { 3758 return error(GL_INVALID_VALUE); 3759 } 3760 if(iParam != 1) UNIMPLEMENTED(); 3761 break; 3762 case GL_OPERAND0_RGB: 3763 switch(iParam) 3764 { 3765 case GL_SRC_COLOR: 3766 case GL_ONE_MINUS_SRC_COLOR: 3767 case GL_SRC_ALPHA: 3768 case GL_ONE_MINUS_SRC_ALPHA: 3769 break; 3770 default: 3771 error(GL_INVALID_ENUM); 3772 } 3773 3774 context->setOperand0RGB(iParam); 3775 break; 3776 case GL_OPERAND1_RGB: 3777 switch(iParam) 3778 { 3779 case GL_SRC_COLOR: 3780 case GL_ONE_MINUS_SRC_COLOR: 3781 case GL_SRC_ALPHA: 3782 case GL_ONE_MINUS_SRC_ALPHA: 3783 break; 3784 default: 3785 error(GL_INVALID_ENUM); 3786 } 3787 3788 context->setOperand1RGB(iParam); 3789 break; 3790 case GL_OPERAND2_RGB: 3791 switch(iParam) 3792 { 3793 case GL_SRC_COLOR: 3794 case GL_ONE_MINUS_SRC_COLOR: 3795 case GL_SRC_ALPHA: 3796 case GL_ONE_MINUS_SRC_ALPHA: 3797 break; 3798 default: 3799 error(GL_INVALID_ENUM); 3800 } 3801 3802 context->setOperand2RGB(iParam); 3803 break; 3804 case GL_OPERAND0_ALPHA: 3805 switch(iParam) 3806 { 3807 case GL_SRC_ALPHA: 3808 case GL_ONE_MINUS_SRC_ALPHA: 3809 break; 3810 default: 3811 error(GL_INVALID_ENUM); 3812 } 3813 3814 context->setOperand0Alpha(iParam); 3815 break; 3816 case GL_OPERAND1_ALPHA: 3817 switch(iParam) 3818 { 3819 case GL_SRC_ALPHA: 3820 case GL_ONE_MINUS_SRC_ALPHA: 3821 break; 3822 default: 3823 error(GL_INVALID_ENUM); 3824 } 3825 3826 context->setOperand1Alpha(iParam); 3827 break; 3828 case GL_OPERAND2_ALPHA: 3829 switch(iParam) 3830 { 3831 case GL_SRC_ALPHA: 3832 case GL_ONE_MINUS_SRC_ALPHA: 3833 break; 3834 default: 3835 error(GL_INVALID_ENUM); 3836 } 3837 3838 context->setOperand2Alpha(iParam); 3839 break; 3840 case GL_SRC0_RGB: 3841 switch(iParam) 3842 { 3843 case GL_TEXTURE: 3844 case GL_CONSTANT: 3845 case GL_PRIMARY_COLOR: 3846 case GL_PREVIOUS: 3847 break; 3848 default: 3849 error(GL_INVALID_ENUM); 3850 } 3851 3852 context->setSrc0RGB(iParam); 3853 break; 3854 case GL_SRC1_RGB: 3855 switch(iParam) 3856 { 3857 case GL_TEXTURE: 3858 case GL_CONSTANT: 3859 case GL_PRIMARY_COLOR: 3860 case GL_PREVIOUS: 3861 break; 3862 default: 3863 error(GL_INVALID_ENUM); 3864 } 3865 3866 context->setSrc1RGB(iParam); 3867 break; 3868 case GL_SRC2_RGB: 3869 switch(iParam) 3870 { 3871 case GL_TEXTURE: 3872 case GL_CONSTANT: 3873 case GL_PRIMARY_COLOR: 3874 case GL_PREVIOUS: 3875 break; 3876 default: 3877 error(GL_INVALID_ENUM); 3878 } 3879 3880 context->setSrc2RGB(iParam); 3881 break; 3882 case GL_SRC0_ALPHA: 3883 switch(iParam) 3884 { 3885 case GL_TEXTURE: 3886 case GL_CONSTANT: 3887 case GL_PRIMARY_COLOR: 3888 case GL_PREVIOUS: 3889 break; 3890 default: 3891 error(GL_INVALID_ENUM); 3892 } 3893 3894 context->setSrc0Alpha(iParam); 3895 break; 3896 case GL_SRC1_ALPHA: 3897 switch(iParam) 3898 { 3899 case GL_TEXTURE: 3900 case GL_CONSTANT: 3901 case GL_PRIMARY_COLOR: 3902 case GL_PREVIOUS: 3903 break; 3904 default: 3905 error(GL_INVALID_ENUM); 3906 } 3907 3908 context->setSrc1Alpha(iParam); 3909 break; 3910 case GL_SRC2_ALPHA: 3911 switch(iParam) 3912 { 3913 case GL_TEXTURE: 3914 case GL_CONSTANT: 3915 case GL_PRIMARY_COLOR: 3916 case GL_PREVIOUS: 3917 break; 3918 default: 3919 error(GL_INVALID_ENUM); 3920 } 3921 3922 context->setSrc2Alpha(iParam); 3923 break; 3924 default: 3925 return error(GL_INVALID_ENUM); 3926 } 3927 break; 3928 default: 3929 return error(GL_INVALID_ENUM); 3930 } 3931 } 3932 } 3933 3934 void TexEnvi(GLenum target, GLenum pname, GLint param) 3935 { 3936 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param); 3937 3938 es1::Context *context = es1::getContext(); 3939 3940 if(context) 3941 { 3942 switch(target) 3943 { 3944 case GL_POINT_SPRITE_OES: 3945 UNIMPLEMENTED(); 3946 break; 3947 case GL_TEXTURE_ENV: 3948 switch(pname) 3949 { 3950 case GL_TEXTURE_ENV_MODE: 3951 switch((GLenum)param) 3952 { 3953 case GL_REPLACE: 3954 case GL_MODULATE: 3955 case GL_DECAL: 3956 case GL_BLEND: 3957 case GL_ADD: 3958 case GL_COMBINE: 3959 break; 3960 default: 3961 error(GL_INVALID_ENUM); 3962 } 3963 3964 context->setTextureEnvMode((GLenum)param); 3965 break; 3966 case GL_TEXTURE_ENV_COLOR: 3967 return error(GL_INVALID_ENUM); // Needs four values, should call glTexEnviv() instead 3968 break; 3969 case GL_COMBINE_RGB: 3970 switch((GLenum)param) 3971 { 3972 case GL_REPLACE: 3973 case GL_MODULATE: 3974 case GL_ADD: 3975 case GL_ADD_SIGNED: 3976 case GL_INTERPOLATE: 3977 case GL_SUBTRACT: 3978 case GL_DOT3_RGB: 3979 case GL_DOT3_RGBA: 3980 break; 3981 default: 3982 error(GL_INVALID_ENUM); 3983 } 3984 3985 context->setCombineRGB((GLenum)param); 3986 break; 3987 case GL_COMBINE_ALPHA: 3988 switch((GLenum)param) 3989 { 3990 case GL_REPLACE: 3991 case GL_MODULATE: 3992 case GL_ADD: 3993 case GL_ADD_SIGNED: 3994 case GL_INTERPOLATE: 3995 case GL_SUBTRACT: 3996 break; 3997 default: 3998 error(GL_INVALID_ENUM); 3999 } 4000 4001 context->setCombineAlpha((GLenum)param); 4002 break; 4003 case GL_RGB_SCALE: 4004 if(param != 1 && param != 2 && param != 4) 4005 { 4006 return error(GL_INVALID_VALUE); 4007 } 4008 if(param != 1) UNIMPLEMENTED(); 4009 break; 4010 case GL_ALPHA_SCALE: 4011 if(param != 1 && param != 2 && param != 4) 4012 { 4013 return error(GL_INVALID_VALUE); 4014 } 4015 if(param != 1) UNIMPLEMENTED(); 4016 break; 4017 case GL_OPERAND0_RGB: 4018 switch((GLenum)param) 4019 { 4020 case GL_SRC_COLOR: 4021 case GL_ONE_MINUS_SRC_COLOR: 4022 case GL_SRC_ALPHA: 4023 case GL_ONE_MINUS_SRC_ALPHA: 4024 break; 4025 default: 4026 error(GL_INVALID_ENUM); 4027 } 4028 4029 context->setOperand0RGB((GLenum)param); 4030 break; 4031 case GL_OPERAND1_RGB: 4032 switch((GLenum)param) 4033 { 4034 case GL_SRC_COLOR: 4035 case GL_ONE_MINUS_SRC_COLOR: 4036 case GL_SRC_ALPHA: 4037 case GL_ONE_MINUS_SRC_ALPHA: 4038 break; 4039 default: 4040 error(GL_INVALID_ENUM); 4041 } 4042 4043 context->setOperand1RGB((GLenum)param); 4044 break; 4045 case GL_OPERAND2_RGB: 4046 switch((GLenum)param) 4047 { 4048 case GL_SRC_COLOR: 4049 case GL_ONE_MINUS_SRC_COLOR: 4050 case GL_SRC_ALPHA: 4051 case GL_ONE_MINUS_SRC_ALPHA: 4052 break; 4053 default: 4054 error(GL_INVALID_ENUM); 4055 } 4056 4057 context->setOperand2RGB((GLenum)param); 4058 break; 4059 case GL_OPERAND0_ALPHA: 4060 switch((GLenum)param) 4061 { 4062 case GL_SRC_ALPHA: 4063 case GL_ONE_MINUS_SRC_ALPHA: 4064 break; 4065 default: 4066 error(GL_INVALID_ENUM); 4067 } 4068 4069 context->setOperand0Alpha((GLenum)param); 4070 break; 4071 case GL_OPERAND1_ALPHA: 4072 switch((GLenum)param) 4073 { 4074 case GL_SRC_ALPHA: 4075 case GL_ONE_MINUS_SRC_ALPHA: 4076 break; 4077 default: 4078 error(GL_INVALID_ENUM); 4079 } 4080 4081 context->setOperand1Alpha((GLenum)param); 4082 break; 4083 case GL_OPERAND2_ALPHA: 4084 switch((GLenum)param) 4085 { 4086 case GL_SRC_ALPHA: 4087 case GL_ONE_MINUS_SRC_ALPHA: 4088 break; 4089 default: 4090 error(GL_INVALID_ENUM); 4091 } 4092 4093 context->setOperand2Alpha((GLenum)param); 4094 break; 4095 case GL_SRC0_RGB: 4096 switch((GLenum)param) 4097 { 4098 case GL_TEXTURE: 4099 case GL_CONSTANT: 4100 case GL_PRIMARY_COLOR: 4101 case GL_PREVIOUS: 4102 break; 4103 default: 4104 error(GL_INVALID_ENUM); 4105 } 4106 4107 context->setSrc0RGB((GLenum)param); 4108 break; 4109 case GL_SRC1_RGB: 4110 switch((GLenum)param) 4111 { 4112 case GL_TEXTURE: 4113 case GL_CONSTANT: 4114 case GL_PRIMARY_COLOR: 4115 case GL_PREVIOUS: 4116 break; 4117 default: 4118 error(GL_INVALID_ENUM); 4119 } 4120 4121 context->setSrc1RGB((GLenum)param); 4122 break; 4123 case GL_SRC2_RGB: 4124 switch((GLenum)param) 4125 { 4126 case GL_TEXTURE: 4127 case GL_CONSTANT: 4128 case GL_PRIMARY_COLOR: 4129 case GL_PREVIOUS: 4130 break; 4131 default: 4132 error(GL_INVALID_ENUM); 4133 } 4134 4135 context->setSrc2RGB((GLenum)param); 4136 break; 4137 case GL_SRC0_ALPHA: 4138 switch((GLenum)param) 4139 { 4140 case GL_TEXTURE: 4141 case GL_CONSTANT: 4142 case GL_PRIMARY_COLOR: 4143 case GL_PREVIOUS: 4144 break; 4145 default: 4146 error(GL_INVALID_ENUM); 4147 } 4148 4149 context->setSrc0Alpha((GLenum)param); 4150 break; 4151 case GL_SRC1_ALPHA: 4152 switch((GLenum)param) 4153 { 4154 case GL_TEXTURE: 4155 case GL_CONSTANT: 4156 case GL_PRIMARY_COLOR: 4157 case GL_PREVIOUS: 4158 break; 4159 default: 4160 error(GL_INVALID_ENUM); 4161 } 4162 4163 context->setSrc1Alpha((GLenum)param); 4164 break; 4165 case GL_SRC2_ALPHA: 4166 switch((GLenum)param) 4167 { 4168 case GL_TEXTURE: 4169 case GL_CONSTANT: 4170 case GL_PRIMARY_COLOR: 4171 case GL_PREVIOUS: 4172 break; 4173 default: 4174 error(GL_INVALID_ENUM); 4175 } 4176 4177 context->setSrc2Alpha((GLenum)param); 4178 break; 4179 default: 4180 return error(GL_INVALID_ENUM); 4181 } 4182 break; 4183 default: 4184 return error(GL_INVALID_ENUM); 4185 } 4186 } 4187 } 4188 4189 void TexEnvx(GLenum target, GLenum pname, GLfixed param) 4190 { 4191 TexEnvi(target, pname, (GLint)param); 4192 } 4193 4194 void TexEnviv(GLenum target, GLenum pname, const GLint *params) 4195 { 4196 UNIMPLEMENTED(); 4197 } 4198 4199 void TexEnvxv(GLenum target, GLenum pname, const GLfixed *params) 4200 { 4201 UNIMPLEMENTED(); 4202 } 4203 4204 void TexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, 4205 GLint border, GLenum format, GLenum type, const GLvoid* pixels) 4206 { 4207 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, GLsizei height = %d, " 4208 "GLint border = %d, GLenum format = 0x%X, GLenum type = 0x%X, const GLvoid* pixels = %p)", 4209 target, level, internalformat, width, height, border, format, type, pixels); 4210 4211 if(!validImageSize(level, width, height)) 4212 { 4213 return error(GL_INVALID_VALUE); 4214 } 4215 4216 if(internalformat != (GLint)format) 4217 { 4218 return error(GL_INVALID_OPERATION); 4219 } 4220 4221 switch(format) 4222 { 4223 case GL_ALPHA: 4224 case GL_LUMINANCE: 4225 case GL_LUMINANCE_ALPHA: 4226 switch(type) 4227 { 4228 case GL_UNSIGNED_BYTE: 4229 case GL_FLOAT: 4230 break; 4231 default: 4232 return error(GL_INVALID_ENUM); 4233 } 4234 break; 4235 case GL_RGB: 4236 switch(type) 4237 { 4238 case GL_UNSIGNED_BYTE: 4239 case GL_UNSIGNED_SHORT_5_6_5: 4240 case GL_FLOAT: 4241 break; 4242 default: 4243 return error(GL_INVALID_ENUM); 4244 } 4245 break; 4246 case GL_RGBA: 4247 switch(type) 4248 { 4249 case GL_UNSIGNED_BYTE: 4250 case GL_UNSIGNED_SHORT_4_4_4_4: 4251 case GL_UNSIGNED_SHORT_5_5_5_1: 4252 case GL_FLOAT: 4253 break; 4254 default: 4255 return error(GL_INVALID_ENUM); 4256 } 4257 break; 4258 case GL_BGRA_EXT: 4259 switch(type) 4260 { 4261 case GL_UNSIGNED_BYTE: 4262 break; 4263 default: 4264 return error(GL_INVALID_ENUM); 4265 } 4266 break; 4267 case GL_ETC1_RGB8_OES: 4268 return error(GL_INVALID_OPERATION); 4269 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: 4270 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: 4271 if(S3TC_SUPPORT) 4272 { 4273 return error(GL_INVALID_OPERATION); 4274 } 4275 else 4276 { 4277 return error(GL_INVALID_ENUM); 4278 } 4279 case GL_DEPTH_STENCIL_OES: 4280 switch(type) 4281 { 4282 case GL_UNSIGNED_INT_24_8_OES: 4283 break; 4284 default: 4285 return error(GL_INVALID_ENUM); 4286 } 4287 break; 4288 default: 4289 return error(GL_INVALID_VALUE); 4290 } 4291 4292 if(border != 0) 4293 { 4294 return error(GL_INVALID_VALUE); 4295 } 4296 4297 es1::Context *context = es1::getContext(); 4298 4299 if(context) 4300 { 4301 switch(target) 4302 { 4303 case GL_TEXTURE_2D: 4304 if(width > (es1::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) || 4305 height > (es1::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level)) 4306 { 4307 return error(GL_INVALID_VALUE); 4308 } 4309 break; 4310 default: 4311 return error(GL_INVALID_ENUM); 4312 } 4313 4314 if(target == GL_TEXTURE_2D) 4315 { 4316 es1::Texture2D *texture = context->getTexture2D(); 4317 4318 if(!texture) 4319 { 4320 return error(GL_INVALID_OPERATION); 4321 } 4322 4323 texture->setImage(level, width, height, format, type, context->getUnpackAlignment(), pixels); 4324 } 4325 else UNREACHABLE(target); 4326 } 4327 } 4328 4329 void TexParameterf(GLenum target, GLenum pname, GLfloat param) 4330 { 4331 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", target, pname, param); 4332 4333 es1::Context *context = es1::getContext(); 4334 4335 if(context) 4336 { 4337 es1::Texture *texture; 4338 4339 switch(target) 4340 { 4341 case GL_TEXTURE_2D: 4342 texture = context->getTexture2D(); 4343 break; 4344 case GL_TEXTURE_EXTERNAL_OES: 4345 texture = context->getTextureExternal(); 4346 break; 4347 default: 4348 return error(GL_INVALID_ENUM); 4349 } 4350 4351 switch(pname) 4352 { 4353 case GL_TEXTURE_WRAP_S: 4354 if(!texture->setWrapS((GLenum)param)) 4355 { 4356 return error(GL_INVALID_ENUM); 4357 } 4358 break; 4359 case GL_TEXTURE_WRAP_T: 4360 if(!texture->setWrapT((GLenum)param)) 4361 { 4362 return error(GL_INVALID_ENUM); 4363 } 4364 break; 4365 case GL_TEXTURE_MIN_FILTER: 4366 if(!texture->setMinFilter((GLenum)param)) 4367 { 4368 return error(GL_INVALID_ENUM); 4369 } 4370 break; 4371 case GL_TEXTURE_MAG_FILTER: 4372 if(!texture->setMagFilter((GLenum)param)) 4373 { 4374 return error(GL_INVALID_ENUM); 4375 } 4376 break; 4377 case GL_TEXTURE_MAX_ANISOTROPY_EXT: 4378 if(!texture->setMaxAnisotropy(param)) 4379 { 4380 return error(GL_INVALID_VALUE); 4381 } 4382 break; 4383 case GL_GENERATE_MIPMAP: 4384 texture->setGenerateMipmap((GLboolean)param); 4385 break; 4386 case GL_TEXTURE_CROP_RECT_OES: 4387 return error(GL_INVALID_ENUM); // Needs four values, should call glTexParameterfv() instead 4388 default: 4389 return error(GL_INVALID_ENUM); 4390 } 4391 } 4392 } 4393 4394 void TexParameterfv(GLenum target, GLenum pname, const GLfloat* params) 4395 { 4396 TexParameterf(target, pname, *params); 4397 } 4398 4399 void TexParameteri(GLenum target, GLenum pname, GLint param) 4400 { 4401 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param); 4402 4403 es1::Context *context = es1::getContext(); 4404 4405 if(context) 4406 { 4407 es1::Texture *texture; 4408 4409 switch(target) 4410 { 4411 case GL_TEXTURE_2D: 4412 texture = context->getTexture2D(); 4413 break; 4414 case GL_TEXTURE_EXTERNAL_OES: 4415 texture = context->getTextureExternal(); 4416 break; 4417 default: 4418 return error(GL_INVALID_ENUM); 4419 } 4420 4421 switch(pname) 4422 { 4423 case GL_TEXTURE_WRAP_S: 4424 if(!texture->setWrapS((GLenum)param)) 4425 { 4426 return error(GL_INVALID_ENUM); 4427 } 4428 break; 4429 case GL_TEXTURE_WRAP_T: 4430 if(!texture->setWrapT((GLenum)param)) 4431 { 4432 return error(GL_INVALID_ENUM); 4433 } 4434 break; 4435 case GL_TEXTURE_MIN_FILTER: 4436 if(!texture->setMinFilter((GLenum)param)) 4437 { 4438 return error(GL_INVALID_ENUM); 4439 } 4440 break; 4441 case GL_TEXTURE_MAG_FILTER: 4442 if(!texture->setMagFilter((GLenum)param)) 4443 { 4444 return error(GL_INVALID_ENUM); 4445 } 4446 break; 4447 case GL_TEXTURE_MAX_ANISOTROPY_EXT: 4448 if(!texture->setMaxAnisotropy((GLfloat)param)) 4449 { 4450 return error(GL_INVALID_VALUE); 4451 } 4452 break; 4453 case GL_GENERATE_MIPMAP: 4454 texture->setGenerateMipmap((GLboolean)param); 4455 break; 4456 case GL_TEXTURE_CROP_RECT_OES: 4457 return error(GL_INVALID_ENUM); // Needs four values, should call glTexParameteriv() instead 4458 default: 4459 return error(GL_INVALID_ENUM); 4460 } 4461 } 4462 } 4463 4464 void TexParameteriv(GLenum target, GLenum pname, const GLint* params) 4465 { 4466 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %p)", target, pname, params); 4467 4468 switch(pname) 4469 { 4470 case GL_TEXTURE_CROP_RECT_OES: 4471 break; 4472 default: 4473 return TexParameteri(target, pname, params[0]); 4474 } 4475 4476 es1::Context *context = es1::getContext(); 4477 4478 if(context) 4479 { 4480 es1::Texture *texture; 4481 4482 switch(target) 4483 { 4484 case GL_TEXTURE_2D: 4485 texture = context->getTexture2D(); 4486 break; 4487 default: 4488 return error(GL_INVALID_ENUM); 4489 } 4490 4491 switch(pname) 4492 { 4493 case GL_TEXTURE_CROP_RECT_OES: 4494 texture->setCropRect(params[0], params[1], params[2], params[3]); 4495 break; 4496 default: 4497 return error(GL_INVALID_ENUM); 4498 } 4499 } 4500 } 4501 4502 void TexParameterx(GLenum target, GLenum pname, GLfixed param) 4503 { 4504 TexParameteri(target, pname, (GLint)param); 4505 } 4506 4507 void TexParameterxv(GLenum target, GLenum pname, const GLfixed *params) 4508 { 4509 UNIMPLEMENTED(); 4510 } 4511 4512 void TexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, 4513 GLenum format, GLenum type, const GLvoid* pixels) 4514 { 4515 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, " 4516 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, " 4517 "const GLvoid* pixels = %p)", 4518 target, level, xoffset, yoffset, width, height, format, type, pixels); 4519 4520 if(!es1::IsTextureTarget(target)) 4521 { 4522 return error(GL_INVALID_ENUM); 4523 } 4524 4525 if(level < 0 || level >= es1::IMPLEMENTATION_MAX_TEXTURE_LEVELS) 4526 { 4527 return error(GL_INVALID_VALUE); 4528 } 4529 4530 if(xoffset < 0 || yoffset < 0 || width < 0 || height < 0) 4531 { 4532 return error(GL_INVALID_VALUE); 4533 } 4534 4535 if(std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height) 4536 { 4537 return error(GL_INVALID_VALUE); 4538 } 4539 4540 if(!es1::CheckTextureFormatType(format, type)) 4541 { 4542 return error(GL_INVALID_ENUM); 4543 } 4544 4545 if(width == 0 || height == 0 || !pixels) 4546 { 4547 return; 4548 } 4549 4550 es1::Context *context = es1::getContext(); 4551 4552 if(context) 4553 { 4554 if(target == GL_TEXTURE_2D) 4555 { 4556 es1::Texture2D *texture = context->getTexture2D(); 4557 4558 if(validateSubImageParams(false, width, height, xoffset, yoffset, target, level, format, texture)) 4559 { 4560 texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels); 4561 } 4562 } 4563 else UNREACHABLE(target); 4564 } 4565 } 4566 4567 void Translatef(GLfloat x, GLfloat y, GLfloat z) 4568 { 4569 TRACE("(GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", x, y, z); 4570 4571 es1::Context *context = es1::getContext(); 4572 4573 if(context) 4574 { 4575 context->translate(x, y, z); 4576 } 4577 } 4578 4579 void Translatex(GLfixed x, GLfixed y, GLfixed z) 4580 { 4581 Translatef((float)x / 0x10000, (float)y / 0x10000, (float)z / 0x10000); 4582 } 4583 4584 void VertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) 4585 { 4586 TRACE("(GLint size = %d, GLenum type = 0x%X, GLsizei stride = %d, const GLvoid *pointer = %p)", size, type, stride, pointer); 4587 4588 if(size < 2 || size > 4) 4589 { 4590 return error(GL_INVALID_VALUE); 4591 } 4592 4593 VertexAttribPointer(sw::Position, size, type, false, stride, pointer); 4594 } 4595 4596 void Viewport(GLint x, GLint y, GLsizei width, GLsizei height) 4597 { 4598 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height); 4599 4600 if(width < 0 || height < 0) 4601 { 4602 return error(GL_INVALID_VALUE); 4603 } 4604 4605 es1::Context *context = es1::getContext(); 4606 4607 if(context) 4608 { 4609 context->setViewportParams(x, y, width, height); 4610 } 4611 } 4612 4613 void EGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image) 4614 { 4615 TRACE("(GLenum target = 0x%X, GLeglImageOES image = %p)", target, image); 4616 4617 switch(target) 4618 { 4619 case GL_TEXTURE_2D: 4620 case GL_TEXTURE_EXTERNAL_OES: 4621 break; 4622 default: 4623 return error(GL_INVALID_ENUM); 4624 } 4625 4626 if(!image) 4627 { 4628 return error(GL_INVALID_OPERATION); 4629 } 4630 4631 es1::Context *context = es1::getContext(); 4632 4633 if(context) 4634 { 4635 es1::Texture2D *texture = 0; 4636 4637 switch(target) 4638 { 4639 case GL_TEXTURE_2D: texture = context->getTexture2D(); break; 4640 case GL_TEXTURE_EXTERNAL_OES: texture = context->getTextureExternal(); break; 4641 default: UNREACHABLE(target); 4642 } 4643 4644 if(!texture) 4645 { 4646 return error(GL_INVALID_OPERATION); 4647 } 4648 4649 egl::Image *glImage = static_cast<egl::Image*>(image); 4650 4651 texture->setImage(glImage); 4652 } 4653 } 4654 4655 void EGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image) 4656 { 4657 TRACE("(GLenum target = 0x%X, GLeglImageOES image = %p)", target, image); 4658 4659 UNIMPLEMENTED(); 4660 } 4661 4662 void DrawTexsOES(GLshort x, GLshort y, GLshort z, GLshort width, GLshort height) 4663 { 4664 UNIMPLEMENTED(); 4665 } 4666 4667 void DrawTexiOES(GLint x, GLint y, GLint z, GLint width, GLint height) 4668 { 4669 TRACE("(GLint x = %d, GLint y = %d, GLint z = %d, GLint width = %d, GLint height = %d)", x, y, z, width, height); 4670 4671 if(width <= 0 || height <= 0) 4672 { 4673 return error(GL_INVALID_VALUE); 4674 } 4675 4676 es1::Context *context = es1::getContext(); 4677 4678 if(context) 4679 { 4680 context->drawTexture((GLfloat)x, (GLfloat)y, (GLfloat)z, (GLfloat)width, (GLfloat)height); 4681 } 4682 } 4683 4684 void DrawTexxOES(GLfixed x, GLfixed y, GLfixed z, GLfixed width, GLfixed height) 4685 { 4686 UNIMPLEMENTED(); 4687 } 4688 4689 void DrawTexsvOES(const GLshort *coords) 4690 { 4691 UNIMPLEMENTED(); 4692 } 4693 4694 void DrawTexivOES(const GLint *coords) 4695 { 4696 UNIMPLEMENTED(); 4697 } 4698 4699 void DrawTexxvOES(const GLfixed *coords) 4700 { 4701 UNIMPLEMENTED(); 4702 } 4703 4704 void DrawTexfOES(GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height) 4705 { 4706 TRACE("(GLfloat x = %f, GLfloat y = %f, GLfloat z = %f, GLfloat width = %f, GLfloat height = %f)", x, y, z, width, height); 4707 4708 if(width <= 0 || height <= 0) 4709 { 4710 return error(GL_INVALID_VALUE); 4711 } 4712 4713 es1::Context *context = es1::getContext(); 4714 4715 if(context) 4716 { 4717 context->drawTexture(x, y, z, width, height); 4718 } 4719 } 4720 4721 void DrawTexfvOES(const GLfloat *coords) 4722 { 4723 UNIMPLEMENTED(); 4724 } 4725 4726 } 4727 4728 extern "C" __eglMustCastToProperFunctionPointerType es1GetProcAddress(const char *procname) 4729 { 4730 struct Extension 4731 { 4732 const char *name; 4733 __eglMustCastToProperFunctionPointerType address; 4734 }; 4735 4736 static const Extension glExtensions[] = 4737 { 4738 #define EXTENSION(name) {#name, (__eglMustCastToProperFunctionPointerType)name} 4739 4740 EXTENSION(glEGLImageTargetTexture2DOES), 4741 EXTENSION(glEGLImageTargetRenderbufferStorageOES), 4742 EXTENSION(glIsRenderbufferOES), 4743 EXTENSION(glBindRenderbufferOES), 4744 EXTENSION(glDeleteRenderbuffersOES), 4745 EXTENSION(glGenRenderbuffersOES), 4746 EXTENSION(glRenderbufferStorageOES), 4747 EXTENSION(glGetRenderbufferParameterivOES), 4748 EXTENSION(glIsFramebufferOES), 4749 EXTENSION(glBindFramebufferOES), 4750 EXTENSION(glDeleteFramebuffersOES), 4751 EXTENSION(glGenFramebuffersOES), 4752 EXTENSION(glCheckFramebufferStatusOES), 4753 EXTENSION(glFramebufferRenderbufferOES), 4754 EXTENSION(glFramebufferTexture2DOES), 4755 EXTENSION(glGetFramebufferAttachmentParameterivOES), 4756 EXTENSION(glGenerateMipmapOES), 4757 EXTENSION(glBlendEquationOES), 4758 EXTENSION(glBlendEquationSeparateOES), 4759 EXTENSION(glBlendFuncSeparateOES), 4760 EXTENSION(glPointSizePointerOES), 4761 4762 #undef EXTENSION 4763 }; 4764 4765 for(unsigned int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++) 4766 { 4767 if(strcmp(procname, glExtensions[ext].name) == 0) 4768 { 4769 return (__eglMustCastToProperFunctionPointerType)glExtensions[ext].address; 4770 } 4771 } 4772 4773 return nullptr; 4774 } 4775