1#include "precompiled.h" 2// 3// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved. 4// Use of this source code is governed by a BSD-style license that can be 5// found in the LICENSE file. 6// 7 8// libGLESv2.cpp: Implements the exported OpenGL ES 2.0 functions. 9 10#include "common/version.h" 11 12#include "libGLESv2/main.h" 13#include "common/utilities.h" 14#include "libGLESv2/formatutils.h" 15#include "libGLESv2/Buffer.h" 16#include "libGLESv2/Fence.h" 17#include "libGLESv2/Framebuffer.h" 18#include "libGLESv2/Renderbuffer.h" 19#include "libGLESv2/Program.h" 20#include "libGLESv2/ProgramBinary.h" 21#include "libGLESv2/Texture.h" 22#include "libGLESv2/Query.h" 23#include "libGLESv2/Context.h" 24#include "libGLESv2/VertexArray.h" 25#include "libGLESv2/TransformFeedback.h" 26 27#include "libGLESv2/validationES.h" 28#include "libGLESv2/validationES2.h" 29#include "libGLESv2/validationES3.h" 30#include "libGLESv2/queryconversions.h" 31 32extern "C" 33{ 34 35// OpenGL ES 2.0 functions 36 37void __stdcall glActiveTexture(GLenum texture) 38{ 39 EVENT("(GLenum texture = 0x%X)", texture); 40 41 try 42 { 43 gl::Context *context = gl::getNonLostContext(); 44 45 if (context) 46 { 47 if (texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + context->getMaximumCombinedTextureImageUnits() - 1) 48 { 49 return gl::error(GL_INVALID_ENUM); 50 } 51 52 context->setActiveSampler(texture - GL_TEXTURE0); 53 } 54 } 55 catch (...) 56 { 57 return gl::error(GL_OUT_OF_MEMORY); 58 } 59} 60 61void __stdcall glAttachShader(GLuint program, GLuint shader) 62{ 63 EVENT("(GLuint program = %d, GLuint shader = %d)", program, shader); 64 65 try 66 { 67 gl::Context *context = gl::getNonLostContext(); 68 69 if (context) 70 { 71 gl::Program *programObject = context->getProgram(program); 72 gl::Shader *shaderObject = context->getShader(shader); 73 74 if (!programObject) 75 { 76 if (context->getShader(program)) 77 { 78 return gl::error(GL_INVALID_OPERATION); 79 } 80 else 81 { 82 return gl::error(GL_INVALID_VALUE); 83 } 84 } 85 86 if (!shaderObject) 87 { 88 if (context->getProgram(shader)) 89 { 90 return gl::error(GL_INVALID_OPERATION); 91 } 92 else 93 { 94 return gl::error(GL_INVALID_VALUE); 95 } 96 } 97 98 if (!programObject->attachShader(shaderObject)) 99 { 100 return gl::error(GL_INVALID_OPERATION); 101 } 102 } 103 } 104 catch (...) 105 { 106 return gl::error(GL_OUT_OF_MEMORY); 107 } 108} 109 110void __stdcall glBeginQueryEXT(GLenum target, GLuint id) 111{ 112 EVENT("(GLenum target = 0x%X, GLuint %d)", target, id); 113 114 try 115 { 116 gl::Context *context = gl::getNonLostContext(); 117 118 if (context) 119 { 120 if (!ValidateBeginQuery(context, target, id)) 121 { 122 return; 123 } 124 125 context->beginQuery(target, id); 126 } 127 } 128 catch (...) 129 { 130 return gl::error(GL_OUT_OF_MEMORY); 131 } 132} 133 134void __stdcall glBindAttribLocation(GLuint program, GLuint index, const GLchar* name) 135{ 136 EVENT("(GLuint program = %d, GLuint index = %d, const GLchar* name = 0x%0.8p)", program, index, name); 137 138 try 139 { 140 if (index >= gl::MAX_VERTEX_ATTRIBS) 141 { 142 return gl::error(GL_INVALID_VALUE); 143 } 144 145 gl::Context *context = gl::getNonLostContext(); 146 147 if (context) 148 { 149 gl::Program *programObject = context->getProgram(program); 150 151 if (!programObject) 152 { 153 if (context->getShader(program)) 154 { 155 return gl::error(GL_INVALID_OPERATION); 156 } 157 else 158 { 159 return gl::error(GL_INVALID_VALUE); 160 } 161 } 162 163 if (strncmp(name, "gl_", 3) == 0) 164 { 165 return gl::error(GL_INVALID_OPERATION); 166 } 167 168 programObject->bindAttributeLocation(index, name); 169 } 170 } 171 catch (...) 172 { 173 return gl::error(GL_OUT_OF_MEMORY); 174 } 175} 176 177void __stdcall glBindBuffer(GLenum target, GLuint buffer) 178{ 179 EVENT("(GLenum target = 0x%X, GLuint buffer = %d)", target, buffer); 180 181 try 182 { 183 gl::Context *context = gl::getNonLostContext(); 184 185 if (context) 186 { 187 if (!gl::ValidBufferTarget(context, target)) 188 { 189 return gl::error(GL_INVALID_ENUM); 190 } 191 192 switch (target) 193 { 194 case GL_ARRAY_BUFFER: 195 context->bindArrayBuffer(buffer); 196 return; 197 case GL_ELEMENT_ARRAY_BUFFER: 198 context->bindElementArrayBuffer(buffer); 199 return; 200 case GL_COPY_READ_BUFFER: 201 context->bindCopyReadBuffer(buffer); 202 return; 203 case GL_COPY_WRITE_BUFFER: 204 context->bindCopyWriteBuffer(buffer); 205 return; 206 case GL_PIXEL_PACK_BUFFER: 207 context->bindPixelPackBuffer(buffer); 208 return; 209 case GL_PIXEL_UNPACK_BUFFER: 210 context->bindPixelUnpackBuffer(buffer); 211 return; 212 case GL_UNIFORM_BUFFER: 213 context->bindGenericUniformBuffer(buffer); 214 return; 215 case GL_TRANSFORM_FEEDBACK_BUFFER: 216 context->bindGenericTransformFeedbackBuffer(buffer); 217 return; 218 default: 219 return gl::error(GL_INVALID_ENUM); 220 } 221 } 222 } 223 catch (...) 224 { 225 return gl::error(GL_OUT_OF_MEMORY); 226 } 227} 228 229void __stdcall glBindFramebuffer(GLenum target, GLuint framebuffer) 230{ 231 EVENT("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer); 232 233 try 234 { 235 if (!gl::ValidFramebufferTarget(target)) 236 { 237 return gl::error(GL_INVALID_ENUM); 238 } 239 240 gl::Context *context = gl::getNonLostContext(); 241 242 if (context) 243 { 244 if (target == GL_READ_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER) 245 { 246 context->bindReadFramebuffer(framebuffer); 247 } 248 249 if (target == GL_DRAW_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER) 250 { 251 context->bindDrawFramebuffer(framebuffer); 252 } 253 } 254 } 255 catch (...) 256 { 257 return gl::error(GL_OUT_OF_MEMORY); 258 } 259} 260 261void __stdcall glBindRenderbuffer(GLenum target, GLuint renderbuffer) 262{ 263 EVENT("(GLenum target = 0x%X, GLuint renderbuffer = %d)", target, renderbuffer); 264 265 try 266 { 267 if (target != GL_RENDERBUFFER) 268 { 269 return gl::error(GL_INVALID_ENUM); 270 } 271 272 gl::Context *context = gl::getNonLostContext(); 273 274 if (context) 275 { 276 context->bindRenderbuffer(renderbuffer); 277 } 278 } 279 catch (...) 280 { 281 return gl::error(GL_OUT_OF_MEMORY); 282 } 283} 284 285void __stdcall glBindTexture(GLenum target, GLuint texture) 286{ 287 EVENT("(GLenum target = 0x%X, GLuint texture = %d)", target, texture); 288 289 try 290 { 291 gl::Context *context = gl::getNonLostContext(); 292 293 if (context) 294 { 295 gl::Texture *textureObject = context->getTexture(texture); 296 297 if (textureObject && textureObject->getTarget() != target && texture != 0) 298 { 299 return gl::error(GL_INVALID_OPERATION); 300 } 301 302 switch (target) 303 { 304 case GL_TEXTURE_2D: 305 context->bindTexture2D(texture); 306 return; 307 case GL_TEXTURE_CUBE_MAP: 308 context->bindTextureCubeMap(texture); 309 return; 310 case GL_TEXTURE_3D: 311 if (context->getClientVersion() < 3) 312 { 313 return gl::error(GL_INVALID_ENUM); 314 } 315 context->bindTexture3D(texture); 316 return; 317 case GL_TEXTURE_2D_ARRAY: 318 if (context->getClientVersion() < 3) 319 { 320 return gl::error(GL_INVALID_ENUM); 321 } 322 context->bindTexture2DArray(texture); 323 return; 324 default: 325 return gl::error(GL_INVALID_ENUM); 326 } 327 } 328 } 329 catch (...) 330 { 331 return gl::error(GL_OUT_OF_MEMORY); 332 } 333} 334 335void __stdcall glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) 336{ 337 EVENT("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)", 338 red, green, blue, alpha); 339 340 try 341 { 342 gl::Context* context = gl::getNonLostContext(); 343 344 if (context) 345 { 346 context->setBlendColor(gl::clamp01(red), gl::clamp01(green), gl::clamp01(blue), gl::clamp01(alpha)); 347 } 348 } 349 catch (...) 350 { 351 return gl::error(GL_OUT_OF_MEMORY); 352 } 353} 354 355void __stdcall glBlendEquation(GLenum mode) 356{ 357 glBlendEquationSeparate(mode, mode); 358} 359 360void __stdcall glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha) 361{ 362 EVENT("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha); 363 364 try 365 { 366 gl::Context *context = gl::getNonLostContext(); 367 368 switch (modeRGB) 369 { 370 case GL_FUNC_ADD: 371 case GL_FUNC_SUBTRACT: 372 case GL_FUNC_REVERSE_SUBTRACT: 373 case GL_MIN: 374 case GL_MAX: 375 break; 376 377 default: 378 return gl::error(GL_INVALID_ENUM); 379 } 380 381 switch (modeAlpha) 382 { 383 case GL_FUNC_ADD: 384 case GL_FUNC_SUBTRACT: 385 case GL_FUNC_REVERSE_SUBTRACT: 386 case GL_MIN: 387 case GL_MAX: 388 break; 389 390 default: 391 return gl::error(GL_INVALID_ENUM); 392 } 393 394 if (context) 395 { 396 context->setBlendEquation(modeRGB, modeAlpha); 397 } 398 } 399 catch (...) 400 { 401 return gl::error(GL_OUT_OF_MEMORY); 402 } 403} 404 405void __stdcall glBlendFunc(GLenum sfactor, GLenum dfactor) 406{ 407 glBlendFuncSeparate(sfactor, dfactor, sfactor, dfactor); 408} 409 410void __stdcall glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) 411{ 412 EVENT("(GLenum srcRGB = 0x%X, GLenum dstRGB = 0x%X, GLenum srcAlpha = 0x%X, GLenum dstAlpha = 0x%X)", 413 srcRGB, dstRGB, srcAlpha, dstAlpha); 414 415 try 416 { 417 gl::Context *context = gl::getNonLostContext(); 418 419 switch (srcRGB) 420 { 421 case GL_ZERO: 422 case GL_ONE: 423 case GL_SRC_COLOR: 424 case GL_ONE_MINUS_SRC_COLOR: 425 case GL_DST_COLOR: 426 case GL_ONE_MINUS_DST_COLOR: 427 case GL_SRC_ALPHA: 428 case GL_ONE_MINUS_SRC_ALPHA: 429 case GL_DST_ALPHA: 430 case GL_ONE_MINUS_DST_ALPHA: 431 case GL_CONSTANT_COLOR: 432 case GL_ONE_MINUS_CONSTANT_COLOR: 433 case GL_CONSTANT_ALPHA: 434 case GL_ONE_MINUS_CONSTANT_ALPHA: 435 case GL_SRC_ALPHA_SATURATE: 436 break; 437 default: 438 return gl::error(GL_INVALID_ENUM); 439 } 440 441 switch (dstRGB) 442 { 443 case GL_ZERO: 444 case GL_ONE: 445 case GL_SRC_COLOR: 446 case GL_ONE_MINUS_SRC_COLOR: 447 case GL_DST_COLOR: 448 case GL_ONE_MINUS_DST_COLOR: 449 case GL_SRC_ALPHA: 450 case GL_ONE_MINUS_SRC_ALPHA: 451 case GL_DST_ALPHA: 452 case GL_ONE_MINUS_DST_ALPHA: 453 case GL_CONSTANT_COLOR: 454 case GL_ONE_MINUS_CONSTANT_COLOR: 455 case GL_CONSTANT_ALPHA: 456 case GL_ONE_MINUS_CONSTANT_ALPHA: 457 break; 458 459 case GL_SRC_ALPHA_SATURATE: 460 if (!context || context->getClientVersion() < 3) 461 { 462 return gl::error(GL_INVALID_ENUM); 463 } 464 break; 465 466 default: 467 return gl::error(GL_INVALID_ENUM); 468 } 469 470 switch (srcAlpha) 471 { 472 case GL_ZERO: 473 case GL_ONE: 474 case GL_SRC_COLOR: 475 case GL_ONE_MINUS_SRC_COLOR: 476 case GL_DST_COLOR: 477 case GL_ONE_MINUS_DST_COLOR: 478 case GL_SRC_ALPHA: 479 case GL_ONE_MINUS_SRC_ALPHA: 480 case GL_DST_ALPHA: 481 case GL_ONE_MINUS_DST_ALPHA: 482 case GL_CONSTANT_COLOR: 483 case GL_ONE_MINUS_CONSTANT_COLOR: 484 case GL_CONSTANT_ALPHA: 485 case GL_ONE_MINUS_CONSTANT_ALPHA: 486 case GL_SRC_ALPHA_SATURATE: 487 break; 488 default: 489 return gl::error(GL_INVALID_ENUM); 490 } 491 492 switch (dstAlpha) 493 { 494 case GL_ZERO: 495 case GL_ONE: 496 case GL_SRC_COLOR: 497 case GL_ONE_MINUS_SRC_COLOR: 498 case GL_DST_COLOR: 499 case GL_ONE_MINUS_DST_COLOR: 500 case GL_SRC_ALPHA: 501 case GL_ONE_MINUS_SRC_ALPHA: 502 case GL_DST_ALPHA: 503 case GL_ONE_MINUS_DST_ALPHA: 504 case GL_CONSTANT_COLOR: 505 case GL_ONE_MINUS_CONSTANT_COLOR: 506 case GL_CONSTANT_ALPHA: 507 case GL_ONE_MINUS_CONSTANT_ALPHA: 508 break; 509 510 case GL_SRC_ALPHA_SATURATE: 511 if (!context || context->getClientVersion() < 3) 512 { 513 return gl::error(GL_INVALID_ENUM); 514 } 515 break; 516 517 default: 518 return gl::error(GL_INVALID_ENUM); 519 } 520 521 bool constantColorUsed = (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR || 522 dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR); 523 524 bool constantAlphaUsed = (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA || 525 dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA); 526 527 if (constantColorUsed && constantAlphaUsed) 528 { 529 ERR("Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR invalid under WebGL"); 530 return gl::error(GL_INVALID_OPERATION); 531 } 532 533 if (context) 534 { 535 context->setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha); 536 } 537 } 538 catch (...) 539 { 540 return gl::error(GL_OUT_OF_MEMORY); 541 } 542} 543 544void __stdcall glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage) 545{ 546 EVENT("(GLenum target = 0x%X, GLsizeiptr size = %d, const GLvoid* data = 0x%0.8p, GLenum usage = %d)", 547 target, size, data, usage); 548 549 try 550 { 551 if (size < 0) 552 { 553 return gl::error(GL_INVALID_VALUE); 554 } 555 556 gl::Context *context = gl::getNonLostContext(); 557 558 switch (usage) 559 { 560 case GL_STREAM_DRAW: 561 case GL_STATIC_DRAW: 562 case GL_DYNAMIC_DRAW: 563 break; 564 565 case GL_STREAM_READ: 566 case GL_STREAM_COPY: 567 case GL_STATIC_READ: 568 case GL_STATIC_COPY: 569 case GL_DYNAMIC_READ: 570 case GL_DYNAMIC_COPY: 571 if (context && context->getClientVersion() < 3) 572 { 573 return gl::error(GL_INVALID_ENUM); 574 } 575 break; 576 577 default: 578 return gl::error(GL_INVALID_ENUM); 579 } 580 581 if (context) 582 { 583 if (!gl::ValidBufferTarget(context, target)) 584 { 585 return gl::error(GL_INVALID_ENUM); 586 } 587 588 gl::Buffer *buffer = context->getTargetBuffer(target); 589 590 if (!buffer) 591 { 592 return gl::error(GL_INVALID_OPERATION); 593 } 594 595 buffer->bufferData(data, size, usage); 596 } 597 } 598 catch (...) 599 { 600 return gl::error(GL_OUT_OF_MEMORY); 601 } 602} 603 604void __stdcall glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data) 605{ 606 EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr size = %d, const GLvoid* data = 0x%0.8p)", 607 target, offset, size, data); 608 609 try 610 { 611 if (size < 0 || offset < 0) 612 { 613 return gl::error(GL_INVALID_VALUE); 614 } 615 616 if (data == NULL) 617 { 618 return; 619 } 620 621 gl::Context *context = gl::getNonLostContext(); 622 623 if (context) 624 { 625 if (!gl::ValidBufferTarget(context, target)) 626 { 627 return gl::error(GL_INVALID_ENUM); 628 } 629 630 gl::Buffer *buffer = context->getTargetBuffer(target); 631 632 if (!buffer) 633 { 634 return gl::error(GL_INVALID_OPERATION); 635 } 636 637 if (buffer->mapped()) 638 { 639 return gl::error(GL_INVALID_OPERATION); 640 } 641 642 // Check for possible overflow of size + offset 643 if (!rx::IsUnsignedAdditionSafe<size_t>(size, offset)) 644 { 645 return gl::error(GL_OUT_OF_MEMORY); 646 } 647 648 if (size + offset > buffer->size()) 649 { 650 return gl::error(GL_INVALID_VALUE); 651 } 652 653 buffer->bufferSubData(data, size, offset); 654 } 655 } 656 catch (...) 657 { 658 return gl::error(GL_OUT_OF_MEMORY); 659 } 660} 661 662GLenum __stdcall glCheckFramebufferStatus(GLenum target) 663{ 664 EVENT("(GLenum target = 0x%X)", target); 665 666 try 667 { 668 if (!gl::ValidFramebufferTarget(target)) 669 { 670 return gl::error(GL_INVALID_ENUM, 0); 671 } 672 673 gl::Context *context = gl::getNonLostContext(); 674 675 if (context) 676 { 677 gl::Framebuffer *framebuffer = context->getTargetFramebuffer(target); 678 ASSERT(framebuffer); 679 return framebuffer->completeness(); 680 } 681 } 682 catch (...) 683 { 684 return gl::error(GL_OUT_OF_MEMORY, 0); 685 } 686 687 return 0; 688} 689 690void __stdcall glClear(GLbitfield mask) 691{ 692 EVENT("(GLbitfield mask = 0x%X)", mask); 693 694 try 695 { 696 gl::Context *context = gl::getNonLostContext(); 697 698 if (context) 699 { 700 gl::Framebuffer *framebufferObject = context->getDrawFramebuffer(); 701 702 if (!framebufferObject || framebufferObject->completeness() != GL_FRAMEBUFFER_COMPLETE) 703 { 704 return gl::error(GL_INVALID_FRAMEBUFFER_OPERATION); 705 } 706 707 if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0) 708 { 709 return gl::error(GL_INVALID_VALUE); 710 } 711 712 context->clear(mask); 713 } 714 } 715 catch (...) 716 { 717 return gl::error(GL_OUT_OF_MEMORY); 718 } 719} 720 721void __stdcall glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) 722{ 723 EVENT("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)", 724 red, green, blue, alpha); 725 726 try 727 { 728 gl::Context *context = gl::getNonLostContext(); 729 730 if (context) 731 { 732 context->setClearColor(red, green, blue, alpha); 733 } 734 } 735 catch (...) 736 { 737 return gl::error(GL_OUT_OF_MEMORY); 738 } 739} 740 741void __stdcall glClearDepthf(GLclampf depth) 742{ 743 EVENT("(GLclampf depth = %f)", depth); 744 745 try 746 { 747 gl::Context *context = gl::getNonLostContext(); 748 749 if (context) 750 { 751 context->setClearDepth(depth); 752 } 753 } 754 catch (...) 755 { 756 return gl::error(GL_OUT_OF_MEMORY); 757 } 758} 759 760void __stdcall glClearStencil(GLint s) 761{ 762 EVENT("(GLint s = %d)", s); 763 764 try 765 { 766 gl::Context *context = gl::getNonLostContext(); 767 768 if (context) 769 { 770 context->setClearStencil(s); 771 } 772 } 773 catch (...) 774 { 775 return gl::error(GL_OUT_OF_MEMORY); 776 } 777} 778 779void __stdcall glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) 780{ 781 EVENT("(GLboolean red = %d, GLboolean green = %u, GLboolean blue = %u, GLboolean alpha = %u)", 782 red, green, blue, alpha); 783 784 try 785 { 786 gl::Context *context = gl::getNonLostContext(); 787 788 if (context) 789 { 790 context->setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE); 791 } 792 } 793 catch (...) 794 { 795 return gl::error(GL_OUT_OF_MEMORY); 796 } 797} 798 799void __stdcall glCompileShader(GLuint shader) 800{ 801 EVENT("(GLuint shader = %d)", shader); 802 803 try 804 { 805 gl::Context *context = gl::getNonLostContext(); 806 807 if (context) 808 { 809 gl::Shader *shaderObject = context->getShader(shader); 810 811 if (!shaderObject) 812 { 813 if (context->getProgram(shader)) 814 { 815 return gl::error(GL_INVALID_OPERATION); 816 } 817 else 818 { 819 return gl::error(GL_INVALID_VALUE); 820 } 821 } 822 823 shaderObject->compile(); 824 } 825 } 826 catch (...) 827 { 828 return gl::error(GL_OUT_OF_MEMORY); 829 } 830} 831 832void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, 833 GLint border, GLsizei imageSize, const GLvoid* data) 834{ 835 EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, " 836 "GLsizei height = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)", 837 target, level, internalformat, width, height, border, imageSize, data); 838 839 try 840 { 841 gl::Context *context = gl::getNonLostContext(); 842 843 if (context) 844 { 845 if (context->getClientVersion() < 3 && 846 !ValidateES2TexImageParameters(context, target, level, internalformat, true, false, 847 0, 0, width, height, border, GL_NONE, GL_NONE, data)) 848 { 849 return; 850 } 851 852 if (context->getClientVersion() >= 3 && 853 !ValidateES3TexImageParameters(context, target, level, internalformat, true, false, 854 0, 0, 0, width, height, 1, border, GL_NONE, GL_NONE, data)) 855 { 856 return; 857 } 858 859 if (imageSize < 0 || imageSize != (GLsizei)gl::GetBlockSize(internalformat, GL_UNSIGNED_BYTE, context->getClientVersion(), width, height)) 860 { 861 return gl::error(GL_INVALID_VALUE); 862 } 863 864 switch (target) 865 { 866 case GL_TEXTURE_2D: 867 { 868 gl::Texture2D *texture = context->getTexture2D(); 869 texture->setCompressedImage(level, internalformat, width, height, imageSize, data); 870 } 871 break; 872 873 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 874 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 875 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 876 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 877 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 878 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 879 { 880 gl::TextureCubeMap *texture = context->getTextureCubeMap(); 881 texture->setCompressedImage(target, level, internalformat, width, height, imageSize, data); 882 } 883 break; 884 885 default: 886 return gl::error(GL_INVALID_ENUM); 887 } 888 } 889 } 890 catch (...) 891 { 892 return gl::error(GL_OUT_OF_MEMORY); 893 } 894} 895 896void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, 897 GLenum format, GLsizei imageSize, const GLvoid* data) 898{ 899 EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, " 900 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, " 901 "GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)", 902 target, level, xoffset, yoffset, width, height, format, imageSize, data); 903 904 try 905 { 906 gl::Context *context = gl::getNonLostContext(); 907 908 if (context) 909 { 910 if (context->getClientVersion() < 3 && 911 !ValidateES2TexImageParameters(context, target, level, GL_NONE, true, true, 912 xoffset, yoffset, width, height, 0, GL_NONE, GL_NONE, data)) 913 { 914 return; 915 } 916 917 if (context->getClientVersion() >= 3 && 918 !ValidateES3TexImageParameters(context, target, level, GL_NONE, true, true, 919 xoffset, yoffset, 0, width, height, 1, 0, GL_NONE, GL_NONE, data)) 920 { 921 return; 922 } 923 924 if (imageSize < 0 || imageSize != (GLsizei)gl::GetBlockSize(format, GL_UNSIGNED_BYTE, context->getClientVersion(), width, height)) 925 { 926 return gl::error(GL_INVALID_VALUE); 927 } 928 929 switch (target) 930 { 931 case GL_TEXTURE_2D: 932 { 933 gl::Texture2D *texture = context->getTexture2D(); 934 texture->subImageCompressed(level, xoffset, yoffset, width, height, format, imageSize, data); 935 } 936 break; 937 938 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 939 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 940 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 941 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 942 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 943 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 944 { 945 gl::TextureCubeMap *texture = context->getTextureCubeMap(); 946 texture->subImageCompressed(target, level, xoffset, yoffset, width, height, format, imageSize, data); 947 } 948 break; 949 950 default: 951 return gl::error(GL_INVALID_ENUM); 952 } 953 } 954 } 955 catch (...) 956 { 957 return gl::error(GL_OUT_OF_MEMORY); 958 } 959} 960 961void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) 962{ 963 EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, " 964 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)", 965 target, level, internalformat, x, y, width, height, border); 966 967 try 968 { 969 gl::Context *context = gl::getNonLostContext(); 970 971 if (context) 972 { 973 if (context->getClientVersion() < 3 && 974 !ValidateES2CopyTexImageParameters(context, target, level, internalformat, false, 975 0, 0, x, y, width, height, border)) 976 { 977 return; 978 } 979 980 if (context->getClientVersion() >= 3 && 981 !ValidateES3CopyTexImageParameters(context, target, level, internalformat, false, 982 0, 0, 0, x, y, width, height, border)) 983 { 984 return; 985 } 986 987 gl::Framebuffer *framebuffer = context->getReadFramebuffer(); 988 989 switch (target) 990 { 991 case GL_TEXTURE_2D: 992 { 993 gl::Texture2D *texture = context->getTexture2D(); 994 texture->copyImage(level, internalformat, x, y, width, height, framebuffer); 995 } 996 break; 997 998 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 999 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 1000 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 1001 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 1002 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 1003 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 1004 { 1005 gl::TextureCubeMap *texture = context->getTextureCubeMap(); 1006 texture->copyImage(target, level, internalformat, x, y, width, height, framebuffer); 1007 } 1008 break; 1009 1010 default: 1011 return gl::error(GL_INVALID_ENUM); 1012 } 1013 } 1014 } 1015 catch (...) 1016 { 1017 return gl::error(GL_OUT_OF_MEMORY); 1018 } 1019} 1020 1021void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) 1022{ 1023 EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, " 1024 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", 1025 target, level, xoffset, yoffset, x, y, width, height); 1026 1027 try 1028 { 1029 gl::Context *context = gl::getNonLostContext(); 1030 1031 if (context) 1032 { 1033 if (context->getClientVersion() < 3 && 1034 !ValidateES2CopyTexImageParameters(context, target, level, GL_NONE, true, 1035 xoffset, yoffset, x, y, width, height, 0)) 1036 { 1037 return; 1038 } 1039 1040 if (context->getClientVersion() >= 3 && 1041 !ValidateES3CopyTexImageParameters(context, target, level, GL_NONE, true, 1042 xoffset, yoffset, 0, x, y, width, height, 0)) 1043 { 1044 return; 1045 } 1046 1047 gl::Framebuffer *framebuffer = context->getReadFramebuffer(); 1048 1049 switch (target) 1050 { 1051 case GL_TEXTURE_2D: 1052 { 1053 gl::Texture2D *texture = context->getTexture2D(); 1054 texture->copySubImage(target, level, xoffset, yoffset, 0, x, y, width, height, framebuffer); 1055 } 1056 break; 1057 1058 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 1059 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 1060 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 1061 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 1062 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 1063 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 1064 { 1065 gl::TextureCubeMap *texture = context->getTextureCubeMap(); 1066 texture->copySubImage(target, level, xoffset, yoffset, 0, x, y, width, height, framebuffer); 1067 } 1068 break; 1069 1070 default: 1071 return gl::error(GL_INVALID_ENUM); 1072 } 1073 } 1074 } 1075 1076 catch (...) 1077 { 1078 return gl::error(GL_OUT_OF_MEMORY); 1079 } 1080} 1081 1082GLuint __stdcall glCreateProgram(void) 1083{ 1084 EVENT("()"); 1085 1086 try 1087 { 1088 gl::Context *context = gl::getNonLostContext(); 1089 1090 if (context) 1091 { 1092 return context->createProgram(); 1093 } 1094 } 1095 catch (...) 1096 { 1097 return gl::error(GL_OUT_OF_MEMORY, 0); 1098 } 1099 1100 return 0; 1101} 1102 1103GLuint __stdcall glCreateShader(GLenum type) 1104{ 1105 EVENT("(GLenum type = 0x%X)", type); 1106 1107 try 1108 { 1109 gl::Context *context = gl::getNonLostContext(); 1110 1111 if (context) 1112 { 1113 switch (type) 1114 { 1115 case GL_FRAGMENT_SHADER: 1116 case GL_VERTEX_SHADER: 1117 return context->createShader(type); 1118 default: 1119 return gl::error(GL_INVALID_ENUM, 0); 1120 } 1121 } 1122 } 1123 catch (...) 1124 { 1125 return gl::error(GL_OUT_OF_MEMORY, 0); 1126 } 1127 1128 return 0; 1129} 1130 1131void __stdcall glCullFace(GLenum mode) 1132{ 1133 EVENT("(GLenum mode = 0x%X)", mode); 1134 1135 try 1136 { 1137 switch (mode) 1138 { 1139 case GL_FRONT: 1140 case GL_BACK: 1141 case GL_FRONT_AND_BACK: 1142 { 1143 gl::Context *context = gl::getNonLostContext(); 1144 1145 if (context) 1146 { 1147 context->setCullMode(mode); 1148 } 1149 } 1150 break; 1151 default: 1152 return gl::error(GL_INVALID_ENUM); 1153 } 1154 } 1155 catch (...) 1156 { 1157 return gl::error(GL_OUT_OF_MEMORY); 1158 } 1159} 1160 1161void __stdcall glDeleteBuffers(GLsizei n, const GLuint* buffers) 1162{ 1163 EVENT("(GLsizei n = %d, const GLuint* buffers = 0x%0.8p)", n, buffers); 1164 1165 try 1166 { 1167 if (n < 0) 1168 { 1169 return gl::error(GL_INVALID_VALUE); 1170 } 1171 1172 gl::Context *context = gl::getNonLostContext(); 1173 1174 if (context) 1175 { 1176 for (int i = 0; i < n; i++) 1177 { 1178 context->deleteBuffer(buffers[i]); 1179 } 1180 } 1181 } 1182 catch (...) 1183 { 1184 return gl::error(GL_OUT_OF_MEMORY); 1185 } 1186} 1187 1188void __stdcall glDeleteFencesNV(GLsizei n, const GLuint* fences) 1189{ 1190 EVENT("(GLsizei n = %d, const GLuint* fences = 0x%0.8p)", n, fences); 1191 1192 try 1193 { 1194 if (n < 0) 1195 { 1196 return gl::error(GL_INVALID_VALUE); 1197 } 1198 1199 gl::Context *context = gl::getNonLostContext(); 1200 1201 if (context) 1202 { 1203 for (int i = 0; i < n; i++) 1204 { 1205 context->deleteFenceNV(fences[i]); 1206 } 1207 } 1208 } 1209 catch (...) 1210 { 1211 return gl::error(GL_OUT_OF_MEMORY); 1212 } 1213} 1214 1215void __stdcall glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers) 1216{ 1217 EVENT("(GLsizei n = %d, const GLuint* framebuffers = 0x%0.8p)", n, framebuffers); 1218 1219 try 1220 { 1221 if (n < 0) 1222 { 1223 return gl::error(GL_INVALID_VALUE); 1224 } 1225 1226 gl::Context *context = gl::getNonLostContext(); 1227 1228 if (context) 1229 { 1230 for (int i = 0; i < n; i++) 1231 { 1232 if (framebuffers[i] != 0) 1233 { 1234 context->deleteFramebuffer(framebuffers[i]); 1235 } 1236 } 1237 } 1238 } 1239 catch (...) 1240 { 1241 return gl::error(GL_OUT_OF_MEMORY); 1242 } 1243} 1244 1245void __stdcall glDeleteProgram(GLuint program) 1246{ 1247 EVENT("(GLuint program = %d)", program); 1248 1249 try 1250 { 1251 if (program == 0) 1252 { 1253 return; 1254 } 1255 1256 gl::Context *context = gl::getNonLostContext(); 1257 1258 if (context) 1259 { 1260 if (!context->getProgram(program)) 1261 { 1262 if(context->getShader(program)) 1263 { 1264 return gl::error(GL_INVALID_OPERATION); 1265 } 1266 else 1267 { 1268 return gl::error(GL_INVALID_VALUE); 1269 } 1270 } 1271 1272 context->deleteProgram(program); 1273 } 1274 } 1275 catch (...) 1276 { 1277 return gl::error(GL_OUT_OF_MEMORY); 1278 } 1279} 1280 1281void __stdcall glDeleteQueriesEXT(GLsizei n, const GLuint *ids) 1282{ 1283 EVENT("(GLsizei n = %d, const GLuint *ids = 0x%0.8p)", n, ids); 1284 1285 try 1286 { 1287 if (n < 0) 1288 { 1289 return gl::error(GL_INVALID_VALUE); 1290 } 1291 1292 gl::Context *context = gl::getNonLostContext(); 1293 1294 if (context) 1295 { 1296 for (int i = 0; i < n; i++) 1297 { 1298 context->deleteQuery(ids[i]); 1299 } 1300 } 1301 } 1302 catch (...) 1303 { 1304 return gl::error(GL_OUT_OF_MEMORY); 1305 } 1306} 1307 1308void __stdcall glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers) 1309{ 1310 EVENT("(GLsizei n = %d, const GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers); 1311 1312 try 1313 { 1314 if (n < 0) 1315 { 1316 return gl::error(GL_INVALID_VALUE); 1317 } 1318 1319 gl::Context *context = gl::getNonLostContext(); 1320 1321 if (context) 1322 { 1323 for (int i = 0; i < n; i++) 1324 { 1325 context->deleteRenderbuffer(renderbuffers[i]); 1326 } 1327 } 1328 } 1329 catch (...) 1330 { 1331 return gl::error(GL_OUT_OF_MEMORY); 1332 } 1333} 1334 1335void __stdcall glDeleteShader(GLuint shader) 1336{ 1337 EVENT("(GLuint shader = %d)", shader); 1338 1339 try 1340 { 1341 if (shader == 0) 1342 { 1343 return; 1344 } 1345 1346 gl::Context *context = gl::getNonLostContext(); 1347 1348 if (context) 1349 { 1350 if (!context->getShader(shader)) 1351 { 1352 if(context->getProgram(shader)) 1353 { 1354 return gl::error(GL_INVALID_OPERATION); 1355 } 1356 else 1357 { 1358 return gl::error(GL_INVALID_VALUE); 1359 } 1360 } 1361 1362 context->deleteShader(shader); 1363 } 1364 } 1365 catch (...) 1366 { 1367 return gl::error(GL_OUT_OF_MEMORY); 1368 } 1369} 1370 1371void __stdcall glDeleteTextures(GLsizei n, const GLuint* textures) 1372{ 1373 EVENT("(GLsizei n = %d, const GLuint* textures = 0x%0.8p)", n, textures); 1374 1375 try 1376 { 1377 if (n < 0) 1378 { 1379 return gl::error(GL_INVALID_VALUE); 1380 } 1381 1382 gl::Context *context = gl::getNonLostContext(); 1383 1384 if (context) 1385 { 1386 for (int i = 0; i < n; i++) 1387 { 1388 if (textures[i] != 0) 1389 { 1390 context->deleteTexture(textures[i]); 1391 } 1392 } 1393 } 1394 } 1395 catch (...) 1396 { 1397 return gl::error(GL_OUT_OF_MEMORY); 1398 } 1399} 1400 1401void __stdcall glDepthFunc(GLenum func) 1402{ 1403 EVENT("(GLenum func = 0x%X)", func); 1404 1405 try 1406 { 1407 switch (func) 1408 { 1409 case GL_NEVER: 1410 case GL_ALWAYS: 1411 case GL_LESS: 1412 case GL_LEQUAL: 1413 case GL_EQUAL: 1414 case GL_GREATER: 1415 case GL_GEQUAL: 1416 case GL_NOTEQUAL: 1417 break; 1418 default: 1419 return gl::error(GL_INVALID_ENUM); 1420 } 1421 1422 gl::Context *context = gl::getNonLostContext(); 1423 1424 if (context) 1425 { 1426 context->setDepthFunc(func); 1427 } 1428 } 1429 catch (...) 1430 { 1431 return gl::error(GL_OUT_OF_MEMORY); 1432 } 1433} 1434 1435void __stdcall glDepthMask(GLboolean flag) 1436{ 1437 EVENT("(GLboolean flag = %u)", flag); 1438 1439 try 1440 { 1441 gl::Context *context = gl::getNonLostContext(); 1442 1443 if (context) 1444 { 1445 context->setDepthMask(flag != GL_FALSE); 1446 } 1447 } 1448 catch (...) 1449 { 1450 return gl::error(GL_OUT_OF_MEMORY); 1451 } 1452} 1453 1454void __stdcall glDepthRangef(GLclampf zNear, GLclampf zFar) 1455{ 1456 EVENT("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar); 1457 1458 try 1459 { 1460 gl::Context *context = gl::getNonLostContext(); 1461 1462 if (context) 1463 { 1464 context->setDepthRange(zNear, zFar); 1465 } 1466 } 1467 catch (...) 1468 { 1469 return gl::error(GL_OUT_OF_MEMORY); 1470 } 1471} 1472 1473void __stdcall glDetachShader(GLuint program, GLuint shader) 1474{ 1475 EVENT("(GLuint program = %d, GLuint shader = %d)", program, shader); 1476 1477 try 1478 { 1479 gl::Context *context = gl::getNonLostContext(); 1480 1481 if (context) 1482 { 1483 1484 gl::Program *programObject = context->getProgram(program); 1485 gl::Shader *shaderObject = context->getShader(shader); 1486 1487 if (!programObject) 1488 { 1489 gl::Shader *shaderByProgramHandle; 1490 shaderByProgramHandle = context->getShader(program); 1491 if (!shaderByProgramHandle) 1492 { 1493 return gl::error(GL_INVALID_VALUE); 1494 } 1495 else 1496 { 1497 return gl::error(GL_INVALID_OPERATION); 1498 } 1499 } 1500 1501 if (!shaderObject) 1502 { 1503 gl::Program *programByShaderHandle = context->getProgram(shader); 1504 if (!programByShaderHandle) 1505 { 1506 return gl::error(GL_INVALID_VALUE); 1507 } 1508 else 1509 { 1510 return gl::error(GL_INVALID_OPERATION); 1511 } 1512 } 1513 1514 if (!programObject->detachShader(shaderObject)) 1515 { 1516 return gl::error(GL_INVALID_OPERATION); 1517 } 1518 } 1519 } 1520 catch (...) 1521 { 1522 return gl::error(GL_OUT_OF_MEMORY); 1523 } 1524} 1525 1526void __stdcall glDisable(GLenum cap) 1527{ 1528 EVENT("(GLenum cap = 0x%X)", cap); 1529 1530 try 1531 { 1532 gl::Context *context = gl::getNonLostContext(); 1533 1534 if (context) 1535 { 1536 if (!ValidCap(context, cap)) 1537 { 1538 return gl::error(GL_INVALID_ENUM); 1539 } 1540 1541 context->setCap(cap, false); 1542 } 1543 } 1544 catch (...) 1545 { 1546 return gl::error(GL_OUT_OF_MEMORY); 1547 } 1548} 1549 1550void __stdcall glDisableVertexAttribArray(GLuint index) 1551{ 1552 EVENT("(GLuint index = %d)", index); 1553 1554 try 1555 { 1556 if (index >= gl::MAX_VERTEX_ATTRIBS) 1557 { 1558 return gl::error(GL_INVALID_VALUE); 1559 } 1560 1561 gl::Context *context = gl::getNonLostContext(); 1562 1563 if (context) 1564 { 1565 context->setEnableVertexAttribArray(index, false); 1566 } 1567 } 1568 catch (...) 1569 { 1570 return gl::error(GL_OUT_OF_MEMORY); 1571 } 1572} 1573 1574void __stdcall glDrawArrays(GLenum mode, GLint first, GLsizei count) 1575{ 1576 EVENT("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count); 1577 1578 try 1579 { 1580 if (count < 0 || first < 0) 1581 { 1582 return gl::error(GL_INVALID_VALUE); 1583 } 1584 1585 gl::Context *context = gl::getNonLostContext(); 1586 1587 // Check for mapped buffers 1588 if (context->hasMappedBuffer(GL_ARRAY_BUFFER)) 1589 { 1590 return gl::error(GL_INVALID_OPERATION); 1591 } 1592 1593 if (context) 1594 { 1595 gl::TransformFeedback *curTransformFeedback = context->getCurrentTransformFeedback(); 1596 if (curTransformFeedback && curTransformFeedback->isStarted() && !curTransformFeedback->isPaused() && 1597 curTransformFeedback->getDrawMode() != mode) 1598 { 1599 // It is an invalid operation to call DrawArrays or DrawArraysInstanced with a draw mode 1600 // that does not match the current transform feedback object's draw mode (if transform feedback 1601 // is active), (3.0.2, section 2.14, pg 86) 1602 return gl::error(GL_INVALID_OPERATION); 1603 } 1604 1605 context->drawArrays(mode, first, count, 0); 1606 } 1607 } 1608 catch (...) 1609 { 1610 return gl::error(GL_OUT_OF_MEMORY); 1611 } 1612} 1613 1614void __stdcall glDrawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei count, GLsizei primcount) 1615{ 1616 EVENT("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d, GLsizei primcount = %d)", mode, first, count, primcount); 1617 1618 try 1619 { 1620 if (count < 0 || first < 0 || primcount < 0) 1621 { 1622 return gl::error(GL_INVALID_VALUE); 1623 } 1624 1625 if (primcount > 0) 1626 { 1627 gl::Context *context = gl::getNonLostContext(); 1628 1629 // Check for mapped buffers 1630 if (context->hasMappedBuffer(GL_ARRAY_BUFFER)) 1631 { 1632 return gl::error(GL_INVALID_OPERATION); 1633 } 1634 1635 if (context) 1636 { 1637 gl::TransformFeedback *curTransformFeedback = context->getCurrentTransformFeedback(); 1638 if (curTransformFeedback && curTransformFeedback->isStarted() && !curTransformFeedback->isPaused() && 1639 curTransformFeedback->getDrawMode() != mode) 1640 { 1641 // It is an invalid operation to call DrawArrays or DrawArraysInstanced with a draw mode 1642 // that does not match the current transform feedback object's draw mode (if transform feedback 1643 // is active), (3.0.2, section 2.14, pg 86) 1644 return gl::error(GL_INVALID_OPERATION); 1645 } 1646 1647 context->drawArrays(mode, first, count, primcount); 1648 } 1649 } 1650 } 1651 catch (...) 1652 { 1653 return gl::error(GL_OUT_OF_MEMORY); 1654 } 1655} 1656 1657void __stdcall glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices) 1658{ 1659 EVENT("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = 0x%0.8p)", 1660 mode, count, type, indices); 1661 1662 try 1663 { 1664 if (count < 0) 1665 { 1666 return gl::error(GL_INVALID_VALUE); 1667 } 1668 1669 gl::Context *context = gl::getNonLostContext(); 1670 1671 if (context) 1672 { 1673 switch (type) 1674 { 1675 case GL_UNSIGNED_BYTE: 1676 case GL_UNSIGNED_SHORT: 1677 break; 1678 case GL_UNSIGNED_INT: 1679 if (!context->supports32bitIndices()) 1680 { 1681 return gl::error(GL_INVALID_ENUM); 1682 } 1683 break; 1684 default: 1685 return gl::error(GL_INVALID_ENUM); 1686 } 1687 1688 gl::TransformFeedback *curTransformFeedback = context->getCurrentTransformFeedback(); 1689 if (curTransformFeedback && curTransformFeedback->isStarted() && !curTransformFeedback->isPaused()) 1690 { 1691 // It is an invalid operation to call DrawElements, DrawRangeElements or DrawElementsInstanced 1692 // while transform feedback is active, (3.0.2, section 2.14, pg 86) 1693 return gl::error(GL_INVALID_OPERATION); 1694 } 1695 1696 // Check for mapped buffers 1697 if (context->hasMappedBuffer(GL_ARRAY_BUFFER) || context->hasMappedBuffer(GL_ELEMENT_ARRAY_BUFFER)) 1698 { 1699 return gl::error(GL_INVALID_OPERATION); 1700 } 1701 1702 context->drawElements(mode, count, type, indices, 0); 1703 } 1704 } 1705 catch (...) 1706 { 1707 return gl::error(GL_OUT_OF_MEMORY); 1708 } 1709} 1710 1711void __stdcall glDrawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount) 1712{ 1713 EVENT("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = 0x%0.8p, GLsizei primcount = %d)", 1714 mode, count, type, indices, primcount); 1715 1716 try 1717 { 1718 if (count < 0 || primcount < 0) 1719 { 1720 return gl::error(GL_INVALID_VALUE); 1721 } 1722 1723 if (primcount > 0) 1724 { 1725 gl::Context *context = gl::getNonLostContext(); 1726 1727 if (context) 1728 { 1729 switch (type) 1730 { 1731 case GL_UNSIGNED_BYTE: 1732 case GL_UNSIGNED_SHORT: 1733 break; 1734 case GL_UNSIGNED_INT: 1735 if (!context->supports32bitIndices()) 1736 { 1737 return gl::error(GL_INVALID_ENUM); 1738 } 1739 break; 1740 default: 1741 return gl::error(GL_INVALID_ENUM); 1742 } 1743 1744 gl::TransformFeedback *curTransformFeedback = context->getCurrentTransformFeedback(); 1745 if (curTransformFeedback && curTransformFeedback->isStarted() && !curTransformFeedback->isPaused()) 1746 { 1747 // It is an invalid operation to call DrawElements, DrawRangeElements or DrawElementsInstanced 1748 // while transform feedback is active, (3.0.2, section 2.14, pg 86) 1749 return gl::error(GL_INVALID_OPERATION); 1750 } 1751 1752 // Check for mapped buffers 1753 if (context->hasMappedBuffer(GL_ARRAY_BUFFER) || context->hasMappedBuffer(GL_ELEMENT_ARRAY_BUFFER)) 1754 { 1755 return gl::error(GL_INVALID_OPERATION); 1756 } 1757 1758 context->drawElements(mode, count, type, indices, primcount); 1759 } 1760 } 1761 } 1762 catch (...) 1763 { 1764 return gl::error(GL_OUT_OF_MEMORY); 1765 } 1766} 1767 1768void __stdcall glEnable(GLenum cap) 1769{ 1770 EVENT("(GLenum cap = 0x%X)", cap); 1771 1772 try 1773 { 1774 gl::Context *context = gl::getNonLostContext(); 1775 1776 if (context) 1777 { 1778 if (!ValidCap(context, cap)) 1779 { 1780 return gl::error(GL_INVALID_ENUM); 1781 } 1782 1783 context->setCap(cap, true); 1784 } 1785 } 1786 catch (...) 1787 { 1788 return gl::error(GL_OUT_OF_MEMORY); 1789 } 1790} 1791 1792void __stdcall glEnableVertexAttribArray(GLuint index) 1793{ 1794 EVENT("(GLuint index = %d)", index); 1795 1796 try 1797 { 1798 if (index >= gl::MAX_VERTEX_ATTRIBS) 1799 { 1800 return gl::error(GL_INVALID_VALUE); 1801 } 1802 1803 gl::Context *context = gl::getNonLostContext(); 1804 1805 if (context) 1806 { 1807 context->setEnableVertexAttribArray(index, true); 1808 } 1809 } 1810 catch (...) 1811 { 1812 return gl::error(GL_OUT_OF_MEMORY); 1813 } 1814} 1815 1816void __stdcall glEndQueryEXT(GLenum target) 1817{ 1818 EVENT("GLenum target = 0x%X)", target); 1819 1820 try 1821 { 1822 gl::Context *context = gl::getNonLostContext(); 1823 1824 if (context) 1825 { 1826 if (!ValidateEndQuery(context, target)) 1827 { 1828 return; 1829 } 1830 1831 context->endQuery(target); 1832 } 1833 } 1834 catch (...) 1835 { 1836 return gl::error(GL_OUT_OF_MEMORY); 1837 } 1838} 1839 1840void __stdcall glFinishFenceNV(GLuint fence) 1841{ 1842 EVENT("(GLuint fence = %d)", fence); 1843 1844 try 1845 { 1846 gl::Context *context = gl::getNonLostContext(); 1847 1848 if (context) 1849 { 1850 gl::FenceNV *fenceObject = context->getFenceNV(fence); 1851 1852 if (fenceObject == NULL) 1853 { 1854 return gl::error(GL_INVALID_OPERATION); 1855 } 1856 1857 if (fenceObject->isFence() != GL_TRUE) 1858 { 1859 return gl::error(GL_INVALID_OPERATION); 1860 } 1861 1862 fenceObject->finishFence(); 1863 } 1864 } 1865 catch (...) 1866 { 1867 return gl::error(GL_OUT_OF_MEMORY); 1868 } 1869} 1870 1871void __stdcall glFinish(void) 1872{ 1873 EVENT("()"); 1874 1875 try 1876 { 1877 gl::Context *context = gl::getNonLostContext(); 1878 1879 if (context) 1880 { 1881 context->sync(true); 1882 } 1883 } 1884 catch (...) 1885 { 1886 return gl::error(GL_OUT_OF_MEMORY); 1887 } 1888} 1889 1890void __stdcall glFlush(void) 1891{ 1892 EVENT("()"); 1893 1894 try 1895 { 1896 gl::Context *context = gl::getNonLostContext(); 1897 1898 if (context) 1899 { 1900 context->sync(false); 1901 } 1902 } 1903 catch (...) 1904 { 1905 return gl::error(GL_OUT_OF_MEMORY); 1906 } 1907} 1908 1909void __stdcall glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) 1910{ 1911 EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, " 1912 "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer); 1913 1914 try 1915 { 1916 if (!gl::ValidFramebufferTarget(target) || (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0)) 1917 { 1918 return gl::error(GL_INVALID_ENUM); 1919 } 1920 1921 gl::Context *context = gl::getNonLostContext(); 1922 1923 if (context) 1924 { 1925 if (!gl::ValidateFramebufferRenderbufferParameters(context, target, attachment, renderbuffertarget, renderbuffer)) 1926 { 1927 return; 1928 } 1929 1930 gl::Framebuffer *framebuffer = context->getTargetFramebuffer(target); 1931 ASSERT(framebuffer); 1932 1933 if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT) 1934 { 1935 unsigned int colorAttachment = (attachment - GL_COLOR_ATTACHMENT0_EXT); 1936 framebuffer->setColorbuffer(colorAttachment, GL_RENDERBUFFER, renderbuffer, 0, 0); 1937 } 1938 else 1939 { 1940 switch (attachment) 1941 { 1942 case GL_DEPTH_ATTACHMENT: 1943 framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer, 0, 0); 1944 break; 1945 case GL_STENCIL_ATTACHMENT: 1946 framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer, 0, 0); 1947 break; 1948 case GL_DEPTH_STENCIL_ATTACHMENT: 1949 framebuffer->setDepthStencilBuffer(GL_RENDERBUFFER, renderbuffer, 0, 0); 1950 break; 1951 default: 1952 UNREACHABLE(); 1953 break; 1954 } 1955 } 1956 } 1957 } 1958 catch (...) 1959 { 1960 return gl::error(GL_OUT_OF_MEMORY); 1961 } 1962} 1963 1964void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) 1965{ 1966 EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, " 1967 "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level); 1968 1969 try 1970 { 1971 gl::Context *context = gl::getNonLostContext(); 1972 if (context) 1973 { 1974 if (context->getClientVersion() < 3 && 1975 !ValidateES2FramebufferTextureParameters(context, target, attachment, textarget, texture, level)) 1976 { 1977 return; 1978 } 1979 1980 if (context->getClientVersion() >= 3 && 1981 !ValidateES3FramebufferTextureParameters(context, target, attachment, textarget, texture, level, 0, false)) 1982 { 1983 return; 1984 } 1985 1986 if (texture == 0) 1987 { 1988 textarget = GL_NONE; 1989 } 1990 1991 gl::Framebuffer *framebuffer = context->getTargetFramebuffer(target); 1992 1993 if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT) 1994 { 1995 const unsigned int colorAttachment = (attachment - GL_COLOR_ATTACHMENT0_EXT); 1996 framebuffer->setColorbuffer(colorAttachment, textarget, texture, level, 0); 1997 } 1998 else 1999 { 2000 switch (attachment) 2001 { 2002 case GL_DEPTH_ATTACHMENT: framebuffer->setDepthbuffer(textarget, texture, level, 0); break; 2003 case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture, level, 0); break; 2004 case GL_DEPTH_STENCIL_ATTACHMENT: framebuffer->setDepthStencilBuffer(textarget, texture, level, 0); break; 2005 } 2006 } 2007 } 2008 } 2009 catch (...) 2010 { 2011 return gl::error(GL_OUT_OF_MEMORY); 2012 } 2013} 2014 2015void __stdcall glFrontFace(GLenum mode) 2016{ 2017 EVENT("(GLenum mode = 0x%X)", mode); 2018 2019 try 2020 { 2021 switch (mode) 2022 { 2023 case GL_CW: 2024 case GL_CCW: 2025 { 2026 gl::Context *context = gl::getNonLostContext(); 2027 2028 if (context) 2029 { 2030 context->setFrontFace(mode); 2031 } 2032 } 2033 break; 2034 default: 2035 return gl::error(GL_INVALID_ENUM); 2036 } 2037 } 2038 catch (...) 2039 { 2040 return gl::error(GL_OUT_OF_MEMORY); 2041 } 2042} 2043 2044void __stdcall glGenBuffers(GLsizei n, GLuint* buffers) 2045{ 2046 EVENT("(GLsizei n = %d, GLuint* buffers = 0x%0.8p)", n, buffers); 2047 2048 try 2049 { 2050 if (n < 0) 2051 { 2052 return gl::error(GL_INVALID_VALUE); 2053 } 2054 2055 gl::Context *context = gl::getNonLostContext(); 2056 2057 if (context) 2058 { 2059 for (int i = 0; i < n; i++) 2060 { 2061 buffers[i] = context->createBuffer(); 2062 } 2063 } 2064 } 2065 catch (...) 2066 { 2067 return gl::error(GL_OUT_OF_MEMORY); 2068 } 2069} 2070 2071void __stdcall glGenerateMipmap(GLenum target) 2072{ 2073 EVENT("(GLenum target = 0x%X)", target); 2074 2075 try 2076 { 2077 gl::Context *context = gl::getNonLostContext(); 2078 2079 if (context) 2080 { 2081 if (!ValidTextureTarget(context, target)) 2082 { 2083 return gl::error(GL_INVALID_ENUM); 2084 } 2085 2086 gl::Texture *texture = context->getTargetTexture(target); 2087 2088 if (texture == NULL) 2089 { 2090 return gl::error(GL_INVALID_OPERATION); 2091 } 2092 2093 GLenum internalFormat = texture->getBaseLevelInternalFormat(); 2094 2095 // Internally, all texture formats are sized so checking if the format 2096 // is color renderable and filterable will not fail. 2097 2098 bool validRenderable = (gl::IsColorRenderingSupported(internalFormat, context) || 2099 gl::IsSizedInternalFormat(internalFormat, context->getClientVersion())); 2100 2101 if (gl::IsDepthRenderingSupported(internalFormat, context) || 2102 gl::IsFormatCompressed(internalFormat, context->getClientVersion()) || 2103 !gl::IsTextureFilteringSupported(internalFormat, context) || 2104 !validRenderable) 2105 { 2106 return gl::error(GL_INVALID_OPERATION); 2107 } 2108 2109 // Non-power of 2 ES2 check 2110 if (!context->supportsNonPower2Texture() && (!gl::isPow2(texture->getBaseLevelWidth()) || !gl::isPow2(texture->getBaseLevelHeight()))) 2111 { 2112 ASSERT(context->getClientVersion() <= 2 && (target == GL_TEXTURE_2D || target == GL_TEXTURE_CUBE_MAP)); 2113 return gl::error(GL_INVALID_OPERATION); 2114 } 2115 2116 // Cube completeness check 2117 if (target == GL_TEXTURE_CUBE_MAP) 2118 { 2119 gl::TextureCubeMap *textureCube = static_cast<gl::TextureCubeMap *>(texture); 2120 if (!textureCube->isCubeComplete()) 2121 { 2122 return gl::error(GL_INVALID_OPERATION); 2123 } 2124 } 2125 2126 texture->generateMipmaps(); 2127 } 2128 } 2129 catch (...) 2130 { 2131 return gl::error(GL_OUT_OF_MEMORY); 2132 } 2133} 2134 2135void __stdcall glGenFencesNV(GLsizei n, GLuint* fences) 2136{ 2137 EVENT("(GLsizei n = %d, GLuint* fences = 0x%0.8p)", n, fences); 2138 2139 try 2140 { 2141 if (n < 0) 2142 { 2143 return gl::error(GL_INVALID_VALUE); 2144 } 2145 2146 gl::Context *context = gl::getNonLostContext(); 2147 2148 if (context) 2149 { 2150 for (int i = 0; i < n; i++) 2151 { 2152 fences[i] = context->createFenceNV(); 2153 } 2154 } 2155 } 2156 catch (...) 2157 { 2158 return gl::error(GL_OUT_OF_MEMORY); 2159 } 2160} 2161 2162void __stdcall glGenFramebuffers(GLsizei n, GLuint* framebuffers) 2163{ 2164 EVENT("(GLsizei n = %d, GLuint* framebuffers = 0x%0.8p)", n, framebuffers); 2165 2166 try 2167 { 2168 if (n < 0) 2169 { 2170 return gl::error(GL_INVALID_VALUE); 2171 } 2172 2173 gl::Context *context = gl::getNonLostContext(); 2174 2175 if (context) 2176 { 2177 for (int i = 0; i < n; i++) 2178 { 2179 framebuffers[i] = context->createFramebuffer(); 2180 } 2181 } 2182 } 2183 catch (...) 2184 { 2185 return gl::error(GL_OUT_OF_MEMORY); 2186 } 2187} 2188 2189void __stdcall glGenQueriesEXT(GLsizei n, GLuint* ids) 2190{ 2191 EVENT("(GLsizei n = %d, GLuint* ids = 0x%0.8p)", n, ids); 2192 2193 try 2194 { 2195 gl::Context *context = gl::getNonLostContext(); 2196 2197 if (context) 2198 { 2199 if (n < 0) 2200 { 2201 return gl::error(GL_INVALID_VALUE); 2202 } 2203 2204 for (GLsizei i = 0; i < n; i++) 2205 { 2206 ids[i] = context->createQuery(); 2207 } 2208 } 2209 } 2210 catch (...) 2211 { 2212 return gl::error(GL_OUT_OF_MEMORY); 2213 } 2214} 2215 2216void __stdcall glGenRenderbuffers(GLsizei n, GLuint* renderbuffers) 2217{ 2218 EVENT("(GLsizei n = %d, GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers); 2219 2220 try 2221 { 2222 if (n < 0) 2223 { 2224 return gl::error(GL_INVALID_VALUE); 2225 } 2226 2227 gl::Context *context = gl::getNonLostContext(); 2228 2229 if (context) 2230 { 2231 for (int i = 0; i < n; i++) 2232 { 2233 renderbuffers[i] = context->createRenderbuffer(); 2234 } 2235 } 2236 } 2237 catch (...) 2238 { 2239 return gl::error(GL_OUT_OF_MEMORY); 2240 } 2241} 2242 2243void __stdcall glGenTextures(GLsizei n, GLuint* textures) 2244{ 2245 EVENT("(GLsizei n = %d, GLuint* textures = 0x%0.8p)", n, textures); 2246 2247 try 2248 { 2249 if (n < 0) 2250 { 2251 return gl::error(GL_INVALID_VALUE); 2252 } 2253 2254 gl::Context *context = gl::getNonLostContext(); 2255 2256 if (context) 2257 { 2258 for (int i = 0; i < n; i++) 2259 { 2260 textures[i] = context->createTexture(); 2261 } 2262 } 2263 } 2264 catch (...) 2265 { 2266 return gl::error(GL_OUT_OF_MEMORY); 2267 } 2268} 2269 2270void __stdcall glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) 2271{ 2272 EVENT("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei *length = 0x%0.8p, " 2273 "GLint *size = 0x%0.8p, GLenum *type = %0.8p, GLchar *name = %0.8p)", 2274 program, index, bufsize, length, size, type, name); 2275 2276 try 2277 { 2278 if (bufsize < 0) 2279 { 2280 return gl::error(GL_INVALID_VALUE); 2281 } 2282 2283 gl::Context *context = gl::getNonLostContext(); 2284 2285 if (context) 2286 { 2287 gl::Program *programObject = context->getProgram(program); 2288 2289 if (!programObject) 2290 { 2291 if (context->getShader(program)) 2292 { 2293 return gl::error(GL_INVALID_OPERATION); 2294 } 2295 else 2296 { 2297 return gl::error(GL_INVALID_VALUE); 2298 } 2299 } 2300 2301 if (index >= (GLuint)programObject->getActiveAttributeCount()) 2302 { 2303 return gl::error(GL_INVALID_VALUE); 2304 } 2305 2306 programObject->getActiveAttribute(index, bufsize, length, size, type, name); 2307 } 2308 } 2309 catch (...) 2310 { 2311 return gl::error(GL_OUT_OF_MEMORY); 2312 } 2313} 2314 2315void __stdcall glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name) 2316{ 2317 EVENT("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, " 2318 "GLsizei* length = 0x%0.8p, GLint* size = 0x%0.8p, GLenum* type = 0x%0.8p, GLchar* name = 0x%0.8p)", 2319 program, index, bufsize, length, size, type, name); 2320 2321 try 2322 { 2323 if (bufsize < 0) 2324 { 2325 return gl::error(GL_INVALID_VALUE); 2326 } 2327 2328 gl::Context *context = gl::getNonLostContext(); 2329 2330 if (context) 2331 { 2332 gl::Program *programObject = context->getProgram(program); 2333 2334 if (!programObject) 2335 { 2336 if (context->getShader(program)) 2337 { 2338 return gl::error(GL_INVALID_OPERATION); 2339 } 2340 else 2341 { 2342 return gl::error(GL_INVALID_VALUE); 2343 } 2344 } 2345 2346 if (index >= (GLuint)programObject->getActiveUniformCount()) 2347 { 2348 return gl::error(GL_INVALID_VALUE); 2349 } 2350 2351 programObject->getActiveUniform(index, bufsize, length, size, type, name); 2352 } 2353 } 2354 catch (...) 2355 { 2356 return gl::error(GL_OUT_OF_MEMORY); 2357 } 2358} 2359 2360void __stdcall glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders) 2361{ 2362 EVENT("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = 0x%0.8p, GLuint* shaders = 0x%0.8p)", 2363 program, maxcount, count, shaders); 2364 2365 try 2366 { 2367 if (maxcount < 0) 2368 { 2369 return gl::error(GL_INVALID_VALUE); 2370 } 2371 2372 gl::Context *context = gl::getNonLostContext(); 2373 2374 if (context) 2375 { 2376 gl::Program *programObject = context->getProgram(program); 2377 2378 if (!programObject) 2379 { 2380 if (context->getShader(program)) 2381 { 2382 return gl::error(GL_INVALID_OPERATION); 2383 } 2384 else 2385 { 2386 return gl::error(GL_INVALID_VALUE); 2387 } 2388 } 2389 2390 return programObject->getAttachedShaders(maxcount, count, shaders); 2391 } 2392 } 2393 catch (...) 2394 { 2395 return gl::error(GL_OUT_OF_MEMORY); 2396 } 2397} 2398 2399int __stdcall glGetAttribLocation(GLuint program, const GLchar* name) 2400{ 2401 EVENT("(GLuint program = %d, const GLchar* name = %s)", program, name); 2402 2403 try 2404 { 2405 gl::Context *context = gl::getNonLostContext(); 2406 2407 if (context) 2408 { 2409 2410 gl::Program *programObject = context->getProgram(program); 2411 2412 if (!programObject) 2413 { 2414 if (context->getShader(program)) 2415 { 2416 return gl::error(GL_INVALID_OPERATION, -1); 2417 } 2418 else 2419 { 2420 return gl::error(GL_INVALID_VALUE, -1); 2421 } 2422 } 2423 2424 gl::ProgramBinary *programBinary = programObject->getProgramBinary(); 2425 if (!programObject->isLinked() || !programBinary) 2426 { 2427 return gl::error(GL_INVALID_OPERATION, -1); 2428 } 2429 2430 return programBinary->getAttributeLocation(name); 2431 } 2432 } 2433 catch (...) 2434 { 2435 return gl::error(GL_OUT_OF_MEMORY, -1); 2436 } 2437 2438 return -1; 2439} 2440 2441void __stdcall glGetBooleanv(GLenum pname, GLboolean* params) 2442{ 2443 EVENT("(GLenum pname = 0x%X, GLboolean* params = 0x%0.8p)", pname, params); 2444 2445 try 2446 { 2447 gl::Context *context = gl::getNonLostContext(); 2448 2449 if (context) 2450 { 2451 GLenum nativeType; 2452 unsigned int numParams = 0; 2453 if (!ValidateStateQuery(context, pname, &nativeType, &numParams)) 2454 { 2455 return; 2456 } 2457 2458 if (nativeType == GL_BOOL) 2459 { 2460 context->getBooleanv(pname, params); 2461 } 2462 else 2463 { 2464 CastStateValues(context, nativeType, pname, numParams, params); 2465 } 2466 } 2467 } 2468 catch (...) 2469 { 2470 return gl::error(GL_OUT_OF_MEMORY); 2471 } 2472} 2473 2474void __stdcall glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params) 2475{ 2476 EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params); 2477 2478 try 2479 { 2480 gl::Context *context = gl::getNonLostContext(); 2481 2482 if (context) 2483 { 2484 if (!gl::ValidBufferTarget(context, target)) 2485 { 2486 return gl::error(GL_INVALID_ENUM); 2487 } 2488 2489 if (!gl::ValidBufferParameter(context, pname)) 2490 { 2491 return gl::error(GL_INVALID_ENUM); 2492 } 2493 2494 gl::Buffer *buffer = context->getTargetBuffer(target); 2495 2496 if (!buffer) 2497 { 2498 // A null buffer means that "0" is bound to the requested buffer target 2499 return gl::error(GL_INVALID_OPERATION); 2500 } 2501 2502 switch (pname) 2503 { 2504 case GL_BUFFER_USAGE: 2505 *params = static_cast<GLint>(buffer->usage()); 2506 break; 2507 case GL_BUFFER_SIZE: 2508 *params = gl::clampCast<GLint>(buffer->size()); 2509 break; 2510 case GL_BUFFER_ACCESS_FLAGS: 2511 *params = buffer->accessFlags(); 2512 break; 2513 case GL_BUFFER_MAPPED: 2514 *params = static_cast<GLint>(buffer->mapped()); 2515 break; 2516 case GL_BUFFER_MAP_OFFSET: 2517 *params = gl::clampCast<GLint>(buffer->mapOffset()); 2518 break; 2519 case GL_BUFFER_MAP_LENGTH: 2520 *params = gl::clampCast<GLint>(buffer->mapLength()); 2521 break; 2522 default: UNREACHABLE(); break; 2523 } 2524 } 2525 } 2526 catch (...) 2527 { 2528 return gl::error(GL_OUT_OF_MEMORY); 2529 } 2530} 2531 2532GLenum __stdcall glGetError(void) 2533{ 2534 EVENT("()"); 2535 2536 gl::Context *context = gl::getContext(); 2537 2538 if (context) 2539 { 2540 return context->getError(); 2541 } 2542 2543 return GL_NO_ERROR; 2544} 2545 2546void __stdcall glGetFenceivNV(GLuint fence, GLenum pname, GLint *params) 2547{ 2548 EVENT("(GLuint fence = %d, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", fence, pname, params); 2549 2550 try 2551 { 2552 2553 gl::Context *context = gl::getNonLostContext(); 2554 2555 if (context) 2556 { 2557 gl::FenceNV *fenceObject = context->getFenceNV(fence); 2558 2559 if (fenceObject == NULL) 2560 { 2561 return gl::error(GL_INVALID_OPERATION); 2562 } 2563 2564 if (fenceObject->isFence() != GL_TRUE) 2565 { 2566 return gl::error(GL_INVALID_OPERATION); 2567 } 2568 2569 switch (pname) 2570 { 2571 case GL_FENCE_STATUS_NV: 2572 case GL_FENCE_CONDITION_NV: 2573 break; 2574 2575 default: return gl::error(GL_INVALID_ENUM); 2576 } 2577 2578 params[0] = fenceObject->getFencei(pname); 2579 } 2580 } 2581 catch (...) 2582 { 2583 return gl::error(GL_OUT_OF_MEMORY); 2584 } 2585} 2586 2587void __stdcall glGetFloatv(GLenum pname, GLfloat* params) 2588{ 2589 EVENT("(GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", pname, params); 2590 2591 try 2592 { 2593 gl::Context *context = gl::getNonLostContext(); 2594 2595 if (context) 2596 { 2597 GLenum nativeType; 2598 unsigned int numParams = 0; 2599 if (!ValidateStateQuery(context, pname, &nativeType, &numParams)) 2600 { 2601 return; 2602 } 2603 2604 if (nativeType == GL_FLOAT) 2605 { 2606 context->getFloatv(pname, params); 2607 } 2608 else 2609 { 2610 CastStateValues(context, nativeType, pname, numParams, params); 2611 } 2612 } 2613 } 2614 catch (...) 2615 { 2616 return gl::error(GL_OUT_OF_MEMORY); 2617 } 2618} 2619 2620void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params) 2621{ 2622 EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", 2623 target, attachment, pname, params); 2624 2625 try 2626 { 2627 gl::Context *context = gl::getNonLostContext(); 2628 2629 if (context) 2630 { 2631 if (!gl::ValidFramebufferTarget(target)) 2632 { 2633 return gl::error(GL_INVALID_ENUM); 2634 } 2635 2636 switch (pname) 2637 { 2638 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE: 2639 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: 2640 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL: 2641 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE: 2642 break; 2643 case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE: 2644 case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE: 2645 case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE: 2646 case GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE: 2647 case GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE: 2648 case GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE: 2649 case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE: 2650 case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING: 2651 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER: 2652 if (context->getClientVersion() >= 3) 2653 { 2654 break; 2655 } 2656 default: 2657 return gl::error(GL_INVALID_ENUM); 2658 } 2659 2660 // Determine if the attachment is a valid enum 2661 switch (attachment) 2662 { 2663 case GL_BACK: 2664 case GL_FRONT: 2665 case GL_DEPTH: 2666 case GL_STENCIL: 2667 case GL_DEPTH_STENCIL_ATTACHMENT: 2668 if (context->getClientVersion() < 3) 2669 { 2670 return gl::error(GL_INVALID_ENUM); 2671 } 2672 break; 2673 2674 case GL_DEPTH_ATTACHMENT: 2675 case GL_STENCIL_ATTACHMENT: 2676 break; 2677 2678 default: 2679 if (attachment < GL_COLOR_ATTACHMENT0_EXT || 2680 (attachment - GL_COLOR_ATTACHMENT0_EXT) >= context->getMaximumRenderTargets()) 2681 { 2682 return gl::error(GL_INVALID_ENUM); 2683 } 2684 break; 2685 } 2686 2687 GLuint framebufferHandle = context->getTargetFramebufferHandle(target); 2688 ASSERT(framebufferHandle != GL_INVALID_INDEX); 2689 gl::Framebuffer *framebuffer = context->getFramebuffer(framebufferHandle); 2690 2691 GLenum attachmentType; 2692 GLuint attachmentHandle; 2693 GLuint attachmentLevel; 2694 GLuint attachmentLayer; 2695 gl::FramebufferAttachment *attachmentObject; 2696 2697 if (framebufferHandle == 0) 2698 { 2699 if (context->getClientVersion() < 3) 2700 { 2701 return gl::error(GL_INVALID_OPERATION); 2702 } 2703 2704 switch (attachment) 2705 { 2706 case GL_BACK: 2707 attachmentType = framebuffer->getColorbufferType(0); 2708 attachmentHandle = framebuffer->getColorbufferHandle(0); 2709 attachmentLevel = framebuffer->getColorbufferMipLevel(0); 2710 attachmentLayer = framebuffer->getColorbufferLayer(0); 2711 attachmentObject = framebuffer->getColorbuffer(0); 2712 break; 2713 case GL_DEPTH: 2714 attachmentType = framebuffer->getDepthbufferType(); 2715 attachmentHandle = framebuffer->getDepthbufferHandle(); 2716 attachmentLevel = framebuffer->getDepthbufferMipLevel(); 2717 attachmentLayer = framebuffer->getDepthbufferLayer(); 2718 attachmentObject = framebuffer->getDepthbuffer(); 2719 break; 2720 case GL_STENCIL: 2721 attachmentType = framebuffer->getStencilbufferType(); 2722 attachmentHandle = framebuffer->getStencilbufferHandle(); 2723 attachmentLevel = framebuffer->getStencilbufferMipLevel(); 2724 attachmentLayer = framebuffer->getStencilbufferLayer(); 2725 attachmentObject = framebuffer->getStencilbuffer(); 2726 break; 2727 default: 2728 return gl::error(GL_INVALID_OPERATION); 2729 } 2730 } 2731 else 2732 { 2733 if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT) 2734 { 2735 const unsigned int colorAttachment = (attachment - GL_COLOR_ATTACHMENT0_EXT); 2736 attachmentType = framebuffer->getColorbufferType(colorAttachment); 2737 attachmentHandle = framebuffer->getColorbufferHandle(colorAttachment); 2738 attachmentLevel = framebuffer->getColorbufferMipLevel(colorAttachment); 2739 attachmentLayer = framebuffer->getColorbufferLayer(colorAttachment); 2740 attachmentObject = framebuffer->getColorbuffer(colorAttachment); 2741 } 2742 else 2743 { 2744 switch (attachment) 2745 { 2746 case GL_DEPTH_ATTACHMENT: 2747 attachmentType = framebuffer->getDepthbufferType(); 2748 attachmentHandle = framebuffer->getDepthbufferHandle(); 2749 attachmentLevel = framebuffer->getDepthbufferMipLevel(); 2750 attachmentLayer = framebuffer->getDepthbufferLayer(); 2751 attachmentObject = framebuffer->getDepthbuffer(); 2752 break; 2753 case GL_STENCIL_ATTACHMENT: 2754 attachmentType = framebuffer->getStencilbufferType(); 2755 attachmentHandle = framebuffer->getStencilbufferHandle(); 2756 attachmentLevel = framebuffer->getStencilbufferMipLevel(); 2757 attachmentLayer = framebuffer->getStencilbufferLayer(); 2758 attachmentObject = framebuffer->getStencilbuffer(); 2759 break; 2760 case GL_DEPTH_STENCIL_ATTACHMENT: 2761 if (framebuffer->getDepthbufferHandle() != framebuffer->getStencilbufferHandle()) 2762 { 2763 return gl::error(GL_INVALID_OPERATION); 2764 } 2765 attachmentType = framebuffer->getDepthStencilbufferType(); 2766 attachmentHandle = framebuffer->getDepthStencilbufferHandle(); 2767 attachmentLevel = framebuffer->getDepthStencilbufferMipLevel(); 2768 attachmentLayer = framebuffer->getDepthStencilbufferLayer(); 2769 attachmentObject = framebuffer->getDepthStencilBuffer(); 2770 break; 2771 default: 2772 return gl::error(GL_INVALID_OPERATION); 2773 } 2774 } 2775 } 2776 2777 GLenum attachmentObjectType; // Type category 2778 if (framebufferHandle == 0) 2779 { 2780 attachmentObjectType = GL_FRAMEBUFFER_DEFAULT; 2781 } 2782 else if (attachmentType == GL_NONE || attachmentType == GL_RENDERBUFFER) 2783 { 2784 attachmentObjectType = attachmentType; 2785 } 2786 else if (gl::IsInternalTextureTarget(attachmentType, context->getClientVersion())) 2787 { 2788 attachmentObjectType = GL_TEXTURE; 2789 } 2790 else 2791 { 2792 UNREACHABLE(); 2793 return; 2794 } 2795 2796 if (attachmentObjectType == GL_NONE) 2797 { 2798 // ES 2.0.25 spec pg 127 states that if the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 2799 // is NONE, then querying any other pname will generate INVALID_ENUM. 2800 2801 // ES 3.0.2 spec pg 235 states that if the attachment type is none, 2802 // GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME will return zero and be an 2803 // INVALID_OPERATION for all other pnames 2804 2805 switch (pname) 2806 { 2807 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE: 2808 *params = attachmentObjectType; 2809 break; 2810 2811 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: 2812 if (context->getClientVersion() < 3) 2813 { 2814 return gl::error(GL_INVALID_ENUM); 2815 } 2816 *params = 0; 2817 break; 2818 2819 default: 2820 if (context->getClientVersion() < 3) 2821 { 2822 return gl::error(GL_INVALID_ENUM); 2823 } 2824 else 2825 { 2826 gl::error(GL_INVALID_OPERATION); 2827 } 2828 } 2829 } 2830 else 2831 { 2832 ASSERT(attachmentObjectType == GL_RENDERBUFFER || attachmentObjectType == GL_TEXTURE || 2833 attachmentObjectType == GL_FRAMEBUFFER_DEFAULT); 2834 ASSERT(attachmentObject != NULL); 2835 2836 switch (pname) 2837 { 2838 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE: 2839 *params = attachmentObjectType; 2840 break; 2841 2842 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: 2843 if (attachmentObjectType != GL_RENDERBUFFER && attachmentObjectType != GL_TEXTURE) 2844 { 2845 return gl::error(GL_INVALID_ENUM); 2846 } 2847 *params = attachmentHandle; 2848 break; 2849 2850 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL: 2851 if (attachmentObjectType != GL_TEXTURE) 2852 { 2853 return gl::error(GL_INVALID_ENUM); 2854 } 2855 *params = attachmentLevel; 2856 break; 2857 2858 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE: 2859 if (attachmentObjectType != GL_TEXTURE) 2860 { 2861 return gl::error(GL_INVALID_ENUM); 2862 } 2863 *params = gl::IsCubemapTextureTarget(attachmentType) ? attachmentType : 0; 2864 break; 2865 2866 case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE: 2867 *params = attachmentObject->getRedSize(); 2868 break; 2869 2870 case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE: 2871 *params = attachmentObject->getGreenSize(); 2872 break; 2873 2874 case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE: 2875 *params = attachmentObject->getBlueSize(); 2876 break; 2877 2878 case GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE: 2879 *params = attachmentObject->getAlphaSize(); 2880 break; 2881 2882 case GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE: 2883 *params = attachmentObject->getDepthSize(); 2884 break; 2885 2886 case GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE: 2887 *params = attachmentObject->getStencilSize(); 2888 break; 2889 2890 case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE: 2891 if (attachment == GL_DEPTH_STENCIL) 2892 { 2893 gl::error(GL_INVALID_OPERATION); 2894 } 2895 *params = attachmentObject->getComponentType(); 2896 break; 2897 2898 case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING: 2899 *params = attachmentObject->getColorEncoding(); 2900 break; 2901 2902 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER: 2903 if (attachmentObjectType != GL_TEXTURE) 2904 { 2905 return gl::error(GL_INVALID_ENUM); 2906 } 2907 *params = attachmentLayer; 2908 break; 2909 2910 default: 2911 UNREACHABLE(); 2912 break; 2913 } 2914 } 2915 } 2916 } 2917 catch (...) 2918 { 2919 return gl::error(GL_OUT_OF_MEMORY); 2920 } 2921} 2922 2923GLenum __stdcall glGetGraphicsResetStatusEXT(void) 2924{ 2925 EVENT("()"); 2926 2927 try 2928 { 2929 gl::Context *context = gl::getContext(); 2930 2931 if (context) 2932 { 2933 return context->getResetStatus(); 2934 } 2935 2936 return GL_NO_ERROR; 2937 } 2938 catch (...) 2939 { 2940 return GL_OUT_OF_MEMORY; 2941 } 2942} 2943 2944void __stdcall glGetIntegerv(GLenum pname, GLint* params) 2945{ 2946 EVENT("(GLenum pname = 0x%X, GLint* params = 0x%0.8p)", pname, params); 2947 2948 try 2949 { 2950 gl::Context *context = gl::getNonLostContext(); 2951 2952 if (context) 2953 { 2954 GLenum nativeType; 2955 unsigned int numParams = 0; 2956 2957 if (!ValidateStateQuery(context, pname, &nativeType, &numParams)) 2958 { 2959 return; 2960 } 2961 2962 if (nativeType == GL_INT) 2963 { 2964 context->getIntegerv(pname, params); 2965 } 2966 else 2967 { 2968 CastStateValues(context, nativeType, pname, numParams, params); 2969 } 2970 } 2971 } 2972 catch (...) 2973 { 2974 return gl::error(GL_OUT_OF_MEMORY); 2975 } 2976} 2977 2978void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params) 2979{ 2980 EVENT("(GLuint program = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", program, pname, params); 2981 2982 try 2983 { 2984 gl::Context *context = gl::getNonLostContext(); 2985 2986 if (context) 2987 { 2988 gl::Program *programObject = context->getProgram(program); 2989 2990 if (!programObject) 2991 { 2992 return gl::error(GL_INVALID_VALUE); 2993 } 2994 2995 if (context->getClientVersion() < 3) 2996 { 2997 switch (pname) 2998 { 2999 case GL_ACTIVE_UNIFORM_BLOCKS: 3000 case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH: 3001 case GL_TRANSFORM_FEEDBACK_BUFFER_MODE: 3002 case GL_TRANSFORM_FEEDBACK_VARYINGS: 3003 case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH: 3004 return gl::error(GL_INVALID_ENUM); 3005 } 3006 } 3007 3008 switch (pname) 3009 { 3010 case GL_DELETE_STATUS: 3011 *params = programObject->isFlaggedForDeletion(); 3012 return; 3013 case GL_LINK_STATUS: 3014 *params = programObject->isLinked(); 3015 return; 3016 case GL_VALIDATE_STATUS: 3017 *params = programObject->isValidated(); 3018 return; 3019 case GL_INFO_LOG_LENGTH: 3020 *params = programObject->getInfoLogLength(); 3021 return; 3022 case GL_ATTACHED_SHADERS: 3023 *params = programObject->getAttachedShadersCount(); 3024 return; 3025 case GL_ACTIVE_ATTRIBUTES: 3026 *params = programObject->getActiveAttributeCount(); 3027 return; 3028 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH: 3029 *params = programObject->getActiveAttributeMaxLength(); 3030 return; 3031 case GL_ACTIVE_UNIFORMS: 3032 *params = programObject->getActiveUniformCount(); 3033 return; 3034 case GL_ACTIVE_UNIFORM_MAX_LENGTH: 3035 *params = programObject->getActiveUniformMaxLength(); 3036 return; 3037 case GL_PROGRAM_BINARY_LENGTH_OES: 3038 *params = programObject->getProgramBinaryLength(); 3039 return; 3040 case GL_ACTIVE_UNIFORM_BLOCKS: 3041 *params = programObject->getActiveUniformBlockCount(); 3042 return; 3043 case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH: 3044 *params = programObject->getActiveUniformBlockMaxLength(); 3045 break; 3046 case GL_TRANSFORM_FEEDBACK_BUFFER_MODE: 3047 *params = programObject->getTransformFeedbackBufferMode(); 3048 break; 3049 case GL_TRANSFORM_FEEDBACK_VARYINGS: 3050 *params = programObject->getTransformFeedbackVaryingCount(); 3051 break; 3052 case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH: 3053 *params = programObject->getTransformFeedbackVaryingMaxLength(); 3054 break; 3055 default: 3056 return gl::error(GL_INVALID_ENUM); 3057 } 3058 } 3059 } 3060 catch (...) 3061 { 3062 return gl::error(GL_OUT_OF_MEMORY); 3063 } 3064} 3065 3066void __stdcall glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog) 3067{ 3068 EVENT("(GLuint program = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* infolog = 0x%0.8p)", 3069 program, bufsize, length, infolog); 3070 3071 try 3072 { 3073 if (bufsize < 0) 3074 { 3075 return gl::error(GL_INVALID_VALUE); 3076 } 3077 3078 gl::Context *context = gl::getNonLostContext(); 3079 3080 if (context) 3081 { 3082 gl::Program *programObject = context->getProgram(program); 3083 3084 if (!programObject) 3085 { 3086 return gl::error(GL_INVALID_VALUE); 3087 } 3088 3089 programObject->getInfoLog(bufsize, length, infolog); 3090 } 3091 } 3092 catch (...) 3093 { 3094 return gl::error(GL_OUT_OF_MEMORY); 3095 } 3096} 3097 3098void __stdcall glGetQueryivEXT(GLenum target, GLenum pname, GLint *params) 3099{ 3100 EVENT("GLenum target = 0x%X, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", target, pname, params); 3101 3102 try 3103 { 3104 gl::Context *context = gl::getNonLostContext(); 3105 3106 if (context) 3107 { 3108 if (!ValidQueryType(context, target)) 3109 { 3110 return gl::error(GL_INVALID_ENUM); 3111 } 3112 3113 switch (pname) 3114 { 3115 case GL_CURRENT_QUERY_EXT: 3116 params[0] = context->getActiveQueryId(target); 3117 break; 3118 3119 default: 3120 return gl::error(GL_INVALID_ENUM); 3121 } 3122 } 3123 } 3124 catch (...) 3125 { 3126 return gl::error(GL_OUT_OF_MEMORY); 3127 } 3128} 3129 3130void __stdcall glGetQueryObjectuivEXT(GLuint id, GLenum pname, GLuint *params) 3131{ 3132 EVENT("(GLuint id = %d, GLenum pname = 0x%X, GLuint *params = 0x%0.8p)", id, pname, params); 3133 3134 try 3135 { 3136 gl::Context *context = gl::getNonLostContext(); 3137 3138 if (context) 3139 { 3140 gl::Query *queryObject = context->getQuery(id, false, GL_NONE); 3141 3142 if (!queryObject) 3143 { 3144 return gl::error(GL_INVALID_OPERATION); 3145 } 3146 3147 if (context->getActiveQueryId(queryObject->getType()) == id) 3148 { 3149 return gl::error(GL_INVALID_OPERATION); 3150 } 3151 3152 switch(pname) 3153 { 3154 case GL_QUERY_RESULT_EXT: 3155 params[0] = queryObject->getResult(); 3156 break; 3157 case GL_QUERY_RESULT_AVAILABLE_EXT: 3158 params[0] = queryObject->isResultAvailable(); 3159 break; 3160 default: 3161 return gl::error(GL_INVALID_ENUM); 3162 } 3163 } 3164 } 3165 catch (...) 3166 { 3167 return gl::error(GL_OUT_OF_MEMORY); 3168 } 3169} 3170 3171void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params) 3172{ 3173 EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params); 3174 3175 try 3176 { 3177 gl::Context *context = gl::getNonLostContext(); 3178 3179 if (context) 3180 { 3181 if (target != GL_RENDERBUFFER) 3182 { 3183 return gl::error(GL_INVALID_ENUM); 3184 } 3185 3186 if (context->getRenderbufferHandle() == 0) 3187 { 3188 return gl::error(GL_INVALID_OPERATION); 3189 } 3190 3191 gl::FramebufferAttachment *attachment = context->getRenderbuffer(context->getRenderbufferHandle()); 3192 3193 switch (pname) 3194 { 3195 case GL_RENDERBUFFER_WIDTH: *params = attachment->getWidth(); break; 3196 case GL_RENDERBUFFER_HEIGHT: *params = attachment->getHeight(); break; 3197 case GL_RENDERBUFFER_INTERNAL_FORMAT: *params = attachment->getInternalFormat(); break; 3198 case GL_RENDERBUFFER_RED_SIZE: *params = attachment->getRedSize(); break; 3199 case GL_RENDERBUFFER_GREEN_SIZE: *params = attachment->getGreenSize(); break; 3200 case GL_RENDERBUFFER_BLUE_SIZE: *params = attachment->getBlueSize(); break; 3201 case GL_RENDERBUFFER_ALPHA_SIZE: *params = attachment->getAlphaSize(); break; 3202 case GL_RENDERBUFFER_DEPTH_SIZE: *params = attachment->getDepthSize(); break; 3203 case GL_RENDERBUFFER_STENCIL_SIZE: *params = attachment->getStencilSize(); break; 3204 case GL_RENDERBUFFER_SAMPLES_ANGLE: 3205 if (context->getMaxSupportedSamples() != 0) 3206 { 3207 *params = attachment->getSamples(); 3208 } 3209 else 3210 { 3211 return gl::error(GL_INVALID_ENUM); 3212 } 3213 break; 3214 default: 3215 return gl::error(GL_INVALID_ENUM); 3216 } 3217 } 3218 } 3219 catch (...) 3220 { 3221 return gl::error(GL_OUT_OF_MEMORY); 3222 } 3223} 3224 3225void __stdcall glGetShaderiv(GLuint shader, GLenum pname, GLint* params) 3226{ 3227 EVENT("(GLuint shader = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", shader, pname, params); 3228 3229 try 3230 { 3231 gl::Context *context = gl::getNonLostContext(); 3232 3233 if (context) 3234 { 3235 gl::Shader *shaderObject = context->getShader(shader); 3236 3237 if (!shaderObject) 3238 { 3239 return gl::error(GL_INVALID_VALUE); 3240 } 3241 3242 switch (pname) 3243 { 3244 case GL_SHADER_TYPE: 3245 *params = shaderObject->getType(); 3246 return; 3247 case GL_DELETE_STATUS: 3248 *params = shaderObject->isFlaggedForDeletion(); 3249 return; 3250 case GL_COMPILE_STATUS: 3251 *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE; 3252 return; 3253 case GL_INFO_LOG_LENGTH: 3254 *params = shaderObject->getInfoLogLength(); 3255 return; 3256 case GL_SHADER_SOURCE_LENGTH: 3257 *params = shaderObject->getSourceLength(); 3258 return; 3259 case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE: 3260 *params = shaderObject->getTranslatedSourceLength(); 3261 return; 3262 default: 3263 return gl::error(GL_INVALID_ENUM); 3264 } 3265 } 3266 } 3267 catch (...) 3268 { 3269 return gl::error(GL_OUT_OF_MEMORY); 3270 } 3271} 3272 3273void __stdcall glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog) 3274{ 3275 EVENT("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* infolog = 0x%0.8p)", 3276 shader, bufsize, length, infolog); 3277 3278 try 3279 { 3280 if (bufsize < 0) 3281 { 3282 return gl::error(GL_INVALID_VALUE); 3283 } 3284 3285 gl::Context *context = gl::getNonLostContext(); 3286 3287 if (context) 3288 { 3289 gl::Shader *shaderObject = context->getShader(shader); 3290 3291 if (!shaderObject) 3292 { 3293 return gl::error(GL_INVALID_VALUE); 3294 } 3295 3296 shaderObject->getInfoLog(bufsize, length, infolog); 3297 } 3298 } 3299 catch (...) 3300 { 3301 return gl::error(GL_OUT_OF_MEMORY); 3302 } 3303} 3304 3305void __stdcall glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) 3306{ 3307 EVENT("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = 0x%0.8p, GLint* precision = 0x%0.8p)", 3308 shadertype, precisiontype, range, precision); 3309 3310 try 3311 { 3312 switch (shadertype) 3313 { 3314 case GL_VERTEX_SHADER: 3315 case GL_FRAGMENT_SHADER: 3316 break; 3317 default: 3318 return gl::error(GL_INVALID_ENUM); 3319 } 3320 3321 switch (precisiontype) 3322 { 3323 case GL_LOW_FLOAT: 3324 case GL_MEDIUM_FLOAT: 3325 case GL_HIGH_FLOAT: 3326 // Assume IEEE 754 precision 3327 range[0] = 127; 3328 range[1] = 127; 3329 *precision = 23; 3330 break; 3331 case GL_LOW_INT: 3332 case GL_MEDIUM_INT: 3333 case GL_HIGH_INT: 3334 // Some (most) hardware only supports single-precision floating-point numbers, 3335 // which can accurately represent integers up to +/-16777216 3336 range[0] = 24; 3337 range[1] = 24; 3338 *precision = 0; 3339 break; 3340 default: 3341 return gl::error(GL_INVALID_ENUM); 3342 } 3343 } 3344 catch (...) 3345 { 3346 return gl::error(GL_OUT_OF_MEMORY); 3347 } 3348} 3349 3350void __stdcall glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source) 3351{ 3352 EVENT("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* source = 0x%0.8p)", 3353 shader, bufsize, length, source); 3354 3355 try 3356 { 3357 if (bufsize < 0) 3358 { 3359 return gl::error(GL_INVALID_VALUE); 3360 } 3361 3362 gl::Context *context = gl::getNonLostContext(); 3363 3364 if (context) 3365 { 3366 gl::Shader *shaderObject = context->getShader(shader); 3367 3368 if (!shaderObject) 3369 { 3370 return gl::error(GL_INVALID_OPERATION); 3371 } 3372 3373 shaderObject->getSource(bufsize, length, source); 3374 } 3375 } 3376 catch (...) 3377 { 3378 return gl::error(GL_OUT_OF_MEMORY); 3379 } 3380} 3381 3382void __stdcall glGetTranslatedShaderSourceANGLE(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source) 3383{ 3384 EVENT("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* source = 0x%0.8p)", 3385 shader, bufsize, length, source); 3386 3387 try 3388 { 3389 if (bufsize < 0) 3390 { 3391 return gl::error(GL_INVALID_VALUE); 3392 } 3393 3394 gl::Context *context = gl::getNonLostContext(); 3395 3396 if (context) 3397 { 3398 gl::Shader *shaderObject = context->getShader(shader); 3399 3400 if (!shaderObject) 3401 { 3402 return gl::error(GL_INVALID_OPERATION); 3403 } 3404 3405 shaderObject->getTranslatedSource(bufsize, length, source); 3406 } 3407 } 3408 catch (...) 3409 { 3410 return gl::error(GL_OUT_OF_MEMORY); 3411 } 3412} 3413 3414const GLubyte* __stdcall glGetString(GLenum name) 3415{ 3416 EVENT("(GLenum name = 0x%X)", name); 3417 3418 try 3419 { 3420 gl::Context *context = gl::getNonLostContext(); 3421 3422 switch (name) 3423 { 3424 case GL_VENDOR: 3425 return (GLubyte*)"Google Inc."; 3426 case GL_RENDERER: 3427 return (GLubyte*)((context != NULL) ? context->getRendererString() : "ANGLE"); 3428 case GL_VERSION: 3429 if (context->getClientVersion() == 2) 3430 { 3431 return (GLubyte*)"OpenGL ES 2.0 (ANGLE " ANGLE_VERSION_STRING ")"; 3432 } 3433 else 3434 { 3435 return (GLubyte*)"OpenGL ES 3.0 (ANGLE " ANGLE_VERSION_STRING ")"; 3436 } 3437 case GL_SHADING_LANGUAGE_VERSION: 3438 if (context->getClientVersion() == 2) 3439 { 3440 return (GLubyte*)"OpenGL ES GLSL ES 1.00 (ANGLE " ANGLE_VERSION_STRING ")"; 3441 } 3442 else 3443 { 3444 return (GLubyte*)"OpenGL ES GLSL ES 3.00 (ANGLE " ANGLE_VERSION_STRING ")"; 3445 } 3446 case GL_EXTENSIONS: 3447 return (GLubyte*)((context != NULL) ? context->getCombinedExtensionsString() : ""); 3448 default: 3449 return gl::error(GL_INVALID_ENUM, (GLubyte*)NULL); 3450 } 3451 } 3452 catch (...) 3453 { 3454 return gl::error(GL_OUT_OF_MEMORY, (GLubyte*)NULL); 3455 } 3456} 3457 3458void __stdcall glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params) 3459{ 3460 EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", target, pname, params); 3461 3462 try 3463 { 3464 gl::Context *context = gl::getNonLostContext(); 3465 3466 if (context) 3467 { 3468 gl::Texture *texture = context->getTargetTexture(target); 3469 3470 if (!texture) 3471 { 3472 return gl::error(GL_INVALID_ENUM); 3473 } 3474 3475 switch (pname) 3476 { 3477 case GL_TEXTURE_MAG_FILTER: 3478 *params = (GLfloat)texture->getMagFilter(); 3479 break; 3480 case GL_TEXTURE_MIN_FILTER: 3481 *params = (GLfloat)texture->getMinFilter(); 3482 break; 3483 case GL_TEXTURE_WRAP_S: 3484 *params = (GLfloat)texture->getWrapS(); 3485 break; 3486 case GL_TEXTURE_WRAP_T: 3487 *params = (GLfloat)texture->getWrapT(); 3488 break; 3489 case GL_TEXTURE_WRAP_R: 3490 if (context->getClientVersion() < 3) 3491 { 3492 return gl::error(GL_INVALID_ENUM); 3493 } 3494 *params = (GLfloat)texture->getWrapR(); 3495 break; 3496 case GL_TEXTURE_IMMUTABLE_FORMAT: 3497 // Exposed to ES2.0 through EXT_texture_storage, no client version validation. 3498 *params = (GLfloat)(texture->isImmutable() ? GL_TRUE : GL_FALSE); 3499 break; 3500 case GL_TEXTURE_IMMUTABLE_LEVELS: 3501 if (context->getClientVersion() < 3) 3502 { 3503 return gl::error(GL_INVALID_ENUM); 3504 } 3505 *params = (GLfloat)texture->immutableLevelCount(); 3506 break; 3507 case GL_TEXTURE_USAGE_ANGLE: 3508 *params = (GLfloat)texture->getUsage(); 3509 break; 3510 case GL_TEXTURE_MAX_ANISOTROPY_EXT: 3511 if (!context->supportsTextureFilterAnisotropy()) 3512 { 3513 return gl::error(GL_INVALID_ENUM); 3514 } 3515 *params = (GLfloat)texture->getMaxAnisotropy(); 3516 break; 3517 case GL_TEXTURE_SWIZZLE_R: 3518 if (context->getClientVersion() < 3) 3519 { 3520 return gl::error(GL_INVALID_ENUM); 3521 } 3522 *params = (GLfloat)texture->getSwizzleRed(); 3523 break; 3524 case GL_TEXTURE_SWIZZLE_G: 3525 if (context->getClientVersion() < 3) 3526 { 3527 return gl::error(GL_INVALID_ENUM); 3528 } 3529 *params = (GLfloat)texture->getSwizzleGreen(); 3530 break; 3531 case GL_TEXTURE_SWIZZLE_B: 3532 if (context->getClientVersion() < 3) 3533 { 3534 return gl::error(GL_INVALID_ENUM); 3535 } 3536 *params = (GLfloat)texture->getSwizzleBlue(); 3537 break; 3538 case GL_TEXTURE_SWIZZLE_A: 3539 if (context->getClientVersion() < 3) 3540 { 3541 return gl::error(GL_INVALID_ENUM); 3542 } 3543 *params = (GLfloat)texture->getSwizzleAlpha(); 3544 break; 3545 case GL_TEXTURE_BASE_LEVEL: 3546 if (context->getClientVersion() < 3) 3547 { 3548 return gl::error(GL_INVALID_ENUM); 3549 } 3550 *params = (GLfloat)texture->getBaseLevel(); 3551 break; 3552 case GL_TEXTURE_MAX_LEVEL: 3553 if (context->getClientVersion() < 3) 3554 { 3555 return gl::error(GL_INVALID_ENUM); 3556 } 3557 *params = (GLfloat)texture->getMaxLevel(); 3558 break; 3559 case GL_TEXTURE_MIN_LOD: 3560 if (context->getClientVersion() < 3) 3561 { 3562 return gl::error(GL_INVALID_ENUM); 3563 } 3564 *params = texture->getMinLod(); 3565 break; 3566 case GL_TEXTURE_MAX_LOD: 3567 if (context->getClientVersion() < 3) 3568 { 3569 return gl::error(GL_INVALID_ENUM); 3570 } 3571 *params = texture->getMaxLod(); 3572 break; 3573 default: 3574 return gl::error(GL_INVALID_ENUM); 3575 } 3576 } 3577 } 3578 catch (...) 3579 { 3580 return gl::error(GL_OUT_OF_MEMORY); 3581 } 3582} 3583 3584void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params) 3585{ 3586 EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params); 3587 3588 try 3589 { 3590 gl::Context *context = gl::getNonLostContext(); 3591 3592 if (context) 3593 { 3594 gl::Texture *texture = context->getTargetTexture(target); 3595 3596 if (!texture) 3597 { 3598 return gl::error(GL_INVALID_ENUM); 3599 } 3600 3601 switch (pname) 3602 { 3603 case GL_TEXTURE_MAG_FILTER: 3604 *params = texture->getMagFilter(); 3605 break; 3606 case GL_TEXTURE_MIN_FILTER: 3607 *params = texture->getMinFilter(); 3608 break; 3609 case GL_TEXTURE_WRAP_S: 3610 *params = texture->getWrapS(); 3611 break; 3612 case GL_TEXTURE_WRAP_T: 3613 *params = texture->getWrapT(); 3614 break; 3615 case GL_TEXTURE_WRAP_R: 3616 if (context->getClientVersion() < 3) 3617 { 3618 return gl::error(GL_INVALID_ENUM); 3619 } 3620 *params = texture->getWrapR(); 3621 break; 3622 case GL_TEXTURE_IMMUTABLE_FORMAT: 3623 // Exposed to ES2.0 through EXT_texture_storage, no client version validation. 3624 *params = texture->isImmutable() ? GL_TRUE : GL_FALSE; 3625 break; 3626 case GL_TEXTURE_IMMUTABLE_LEVELS: 3627 if (context->getClientVersion() < 3) 3628 { 3629 return gl::error(GL_INVALID_ENUM); 3630 } 3631 *params = texture->immutableLevelCount(); 3632 break; 3633 case GL_TEXTURE_USAGE_ANGLE: 3634 *params = texture->getUsage(); 3635 break; 3636 case GL_TEXTURE_MAX_ANISOTROPY_EXT: 3637 if (!context->supportsTextureFilterAnisotropy()) 3638 { 3639 return gl::error(GL_INVALID_ENUM); 3640 } 3641 *params = (GLint)texture->getMaxAnisotropy(); 3642 break; 3643 case GL_TEXTURE_SWIZZLE_R: 3644 if (context->getClientVersion() < 3) 3645 { 3646 return gl::error(GL_INVALID_ENUM); 3647 } 3648 *params = texture->getSwizzleRed(); 3649 break; 3650 case GL_TEXTURE_SWIZZLE_G: 3651 if (context->getClientVersion() < 3) 3652 { 3653 return gl::error(GL_INVALID_ENUM); 3654 } 3655 *params = texture->getSwizzleGreen(); 3656 break; 3657 case GL_TEXTURE_SWIZZLE_B: 3658 if (context->getClientVersion() < 3) 3659 { 3660 return gl::error(GL_INVALID_ENUM); 3661 } 3662 *params = texture->getSwizzleBlue(); 3663 break; 3664 case GL_TEXTURE_SWIZZLE_A: 3665 if (context->getClientVersion() < 3) 3666 { 3667 return gl::error(GL_INVALID_ENUM); 3668 } 3669 *params = texture->getSwizzleAlpha(); 3670 break; 3671 case GL_TEXTURE_BASE_LEVEL: 3672 if (context->getClientVersion() < 3) 3673 { 3674 return gl::error(GL_INVALID_ENUM); 3675 } 3676 *params = texture->getBaseLevel(); 3677 break; 3678 case GL_TEXTURE_MAX_LEVEL: 3679 if (context->getClientVersion() < 3) 3680 { 3681 return gl::error(GL_INVALID_ENUM); 3682 } 3683 *params = texture->getMaxLevel(); 3684 break; 3685 case GL_TEXTURE_MIN_LOD: 3686 if (context->getClientVersion() < 3) 3687 { 3688 return gl::error(GL_INVALID_ENUM); 3689 } 3690 *params = (GLint)texture->getMinLod(); 3691 break; 3692 case GL_TEXTURE_MAX_LOD: 3693 if (context->getClientVersion() < 3) 3694 { 3695 return gl::error(GL_INVALID_ENUM); 3696 } 3697 *params = (GLint)texture->getMaxLod(); 3698 break; 3699 default: 3700 return gl::error(GL_INVALID_ENUM); 3701 } 3702 } 3703 } 3704 catch (...) 3705 { 3706 return gl::error(GL_OUT_OF_MEMORY); 3707 } 3708} 3709 3710void __stdcall glGetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSize, GLfloat* params) 3711{ 3712 EVENT("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLfloat* params = 0x%0.8p)", 3713 program, location, bufSize, params); 3714 3715 try 3716 { 3717 if (bufSize < 0) 3718 { 3719 return gl::error(GL_INVALID_VALUE); 3720 } 3721 3722 gl::Context *context = gl::getNonLostContext(); 3723 3724 if (context) 3725 { 3726 if (program == 0) 3727 { 3728 return gl::error(GL_INVALID_VALUE); 3729 } 3730 3731 gl::Program *programObject = context->getProgram(program); 3732 3733 if (!programObject || !programObject->isLinked()) 3734 { 3735 return gl::error(GL_INVALID_OPERATION); 3736 } 3737 3738 gl::ProgramBinary *programBinary = programObject->getProgramBinary(); 3739 if (!programBinary) 3740 { 3741 return gl::error(GL_INVALID_OPERATION); 3742 } 3743 3744 if (!programBinary->getUniformfv(location, &bufSize, params)) 3745 { 3746 return gl::error(GL_INVALID_OPERATION); 3747 } 3748 } 3749 } 3750 catch (...) 3751 { 3752 return gl::error(GL_OUT_OF_MEMORY); 3753 } 3754} 3755 3756void __stdcall glGetUniformfv(GLuint program, GLint location, GLfloat* params) 3757{ 3758 EVENT("(GLuint program = %d, GLint location = %d, GLfloat* params = 0x%0.8p)", program, location, params); 3759 3760 try 3761 { 3762 gl::Context *context = gl::getNonLostContext(); 3763 3764 if (context) 3765 { 3766 if (program == 0) 3767 { 3768 return gl::error(GL_INVALID_VALUE); 3769 } 3770 3771 gl::Program *programObject = context->getProgram(program); 3772 3773 if (!programObject || !programObject->isLinked()) 3774 { 3775 return gl::error(GL_INVALID_OPERATION); 3776 } 3777 3778 gl::ProgramBinary *programBinary = programObject->getProgramBinary(); 3779 if (!programBinary) 3780 { 3781 return gl::error(GL_INVALID_OPERATION); 3782 } 3783 3784 if (!programBinary->getUniformfv(location, NULL, params)) 3785 { 3786 return gl::error(GL_INVALID_OPERATION); 3787 } 3788 } 3789 } 3790 catch (...) 3791 { 3792 return gl::error(GL_OUT_OF_MEMORY); 3793 } 3794} 3795 3796void __stdcall glGetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint* params) 3797{ 3798 EVENT("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLint* params = 0x%0.8p)", 3799 program, location, bufSize, params); 3800 3801 try 3802 { 3803 if (bufSize < 0) 3804 { 3805 return gl::error(GL_INVALID_VALUE); 3806 } 3807 3808 gl::Context *context = gl::getNonLostContext(); 3809 3810 if (context) 3811 { 3812 if (program == 0) 3813 { 3814 return gl::error(GL_INVALID_VALUE); 3815 } 3816 3817 gl::Program *programObject = context->getProgram(program); 3818 3819 if (!programObject || !programObject->isLinked()) 3820 { 3821 return gl::error(GL_INVALID_OPERATION); 3822 } 3823 3824 gl::ProgramBinary *programBinary = programObject->getProgramBinary(); 3825 if (!programBinary) 3826 { 3827 return gl::error(GL_INVALID_OPERATION); 3828 } 3829 3830 if (!programBinary->getUniformiv(location, &bufSize, params)) 3831 { 3832 return gl::error(GL_INVALID_OPERATION); 3833 } 3834 } 3835 } 3836 catch (...) 3837 { 3838 return gl::error(GL_OUT_OF_MEMORY); 3839 } 3840} 3841 3842void __stdcall glGetUniformiv(GLuint program, GLint location, GLint* params) 3843{ 3844 EVENT("(GLuint program = %d, GLint location = %d, GLint* params = 0x%0.8p)", program, location, params); 3845 3846 try 3847 { 3848 gl::Context *context = gl::getNonLostContext(); 3849 3850 if (context) 3851 { 3852 if (program == 0) 3853 { 3854 return gl::error(GL_INVALID_VALUE); 3855 } 3856 3857 gl::Program *programObject = context->getProgram(program); 3858 3859 if (!programObject || !programObject->isLinked()) 3860 { 3861 return gl::error(GL_INVALID_OPERATION); 3862 } 3863 3864 gl::ProgramBinary *programBinary = programObject->getProgramBinary(); 3865 if (!programBinary) 3866 { 3867 return gl::error(GL_INVALID_OPERATION); 3868 } 3869 3870 if (!programBinary->getUniformiv(location, NULL, params)) 3871 { 3872 return gl::error(GL_INVALID_OPERATION); 3873 } 3874 } 3875 } 3876 catch (...) 3877 { 3878 return gl::error(GL_OUT_OF_MEMORY); 3879 } 3880} 3881 3882int __stdcall glGetUniformLocation(GLuint program, const GLchar* name) 3883{ 3884 EVENT("(GLuint program = %d, const GLchar* name = 0x%0.8p)", program, name); 3885 3886 try 3887 { 3888 gl::Context *context = gl::getNonLostContext(); 3889 3890 if (strstr(name, "gl_") == name) 3891 { 3892 return -1; 3893 } 3894 3895 if (context) 3896 { 3897 gl::Program *programObject = context->getProgram(program); 3898 3899 if (!programObject) 3900 { 3901 if (context->getShader(program)) 3902 { 3903 return gl::error(GL_INVALID_OPERATION, -1); 3904 } 3905 else 3906 { 3907 return gl::error(GL_INVALID_VALUE, -1); 3908 } 3909 } 3910 3911 gl::ProgramBinary *programBinary = programObject->getProgramBinary(); 3912 if (!programObject->isLinked() || !programBinary) 3913 { 3914 return gl::error(GL_INVALID_OPERATION, -1); 3915 } 3916 3917 return programBinary->getUniformLocation(name); 3918 } 3919 } 3920 catch (...) 3921 { 3922 return gl::error(GL_OUT_OF_MEMORY, -1); 3923 } 3924 3925 return -1; 3926} 3927 3928void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params) 3929{ 3930 EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", index, pname, params); 3931 3932 try 3933 { 3934 gl::Context *context = gl::getNonLostContext(); 3935 3936 if (context) 3937 { 3938 if (index >= gl::MAX_VERTEX_ATTRIBS) 3939 { 3940 return gl::error(GL_INVALID_VALUE); 3941 } 3942 3943 const gl::VertexAttribute &attribState = context->getVertexAttribState(index); 3944 3945 if (!gl::ValidateGetVertexAttribParameters(pname, context->getClientVersion())) 3946 { 3947 return; 3948 } 3949 3950 if (pname == GL_CURRENT_VERTEX_ATTRIB) 3951 { 3952 const gl::VertexAttribCurrentValueData ¤tValueData = context->getVertexAttribCurrentValue(index); 3953 for (int i = 0; i < 4; ++i) 3954 { 3955 params[i] = currentValueData.FloatValues[i]; 3956 } 3957 } 3958 else 3959 { 3960 *params = attribState.querySingleParameter<GLfloat>(pname); 3961 } 3962 } 3963 } 3964 catch (...) 3965 { 3966 return gl::error(GL_OUT_OF_MEMORY); 3967 } 3968} 3969 3970void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params) 3971{ 3972 EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params); 3973 3974 try 3975 { 3976 gl::Context *context = gl::getNonLostContext(); 3977 3978 if (context) 3979 { 3980 if (index >= gl::MAX_VERTEX_ATTRIBS) 3981 { 3982 return gl::error(GL_INVALID_VALUE); 3983 } 3984 3985 const gl::VertexAttribute &attribState = context->getVertexAttribState(index); 3986 3987 if (!gl::ValidateGetVertexAttribParameters(pname, context->getClientVersion())) 3988 { 3989 return; 3990 } 3991 3992 if (pname == GL_CURRENT_VERTEX_ATTRIB) 3993 { 3994 const gl::VertexAttribCurrentValueData ¤tValueData = context->getVertexAttribCurrentValue(index); 3995 for (int i = 0; i < 4; ++i) 3996 { 3997 float currentValue = currentValueData.FloatValues[i]; 3998 params[i] = gl::iround<GLint>(currentValue); 3999 } 4000 } 4001 else 4002 { 4003 *params = attribState.querySingleParameter<GLint>(pname); 4004 } 4005 } 4006 } 4007 catch (...) 4008 { 4009 return gl::error(GL_OUT_OF_MEMORY); 4010 } 4011} 4012 4013void __stdcall glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer) 4014{ 4015 EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = 0x%0.8p)", index, pname, pointer); 4016 4017 try 4018 { 4019 gl::Context *context = gl::getNonLostContext(); 4020 4021 if (context) 4022 { 4023 if (index >= gl::MAX_VERTEX_ATTRIBS) 4024 { 4025 return gl::error(GL_INVALID_VALUE); 4026 } 4027 4028 if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER) 4029 { 4030 return gl::error(GL_INVALID_ENUM); 4031 } 4032 4033 *pointer = const_cast<GLvoid*>(context->getVertexAttribPointer(index)); 4034 } 4035 } 4036 catch (...) 4037 { 4038 return gl::error(GL_OUT_OF_MEMORY); 4039 } 4040} 4041 4042void __stdcall glHint(GLenum target, GLenum mode) 4043{ 4044 EVENT("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode); 4045 4046 try 4047 { 4048 switch (mode) 4049 { 4050 case GL_FASTEST: 4051 case GL_NICEST: 4052 case GL_DONT_CARE: 4053 break; 4054 default: 4055 return gl::error(GL_INVALID_ENUM); 4056 } 4057 4058 gl::Context *context = gl::getNonLostContext(); 4059 switch (target) 4060 { 4061 case GL_GENERATE_MIPMAP_HINT: 4062 if (context) context->setGenerateMipmapHint(mode); 4063 break; 4064 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: 4065 if (context) context->setFragmentShaderDerivativeHint(mode); 4066 break; 4067 default: 4068 return gl::error(GL_INVALID_ENUM); 4069 } 4070 } 4071 catch (...) 4072 { 4073 return gl::error(GL_OUT_OF_MEMORY); 4074 } 4075} 4076 4077GLboolean __stdcall glIsBuffer(GLuint buffer) 4078{ 4079 EVENT("(GLuint buffer = %d)", buffer); 4080 4081 try 4082 { 4083 gl::Context *context = gl::getNonLostContext(); 4084 4085 if (context && buffer) 4086 { 4087 gl::Buffer *bufferObject = context->getBuffer(buffer); 4088 4089 if (bufferObject) 4090 { 4091 return GL_TRUE; 4092 } 4093 } 4094 } 4095 catch (...) 4096 { 4097 return gl::error(GL_OUT_OF_MEMORY, GL_FALSE); 4098 } 4099 4100 return GL_FALSE; 4101} 4102 4103GLboolean __stdcall glIsEnabled(GLenum cap) 4104{ 4105 EVENT("(GLenum cap = 0x%X)", cap); 4106 4107 try 4108 { 4109 gl::Context *context = gl::getNonLostContext(); 4110 4111 if (context) 4112 { 4113 if (!ValidCap(context, cap)) 4114 { 4115 return gl::error(GL_INVALID_ENUM, false); 4116 } 4117 4118 return context->getCap(cap); 4119 } 4120 } 4121 catch (...) 4122 { 4123 return gl::error(GL_OUT_OF_MEMORY, false); 4124 } 4125 4126 return false; 4127} 4128 4129GLboolean __stdcall glIsFenceNV(GLuint fence) 4130{ 4131 EVENT("(GLuint fence = %d)", fence); 4132 4133 try 4134 { 4135 gl::Context *context = gl::getNonLostContext(); 4136 4137 if (context) 4138 { 4139 gl::FenceNV *fenceObject = context->getFenceNV(fence); 4140 4141 if (fenceObject == NULL) 4142 { 4143 return GL_FALSE; 4144 } 4145 4146 return fenceObject->isFence(); 4147 } 4148 } 4149 catch (...) 4150 { 4151 return gl::error(GL_OUT_OF_MEMORY, GL_FALSE); 4152 } 4153 4154 return GL_FALSE; 4155} 4156 4157GLboolean __stdcall glIsFramebuffer(GLuint framebuffer) 4158{ 4159 EVENT("(GLuint framebuffer = %d)", framebuffer); 4160 4161 try 4162 { 4163 gl::Context *context = gl::getNonLostContext(); 4164 4165 if (context && framebuffer) 4166 { 4167 gl::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer); 4168 4169 if (framebufferObject) 4170 { 4171 return GL_TRUE; 4172 } 4173 } 4174 } 4175 catch (...) 4176 { 4177 return gl::error(GL_OUT_OF_MEMORY, GL_FALSE); 4178 } 4179 4180 return GL_FALSE; 4181} 4182 4183GLboolean __stdcall glIsProgram(GLuint program) 4184{ 4185 EVENT("(GLuint program = %d)", program); 4186 4187 try 4188 { 4189 gl::Context *context = gl::getNonLostContext(); 4190 4191 if (context && program) 4192 { 4193 gl::Program *programObject = context->getProgram(program); 4194 4195 if (programObject) 4196 { 4197 return GL_TRUE; 4198 } 4199 } 4200 } 4201 catch (...) 4202 { 4203 return gl::error(GL_OUT_OF_MEMORY, GL_FALSE); 4204 } 4205 4206 return GL_FALSE; 4207} 4208 4209GLboolean __stdcall glIsQueryEXT(GLuint id) 4210{ 4211 EVENT("(GLuint id = %d)", id); 4212 4213 try 4214 { 4215 gl::Context *context = gl::getNonLostContext(); 4216 4217 if (context) 4218 { 4219 return (context->getQuery(id, false, GL_NONE) != NULL) ? GL_TRUE : GL_FALSE; 4220 } 4221 } 4222 catch (...) 4223 { 4224 return gl::error(GL_OUT_OF_MEMORY, GL_FALSE); 4225 } 4226 4227 return GL_FALSE; 4228} 4229 4230GLboolean __stdcall glIsRenderbuffer(GLuint renderbuffer) 4231{ 4232 EVENT("(GLuint renderbuffer = %d)", renderbuffer); 4233 4234 try 4235 { 4236 gl::Context *context = gl::getNonLostContext(); 4237 4238 if (context && renderbuffer) 4239 { 4240 gl::FramebufferAttachment *renderbufferObject = context->getRenderbuffer(renderbuffer); 4241 4242 if (renderbufferObject) 4243 { 4244 return GL_TRUE; 4245 } 4246 } 4247 } 4248 catch (...) 4249 { 4250 return gl::error(GL_OUT_OF_MEMORY, GL_FALSE); 4251 } 4252 4253 return GL_FALSE; 4254} 4255 4256GLboolean __stdcall glIsShader(GLuint shader) 4257{ 4258 EVENT("(GLuint shader = %d)", shader); 4259 4260 try 4261 { 4262 gl::Context *context = gl::getNonLostContext(); 4263 4264 if (context && shader) 4265 { 4266 gl::Shader *shaderObject = context->getShader(shader); 4267 4268 if (shaderObject) 4269 { 4270 return GL_TRUE; 4271 } 4272 } 4273 } 4274 catch (...) 4275 { 4276 return gl::error(GL_OUT_OF_MEMORY, GL_FALSE); 4277 } 4278 4279 return GL_FALSE; 4280} 4281 4282GLboolean __stdcall glIsTexture(GLuint texture) 4283{ 4284 EVENT("(GLuint texture = %d)", texture); 4285 4286 try 4287 { 4288 gl::Context *context = gl::getNonLostContext(); 4289 4290 if (context && texture) 4291 { 4292 gl::Texture *textureObject = context->getTexture(texture); 4293 4294 if (textureObject) 4295 { 4296 return GL_TRUE; 4297 } 4298 } 4299 } 4300 catch (...) 4301 { 4302 return gl::error(GL_OUT_OF_MEMORY, GL_FALSE); 4303 } 4304 4305 return GL_FALSE; 4306} 4307 4308void __stdcall glLineWidth(GLfloat width) 4309{ 4310 EVENT("(GLfloat width = %f)", width); 4311 4312 try 4313 { 4314 if (width <= 0.0f) 4315 { 4316 return gl::error(GL_INVALID_VALUE); 4317 } 4318 4319 gl::Context *context = gl::getNonLostContext(); 4320 4321 if (context) 4322 { 4323 context->setLineWidth(width); 4324 } 4325 } 4326 catch (...) 4327 { 4328 return gl::error(GL_OUT_OF_MEMORY); 4329 } 4330} 4331 4332void __stdcall glLinkProgram(GLuint program) 4333{ 4334 EVENT("(GLuint program = %d)", program); 4335 4336 try 4337 { 4338 gl::Context *context = gl::getNonLostContext(); 4339 4340 if (context) 4341 { 4342 gl::Program *programObject = context->getProgram(program); 4343 4344 if (!programObject) 4345 { 4346 if (context->getShader(program)) 4347 { 4348 return gl::error(GL_INVALID_OPERATION); 4349 } 4350 else 4351 { 4352 return gl::error(GL_INVALID_VALUE); 4353 } 4354 } 4355 4356 context->linkProgram(program); 4357 } 4358 } 4359 catch (...) 4360 { 4361 return gl::error(GL_OUT_OF_MEMORY); 4362 } 4363} 4364 4365void __stdcall glPixelStorei(GLenum pname, GLint param) 4366{ 4367 EVENT("(GLenum pname = 0x%X, GLint param = %d)", pname, param); 4368 4369 try 4370 { 4371 gl::Context *context = gl::getNonLostContext(); 4372 4373 if (context) 4374 { 4375 switch (pname) 4376 { 4377 case GL_UNPACK_ALIGNMENT: 4378 if (param != 1 && param != 2 && param != 4 && param != 8) 4379 { 4380 return gl::error(GL_INVALID_VALUE); 4381 } 4382 4383 context->setUnpackAlignment(param); 4384 break; 4385 4386 case GL_PACK_ALIGNMENT: 4387 if (param != 1 && param != 2 && param != 4 && param != 8) 4388 { 4389 return gl::error(GL_INVALID_VALUE); 4390 } 4391 4392 context->setPackAlignment(param); 4393 break; 4394 4395 case GL_PACK_REVERSE_ROW_ORDER_ANGLE: 4396 context->setPackReverseRowOrder(param != 0); 4397 break; 4398 4399 case GL_UNPACK_IMAGE_HEIGHT: 4400 case GL_UNPACK_SKIP_IMAGES: 4401 case GL_UNPACK_ROW_LENGTH: 4402 case GL_UNPACK_SKIP_ROWS: 4403 case GL_UNPACK_SKIP_PIXELS: 4404 case GL_PACK_ROW_LENGTH: 4405 case GL_PACK_SKIP_ROWS: 4406 case GL_PACK_SKIP_PIXELS: 4407 if (context->getClientVersion() < 3) 4408 { 4409 return gl::error(GL_INVALID_ENUM); 4410 } 4411 UNIMPLEMENTED(); 4412 break; 4413 4414 default: 4415 return gl::error(GL_INVALID_ENUM); 4416 } 4417 } 4418 } 4419 catch (...) 4420 { 4421 return gl::error(GL_OUT_OF_MEMORY); 4422 } 4423} 4424 4425void __stdcall glPolygonOffset(GLfloat factor, GLfloat units) 4426{ 4427 EVENT("(GLfloat factor = %f, GLfloat units = %f)", factor, units); 4428 4429 try 4430 { 4431 gl::Context *context = gl::getNonLostContext(); 4432 4433 if (context) 4434 { 4435 context->setPolygonOffsetParams(factor, units); 4436 } 4437 } 4438 catch (...) 4439 { 4440 return gl::error(GL_OUT_OF_MEMORY); 4441 } 4442} 4443 4444void __stdcall glReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height, 4445 GLenum format, GLenum type, GLsizei bufSize, 4446 GLvoid *data) 4447{ 4448 EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, " 4449 "GLenum format = 0x%X, GLenum type = 0x%X, GLsizei bufSize = 0x%d, GLvoid *data = 0x%0.8p)", 4450 x, y, width, height, format, type, bufSize, data); 4451 4452 try 4453 { 4454 if (width < 0 || height < 0 || bufSize < 0) 4455 { 4456 return gl::error(GL_INVALID_VALUE); 4457 } 4458 4459 gl::Context *context = gl::getNonLostContext(); 4460 4461 if (context) 4462 { 4463 if (!gl::ValidateReadPixelsParameters(context, x, y, width, height, 4464 format, type, &bufSize, data)) 4465 { 4466 return; 4467 } 4468 4469 context->readPixels(x, y, width, height, format, type, &bufSize, data); 4470 } 4471 } 4472 catch (...) 4473 { 4474 return gl::error(GL_OUT_OF_MEMORY); 4475 } 4476} 4477 4478void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, 4479 GLenum format, GLenum type, GLvoid* pixels) 4480{ 4481 EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, " 4482 "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = 0x%0.8p)", 4483 x, y, width, height, format, type, pixels); 4484 4485 try 4486 { 4487 if (width < 0 || height < 0) 4488 { 4489 return gl::error(GL_INVALID_VALUE); 4490 } 4491 4492 gl::Context *context = gl::getNonLostContext(); 4493 4494 if (context) 4495 { 4496 if (!gl::ValidateReadPixelsParameters(context, x, y, width, height, 4497 format, type, NULL, pixels)) 4498 { 4499 return; 4500 } 4501 4502 context->readPixels(x, y, width, height, format, type, NULL, pixels); 4503 } 4504 } 4505 catch (...) 4506 { 4507 return gl::error(GL_OUT_OF_MEMORY); 4508 } 4509} 4510 4511void __stdcall glReleaseShaderCompiler(void) 4512{ 4513 EVENT("()"); 4514 4515 try 4516 { 4517 gl::Shader::releaseCompiler(); 4518 } 4519 catch (...) 4520 { 4521 return gl::error(GL_OUT_OF_MEMORY); 4522 } 4523} 4524 4525void __stdcall glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) 4526{ 4527 EVENT("(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)", 4528 target, samples, internalformat, width, height); 4529 4530 try 4531 { 4532 gl::Context *context = gl::getNonLostContext(); 4533 4534 if (context) 4535 { 4536 if (!ValidateRenderbufferStorageParameters(context, target, samples, internalformat, 4537 width, height, true)) 4538 { 4539 return; 4540 } 4541 4542 context->setRenderbufferStorage(width, height, internalformat, samples); 4543 } 4544 } 4545 catch (...) 4546 { 4547 return gl::error(GL_OUT_OF_MEMORY); 4548 } 4549} 4550 4551void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height) 4552{ 4553 glRenderbufferStorageMultisampleANGLE(target, 0, internalformat, width, height); 4554} 4555 4556void __stdcall glSampleCoverage(GLclampf value, GLboolean invert) 4557{ 4558 EVENT("(GLclampf value = %f, GLboolean invert = %u)", value, invert); 4559 4560 try 4561 { 4562 gl::Context* context = gl::getNonLostContext(); 4563 4564 if (context) 4565 { 4566 context->setSampleCoverageParams(gl::clamp01(value), invert == GL_TRUE); 4567 } 4568 } 4569 catch (...) 4570 { 4571 return gl::error(GL_OUT_OF_MEMORY); 4572 } 4573} 4574 4575void __stdcall glSetFenceNV(GLuint fence, GLenum condition) 4576{ 4577 EVENT("(GLuint fence = %d, GLenum condition = 0x%X)", fence, condition); 4578 4579 try 4580 { 4581 if (condition != GL_ALL_COMPLETED_NV) 4582 { 4583 return gl::error(GL_INVALID_ENUM); 4584 } 4585 4586 gl::Context *context = gl::getNonLostContext(); 4587 4588 if (context) 4589 { 4590 gl::FenceNV *fenceObject = context->getFenceNV(fence); 4591 4592 if (fenceObject == NULL) 4593 { 4594 return gl::error(GL_INVALID_OPERATION); 4595 } 4596 4597 fenceObject->setFence(condition); 4598 } 4599 } 4600 catch (...) 4601 { 4602 return gl::error(GL_OUT_OF_MEMORY); 4603 } 4604} 4605 4606void __stdcall glScissor(GLint x, GLint y, GLsizei width, GLsizei height) 4607{ 4608 EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height); 4609 4610 try 4611 { 4612 if (width < 0 || height < 0) 4613 { 4614 return gl::error(GL_INVALID_VALUE); 4615 } 4616 4617 gl::Context* context = gl::getNonLostContext(); 4618 4619 if (context) 4620 { 4621 context->setScissorParams(x, y, width, height); 4622 } 4623 } 4624 catch (...) 4625 { 4626 return gl::error(GL_OUT_OF_MEMORY); 4627 } 4628} 4629 4630void __stdcall glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length) 4631{ 4632 EVENT("(GLsizei n = %d, const GLuint* shaders = 0x%0.8p, GLenum binaryformat = 0x%X, " 4633 "const GLvoid* binary = 0x%0.8p, GLsizei length = %d)", 4634 n, shaders, binaryformat, binary, length); 4635 4636 try 4637 { 4638 // No binary shader formats are supported. 4639 return gl::error(GL_INVALID_ENUM); 4640 } 4641 catch (...) 4642 { 4643 return gl::error(GL_OUT_OF_MEMORY); 4644 } 4645} 4646 4647void __stdcall glShaderSource(GLuint shader, GLsizei count, const GLchar* const* string, const GLint* length) 4648{ 4649 EVENT("(GLuint shader = %d, GLsizei count = %d, const GLchar** string = 0x%0.8p, const GLint* length = 0x%0.8p)", 4650 shader, count, string, length); 4651 4652 try 4653 { 4654 if (count < 0) 4655 { 4656 return gl::error(GL_INVALID_VALUE); 4657 } 4658 4659 gl::Context *context = gl::getNonLostContext(); 4660 4661 if (context) 4662 { 4663 gl::Shader *shaderObject = context->getShader(shader); 4664 4665 if (!shaderObject) 4666 { 4667 if (context->getProgram(shader)) 4668 { 4669 return gl::error(GL_INVALID_OPERATION); 4670 } 4671 else 4672 { 4673 return gl::error(GL_INVALID_VALUE); 4674 } 4675 } 4676 4677 shaderObject->setSource(count, string, length); 4678 } 4679 } 4680 catch (...) 4681 { 4682 return gl::error(GL_OUT_OF_MEMORY); 4683 } 4684} 4685 4686void __stdcall glStencilFunc(GLenum func, GLint ref, GLuint mask) 4687{ 4688 glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask); 4689} 4690 4691void __stdcall glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask) 4692{ 4693 EVENT("(GLenum face = 0x%X, GLenum func = 0x%X, GLint ref = %d, GLuint mask = %d)", face, func, ref, mask); 4694 4695 try 4696 { 4697 switch (face) 4698 { 4699 case GL_FRONT: 4700 case GL_BACK: 4701 case GL_FRONT_AND_BACK: 4702 break; 4703 default: 4704 return gl::error(GL_INVALID_ENUM); 4705 } 4706 4707 switch (func) 4708 { 4709 case GL_NEVER: 4710 case GL_ALWAYS: 4711 case GL_LESS: 4712 case GL_LEQUAL: 4713 case GL_EQUAL: 4714 case GL_GEQUAL: 4715 case GL_GREATER: 4716 case GL_NOTEQUAL: 4717 break; 4718 default: 4719 return gl::error(GL_INVALID_ENUM); 4720 } 4721 4722 gl::Context *context = gl::getNonLostContext(); 4723 4724 if (context) 4725 { 4726 if (face == GL_FRONT || face == GL_FRONT_AND_BACK) 4727 { 4728 context->setStencilParams(func, ref, mask); 4729 } 4730 4731 if (face == GL_BACK || face == GL_FRONT_AND_BACK) 4732 { 4733 context->setStencilBackParams(func, ref, mask); 4734 } 4735 } 4736 } 4737 catch (...) 4738 { 4739 return gl::error(GL_OUT_OF_MEMORY); 4740 } 4741} 4742 4743void __stdcall glStencilMask(GLuint mask) 4744{ 4745 glStencilMaskSeparate(GL_FRONT_AND_BACK, mask); 4746} 4747 4748void __stdcall glStencilMaskSeparate(GLenum face, GLuint mask) 4749{ 4750 EVENT("(GLenum face = 0x%X, GLuint mask = %d)", face, mask); 4751 4752 try 4753 { 4754 switch (face) 4755 { 4756 case GL_FRONT: 4757 case GL_BACK: 4758 case GL_FRONT_AND_BACK: 4759 break; 4760 default: 4761 return gl::error(GL_INVALID_ENUM); 4762 } 4763 4764 gl::Context *context = gl::getNonLostContext(); 4765 4766 if (context) 4767 { 4768 if (face == GL_FRONT || face == GL_FRONT_AND_BACK) 4769 { 4770 context->setStencilWritemask(mask); 4771 } 4772 4773 if (face == GL_BACK || face == GL_FRONT_AND_BACK) 4774 { 4775 context->setStencilBackWritemask(mask); 4776 } 4777 } 4778 } 4779 catch (...) 4780 { 4781 return gl::error(GL_OUT_OF_MEMORY); 4782 } 4783} 4784 4785void __stdcall glStencilOp(GLenum fail, GLenum zfail, GLenum zpass) 4786{ 4787 glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass); 4788} 4789 4790void __stdcall glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass) 4791{ 4792 EVENT("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)", 4793 face, fail, zfail, zpass); 4794 4795 try 4796 { 4797 switch (face) 4798 { 4799 case GL_FRONT: 4800 case GL_BACK: 4801 case GL_FRONT_AND_BACK: 4802 break; 4803 default: 4804 return gl::error(GL_INVALID_ENUM); 4805 } 4806 4807 switch (fail) 4808 { 4809 case GL_ZERO: 4810 case GL_KEEP: 4811 case GL_REPLACE: 4812 case GL_INCR: 4813 case GL_DECR: 4814 case GL_INVERT: 4815 case GL_INCR_WRAP: 4816 case GL_DECR_WRAP: 4817 break; 4818 default: 4819 return gl::error(GL_INVALID_ENUM); 4820 } 4821 4822 switch (zfail) 4823 { 4824 case GL_ZERO: 4825 case GL_KEEP: 4826 case GL_REPLACE: 4827 case GL_INCR: 4828 case GL_DECR: 4829 case GL_INVERT: 4830 case GL_INCR_WRAP: 4831 case GL_DECR_WRAP: 4832 break; 4833 default: 4834 return gl::error(GL_INVALID_ENUM); 4835 } 4836 4837 switch (zpass) 4838 { 4839 case GL_ZERO: 4840 case GL_KEEP: 4841 case GL_REPLACE: 4842 case GL_INCR: 4843 case GL_DECR: 4844 case GL_INVERT: 4845 case GL_INCR_WRAP: 4846 case GL_DECR_WRAP: 4847 break; 4848 default: 4849 return gl::error(GL_INVALID_ENUM); 4850 } 4851 4852 gl::Context *context = gl::getNonLostContext(); 4853 4854 if (context) 4855 { 4856 if (face == GL_FRONT || face == GL_FRONT_AND_BACK) 4857 { 4858 context->setStencilOperations(fail, zfail, zpass); 4859 } 4860 4861 if (face == GL_BACK || face == GL_FRONT_AND_BACK) 4862 { 4863 context->setStencilBackOperations(fail, zfail, zpass); 4864 } 4865 } 4866 } 4867 catch (...) 4868 { 4869 return gl::error(GL_OUT_OF_MEMORY); 4870 } 4871} 4872 4873GLboolean __stdcall glTestFenceNV(GLuint fence) 4874{ 4875 EVENT("(GLuint fence = %d)", fence); 4876 4877 try 4878 { 4879 gl::Context *context = gl::getNonLostContext(); 4880 4881 if (context) 4882 { 4883 gl::FenceNV *fenceObject = context->getFenceNV(fence); 4884 4885 if (fenceObject == NULL) 4886 { 4887 return gl::error(GL_INVALID_OPERATION, GL_TRUE); 4888 } 4889 4890 if (fenceObject->isFence() != GL_TRUE) 4891 { 4892 return gl::error(GL_INVALID_OPERATION, GL_TRUE); 4893 } 4894 4895 return fenceObject->testFence(); 4896 } 4897 } 4898 catch (...) 4899 { 4900 gl::error(GL_OUT_OF_MEMORY); 4901 } 4902 4903 return GL_TRUE; 4904} 4905 4906void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, 4907 GLint border, GLenum format, GLenum type, const GLvoid* pixels) 4908{ 4909 EVENT("(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, GLsizei height = %d, " 4910 "GLint border = %d, GLenum format = 0x%X, GLenum type = 0x%X, const GLvoid* pixels = 0x%0.8p)", 4911 target, level, internalformat, width, height, border, format, type, pixels); 4912 4913 try 4914 { 4915 gl::Context *context = gl::getNonLostContext(); 4916 4917 if (context) 4918 { 4919 if (context->getClientVersion() < 3 && 4920 !ValidateES2TexImageParameters(context, target, level, internalformat, false, false, 4921 0, 0, width, height, border, format, type, pixels)) 4922 { 4923 return; 4924 } 4925 4926 if (context->getClientVersion() >= 3 && 4927 !ValidateES3TexImageParameters(context, target, level, internalformat, false, false, 4928 0, 0, 0, width, height, 1, border, format, type, pixels)) 4929 { 4930 return; 4931 } 4932 4933 switch (target) 4934 { 4935 case GL_TEXTURE_2D: 4936 { 4937 gl::Texture2D *texture = context->getTexture2D(); 4938 texture->setImage(level, width, height, internalformat, format, type, context->getUnpackState(), pixels); 4939 } 4940 break; 4941 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 4942 { 4943 gl::TextureCubeMap *texture = context->getTextureCubeMap(); 4944 texture->setImagePosX(level, width, height, internalformat, format, type, context->getUnpackState(), pixels); 4945 } 4946 break; 4947 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 4948 { 4949 gl::TextureCubeMap *texture = context->getTextureCubeMap(); 4950 texture->setImageNegX(level, width, height, internalformat, format, type, context->getUnpackState(), pixels); 4951 } 4952 break; 4953 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 4954 { 4955 gl::TextureCubeMap *texture = context->getTextureCubeMap(); 4956 texture->setImagePosY(level, width, height, internalformat, format, type, context->getUnpackState(), pixels); 4957 } 4958 break; 4959 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 4960 { 4961 gl::TextureCubeMap *texture = context->getTextureCubeMap(); 4962 texture->setImageNegY(level, width, height, internalformat, format, type, context->getUnpackState(), pixels); 4963 } 4964 break; 4965 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 4966 { 4967 gl::TextureCubeMap *texture = context->getTextureCubeMap(); 4968 texture->setImagePosZ(level, width, height, internalformat, format, type, context->getUnpackState(), pixels); 4969 } 4970 break; 4971 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 4972 { 4973 gl::TextureCubeMap *texture = context->getTextureCubeMap(); 4974 texture->setImageNegZ(level, width, height, internalformat, format, type, context->getUnpackState(), pixels); 4975 } 4976 break; 4977 default: UNREACHABLE(); 4978 } 4979 } 4980 } 4981 catch (...) 4982 { 4983 return gl::error(GL_OUT_OF_MEMORY); 4984 } 4985} 4986 4987void __stdcall glTexParameterf(GLenum target, GLenum pname, GLfloat param) 4988{ 4989 EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %f)", target, pname, param); 4990 4991 try 4992 { 4993 gl::Context *context = gl::getNonLostContext(); 4994 4995 if (context) 4996 { 4997 if (!ValidateTexParamParameters(context, pname, static_cast<GLint>(param))) 4998 { 4999 return; 5000 } 5001 5002 gl::Texture *texture = context->getTargetTexture(target); 5003 5004 if (!texture) 5005 { 5006 return gl::error(GL_INVALID_ENUM); 5007 } 5008 5009 switch (pname) 5010 { 5011 case GL_TEXTURE_WRAP_S: texture->setWrapS(gl::uiround<GLenum>(param)); break; 5012 case GL_TEXTURE_WRAP_T: texture->setWrapT(gl::uiround<GLenum>(param)); break; 5013 case GL_TEXTURE_WRAP_R: texture->setWrapR(gl::uiround<GLenum>(param)); break; 5014 case GL_TEXTURE_MIN_FILTER: texture->setMinFilter(gl::uiround<GLenum>(param)); break; 5015 case GL_TEXTURE_MAG_FILTER: texture->setMagFilter(gl::uiround<GLenum>(param)); break; 5016 case GL_TEXTURE_USAGE_ANGLE: texture->setUsage(gl::uiround<GLenum>(param)); break; 5017 case GL_TEXTURE_MAX_ANISOTROPY_EXT: texture->setMaxAnisotropy(param, context->getTextureMaxAnisotropy()); break; 5018 case GL_TEXTURE_COMPARE_MODE: texture->setCompareMode(gl::uiround<GLenum>(param)); break; 5019 case GL_TEXTURE_COMPARE_FUNC: texture->setCompareFunc(gl::uiround<GLenum>(param)); break; 5020 case GL_TEXTURE_SWIZZLE_R: texture->setSwizzleRed(gl::uiround<GLenum>(param)); break; 5021 case GL_TEXTURE_SWIZZLE_G: texture->setSwizzleGreen(gl::uiround<GLenum>(param)); break; 5022 case GL_TEXTURE_SWIZZLE_B: texture->setSwizzleBlue(gl::uiround<GLenum>(param)); break; 5023 case GL_TEXTURE_SWIZZLE_A: texture->setSwizzleAlpha(gl::uiround<GLenum>(param)); break; 5024 case GL_TEXTURE_BASE_LEVEL: texture->setBaseLevel(gl::iround<GLint>(param)); break; 5025 case GL_TEXTURE_MAX_LEVEL: texture->setMaxLevel(gl::iround<GLint>(param)); break; 5026 case GL_TEXTURE_MIN_LOD: texture->setMinLod(param); break; 5027 case GL_TEXTURE_MAX_LOD: texture->setMaxLod(param); break; 5028 default: UNREACHABLE(); break; 5029 } 5030 } 5031 } 5032 catch (...) 5033 { 5034 return gl::error(GL_OUT_OF_MEMORY); 5035 } 5036} 5037 5038void __stdcall glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params) 5039{ 5040 glTexParameterf(target, pname, (GLfloat)*params); 5041} 5042 5043void __stdcall glTexParameteri(GLenum target, GLenum pname, GLint param) 5044{ 5045 EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param); 5046 5047 try 5048 { 5049 gl::Context *context = gl::getNonLostContext(); 5050 5051 if (context) 5052 { 5053 if (!ValidateTexParamParameters(context, pname, param)) 5054 { 5055 return; 5056 } 5057 5058 gl::Texture *texture = context->getTargetTexture(target); 5059 5060 if (!texture) 5061 { 5062 return gl::error(GL_INVALID_ENUM); 5063 } 5064 5065 switch (pname) 5066 { 5067 case GL_TEXTURE_WRAP_S: texture->setWrapS((GLenum)param); break; 5068 case GL_TEXTURE_WRAP_T: texture->setWrapT((GLenum)param); break; 5069 case GL_TEXTURE_WRAP_R: texture->setWrapR((GLenum)param); break; 5070 case GL_TEXTURE_MIN_FILTER: texture->setMinFilter((GLenum)param); break; 5071 case GL_TEXTURE_MAG_FILTER: texture->setMagFilter((GLenum)param); break; 5072 case GL_TEXTURE_USAGE_ANGLE: texture->setUsage((GLenum)param); break; 5073 case GL_TEXTURE_MAX_ANISOTROPY_EXT: texture->setMaxAnisotropy((float)param, context->getTextureMaxAnisotropy()); break; 5074 case GL_TEXTURE_COMPARE_MODE: texture->setCompareMode((GLenum)param); break; 5075 case GL_TEXTURE_COMPARE_FUNC: texture->setCompareFunc((GLenum)param); break; 5076 case GL_TEXTURE_SWIZZLE_R: texture->setSwizzleRed((GLenum)param); break; 5077 case GL_TEXTURE_SWIZZLE_G: texture->setSwizzleGreen((GLenum)param); break; 5078 case GL_TEXTURE_SWIZZLE_B: texture->setSwizzleBlue((GLenum)param); break; 5079 case GL_TEXTURE_SWIZZLE_A: texture->setSwizzleAlpha((GLenum)param); break; 5080 case GL_TEXTURE_BASE_LEVEL: texture->setBaseLevel(param); break; 5081 case GL_TEXTURE_MAX_LEVEL: texture->setMaxLevel(param); break; 5082 case GL_TEXTURE_MIN_LOD: texture->setMinLod((GLfloat)param); break; 5083 case GL_TEXTURE_MAX_LOD: texture->setMaxLod((GLfloat)param); break; 5084 default: UNREACHABLE(); break; 5085 } 5086 } 5087 } 5088 catch (...) 5089 { 5090 return gl::error(GL_OUT_OF_MEMORY); 5091 } 5092} 5093 5094void __stdcall glTexParameteriv(GLenum target, GLenum pname, const GLint* params) 5095{ 5096 glTexParameteri(target, pname, *params); 5097} 5098 5099void __stdcall glTexStorage2DEXT(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) 5100{ 5101 EVENT("(GLenum target = 0x%X, GLsizei levels = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)", 5102 target, levels, internalformat, width, height); 5103 5104 try 5105 { 5106 gl::Context *context = gl::getNonLostContext(); 5107 5108 if (context) 5109 { 5110 if (context->getClientVersion() < 3 && 5111 !ValidateES2TexStorageParameters(context, target, levels, internalformat, width, height)) 5112 { 5113 return; 5114 } 5115 5116 if (context->getClientVersion() >= 3 && 5117 !ValidateES3TexStorageParameters(context, target, levels, internalformat, width, height, 1)) 5118 { 5119 return; 5120 } 5121 5122 switch (target) 5123 { 5124 case GL_TEXTURE_2D: 5125 { 5126 gl::Texture2D *texture2d = context->getTexture2D(); 5127 texture2d->storage(levels, internalformat, width, height); 5128 } 5129 break; 5130 5131 case GL_TEXTURE_CUBE_MAP: 5132 { 5133 gl::TextureCubeMap *textureCube = context->getTextureCubeMap(); 5134 textureCube->storage(levels, internalformat, width); 5135 } 5136 break; 5137 5138 default: 5139 return gl::error(GL_INVALID_ENUM); 5140 } 5141 } 5142 } 5143 catch (...) 5144 { 5145 return gl::error(GL_OUT_OF_MEMORY); 5146 } 5147} 5148 5149void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, 5150 GLenum format, GLenum type, const GLvoid* pixels) 5151{ 5152 EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, " 5153 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, " 5154 "const GLvoid* pixels = 0x%0.8p)", 5155 target, level, xoffset, yoffset, width, height, format, type, pixels); 5156 5157 try 5158 { 5159 gl::Context *context = gl::getNonLostContext(); 5160 5161 if (context) 5162 { 5163 if (context->getClientVersion() < 3 && 5164 !ValidateES2TexImageParameters(context, target, level, GL_NONE, false, true, 5165 xoffset, yoffset, width, height, 0, format, type, pixels)) 5166 { 5167 return; 5168 } 5169 5170 if (context->getClientVersion() >= 3 && 5171 !ValidateES3TexImageParameters(context, target, level, GL_NONE, false, true, 5172 xoffset, yoffset, 0, width, height, 1, 0, format, type, pixels)) 5173 { 5174 return; 5175 } 5176 5177 // Zero sized uploads are valid but no-ops 5178 if (width == 0 || height == 0) 5179 { 5180 return; 5181 } 5182 5183 switch (target) 5184 { 5185 case GL_TEXTURE_2D: 5186 { 5187 gl::Texture2D *texture = context->getTexture2D(); 5188 texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackState(), pixels); 5189 } 5190 break; 5191 5192 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 5193 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 5194 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 5195 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 5196 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 5197 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 5198 { 5199 gl::TextureCubeMap *texture = context->getTextureCubeMap(); 5200 texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackState(), pixels); 5201 } 5202 break; 5203 5204 default: 5205 UNREACHABLE(); 5206 } 5207 } 5208 } 5209 catch (...) 5210 { 5211 return gl::error(GL_OUT_OF_MEMORY); 5212 } 5213} 5214 5215void __stdcall glUniform1f(GLint location, GLfloat x) 5216{ 5217 glUniform1fv(location, 1, &x); 5218} 5219 5220void __stdcall glUniform1fv(GLint location, GLsizei count, const GLfloat* v) 5221{ 5222 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v); 5223 5224 try 5225 { 5226 gl::Context *context = gl::getNonLostContext(); 5227 5228 if (context) 5229 { 5230 if (!ValidateUniform(context, GL_FLOAT, location, count)) 5231 { 5232 return; 5233 } 5234 5235 gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); 5236 programBinary->setUniform1fv(location, count, v); 5237 } 5238 } 5239 catch (...) 5240 { 5241 return gl::error(GL_OUT_OF_MEMORY); 5242 } 5243} 5244 5245void __stdcall glUniform1i(GLint location, GLint x) 5246{ 5247 glUniform1iv(location, 1, &x); 5248} 5249 5250void __stdcall glUniform1iv(GLint location, GLsizei count, const GLint* v) 5251{ 5252 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v); 5253 5254 try 5255 { 5256 gl::Context *context = gl::getNonLostContext(); 5257 5258 if (context) 5259 { 5260 if (!ValidateUniform(context, GL_INT, location, count)) 5261 { 5262 return; 5263 } 5264 5265 gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); 5266 programBinary->setUniform1iv(location, count, v); 5267 } 5268 } 5269 catch (...) 5270 { 5271 return gl::error(GL_OUT_OF_MEMORY); 5272 } 5273} 5274 5275void __stdcall glUniform2f(GLint location, GLfloat x, GLfloat y) 5276{ 5277 GLfloat xy[2] = {x, y}; 5278 5279 glUniform2fv(location, 1, xy); 5280} 5281 5282void __stdcall glUniform2fv(GLint location, GLsizei count, const GLfloat* v) 5283{ 5284 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v); 5285 5286 try 5287 { 5288 gl::Context *context = gl::getNonLostContext(); 5289 5290 if (context) 5291 { 5292 if (!ValidateUniform(context, GL_FLOAT_VEC2, location, count)) 5293 { 5294 return; 5295 } 5296 5297 gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); 5298 programBinary->setUniform2fv(location, count, v); 5299 } 5300 } 5301 catch (...) 5302 { 5303 return gl::error(GL_OUT_OF_MEMORY); 5304 } 5305} 5306 5307void __stdcall glUniform2i(GLint location, GLint x, GLint y) 5308{ 5309 GLint xy[2] = {x, y}; 5310 5311 glUniform2iv(location, 1, xy); 5312} 5313 5314void __stdcall glUniform2iv(GLint location, GLsizei count, const GLint* v) 5315{ 5316 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v); 5317 5318 try 5319 { 5320 gl::Context *context = gl::getNonLostContext(); 5321 5322 if (context) 5323 { 5324 if (!ValidateUniform(context, GL_INT_VEC2, location, count)) 5325 { 5326 return; 5327 } 5328 5329 gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); 5330 programBinary->setUniform2iv(location, count, v); 5331 } 5332 } 5333 catch (...) 5334 { 5335 return gl::error(GL_OUT_OF_MEMORY); 5336 } 5337} 5338 5339void __stdcall glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z) 5340{ 5341 GLfloat xyz[3] = {x, y, z}; 5342 5343 glUniform3fv(location, 1, xyz); 5344} 5345 5346void __stdcall glUniform3fv(GLint location, GLsizei count, const GLfloat* v) 5347{ 5348 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v); 5349 5350 try 5351 { 5352 gl::Context *context = gl::getNonLostContext(); 5353 5354 if (context) 5355 { 5356 if (!ValidateUniform(context, GL_FLOAT_VEC3, location, count)) 5357 { 5358 return; 5359 } 5360 5361 gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); 5362 programBinary->setUniform3fv(location, count, v); 5363 } 5364 } 5365 catch (...) 5366 { 5367 return gl::error(GL_OUT_OF_MEMORY); 5368 } 5369} 5370 5371void __stdcall glUniform3i(GLint location, GLint x, GLint y, GLint z) 5372{ 5373 GLint xyz[3] = {x, y, z}; 5374 5375 glUniform3iv(location, 1, xyz); 5376} 5377 5378void __stdcall glUniform3iv(GLint location, GLsizei count, const GLint* v) 5379{ 5380 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v); 5381 5382 try 5383 { 5384 gl::Context *context = gl::getNonLostContext(); 5385 5386 if (context) 5387 { 5388 if (!ValidateUniform(context, GL_INT_VEC3, location, count)) 5389 { 5390 return; 5391 } 5392 5393 gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); 5394 programBinary->setUniform3iv(location, count, v); 5395 } 5396 } 5397 catch (...) 5398 { 5399 return gl::error(GL_OUT_OF_MEMORY); 5400 } 5401} 5402 5403void __stdcall glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w) 5404{ 5405 GLfloat xyzw[4] = {x, y, z, w}; 5406 5407 glUniform4fv(location, 1, xyzw); 5408} 5409 5410void __stdcall glUniform4fv(GLint location, GLsizei count, const GLfloat* v) 5411{ 5412 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v); 5413 5414 try 5415 { 5416 gl::Context *context = gl::getNonLostContext(); 5417 5418 if (context) 5419 { 5420 if (!ValidateUniform(context, GL_FLOAT_VEC4, location, count)) 5421 { 5422 return; 5423 } 5424 5425 gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); 5426 programBinary->setUniform4fv(location, count, v); 5427 } 5428 } 5429 catch (...) 5430 { 5431 return gl::error(GL_OUT_OF_MEMORY); 5432 } 5433} 5434 5435void __stdcall glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w) 5436{ 5437 GLint xyzw[4] = {x, y, z, w}; 5438 5439 glUniform4iv(location, 1, xyzw); 5440} 5441 5442void __stdcall glUniform4iv(GLint location, GLsizei count, const GLint* v) 5443{ 5444 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v); 5445 5446 try 5447 { 5448 gl::Context *context = gl::getNonLostContext(); 5449 5450 if (context) 5451 { 5452 if (!ValidateUniform(context, GL_INT_VEC4, location, count)) 5453 { 5454 return; 5455 } 5456 5457 gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); 5458 programBinary->setUniform4iv(location, count, v); 5459 } 5460 } 5461 catch (...) 5462 { 5463 return gl::error(GL_OUT_OF_MEMORY); 5464 } 5465} 5466 5467void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) 5468{ 5469 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)", 5470 location, count, transpose, value); 5471 5472 try 5473 { 5474 gl::Context *context = gl::getNonLostContext(); 5475 5476 if (context) 5477 { 5478 if (!ValidateUniformMatrix(context, GL_FLOAT_MAT2, location, count, transpose)) 5479 { 5480 return; 5481 } 5482 5483 gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); 5484 programBinary->setUniformMatrix2fv(location, count, transpose, value); 5485 } 5486 } 5487 catch (...) 5488 { 5489 return gl::error(GL_OUT_OF_MEMORY); 5490 } 5491} 5492 5493void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) 5494{ 5495 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)", 5496 location, count, transpose, value); 5497 5498 try 5499 { 5500 gl::Context *context = gl::getNonLostContext(); 5501 5502 if (context) 5503 { 5504 if (!ValidateUniformMatrix(context, GL_FLOAT_MAT3, location, count, transpose)) 5505 { 5506 return; 5507 } 5508 5509 gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); 5510 programBinary->setUniformMatrix3fv(location, count, transpose, value); 5511 } 5512 } 5513 catch (...) 5514 { 5515 return gl::error(GL_OUT_OF_MEMORY); 5516 } 5517} 5518 5519void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) 5520{ 5521 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)", 5522 location, count, transpose, value); 5523 5524 try 5525 { 5526 gl::Context *context = gl::getNonLostContext(); 5527 5528 if (context) 5529 { 5530 if (!ValidateUniformMatrix(context, GL_FLOAT_MAT4, location, count, transpose)) 5531 { 5532 return; 5533 } 5534 5535 gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); 5536 programBinary->setUniformMatrix4fv(location, count, transpose, value); 5537 } 5538 } 5539 catch (...) 5540 { 5541 return gl::error(GL_OUT_OF_MEMORY); 5542 } 5543} 5544 5545void __stdcall glUseProgram(GLuint program) 5546{ 5547 EVENT("(GLuint program = %d)", program); 5548 5549 try 5550 { 5551 gl::Context *context = gl::getNonLostContext(); 5552 5553 if (context) 5554 { 5555 gl::Program *programObject = context->getProgram(program); 5556 5557 if (!programObject && program != 0) 5558 { 5559 if (context->getShader(program)) 5560 { 5561 return gl::error(GL_INVALID_OPERATION); 5562 } 5563 else 5564 { 5565 return gl::error(GL_INVALID_VALUE); 5566 } 5567 } 5568 5569 if (program != 0 && !programObject->isLinked()) 5570 { 5571 return gl::error(GL_INVALID_OPERATION); 5572 } 5573 5574 context->useProgram(program); 5575 } 5576 } 5577 catch (...) 5578 { 5579 return gl::error(GL_OUT_OF_MEMORY); 5580 } 5581} 5582 5583void __stdcall glValidateProgram(GLuint program) 5584{ 5585 EVENT("(GLuint program = %d)", program); 5586 5587 try 5588 { 5589 gl::Context *context = gl::getNonLostContext(); 5590 5591 if (context) 5592 { 5593 gl::Program *programObject = context->getProgram(program); 5594 5595 if (!programObject) 5596 { 5597 if (context->getShader(program)) 5598 { 5599 return gl::error(GL_INVALID_OPERATION); 5600 } 5601 else 5602 { 5603 return gl::error(GL_INVALID_VALUE); 5604 } 5605 } 5606 5607 programObject->validate(); 5608 } 5609 } 5610 catch (...) 5611 { 5612 return gl::error(GL_OUT_OF_MEMORY); 5613 } 5614} 5615 5616void __stdcall glVertexAttrib1f(GLuint index, GLfloat x) 5617{ 5618 EVENT("(GLuint index = %d, GLfloat x = %f)", index, x); 5619 5620 try 5621 { 5622 if (index >= gl::MAX_VERTEX_ATTRIBS) 5623 { 5624 return gl::error(GL_INVALID_VALUE); 5625 } 5626 5627 gl::Context *context = gl::getNonLostContext(); 5628 5629 if (context) 5630 { 5631 GLfloat vals[4] = { x, 0, 0, 1 }; 5632 context->setVertexAttribf(index, vals); 5633 } 5634 } 5635 catch (...) 5636 { 5637 return gl::error(GL_OUT_OF_MEMORY); 5638 } 5639} 5640 5641void __stdcall glVertexAttrib1fv(GLuint index, const GLfloat* values) 5642{ 5643 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values); 5644 5645 try 5646 { 5647 if (index >= gl::MAX_VERTEX_ATTRIBS) 5648 { 5649 return gl::error(GL_INVALID_VALUE); 5650 } 5651 5652 gl::Context *context = gl::getNonLostContext(); 5653 5654 if (context) 5655 { 5656 GLfloat vals[4] = { values[0], 0, 0, 1 }; 5657 context->setVertexAttribf(index, vals); 5658 } 5659 } 5660 catch (...) 5661 { 5662 return gl::error(GL_OUT_OF_MEMORY); 5663 } 5664} 5665 5666void __stdcall glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y) 5667{ 5668 EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y); 5669 5670 try 5671 { 5672 if (index >= gl::MAX_VERTEX_ATTRIBS) 5673 { 5674 return gl::error(GL_INVALID_VALUE); 5675 } 5676 5677 gl::Context *context = gl::getNonLostContext(); 5678 5679 if (context) 5680 { 5681 GLfloat vals[4] = { x, y, 0, 1 }; 5682 context->setVertexAttribf(index, vals); 5683 } 5684 } 5685 catch (...) 5686 { 5687 return gl::error(GL_OUT_OF_MEMORY); 5688 } 5689} 5690 5691void __stdcall glVertexAttrib2fv(GLuint index, const GLfloat* values) 5692{ 5693 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values); 5694 5695 try 5696 { 5697 if (index >= gl::MAX_VERTEX_ATTRIBS) 5698 { 5699 return gl::error(GL_INVALID_VALUE); 5700 } 5701 5702 gl::Context *context = gl::getNonLostContext(); 5703 5704 if (context) 5705 { 5706 GLfloat vals[4] = { values[0], values[1], 0, 1 }; 5707 context->setVertexAttribf(index, vals); 5708 } 5709 } 5710 catch (...) 5711 { 5712 return gl::error(GL_OUT_OF_MEMORY); 5713 } 5714} 5715 5716void __stdcall glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z) 5717{ 5718 EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", index, x, y, z); 5719 5720 try 5721 { 5722 if (index >= gl::MAX_VERTEX_ATTRIBS) 5723 { 5724 return gl::error(GL_INVALID_VALUE); 5725 } 5726 5727 gl::Context *context = gl::getNonLostContext(); 5728 5729 if (context) 5730 { 5731 GLfloat vals[4] = { x, y, z, 1 }; 5732 context->setVertexAttribf(index, vals); 5733 } 5734 } 5735 catch (...) 5736 { 5737 return gl::error(GL_OUT_OF_MEMORY); 5738 } 5739} 5740 5741void __stdcall glVertexAttrib3fv(GLuint index, const GLfloat* values) 5742{ 5743 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values); 5744 5745 try 5746 { 5747 if (index >= gl::MAX_VERTEX_ATTRIBS) 5748 { 5749 return gl::error(GL_INVALID_VALUE); 5750 } 5751 5752 gl::Context *context = gl::getNonLostContext(); 5753 5754 if (context) 5755 { 5756 GLfloat vals[4] = { values[0], values[1], values[2], 1 }; 5757 context->setVertexAttribf(index, vals); 5758 } 5759 } 5760 catch (...) 5761 { 5762 return gl::error(GL_OUT_OF_MEMORY); 5763 } 5764} 5765 5766void __stdcall glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) 5767{ 5768 EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f, GLfloat w = %f)", index, x, y, z, w); 5769 5770 try 5771 { 5772 if (index >= gl::MAX_VERTEX_ATTRIBS) 5773 { 5774 return gl::error(GL_INVALID_VALUE); 5775 } 5776 5777 gl::Context *context = gl::getNonLostContext(); 5778 5779 if (context) 5780 { 5781 GLfloat vals[4] = { x, y, z, w }; 5782 context->setVertexAttribf(index, vals); 5783 } 5784 } 5785 catch (...) 5786 { 5787 return gl::error(GL_OUT_OF_MEMORY); 5788 } 5789} 5790 5791void __stdcall glVertexAttrib4fv(GLuint index, const GLfloat* values) 5792{ 5793 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values); 5794 5795 try 5796 { 5797 if (index >= gl::MAX_VERTEX_ATTRIBS) 5798 { 5799 return gl::error(GL_INVALID_VALUE); 5800 } 5801 5802 gl::Context *context = gl::getNonLostContext(); 5803 5804 if (context) 5805 { 5806 context->setVertexAttribf(index, values); 5807 } 5808 } 5809 catch (...) 5810 { 5811 return gl::error(GL_OUT_OF_MEMORY); 5812 } 5813} 5814 5815void __stdcall glVertexAttribDivisorANGLE(GLuint index, GLuint divisor) 5816{ 5817 EVENT("(GLuint index = %d, GLuint divisor = %d)", index, divisor); 5818 5819 try 5820 { 5821 if (index >= gl::MAX_VERTEX_ATTRIBS) 5822 { 5823 return gl::error(GL_INVALID_VALUE); 5824 } 5825 5826 gl::Context *context = gl::getNonLostContext(); 5827 5828 if (context) 5829 { 5830 context->setVertexAttribDivisor(index, divisor); 5831 } 5832 } 5833 catch (...) 5834 { 5835 return gl::error(GL_OUT_OF_MEMORY); 5836 } 5837} 5838 5839void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr) 5840{ 5841 EVENT("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, " 5842 "GLboolean normalized = %u, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)", 5843 index, size, type, normalized, stride, ptr); 5844 5845 try 5846 { 5847 if (index >= gl::MAX_VERTEX_ATTRIBS) 5848 { 5849 return gl::error(GL_INVALID_VALUE); 5850 } 5851 5852 if (size < 1 || size > 4) 5853 { 5854 return gl::error(GL_INVALID_VALUE); 5855 } 5856 5857 gl::Context *context = gl::getNonLostContext(); 5858 5859 switch (type) 5860 { 5861 case GL_BYTE: 5862 case GL_UNSIGNED_BYTE: 5863 case GL_SHORT: 5864 case GL_UNSIGNED_SHORT: 5865 case GL_FIXED: 5866 case GL_FLOAT: 5867 break; 5868 case GL_HALF_FLOAT: 5869 case GL_INT: 5870 case GL_UNSIGNED_INT: 5871 case GL_INT_2_10_10_10_REV: 5872 case GL_UNSIGNED_INT_2_10_10_10_REV: 5873 if (context && context->getClientVersion() < 3) 5874 { 5875 return gl::error(GL_INVALID_ENUM); 5876 } 5877 else 5878 { 5879 break; 5880 } 5881 default: 5882 return gl::error(GL_INVALID_ENUM); 5883 } 5884 5885 if (stride < 0) 5886 { 5887 return gl::error(GL_INVALID_VALUE); 5888 } 5889 5890 if ((type == GL_INT_2_10_10_10_REV || type == GL_UNSIGNED_INT_2_10_10_10_REV) && size != 4) 5891 { 5892 return gl::error(GL_INVALID_OPERATION); 5893 } 5894 5895 if (context) 5896 { 5897 // [OpenGL ES 3.0.2] Section 2.8 page 24: 5898 // An INVALID_OPERATION error is generated when a non-zero vertex array object 5899 // is bound, zero is bound to the ARRAY_BUFFER buffer object binding point, 5900 // and the pointer argument is not NULL. 5901 if (context->getVertexArrayHandle() != 0 && context->getArrayBufferHandle() == 0 && ptr != NULL) 5902 { 5903 return gl::error(GL_INVALID_OPERATION); 5904 } 5905 5906 context->setVertexAttribState(index, context->getArrayBuffer(), size, type, 5907 normalized == GL_TRUE, false, stride, ptr); 5908 } 5909 } 5910 catch (...) 5911 { 5912 return gl::error(GL_OUT_OF_MEMORY); 5913 } 5914} 5915 5916void __stdcall glViewport(GLint x, GLint y, GLsizei width, GLsizei height) 5917{ 5918 EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height); 5919 5920 try 5921 { 5922 if (width < 0 || height < 0) 5923 { 5924 return gl::error(GL_INVALID_VALUE); 5925 } 5926 5927 gl::Context *context = gl::getNonLostContext(); 5928 5929 if (context) 5930 { 5931 context->setViewportParams(x, y, width, height); 5932 } 5933 } 5934 catch (...) 5935 { 5936 return gl::error(GL_OUT_OF_MEMORY); 5937 } 5938} 5939 5940// OpenGL ES 3.0 functions 5941 5942void __stdcall glReadBuffer(GLenum mode) 5943{ 5944 EVENT("(GLenum mode = 0x%X)", mode); 5945 5946 try 5947 { 5948 gl::Context *context = gl::getNonLostContext(); 5949 5950 if (context) 5951 { 5952 if (context->getClientVersion() < 3) 5953 { 5954 return gl::error(GL_INVALID_OPERATION); 5955 } 5956 5957 // glReadBuffer 5958 UNIMPLEMENTED(); 5959 } 5960 } 5961 catch (...) 5962 { 5963 return gl::error(GL_OUT_OF_MEMORY); 5964 } 5965} 5966 5967void __stdcall glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid* indices) 5968{ 5969 EVENT("(GLenum mode = 0x%X, GLuint start = %u, GLuint end = %u, GLsizei count = %d, GLenum type = 0x%X, " 5970 "const GLvoid* indices = 0x%0.8p)", mode, start, end, count, type, indices); 5971 5972 try 5973 { 5974 gl::Context *context = gl::getNonLostContext(); 5975 5976 if (context) 5977 { 5978 if (context->getClientVersion() < 3) 5979 { 5980 return gl::error(GL_INVALID_OPERATION); 5981 } 5982 5983 // glDrawRangeElements 5984 UNIMPLEMENTED(); 5985 } 5986 } 5987 catch (...) 5988 { 5989 return gl::error(GL_OUT_OF_MEMORY); 5990 } 5991} 5992 5993void __stdcall glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels) 5994{ 5995 EVENT("(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, " 5996 "GLsizei height = %d, GLsizei depth = %d, GLint border = %d, GLenum format = 0x%X, " 5997 "GLenum type = 0x%X, const GLvoid* pixels = 0x%0.8p)", 5998 target, level, internalformat, width, height, depth, border, format, type, pixels); 5999 6000 try 6001 { 6002 gl::Context *context = gl::getNonLostContext(); 6003 6004 if (context) 6005 { 6006 if (context->getClientVersion() < 3) 6007 { 6008 return gl::error(GL_INVALID_OPERATION); 6009 } 6010 6011 // validateES3TexImageFormat sets the error code if there is an error 6012 if (!ValidateES3TexImageParameters(context, target, level, internalformat, false, false, 6013 0, 0, 0, width, height, depth, border, format, type, pixels)) 6014 { 6015 return; 6016 } 6017 6018 switch(target) 6019 { 6020 case GL_TEXTURE_3D: 6021 { 6022 gl::Texture3D *texture = context->getTexture3D(); 6023 texture->setImage(level, width, height, depth, internalformat, format, type, context->getUnpackState(), pixels); 6024 } 6025 break; 6026 6027 case GL_TEXTURE_2D_ARRAY: 6028 { 6029 gl::Texture2DArray *texture = context->getTexture2DArray(); 6030 texture->setImage(level, width, height, depth, internalformat, format, type, context->getUnpackState(), pixels); 6031 } 6032 break; 6033 6034 default: 6035 return gl::error(GL_INVALID_ENUM); 6036 } 6037 } 6038 } 6039 catch (...) 6040 { 6041 return gl::error(GL_OUT_OF_MEMORY); 6042 } 6043} 6044 6045void __stdcall glTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels) 6046{ 6047 EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, " 6048 "GLint zoffset = %d, GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, " 6049 "GLenum format = 0x%X, GLenum type = 0x%X, const GLvoid* pixels = 0x%0.8p)", 6050 target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels); 6051 6052 try 6053 { 6054 gl::Context *context = gl::getNonLostContext(); 6055 6056 if (context) 6057 { 6058 if (context->getClientVersion() < 3) 6059 { 6060 return gl::error(GL_INVALID_OPERATION); 6061 } 6062 6063 // validateES3TexImageFormat sets the error code if there is an error 6064 if (!ValidateES3TexImageParameters(context, target, level, GL_NONE, false, true, 6065 xoffset, yoffset, zoffset, width, height, depth, 0, 6066 format, type, pixels)) 6067 { 6068 return; 6069 } 6070 6071 // Zero sized uploads are valid but no-ops 6072 if (width == 0 || height == 0 || depth == 0) 6073 { 6074 return; 6075 } 6076 6077 switch(target) 6078 { 6079 case GL_TEXTURE_3D: 6080 { 6081 gl::Texture3D *texture = context->getTexture3D(); 6082 texture->subImage(level, xoffset, yoffset, zoffset, width, height, depth, format, type, context->getUnpackState(), pixels); 6083 } 6084 break; 6085 6086 case GL_TEXTURE_2D_ARRAY: 6087 { 6088 gl::Texture2DArray *texture = context->getTexture2DArray(); 6089 texture->subImage(level, xoffset, yoffset, zoffset, width, height, depth, format, type, context->getUnpackState(), pixels); 6090 } 6091 break; 6092 6093 default: 6094 return gl::error(GL_INVALID_ENUM); 6095 } 6096 } 6097 } 6098 catch (...) 6099 { 6100 return gl::error(GL_OUT_OF_MEMORY); 6101 } 6102} 6103 6104void __stdcall glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) 6105{ 6106 EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, " 6107 "GLint zoffset = %d, GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", 6108 target, level, xoffset, yoffset, zoffset, x, y, width, height); 6109 6110 try 6111 { 6112 gl::Context *context = gl::getNonLostContext(); 6113 6114 if (context) 6115 { 6116 if (context->getClientVersion() < 3) 6117 { 6118 return gl::error(GL_INVALID_OPERATION); 6119 } 6120 6121 if (!ValidateES3CopyTexImageParameters(context, target, level, GL_NONE, true, xoffset, yoffset, zoffset, 6122 x, y, width, height, 0)) 6123 { 6124 return; 6125 } 6126 6127 gl::Framebuffer *framebuffer = context->getReadFramebuffer(); 6128 gl::Texture *texture = NULL; 6129 switch (target) 6130 { 6131 case GL_TEXTURE_3D: 6132 texture = context->getTexture3D(); 6133 break; 6134 6135 case GL_TEXTURE_2D_ARRAY: 6136 texture = context->getTexture2DArray(); 6137 break; 6138 6139 default: 6140 return gl::error(GL_INVALID_ENUM); 6141 } 6142 6143 texture->copySubImage(target, level, xoffset, yoffset, zoffset, x, y, width, height, framebuffer); 6144 } 6145 } 6146 catch (...) 6147 { 6148 return gl::error(GL_OUT_OF_MEMORY); 6149 } 6150} 6151 6152void __stdcall glCompressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data) 6153{ 6154 EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, " 6155 "GLsizei height = %d, GLsizei depth = %d, GLint border = %d, GLsizei imageSize = %d, " 6156 "const GLvoid* data = 0x%0.8p)", 6157 target, level, internalformat, width, height, depth, border, imageSize, data); 6158 6159 try 6160 { 6161 gl::Context *context = gl::getNonLostContext(); 6162 6163 if (context) 6164 { 6165 if (context->getClientVersion() < 3) 6166 { 6167 return gl::error(GL_INVALID_OPERATION); 6168 } 6169 6170 if (imageSize < 0 || imageSize != (GLsizei)gl::GetBlockSize(internalformat, GL_UNSIGNED_BYTE, context->getClientVersion(), width, height)) 6171 { 6172 return gl::error(GL_INVALID_VALUE); 6173 } 6174 6175 // validateES3TexImageFormat sets the error code if there is an error 6176 if (!ValidateES3TexImageParameters(context, target, level, internalformat, true, false, 6177 0, 0, 0, width, height, depth, border, GL_NONE, GL_NONE, data)) 6178 { 6179 return; 6180 } 6181 6182 switch(target) 6183 { 6184 case GL_TEXTURE_3D: 6185 { 6186 gl::Texture3D *texture = context->getTexture3D(); 6187 texture->setCompressedImage(level, internalformat, width, height, depth, imageSize, data); 6188 } 6189 break; 6190 6191 case GL_TEXTURE_2D_ARRAY: 6192 { 6193 gl::Texture2DArray *texture = context->getTexture2DArray(); 6194 texture->setCompressedImage(level, internalformat, width, height, depth, imageSize, data); 6195 } 6196 break; 6197 6198 default: 6199 return gl::error(GL_INVALID_ENUM); 6200 } 6201 } 6202 } 6203 catch (...) 6204 { 6205 return gl::error(GL_OUT_OF_MEMORY); 6206 } 6207} 6208 6209void __stdcall glCompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data) 6210{ 6211 EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, " 6212 "GLint zoffset = %d, GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, " 6213 "GLenum format = 0x%X, GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)", 6214 target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data); 6215 6216 try 6217 { 6218 gl::Context *context = gl::getNonLostContext(); 6219 6220 if (context) 6221 { 6222 if (context->getClientVersion() < 3) 6223 { 6224 return gl::error(GL_INVALID_OPERATION); 6225 } 6226 6227 if (imageSize < 0 || imageSize != (GLsizei)gl::GetBlockSize(format, GL_UNSIGNED_BYTE, context->getClientVersion(), width, height)) 6228 { 6229 return gl::error(GL_INVALID_VALUE); 6230 } 6231 6232 if (!data) 6233 { 6234 return gl::error(GL_INVALID_VALUE); 6235 } 6236 6237 // validateES3TexImageFormat sets the error code if there is an error 6238 if (!ValidateES3TexImageParameters(context, target, level, GL_NONE, true, true, 6239 0, 0, 0, width, height, depth, 0, GL_NONE, GL_NONE, data)) 6240 { 6241 return; 6242 } 6243 6244 // Zero sized uploads are valid but no-ops 6245 if (width == 0 || height == 0) 6246 { 6247 return; 6248 } 6249 6250 switch(target) 6251 { 6252 case GL_TEXTURE_3D: 6253 { 6254 gl::Texture3D *texture = context->getTexture3D(); 6255 texture->subImageCompressed(level, xoffset, yoffset, zoffset, width, height, depth, 6256 format, imageSize, data); 6257 } 6258 break; 6259 6260 case GL_TEXTURE_2D_ARRAY: 6261 { 6262 gl::Texture2DArray *texture = context->getTexture2DArray(); 6263 texture->subImageCompressed(level, xoffset, yoffset, zoffset, width, height, depth, 6264 format, imageSize, data); 6265 } 6266 break; 6267 6268 default: 6269 return gl::error(GL_INVALID_ENUM); 6270 } 6271 } 6272 } 6273 catch (...) 6274 { 6275 return gl::error(GL_OUT_OF_MEMORY); 6276 } 6277} 6278 6279void __stdcall glGenQueries(GLsizei n, GLuint* ids) 6280{ 6281 EVENT("(GLsizei n = %d, GLuint* ids = 0x%0.8p)", n, ids); 6282 6283 try 6284 { 6285 gl::Context *context = gl::getNonLostContext(); 6286 6287 if (context) 6288 { 6289 if (context->getClientVersion() < 3) 6290 { 6291 return gl::error(GL_INVALID_OPERATION); 6292 } 6293 6294 if (n < 0) 6295 { 6296 return gl::error(GL_INVALID_VALUE); 6297 } 6298 6299 for (GLsizei i = 0; i < n; i++) 6300 { 6301 ids[i] = context->createQuery(); 6302 } 6303 } 6304 } 6305 catch (...) 6306 { 6307 return gl::error(GL_OUT_OF_MEMORY); 6308 } 6309} 6310 6311void __stdcall glDeleteQueries(GLsizei n, const GLuint* ids) 6312{ 6313 EVENT("(GLsizei n = %d, GLuint* ids = 0x%0.8p)", n, ids); 6314 6315 try 6316 { 6317 gl::Context *context = gl::getNonLostContext(); 6318 6319 if (context) 6320 { 6321 if (context->getClientVersion() < 3) 6322 { 6323 return gl::error(GL_INVALID_OPERATION); 6324 } 6325 6326 if (n < 0) 6327 { 6328 return gl::error(GL_INVALID_VALUE); 6329 } 6330 6331 for (GLsizei i = 0; i < n; i++) 6332 { 6333 context->deleteQuery(ids[i]); 6334 } 6335 } 6336 } 6337 catch (...) 6338 { 6339 return gl::error(GL_OUT_OF_MEMORY); 6340 } 6341} 6342 6343GLboolean __stdcall glIsQuery(GLuint id) 6344{ 6345 EVENT("(GLuint id = %u)", id); 6346 6347 try 6348 { 6349 gl::Context *context = gl::getNonLostContext(); 6350 6351 if (context) 6352 { 6353 if (context->getClientVersion() < 3) 6354 { 6355 return gl::error(GL_INVALID_OPERATION, GL_FALSE); 6356 } 6357 6358 return (context->getQuery(id, false, GL_NONE) != NULL) ? GL_TRUE : GL_FALSE; 6359 } 6360 } 6361 catch (...) 6362 { 6363 return gl::error(GL_OUT_OF_MEMORY, GL_FALSE); 6364 } 6365 6366 return GL_FALSE; 6367} 6368 6369void __stdcall glBeginQuery(GLenum target, GLuint id) 6370{ 6371 EVENT("(GLenum target = 0x%X, GLuint id = %u)", target, id); 6372 6373 try 6374 { 6375 gl::Context *context = gl::getNonLostContext(); 6376 6377 if (context) 6378 { 6379 if (context->getClientVersion() < 3) 6380 { 6381 return gl::error(GL_INVALID_OPERATION); 6382 } 6383 6384 if (!ValidateBeginQuery(context, target, id)) 6385 { 6386 return; 6387 } 6388 context->beginQuery(target, id); 6389 } 6390 } 6391 catch (...) 6392 { 6393 return gl::error(GL_OUT_OF_MEMORY); 6394 } 6395} 6396 6397void __stdcall glEndQuery(GLenum target) 6398{ 6399 EVENT("(GLenum target = 0x%X)", target); 6400 6401 try 6402 { 6403 gl::Context *context = gl::getNonLostContext(); 6404 6405 if (context) 6406 { 6407 if (context->getClientVersion() < 3) 6408 { 6409 return gl::error(GL_INVALID_OPERATION); 6410 } 6411 6412 if (!ValidateEndQuery(context, target)) 6413 { 6414 return; 6415 } 6416 6417 context->endQuery(target); 6418 } 6419 } 6420 catch (...) 6421 { 6422 return gl::error(GL_OUT_OF_MEMORY); 6423 } 6424} 6425 6426void __stdcall glGetQueryiv(GLenum target, GLenum pname, GLint* params) 6427{ 6428 EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params); 6429 6430 try 6431 { 6432 gl::Context *context = gl::getNonLostContext(); 6433 6434 if (context) 6435 { 6436 if (context->getClientVersion() < 3) 6437 { 6438 return gl::error(GL_INVALID_OPERATION); 6439 } 6440 6441 if (!ValidQueryType(context, target)) 6442 { 6443 return gl::error(GL_INVALID_ENUM); 6444 } 6445 6446 switch (pname) 6447 { 6448 case GL_CURRENT_QUERY: 6449 params[0] = static_cast<GLint>(context->getActiveQueryId(target)); 6450 break; 6451 6452 default: 6453 return gl::error(GL_INVALID_ENUM); 6454 } 6455 } 6456 } 6457 catch (...) 6458 { 6459 return gl::error(GL_OUT_OF_MEMORY); 6460 } 6461} 6462 6463void __stdcall glGetQueryObjectuiv(GLuint id, GLenum pname, GLuint* params) 6464{ 6465 EVENT("(GLuint id = %u, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", id, pname, params); 6466 6467 try 6468 { 6469 gl::Context *context = gl::getNonLostContext(); 6470 6471 if (context) 6472 { 6473 if (context->getClientVersion() < 3) 6474 { 6475 return gl::error(GL_INVALID_OPERATION); 6476 } 6477 6478 gl::Query *queryObject = context->getQuery(id, false, GL_NONE); 6479 6480 if (!queryObject) 6481 { 6482 return gl::error(GL_INVALID_OPERATION); 6483 } 6484 6485 if (context->getActiveQueryId(queryObject->getType()) == id) 6486 { 6487 return gl::error(GL_INVALID_OPERATION); 6488 } 6489 6490 switch(pname) 6491 { 6492 case GL_QUERY_RESULT: 6493 params[0] = queryObject->getResult(); 6494 break; 6495 case GL_QUERY_RESULT_AVAILABLE: 6496 params[0] = queryObject->isResultAvailable(); 6497 break; 6498 default: 6499 return gl::error(GL_INVALID_ENUM); 6500 } 6501 } 6502 } 6503 catch (...) 6504 { 6505 return gl::error(GL_OUT_OF_MEMORY); 6506 } 6507} 6508 6509GLboolean __stdcall glUnmapBuffer(GLenum target) 6510{ 6511 EVENT("(GLenum target = 0x%X)", target); 6512 6513 try 6514 { 6515 gl::Context *context = gl::getNonLostContext(); 6516 6517 if (context) 6518 { 6519 if (context->getClientVersion() < 3) 6520 { 6521 return gl::error(GL_INVALID_OPERATION, GL_FALSE); 6522 } 6523 6524 return glUnmapBufferOES(target); 6525 } 6526 } 6527 catch (...) 6528 { 6529 return gl::error(GL_OUT_OF_MEMORY, GL_FALSE); 6530 } 6531 6532 return GL_FALSE; 6533} 6534 6535void __stdcall glGetBufferPointerv(GLenum target, GLenum pname, GLvoid** params) 6536{ 6537 EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLvoid** params = 0x%0.8p)", target, pname, params); 6538 6539 try 6540 { 6541 gl::Context *context = gl::getNonLostContext(); 6542 6543 if (context) 6544 { 6545 if (context->getClientVersion() < 3) 6546 { 6547 return gl::error(GL_INVALID_OPERATION); 6548 } 6549 6550 glGetBufferPointervOES(target, pname, params); 6551 } 6552 } 6553 catch (...) 6554 { 6555 return gl::error(GL_OUT_OF_MEMORY); 6556 } 6557} 6558 6559void __stdcall glDrawBuffers(GLsizei n, const GLenum* bufs) 6560{ 6561 try 6562 { 6563 gl::Context *context = gl::getNonLostContext(); 6564 6565 if (context) 6566 { 6567 if (context->getClientVersion() < 3) 6568 { 6569 return gl::error(GL_INVALID_OPERATION); 6570 } 6571 6572 glDrawBuffersEXT(n, bufs); 6573 } 6574 } 6575 catch (...) 6576 { 6577 return gl::error(GL_OUT_OF_MEMORY); 6578 } 6579} 6580 6581void __stdcall glUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) 6582{ 6583 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)", 6584 location, count, transpose, value); 6585 6586 try 6587 { 6588 gl::Context *context = gl::getNonLostContext(); 6589 6590 if (context) 6591 { 6592 if (!ValidateUniformMatrix(context, GL_FLOAT_MAT2x3, location, count, transpose)) 6593 { 6594 return; 6595 } 6596 6597 gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); 6598 programBinary->setUniformMatrix2x3fv(location, count, transpose, value); 6599 } 6600 } 6601 catch (...) 6602 { 6603 return gl::error(GL_OUT_OF_MEMORY); 6604 } 6605} 6606 6607void __stdcall glUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) 6608{ 6609 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)", 6610 location, count, transpose, value); 6611 6612 try 6613 { 6614 gl::Context *context = gl::getNonLostContext(); 6615 6616 if (context) 6617 { 6618 if (!ValidateUniformMatrix(context, GL_FLOAT_MAT3x2, location, count, transpose)) 6619 { 6620 return; 6621 } 6622 6623 gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); 6624 programBinary->setUniformMatrix3x2fv(location, count, transpose, value); 6625 } 6626 } 6627 catch (...) 6628 { 6629 return gl::error(GL_OUT_OF_MEMORY); 6630 } 6631} 6632 6633void __stdcall glUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) 6634{ 6635 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)", 6636 location, count, transpose, value); 6637 6638 try 6639 { 6640 gl::Context *context = gl::getNonLostContext(); 6641 6642 if (context) 6643 { 6644 if (!ValidateUniformMatrix(context, GL_FLOAT_MAT2x4, location, count, transpose)) 6645 { 6646 return; 6647 } 6648 6649 gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); 6650 programBinary->setUniformMatrix2x4fv(location, count, transpose, value); 6651 } 6652 } 6653 catch (...) 6654 { 6655 return gl::error(GL_OUT_OF_MEMORY); 6656 } 6657} 6658 6659void __stdcall glUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) 6660{ 6661 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)", 6662 location, count, transpose, value); 6663 6664 try 6665 { 6666 gl::Context *context = gl::getNonLostContext(); 6667 6668 if (context) 6669 { 6670 if (!ValidateUniformMatrix(context, GL_FLOAT_MAT4x2, location, count, transpose)) 6671 { 6672 return; 6673 } 6674 6675 gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); 6676 programBinary->setUniformMatrix4x2fv(location, count, transpose, value); 6677 } 6678 } 6679 catch (...) 6680 { 6681 return gl::error(GL_OUT_OF_MEMORY); 6682 } 6683} 6684 6685void __stdcall glUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) 6686{ 6687 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)", 6688 location, count, transpose, value); 6689 6690 try 6691 { 6692 gl::Context *context = gl::getNonLostContext(); 6693 6694 if (context) 6695 { 6696 if (!ValidateUniformMatrix(context, GL_FLOAT_MAT3x4, location, count, transpose)) 6697 { 6698 return; 6699 } 6700 6701 gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); 6702 programBinary->setUniformMatrix3x4fv(location, count, transpose, value); 6703 } 6704 } 6705 catch (...) 6706 { 6707 return gl::error(GL_OUT_OF_MEMORY); 6708 } 6709} 6710 6711void __stdcall glUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) 6712{ 6713 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)", 6714 location, count, transpose, value); 6715 6716 try 6717 { 6718 gl::Context *context = gl::getNonLostContext(); 6719 6720 if (context) 6721 { 6722 if (!ValidateUniformMatrix(context, GL_FLOAT_MAT4x3, location, count, transpose)) 6723 { 6724 return; 6725 } 6726 6727 gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); 6728 programBinary->setUniformMatrix4x3fv(location, count, transpose, value); 6729 } 6730 } 6731 catch (...) 6732 { 6733 return gl::error(GL_OUT_OF_MEMORY); 6734 } 6735} 6736 6737void __stdcall glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) 6738{ 6739 EVENT("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, GLint dstX0 = %d, " 6740 "GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, GLbitfield mask = 0x%X, GLenum filter = 0x%X)", 6741 srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); 6742 6743 try 6744 { 6745 gl::Context *context = gl::getNonLostContext(); 6746 if (context) 6747 { 6748 if (context->getClientVersion() < 3) 6749 { 6750 return gl::error(GL_INVALID_OPERATION); 6751 } 6752 6753 if (!ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1, 6754 dstX0, dstY0, dstX1, dstY1, mask, filter, 6755 false)) 6756 { 6757 return; 6758 } 6759 6760 context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, 6761 mask, filter); 6762 } 6763 } 6764 catch (...) 6765 { 6766 return gl::error(GL_OUT_OF_MEMORY); 6767 } 6768} 6769 6770void __stdcall glRenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) 6771{ 6772 EVENT("(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)", 6773 target, samples, internalformat, width, height); 6774 6775 try 6776 { 6777 gl::Context *context = gl::getNonLostContext(); 6778 6779 if (context) 6780 { 6781 if (context->getClientVersion() < 3) 6782 { 6783 return gl::error(GL_INVALID_OPERATION); 6784 } 6785 6786 if (!ValidateRenderbufferStorageParameters(context, target, samples, internalformat, 6787 width, height, false)) 6788 { 6789 return; 6790 } 6791 6792 context->setRenderbufferStorage(width, height, internalformat, samples); 6793 } 6794 } 6795 catch (...) 6796 { 6797 return gl::error(GL_OUT_OF_MEMORY); 6798 } 6799} 6800 6801void __stdcall glFramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer) 6802{ 6803 EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLuint texture = %u, GLint level = %d, GLint layer = %d)", 6804 target, attachment, texture, level, layer); 6805 6806 try 6807 { 6808 gl::Context *context = gl::getNonLostContext(); 6809 6810 if (context) 6811 { 6812 if (context->getClientVersion() < 3) 6813 { 6814 return gl::error(GL_INVALID_OPERATION); 6815 } 6816 6817 if (!ValidateES3FramebufferTextureParameters(context, target, attachment, GL_NONE, texture, level, layer, true)) 6818 { 6819 return; 6820 } 6821 6822 gl::Framebuffer *framebuffer = context->getTargetFramebuffer(target); 6823 ASSERT(framebuffer); 6824 6825 gl::Texture *textureObject = context->getTexture(texture); 6826 GLenum textarget = textureObject ? textureObject->getTarget() : GL_NONE; 6827 6828 if (attachment >= GL_COLOR_ATTACHMENT0_EXT && attachment <= GL_COLOR_ATTACHMENT15_EXT) 6829 { 6830 const unsigned int colorAttachment = (attachment - GL_COLOR_ATTACHMENT0_EXT); 6831 framebuffer->setColorbuffer(colorAttachment, textarget, texture, level, layer); 6832 } 6833 else 6834 { 6835 switch (attachment) 6836 { 6837 case GL_DEPTH_ATTACHMENT: framebuffer->setDepthbuffer(textarget, texture, level, layer); break; 6838 case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture, level, layer); break; 6839 case GL_DEPTH_STENCIL_ATTACHMENT: framebuffer->setDepthStencilBuffer(textarget, texture, level, layer); break; 6840 } 6841 } 6842 } 6843 } 6844 catch (...) 6845 { 6846 return gl::error(GL_OUT_OF_MEMORY); 6847 } 6848} 6849 6850GLvoid* __stdcall glMapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access) 6851{ 6852 EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr length = %d, GLbitfield access = 0x%X)", 6853 target, offset, length, access); 6854 6855 try 6856 { 6857 gl::Context *context = gl::getNonLostContext(); 6858 6859 if (context) 6860 { 6861 if (context->getClientVersion() < 3) 6862 { 6863 return gl::error(GL_INVALID_OPERATION, reinterpret_cast<GLvoid*>(NULL)); 6864 } 6865 6866 return glMapBufferRangeEXT(target, offset, length, access); 6867 } 6868 } 6869 catch (...) 6870 { 6871 return gl::error(GL_OUT_OF_MEMORY, reinterpret_cast<GLvoid*>(NULL)); 6872 } 6873 6874 return NULL; 6875} 6876 6877void __stdcall glFlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length) 6878{ 6879 EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr length = %d)", target, offset, length); 6880 6881 try 6882 { 6883 gl::Context *context = gl::getNonLostContext(); 6884 6885 if (context) 6886 { 6887 if (context->getClientVersion() < 3) 6888 { 6889 return gl::error(GL_INVALID_OPERATION); 6890 } 6891 6892 glFlushMappedBufferRangeEXT(target, offset, length); 6893 } 6894 } 6895 catch (...) 6896 { 6897 return gl::error(GL_OUT_OF_MEMORY); 6898 } 6899} 6900 6901void __stdcall glBindVertexArray(GLuint array) 6902{ 6903 EVENT("(GLuint array = %u)", array); 6904 6905 try 6906 { 6907 gl::Context *context = gl::getNonLostContext(); 6908 6909 if (context) 6910 { 6911 if (context->getClientVersion() < 3) 6912 { 6913 return gl::error(GL_INVALID_OPERATION); 6914 } 6915 6916 gl::VertexArray *vao = context->getVertexArray(array); 6917 6918 if (!vao) 6919 { 6920 // The default VAO should always exist 6921 ASSERT(array != 0); 6922 return gl::error(GL_INVALID_OPERATION); 6923 } 6924 6925 context->bindVertexArray(array); 6926 } 6927 } 6928 catch (...) 6929 { 6930 return gl::error(GL_OUT_OF_MEMORY); 6931 } 6932} 6933 6934void __stdcall glDeleteVertexArrays(GLsizei n, const GLuint* arrays) 6935{ 6936 EVENT("(GLsizei n = %d, const GLuint* arrays = 0x%0.8p)", n, arrays); 6937 6938 try 6939 { 6940 gl::Context *context = gl::getNonLostContext(); 6941 6942 if (context) 6943 { 6944 if (context->getClientVersion() < 3) 6945 { 6946 return gl::error(GL_INVALID_OPERATION); 6947 } 6948 6949 if (n < 0) 6950 { 6951 return gl::error(GL_INVALID_VALUE); 6952 } 6953 6954 for (int arrayIndex = 0; arrayIndex < n; arrayIndex++) 6955 { 6956 if (arrays[arrayIndex] != 0) 6957 { 6958 context->deleteVertexArray(arrays[arrayIndex]); 6959 } 6960 } 6961 } 6962 } 6963 catch (...) 6964 { 6965 return gl::error(GL_OUT_OF_MEMORY); 6966 } 6967} 6968 6969void __stdcall glGenVertexArrays(GLsizei n, GLuint* arrays) 6970{ 6971 EVENT("(GLsizei n = %d, GLuint* arrays = 0x%0.8p)", n, arrays); 6972 6973 try 6974 { 6975 gl::Context *context = gl::getNonLostContext(); 6976 6977 if (context) 6978 { 6979 if (context->getClientVersion() < 3) 6980 { 6981 return gl::error(GL_INVALID_OPERATION); 6982 } 6983 6984 if (n < 0) 6985 { 6986 return gl::error(GL_INVALID_VALUE); 6987 } 6988 6989 for (int arrayIndex = 0; arrayIndex < n; arrayIndex++) 6990 { 6991 arrays[arrayIndex] = context->createVertexArray(); 6992 } 6993 } 6994 } 6995 catch (...) 6996 { 6997 return gl::error(GL_OUT_OF_MEMORY); 6998 } 6999} 7000 7001GLboolean __stdcall glIsVertexArray(GLuint array) 7002{ 7003 EVENT("(GLuint array = %u)", array); 7004 7005 try 7006 { 7007 gl::Context *context = gl::getNonLostContext(); 7008 7009 if (context) 7010 { 7011 if (context->getClientVersion() < 3) 7012 { 7013 return gl::error(GL_INVALID_OPERATION, GL_FALSE); 7014 } 7015 7016 if (array == 0) 7017 { 7018 return GL_FALSE; 7019 } 7020 7021 gl::VertexArray *vao = context->getVertexArray(array); 7022 7023 return (vao != NULL ? GL_TRUE : GL_FALSE); 7024 } 7025 } 7026 catch (...) 7027 { 7028 return gl::error(GL_OUT_OF_MEMORY, GL_FALSE); 7029 } 7030 7031 return GL_FALSE; 7032} 7033 7034void __stdcall glGetIntegeri_v(GLenum target, GLuint index, GLint* data) 7035{ 7036 EVENT("(GLenum target = 0x%X, GLuint index = %u, GLint* data = 0x%0.8p)", 7037 target, index, data); 7038 7039 try 7040 { 7041 gl::Context *context = gl::getNonLostContext(); 7042 7043 if (context) 7044 { 7045 if (context->getClientVersion() < 3) 7046 { 7047 return gl::error(GL_INVALID_OPERATION); 7048 } 7049 7050 switch (target) 7051 { 7052 case GL_TRANSFORM_FEEDBACK_BUFFER_START: 7053 case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE: 7054 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: 7055 if (index >= context->getMaxTransformFeedbackBufferBindings()) 7056 return gl::error(GL_INVALID_VALUE); 7057 break; 7058 case GL_UNIFORM_BUFFER_START: 7059 case GL_UNIFORM_BUFFER_SIZE: 7060 case GL_UNIFORM_BUFFER_BINDING: 7061 if (index >= context->getMaximumCombinedUniformBufferBindings()) 7062 return gl::error(GL_INVALID_VALUE); 7063 break; 7064 default: 7065 return gl::error(GL_INVALID_ENUM); 7066 } 7067 7068 if (!(context->getIndexedIntegerv(target, index, data))) 7069 { 7070 GLenum nativeType; 7071 unsigned int numParams = 0; 7072 if (!context->getIndexedQueryParameterInfo(target, &nativeType, &numParams)) 7073 return gl::error(GL_INVALID_ENUM); 7074 7075 if (numParams == 0) 7076 return; // it is known that pname is valid, but there are no parameters to return 7077 7078 if (nativeType == GL_INT_64_ANGLEX) 7079 { 7080 GLint64 minIntValue = static_cast<GLint64>(std::numeric_limits<int>::min()); 7081 GLint64 maxIntValue = static_cast<GLint64>(std::numeric_limits<int>::max()); 7082 GLint64 *int64Params = new GLint64[numParams]; 7083 7084 context->getIndexedInteger64v(target, index, int64Params); 7085 7086 for (unsigned int i = 0; i < numParams; ++i) 7087 { 7088 GLint64 clampedValue = std::max(std::min(int64Params[i], maxIntValue), minIntValue); 7089 data[i] = static_cast<GLint>(clampedValue); 7090 } 7091 7092 delete [] int64Params; 7093 } 7094 else 7095 { 7096 UNREACHABLE(); 7097 } 7098 } 7099 } 7100 } 7101 catch (...) 7102 { 7103 return gl::error(GL_OUT_OF_MEMORY); 7104 } 7105} 7106 7107void __stdcall glBeginTransformFeedback(GLenum primitiveMode) 7108{ 7109 EVENT("(GLenum primitiveMode = 0x%X)", primitiveMode); 7110 7111 try 7112 { 7113 gl::Context *context = gl::getNonLostContext(); 7114 7115 if (context) 7116 { 7117 if (context->getClientVersion() < 3) 7118 { 7119 return gl::error(GL_INVALID_OPERATION); 7120 } 7121 7122 switch (primitiveMode) 7123 { 7124 case GL_TRIANGLES: 7125 case GL_LINES: 7126 case GL_POINTS: 7127 break; 7128 default: 7129 return gl::error(GL_INVALID_ENUM); 7130 } 7131 7132 gl::TransformFeedback *transformFeedback = context->getCurrentTransformFeedback(); 7133 ASSERT(transformFeedback != NULL); 7134 7135 if (transformFeedback->isStarted()) 7136 { 7137 return gl::error(GL_INVALID_OPERATION); 7138 } 7139 7140 if (transformFeedback->isPaused()) 7141 { 7142 transformFeedback->resume(); 7143 } 7144 else 7145 { 7146 transformFeedback->start(primitiveMode); 7147 } 7148 } 7149 } 7150 catch (...) 7151 { 7152 return gl::error(GL_OUT_OF_MEMORY); 7153 } 7154} 7155 7156void __stdcall glEndTransformFeedback(void) 7157{ 7158 EVENT("(void)"); 7159 7160 try 7161 { 7162 gl::Context *context = gl::getNonLostContext(); 7163 7164 if (context) 7165 { 7166 if (context->getClientVersion() < 3) 7167 { 7168 return gl::error(GL_INVALID_OPERATION); 7169 } 7170 7171 gl::TransformFeedback *transformFeedback = context->getCurrentTransformFeedback(); 7172 ASSERT(transformFeedback != NULL); 7173 7174 if (!transformFeedback->isStarted()) 7175 { 7176 return gl::error(GL_INVALID_OPERATION); 7177 } 7178 7179 transformFeedback->stop(); 7180 } 7181 } 7182 catch (...) 7183 { 7184 return gl::error(GL_OUT_OF_MEMORY); 7185 } 7186} 7187 7188void __stdcall glBindBufferRange(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size) 7189{ 7190 EVENT("(GLenum target = 0x%X, GLuint index = %u, GLuint buffer = %u, GLintptr offset = %d, GLsizeiptr size = %d)", 7191 target, index, buffer, offset, size); 7192 7193 try 7194 { 7195 gl::Context *context = gl::getNonLostContext(); 7196 7197 if (context) 7198 { 7199 if (context->getClientVersion() < 3) 7200 { 7201 return gl::error(GL_INVALID_OPERATION); 7202 } 7203 7204 switch (target) 7205 { 7206 case GL_TRANSFORM_FEEDBACK_BUFFER: 7207 if (index >= context->getMaxTransformFeedbackBufferBindings()) 7208 { 7209 return gl::error(GL_INVALID_VALUE); 7210 } 7211 break; 7212 7213 case GL_UNIFORM_BUFFER: 7214 if (index >= context->getMaximumCombinedUniformBufferBindings()) 7215 { 7216 return gl::error(GL_INVALID_VALUE); 7217 } 7218 break; 7219 7220 default: 7221 return gl::error(GL_INVALID_ENUM); 7222 } 7223 7224 if (buffer != 0 && size <= 0) 7225 { 7226 return gl::error(GL_INVALID_VALUE); 7227 } 7228 7229 switch (target) 7230 { 7231 case GL_TRANSFORM_FEEDBACK_BUFFER: 7232 7233 // size and offset must be a multiple of 4 7234 if (buffer != 0 && ((offset % 4) != 0 || (size % 4) != 0)) 7235 { 7236 return gl::error(GL_INVALID_VALUE); 7237 } 7238 7239 context->bindIndexedTransformFeedbackBuffer(buffer, index, offset, size); 7240 context->bindGenericTransformFeedbackBuffer(buffer); 7241 break; 7242 7243 case GL_UNIFORM_BUFFER: 7244 7245 // it is an error to bind an offset not a multiple of the alignment 7246 if (buffer != 0 && (offset % context->getUniformBufferOffsetAlignment()) != 0) 7247 { 7248 return gl::error(GL_INVALID_VALUE); 7249 } 7250 7251 context->bindIndexedUniformBuffer(buffer, index, offset, size); 7252 context->bindGenericUniformBuffer(buffer); 7253 break; 7254 7255 default: 7256 UNREACHABLE(); 7257 } 7258 } 7259 } 7260 catch (...) 7261 { 7262 return gl::error(GL_OUT_OF_MEMORY); 7263 } 7264} 7265 7266void __stdcall glBindBufferBase(GLenum target, GLuint index, GLuint buffer) 7267{ 7268 EVENT("(GLenum target = 0x%X, GLuint index = %u, GLuint buffer = %u)", 7269 target, index, buffer); 7270 7271 try 7272 { 7273 gl::Context *context = gl::getNonLostContext(); 7274 7275 if (context) 7276 { 7277 if (context->getClientVersion() < 3) 7278 { 7279 return gl::error(GL_INVALID_OPERATION); 7280 } 7281 7282 switch (target) 7283 { 7284 case GL_TRANSFORM_FEEDBACK_BUFFER: 7285 if (index >= context->getMaxTransformFeedbackBufferBindings()) 7286 { 7287 return gl::error(GL_INVALID_VALUE); 7288 } 7289 break; 7290 7291 case GL_UNIFORM_BUFFER: 7292 if (index >= context->getMaximumCombinedUniformBufferBindings()) 7293 { 7294 return gl::error(GL_INVALID_VALUE); 7295 } 7296 break; 7297 7298 default: 7299 return gl::error(GL_INVALID_ENUM); 7300 } 7301 7302 switch (target) 7303 { 7304 case GL_TRANSFORM_FEEDBACK_BUFFER: 7305 context->bindIndexedTransformFeedbackBuffer(buffer, index, 0, 0); 7306 context->bindGenericTransformFeedbackBuffer(buffer); 7307 break; 7308 7309 case GL_UNIFORM_BUFFER: 7310 context->bindIndexedUniformBuffer(buffer, index, 0, 0); 7311 context->bindGenericUniformBuffer(buffer); 7312 break; 7313 7314 default: 7315 UNREACHABLE(); 7316 } 7317 } 7318 } 7319 catch (...) 7320 { 7321 return gl::error(GL_OUT_OF_MEMORY); 7322 } 7323} 7324 7325void __stdcall glTransformFeedbackVaryings(GLuint program, GLsizei count, const GLchar* const* varyings, GLenum bufferMode) 7326{ 7327 EVENT("(GLuint program = %u, GLsizei count = %d, const GLchar* const* varyings = 0x%0.8p, GLenum bufferMode = 0x%X)", 7328 program, count, varyings, bufferMode); 7329 7330 try 7331 { 7332 gl::Context *context = gl::getNonLostContext(); 7333 7334 if (context) 7335 { 7336 if (context->getClientVersion() < 3) 7337 { 7338 return gl::error(GL_INVALID_OPERATION); 7339 } 7340 7341 if (count < 0) 7342 { 7343 return gl::error(GL_INVALID_VALUE); 7344 } 7345 7346 switch (bufferMode) 7347 { 7348 case GL_INTERLEAVED_ATTRIBS: 7349 break; 7350 case GL_SEPARATE_ATTRIBS: 7351 if (static_cast<GLuint>(count) > context->getMaxTransformFeedbackBufferBindings()) 7352 { 7353 return gl::error(GL_INVALID_VALUE); 7354 } 7355 break; 7356 default: 7357 return gl::error(GL_INVALID_ENUM); 7358 } 7359 7360 if (!gl::ValidProgram(context, program)) 7361 { 7362 return; 7363 } 7364 7365 gl::Program *programObject = context->getProgram(program); 7366 ASSERT(programObject); 7367 7368 programObject->setTransformFeedbackVaryings(count, varyings, bufferMode); 7369 } 7370 } 7371 catch (...) 7372 { 7373 return gl::error(GL_OUT_OF_MEMORY); 7374 } 7375} 7376 7377void __stdcall glGetTransformFeedbackVarying(GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLsizei* size, GLenum* type, GLchar* name) 7378{ 7379 EVENT("(GLuint program = %u, GLuint index = %u, GLsizei bufSize = %d, GLsizei* length = 0x%0.8p, " 7380 "GLsizei* size = 0x%0.8p, GLenum* type = 0x%0.8p, GLchar* name = 0x%0.8p)", 7381 program, index, bufSize, length, size, type, name); 7382 7383 try 7384 { 7385 gl::Context *context = gl::getNonLostContext(); 7386 7387 if (context) 7388 { 7389 if (context->getClientVersion() < 3) 7390 { 7391 return gl::error(GL_INVALID_OPERATION); 7392 } 7393 7394 if (bufSize < 0) 7395 { 7396 return gl::error(GL_INVALID_VALUE); 7397 } 7398 7399 if (!gl::ValidProgram(context, program)) 7400 { 7401 return; 7402 } 7403 7404 gl::Program *programObject = context->getProgram(program); 7405 ASSERT(programObject); 7406 7407 if (index >= static_cast<GLuint>(programObject->getTransformFeedbackVaryingCount())) 7408 { 7409 return gl::error(GL_INVALID_VALUE); 7410 } 7411 7412 programObject->getTransformFeedbackVarying(index, bufSize, length, size, type, name); 7413 } 7414 } 7415 catch (...) 7416 { 7417 return gl::error(GL_OUT_OF_MEMORY); 7418 } 7419} 7420 7421void __stdcall glVertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid* pointer) 7422{ 7423 EVENT("(GLuint index = %u, GLint size = %d, GLenum type = 0x%X, GLsizei stride = %d, const GLvoid* pointer = 0x%0.8p)", 7424 index, size, type, stride, pointer); 7425 7426 try 7427 { 7428 gl::Context *context = gl::getNonLostContext(); 7429 7430 if (context) 7431 { 7432 if (context->getClientVersion() < 3) 7433 { 7434 return gl::error(GL_INVALID_OPERATION); 7435 } 7436 } 7437 7438 if (index >= gl::MAX_VERTEX_ATTRIBS) 7439 { 7440 return gl::error(GL_INVALID_VALUE); 7441 } 7442 7443 if (size < 1 || size > 4) 7444 { 7445 return gl::error(GL_INVALID_VALUE); 7446 } 7447 7448 switch (type) 7449 { 7450 case GL_BYTE: 7451 case GL_UNSIGNED_BYTE: 7452 case GL_SHORT: 7453 case GL_UNSIGNED_SHORT: 7454 case GL_INT: 7455 case GL_UNSIGNED_INT: 7456 case GL_INT_2_10_10_10_REV: 7457 case GL_UNSIGNED_INT_2_10_10_10_REV: 7458 break; 7459 default: 7460 return gl::error(GL_INVALID_ENUM); 7461 } 7462 7463 if (stride < 0) 7464 { 7465 return gl::error(GL_INVALID_VALUE); 7466 } 7467 7468 if ((type == GL_INT_2_10_10_10_REV || type == GL_UNSIGNED_INT_2_10_10_10_REV) && size != 4) 7469 { 7470 return gl::error(GL_INVALID_OPERATION); 7471 } 7472 7473 if (context) 7474 { 7475 // [OpenGL ES 3.0.2] Section 2.8 page 24: 7476 // An INVALID_OPERATION error is generated when a non-zero vertex array object 7477 // is bound, zero is bound to the ARRAY_BUFFER buffer object binding point, 7478 // and the pointer argument is not NULL. 7479 if (context->getVertexArrayHandle() != 0 && context->getArrayBufferHandle() == 0 && pointer != NULL) 7480 { 7481 return gl::error(GL_INVALID_OPERATION); 7482 } 7483 7484 context->setVertexAttribState(index, context->getArrayBuffer(), size, type, false, true, 7485 stride, pointer); 7486 } 7487 } 7488 catch (...) 7489 { 7490 return gl::error(GL_OUT_OF_MEMORY); 7491 } 7492} 7493 7494void __stdcall glGetVertexAttribIiv(GLuint index, GLenum pname, GLint* params) 7495{ 7496 EVENT("(GLuint index = %u, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", 7497 index, pname, params); 7498 7499 try 7500 { 7501 gl::Context *context = gl::getNonLostContext(); 7502 7503 if (context) 7504 { 7505 if (context->getClientVersion() < 3) 7506 { 7507 return gl::error(GL_INVALID_OPERATION); 7508 } 7509 7510 if (index >= gl::MAX_VERTEX_ATTRIBS) 7511 { 7512 return gl::error(GL_INVALID_VALUE); 7513 } 7514 7515 const gl::VertexAttribute &attribState = context->getVertexAttribState(index); 7516 7517 if (!gl::ValidateGetVertexAttribParameters(pname, context->getClientVersion())) 7518 { 7519 return; 7520 } 7521 7522 if (pname == GL_CURRENT_VERTEX_ATTRIB) 7523 { 7524 const gl::VertexAttribCurrentValueData ¤tValueData = context->getVertexAttribCurrentValue(index); 7525 for (int i = 0; i < 4; ++i) 7526 { 7527 params[i] = currentValueData.IntValues[i]; 7528 } 7529 } 7530 else 7531 { 7532 *params = attribState.querySingleParameter<GLint>(pname); 7533 } 7534 } 7535 } 7536 catch (...) 7537 { 7538 return gl::error(GL_OUT_OF_MEMORY); 7539 } 7540} 7541 7542void __stdcall glGetVertexAttribIuiv(GLuint index, GLenum pname, GLuint* params) 7543{ 7544 EVENT("(GLuint index = %u, GLenum pname = 0x%X, GLuint* params = 0x%0.8p)", 7545 index, pname, params); 7546 7547 try 7548 { 7549 gl::Context *context = gl::getNonLostContext(); 7550 7551 if (context) 7552 { 7553 if (context->getClientVersion() < 3) 7554 { 7555 return gl::error(GL_INVALID_OPERATION); 7556 } 7557 7558 if (index >= gl::MAX_VERTEX_ATTRIBS) 7559 { 7560 return gl::error(GL_INVALID_VALUE); 7561 } 7562 7563 const gl::VertexAttribute &attribState = context->getVertexAttribState(index); 7564 7565 if (!gl::ValidateGetVertexAttribParameters(pname, context->getClientVersion())) 7566 { 7567 return; 7568 } 7569 7570 if (pname == GL_CURRENT_VERTEX_ATTRIB) 7571 { 7572 const gl::VertexAttribCurrentValueData ¤tValueData = context->getVertexAttribCurrentValue(index); 7573 for (int i = 0; i < 4; ++i) 7574 { 7575 params[i] = currentValueData.UnsignedIntValues[i]; 7576 } 7577 } 7578 else 7579 { 7580 *params = attribState.querySingleParameter<GLuint>(pname); 7581 } 7582 } 7583 } 7584 catch (...) 7585 { 7586 return gl::error(GL_OUT_OF_MEMORY); 7587 } 7588} 7589 7590void __stdcall glVertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w) 7591{ 7592 EVENT("(GLuint index = %u, GLint x = %d, GLint y = %d, GLint z = %d, GLint w = %d)", 7593 index, x, y, z, w); 7594 7595 try 7596 { 7597 gl::Context *context = gl::getNonLostContext(); 7598 7599 if (context) 7600 { 7601 if (context->getClientVersion() < 3) 7602 { 7603 return gl::error(GL_INVALID_OPERATION); 7604 } 7605 7606 if (index >= gl::MAX_VERTEX_ATTRIBS) 7607 { 7608 return gl::error(GL_INVALID_VALUE); 7609 } 7610 7611 GLint vals[4] = { x, y, z, w }; 7612 context->setVertexAttribi(index, vals); 7613 } 7614 } 7615 catch (...) 7616 { 7617 return gl::error(GL_OUT_OF_MEMORY); 7618 } 7619} 7620 7621void __stdcall glVertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w) 7622{ 7623 EVENT("(GLuint index = %u, GLuint x = %u, GLuint y = %u, GLuint z = %u, GLuint w = %u)", 7624 index, x, y, z, w); 7625 7626 try 7627 { 7628 gl::Context *context = gl::getNonLostContext(); 7629 7630 if (context) 7631 { 7632 if (context->getClientVersion() < 3) 7633 { 7634 return gl::error(GL_INVALID_OPERATION); 7635 } 7636 7637 if (index >= gl::MAX_VERTEX_ATTRIBS) 7638 { 7639 return gl::error(GL_INVALID_VALUE); 7640 } 7641 7642 GLuint vals[4] = { x, y, z, w }; 7643 context->setVertexAttribu(index, vals); 7644 } 7645 } 7646 catch (...) 7647 { 7648 return gl::error(GL_OUT_OF_MEMORY); 7649 } 7650} 7651 7652void __stdcall glVertexAttribI4iv(GLuint index, const GLint* v) 7653{ 7654 EVENT("(GLuint index = %u, const GLint* v = 0x%0.8p)", index, v); 7655 7656 try 7657 { 7658 gl::Context *context = gl::getNonLostContext(); 7659 7660 if (context) 7661 { 7662 if (context->getClientVersion() < 3) 7663 { 7664 return gl::error(GL_INVALID_OPERATION); 7665 } 7666 7667 if (index >= gl::MAX_VERTEX_ATTRIBS) 7668 { 7669 return gl::error(GL_INVALID_VALUE); 7670 } 7671 7672 context->setVertexAttribi(index, v); 7673 } 7674 } 7675 catch (...) 7676 { 7677 return gl::error(GL_OUT_OF_MEMORY); 7678 } 7679} 7680 7681void __stdcall glVertexAttribI4uiv(GLuint index, const GLuint* v) 7682{ 7683 EVENT("(GLuint index = %u, const GLuint* v = 0x%0.8p)", index, v); 7684 7685 try 7686 { 7687 gl::Context *context = gl::getNonLostContext(); 7688 7689 if (context) 7690 { 7691 if (context->getClientVersion() < 3) 7692 { 7693 return gl::error(GL_INVALID_OPERATION); 7694 } 7695 7696 if (index >= gl::MAX_VERTEX_ATTRIBS) 7697 { 7698 return gl::error(GL_INVALID_VALUE); 7699 } 7700 7701 context->setVertexAttribu(index, v); 7702 } 7703 } 7704 catch (...) 7705 { 7706 return gl::error(GL_OUT_OF_MEMORY); 7707 } 7708} 7709 7710void __stdcall glGetUniformuiv(GLuint program, GLint location, GLuint* params) 7711{ 7712 EVENT("(GLuint program = %u, GLint location = %d, GLuint* params = 0x%0.8p)", 7713 program, location, params); 7714 7715 try 7716 { 7717 gl::Context *context = gl::getNonLostContext(); 7718 7719 if (context) 7720 { 7721 if (context->getClientVersion() < 3) 7722 { 7723 return gl::error(GL_INVALID_OPERATION); 7724 } 7725 7726 if (program == 0) 7727 { 7728 return gl::error(GL_INVALID_VALUE); 7729 } 7730 7731 gl::Program *programObject = context->getProgram(program); 7732 7733 if (!programObject || !programObject->isLinked()) 7734 { 7735 return gl::error(GL_INVALID_OPERATION); 7736 } 7737 7738 gl::ProgramBinary *programBinary = programObject->getProgramBinary(); 7739 if (!programBinary) 7740 { 7741 return gl::error(GL_INVALID_OPERATION); 7742 } 7743 7744 if (!programBinary->getUniformuiv(location, NULL, params)) 7745 { 7746 return gl::error(GL_INVALID_OPERATION); 7747 } 7748 } 7749 } 7750 catch (...) 7751 { 7752 return gl::error(GL_OUT_OF_MEMORY); 7753 } 7754} 7755 7756GLint __stdcall glGetFragDataLocation(GLuint program, const GLchar *name) 7757{ 7758 EVENT("(GLuint program = %u, const GLchar *name = 0x%0.8p)", 7759 program, name); 7760 7761 try 7762 { 7763 gl::Context *context = gl::getNonLostContext(); 7764 7765 if (context) 7766 { 7767 if (context->getClientVersion() < 3) 7768 { 7769 return gl::error(GL_INVALID_OPERATION, -1); 7770 } 7771 7772 if (program == 0) 7773 { 7774 return gl::error(GL_INVALID_VALUE, -1); 7775 } 7776 7777 gl::Program *programObject = context->getProgram(program); 7778 7779 if (!programObject || !programObject->isLinked()) 7780 { 7781 return gl::error(GL_INVALID_OPERATION, -1); 7782 } 7783 7784 gl::ProgramBinary *programBinary = programObject->getProgramBinary(); 7785 if (!programBinary) 7786 { 7787 return gl::error(GL_INVALID_OPERATION, -1); 7788 } 7789 7790 return programBinary->getFragDataLocation(name); 7791 } 7792 } 7793 catch (...) 7794 { 7795 return gl::error(GL_OUT_OF_MEMORY, 0); 7796 } 7797 7798 return 0; 7799} 7800 7801void __stdcall glUniform1ui(GLint location, GLuint v0) 7802{ 7803 glUniform1uiv(location, 1, &v0); 7804} 7805 7806void __stdcall glUniform2ui(GLint location, GLuint v0, GLuint v1) 7807{ 7808 const GLuint xy[] = { v0, v1 }; 7809 glUniform2uiv(location, 1, xy); 7810} 7811 7812void __stdcall glUniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2) 7813{ 7814 const GLuint xyz[] = { v0, v1, v2 }; 7815 glUniform3uiv(location, 1, xyz); 7816} 7817 7818void __stdcall glUniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3) 7819{ 7820 const GLuint xyzw[] = { v0, v1, v2, v3 }; 7821 glUniform4uiv(location, 1, xyzw); 7822} 7823 7824void __stdcall glUniform1uiv(GLint location, GLsizei count, const GLuint* value) 7825{ 7826 EVENT("(GLint location = %d, GLsizei count = %d, const GLuint* value = 0x%0.8p)", 7827 location, count, value); 7828 7829 try 7830 { 7831 gl::Context *context = gl::getNonLostContext(); 7832 7833 if (context) 7834 { 7835 if (!ValidateUniform(context, GL_UNSIGNED_INT, location, count)) 7836 { 7837 return; 7838 } 7839 7840 gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); 7841 programBinary->setUniform1uiv(location, count, value); 7842 } 7843 } 7844 catch (...) 7845 { 7846 return gl::error(GL_OUT_OF_MEMORY); 7847 } 7848} 7849 7850void __stdcall glUniform2uiv(GLint location, GLsizei count, const GLuint* value) 7851{ 7852 EVENT("(GLint location = %d, GLsizei count = %d, const GLuint* value = 0x%0.8p)", 7853 location, count, value); 7854 7855 try 7856 { 7857 gl::Context *context = gl::getNonLostContext(); 7858 7859 if (context) 7860 { 7861 if (!ValidateUniform(context, GL_UNSIGNED_INT_VEC2, location, count)) 7862 { 7863 return; 7864 } 7865 7866 gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); 7867 programBinary->setUniform2uiv(location, count, value); 7868 } 7869 } 7870 catch (...) 7871 { 7872 return gl::error(GL_OUT_OF_MEMORY); 7873 } 7874} 7875 7876void __stdcall glUniform3uiv(GLint location, GLsizei count, const GLuint* value) 7877{ 7878 EVENT("(GLint location = %d, GLsizei count = %d, const GLuint* value)", 7879 location, count, value); 7880 7881 try 7882 { 7883 gl::Context *context = gl::getNonLostContext(); 7884 7885 if (context) 7886 { 7887 if (!ValidateUniform(context, GL_UNSIGNED_INT_VEC3, location, count)) 7888 { 7889 return; 7890 } 7891 7892 gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); 7893 programBinary->setUniform3uiv(location, count, value); 7894 } 7895 } 7896 catch (...) 7897 { 7898 return gl::error(GL_OUT_OF_MEMORY); 7899 } 7900} 7901 7902void __stdcall glUniform4uiv(GLint location, GLsizei count, const GLuint* value) 7903{ 7904 EVENT("(GLint location = %d, GLsizei count = %d, const GLuint* value = 0x%0.8p)", 7905 location, count, value); 7906 7907 try 7908 { 7909 gl::Context *context = gl::getNonLostContext(); 7910 7911 if (context) 7912 { 7913 if (!ValidateUniform(context, GL_UNSIGNED_INT_VEC4, location, count)) 7914 { 7915 return; 7916 } 7917 7918 gl::ProgramBinary *programBinary = context->getCurrentProgramBinary(); 7919 programBinary->setUniform4uiv(location, count, value); 7920 } 7921 } 7922 catch (...) 7923 { 7924 return gl::error(GL_OUT_OF_MEMORY); 7925 } 7926} 7927 7928void __stdcall glClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint* value) 7929{ 7930 EVENT("(GLenum buffer = 0x%X, GLint drawbuffer = %d, const GLint* value = 0x%0.8p)", 7931 buffer, drawbuffer, value); 7932 7933 try 7934 { 7935 gl::Context *context = gl::getNonLostContext(); 7936 7937 if (context) 7938 { 7939 if (context->getClientVersion() < 3) 7940 { 7941 return gl::error(GL_INVALID_OPERATION); 7942 } 7943 7944 switch (buffer) 7945 { 7946 case GL_COLOR: 7947 if (drawbuffer < 0 || drawbuffer >= static_cast<GLint>(context->getMaximumRenderTargets())) 7948 { 7949 return gl::error(GL_INVALID_VALUE); 7950 } 7951 break; 7952 case GL_STENCIL: 7953 if (drawbuffer != 0) 7954 { 7955 return gl::error(GL_INVALID_VALUE); 7956 } 7957 break; 7958 default: 7959 return gl::error(GL_INVALID_ENUM); 7960 } 7961 7962 context->clearBufferiv(buffer, drawbuffer, value); 7963 } 7964 } 7965 catch (...) 7966 { 7967 return gl::error(GL_OUT_OF_MEMORY); 7968 } 7969} 7970 7971void __stdcall glClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint* value) 7972{ 7973 EVENT("(GLenum buffer = 0x%X, GLint drawbuffer = %d, const GLuint* value = 0x%0.8p)", 7974 buffer, drawbuffer, value); 7975 7976 try 7977 { 7978 gl::Context *context = gl::getNonLostContext(); 7979 7980 if (context) 7981 { 7982 if (context->getClientVersion() < 3) 7983 { 7984 return gl::error(GL_INVALID_OPERATION); 7985 } 7986 7987 switch (buffer) 7988 { 7989 case GL_COLOR: 7990 if (drawbuffer < 0 || drawbuffer >= static_cast<GLint>(context->getMaximumRenderTargets())) 7991 { 7992 return gl::error(GL_INVALID_VALUE); 7993 } 7994 break; 7995 default: 7996 return gl::error(GL_INVALID_ENUM); 7997 } 7998 7999 context->clearBufferuiv(buffer, drawbuffer, value); 8000 } 8001 } 8002 catch (...) 8003 { 8004 return gl::error(GL_OUT_OF_MEMORY); 8005 } 8006} 8007 8008void __stdcall glClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat* value) 8009{ 8010 EVENT("(GLenum buffer = 0x%X, GLint drawbuffer = %d, const GLfloat* value = 0x%0.8p)", 8011 buffer, drawbuffer, value); 8012 8013 try 8014 { 8015 gl::Context *context = gl::getNonLostContext(); 8016 8017 if (context) 8018 { 8019 if (context->getClientVersion() < 3) 8020 { 8021 return gl::error(GL_INVALID_OPERATION); 8022 } 8023 8024 switch (buffer) 8025 { 8026 case GL_COLOR: 8027 if (drawbuffer < 0 || drawbuffer >= static_cast<GLint>(context->getMaximumRenderTargets())) 8028 { 8029 return gl::error(GL_INVALID_VALUE); 8030 } 8031 break; 8032 case GL_DEPTH: 8033 if (drawbuffer != 0) 8034 { 8035 return gl::error(GL_INVALID_VALUE); 8036 } 8037 break; 8038 default: 8039 return gl::error(GL_INVALID_ENUM); 8040 } 8041 8042 context->clearBufferfv(buffer, drawbuffer, value); 8043 } 8044 } 8045 catch (...) 8046 { 8047 return gl::error(GL_OUT_OF_MEMORY); 8048 } 8049} 8050 8051void __stdcall glClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) 8052{ 8053 EVENT("(GLenum buffer = 0x%X, GLint drawbuffer = %d, GLfloat depth, GLint stencil = %d)", 8054 buffer, drawbuffer, depth, stencil); 8055 8056 try 8057 { 8058 gl::Context *context = gl::getNonLostContext(); 8059 8060 if (context) 8061 { 8062 if (context->getClientVersion() < 3) 8063 { 8064 return gl::error(GL_INVALID_OPERATION); 8065 } 8066 8067 switch (buffer) 8068 { 8069 case GL_DEPTH_STENCIL: 8070 if (drawbuffer != 0) 8071 { 8072 return gl::error(GL_INVALID_VALUE); 8073 } 8074 break; 8075 default: 8076 return gl::error(GL_INVALID_ENUM); 8077 } 8078 8079 context->clearBufferfi(buffer, drawbuffer, depth, stencil); 8080 } 8081 } 8082 catch (...) 8083 { 8084 return gl::error(GL_OUT_OF_MEMORY); 8085 } 8086} 8087 8088const GLubyte* __stdcall glGetStringi(GLenum name, GLuint index) 8089{ 8090 EVENT("(GLenum name = 0x%X, GLuint index = %u)", name, index); 8091 8092 try 8093 { 8094 gl::Context *context = gl::getNonLostContext(); 8095 8096 if (context) 8097 { 8098 if (context->getClientVersion() < 3) 8099 { 8100 return gl::error(GL_INVALID_OPERATION, reinterpret_cast<GLubyte*>(NULL)); 8101 } 8102 8103 if (name != GL_EXTENSIONS) 8104 { 8105 return gl::error(GL_INVALID_ENUM, reinterpret_cast<GLubyte*>(NULL)); 8106 } 8107 8108 if (index >= context->getNumExtensions()) 8109 { 8110 return gl::error(GL_INVALID_VALUE, reinterpret_cast<GLubyte*>(NULL)); 8111 } 8112 8113 return reinterpret_cast<const GLubyte*>(context->getExtensionString(index)); 8114 } 8115 } 8116 catch (...) 8117 { 8118 return gl::error(GL_OUT_OF_MEMORY, reinterpret_cast<GLubyte*>(NULL)); 8119 } 8120 8121 return NULL; 8122} 8123 8124void __stdcall glCopyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size) 8125{ 8126 EVENT("(GLenum readTarget = 0x%X, GLenum writeTarget = 0x%X, GLintptr readOffset = %d, GLintptr writeOffset = %d, GLsizeiptr size = %d)", 8127 readTarget, writeTarget, readOffset, writeOffset, size); 8128 8129 try 8130 { 8131 gl::Context *context = gl::getNonLostContext(); 8132 8133 if (context) 8134 { 8135 if (context->getClientVersion() < 3) 8136 { 8137 return gl::error(GL_INVALID_OPERATION); 8138 } 8139 8140 if (!gl::ValidBufferTarget(context, readTarget) || !gl::ValidBufferTarget(context, readTarget)) 8141 { 8142 return gl::error(GL_INVALID_ENUM); 8143 } 8144 8145 gl::Buffer *readBuffer = context->getTargetBuffer(readTarget); 8146 gl::Buffer *writeBuffer = context->getTargetBuffer(writeTarget); 8147 8148 if (!readBuffer || !writeBuffer) 8149 { 8150 return gl::error(GL_INVALID_OPERATION); 8151 } 8152 8153 if (readBuffer->mapped() || writeBuffer->mapped()) 8154 { 8155 return gl::error(GL_INVALID_OPERATION); 8156 } 8157 8158 if (readOffset < 0 || writeOffset < 0 || size < 0 || 8159 static_cast<unsigned int>(readOffset + size) > readBuffer->size() || 8160 static_cast<unsigned int>(writeOffset + size) > writeBuffer->size()) 8161 { 8162 return gl::error(GL_INVALID_VALUE); 8163 } 8164 8165 if (readBuffer == writeBuffer && abs(readOffset - writeOffset) < size) 8166 { 8167 return gl::error(GL_INVALID_VALUE); 8168 } 8169 8170 // TODO: Verify that readBuffer and writeBuffer are not currently mapped (GL_INVALID_OPERATION) 8171 8172 // if size is zero, the copy is a successful no-op 8173 if (size > 0) 8174 { 8175 writeBuffer->copyBufferSubData(readBuffer, readOffset, writeOffset, size); 8176 } 8177 } 8178 } 8179 catch (...) 8180 { 8181 return gl::error(GL_OUT_OF_MEMORY); 8182 } 8183} 8184 8185void __stdcall glGetUniformIndices(GLuint program, GLsizei uniformCount, const GLchar* const* uniformNames, GLuint* uniformIndices) 8186{ 8187 EVENT("(GLuint program = %u, GLsizei uniformCount = %d, const GLchar* const* uniformNames = 0x%0.8p, GLuint* uniformIndices = 0x%0.8p)", 8188 program, uniformCount, uniformNames, uniformIndices); 8189 8190 try 8191 { 8192 gl::Context *context = gl::getNonLostContext(); 8193 8194 if (context) 8195 { 8196 if (context->getClientVersion() < 3) 8197 { 8198 return gl::error(GL_INVALID_OPERATION); 8199 } 8200 8201 if (uniformCount < 0) 8202 { 8203 return gl::error(GL_INVALID_VALUE); 8204 } 8205 8206 gl::Program *programObject = context->getProgram(program); 8207 8208 if (!programObject) 8209 { 8210 if (context->getShader(program)) 8211 { 8212 return gl::error(GL_INVALID_OPERATION); 8213 } 8214 else 8215 { 8216 return gl::error(GL_INVALID_VALUE); 8217 } 8218 } 8219 8220 gl::ProgramBinary *programBinary = programObject->getProgramBinary(); 8221 if (!programObject->isLinked() || !programBinary) 8222 { 8223 for (int uniformId = 0; uniformId < uniformCount; uniformId++) 8224 { 8225 uniformIndices[uniformId] = GL_INVALID_INDEX; 8226 } 8227 } 8228 else 8229 { 8230 for (int uniformId = 0; uniformId < uniformCount; uniformId++) 8231 { 8232 uniformIndices[uniformId] = programBinary->getUniformIndex(uniformNames[uniformId]); 8233 } 8234 } 8235 } 8236 } 8237 catch (...) 8238 { 8239 return gl::error(GL_OUT_OF_MEMORY); 8240 } 8241} 8242 8243void __stdcall glGetActiveUniformsiv(GLuint program, GLsizei uniformCount, const GLuint* uniformIndices, GLenum pname, GLint* params) 8244{ 8245 EVENT("(GLuint program = %u, GLsizei uniformCount = %d, const GLuint* uniformIndices = 0x%0.8p, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", 8246 program, uniformCount, uniformIndices, pname, params); 8247 8248 try 8249 { 8250 gl::Context *context = gl::getNonLostContext(); 8251 8252 if (context) 8253 { 8254 if (context->getClientVersion() < 3) 8255 { 8256 return gl::error(GL_INVALID_OPERATION); 8257 } 8258 8259 if (uniformCount < 0) 8260 { 8261 return gl::error(GL_INVALID_VALUE); 8262 } 8263 8264 gl::Program *programObject = context->getProgram(program); 8265 8266 if (!programObject) 8267 { 8268 if (context->getShader(program)) 8269 { 8270 return gl::error(GL_INVALID_OPERATION); 8271 } 8272 else 8273 { 8274 return gl::error(GL_INVALID_VALUE); 8275 } 8276 } 8277 8278 switch (pname) 8279 { 8280 case GL_UNIFORM_TYPE: 8281 case GL_UNIFORM_SIZE: 8282 case GL_UNIFORM_NAME_LENGTH: 8283 case GL_UNIFORM_BLOCK_INDEX: 8284 case GL_UNIFORM_OFFSET: 8285 case GL_UNIFORM_ARRAY_STRIDE: 8286 case GL_UNIFORM_MATRIX_STRIDE: 8287 case GL_UNIFORM_IS_ROW_MAJOR: 8288 break; 8289 default: 8290 return gl::error(GL_INVALID_ENUM); 8291 } 8292 8293 gl::ProgramBinary *programBinary = programObject->getProgramBinary(); 8294 8295 if (!programBinary && uniformCount > 0) 8296 { 8297 return gl::error(GL_INVALID_VALUE); 8298 } 8299 8300 for (int uniformId = 0; uniformId < uniformCount; uniformId++) 8301 { 8302 const GLuint index = uniformIndices[uniformId]; 8303 8304 if (index >= (GLuint)programBinary->getActiveUniformCount()) 8305 { 8306 return gl::error(GL_INVALID_VALUE); 8307 } 8308 } 8309 8310 for (int uniformId = 0; uniformId < uniformCount; uniformId++) 8311 { 8312 const GLuint index = uniformIndices[uniformId]; 8313 params[uniformId] = programBinary->getActiveUniformi(index, pname); 8314 } 8315 } 8316 } 8317 catch (...) 8318 { 8319 return gl::error(GL_OUT_OF_MEMORY); 8320 } 8321} 8322 8323GLuint __stdcall glGetUniformBlockIndex(GLuint program, const GLchar* uniformBlockName) 8324{ 8325 EVENT("(GLuint program = %u, const GLchar* uniformBlockName = 0x%0.8p)", program, uniformBlockName); 8326 8327 try 8328 { 8329 gl::Context *context = gl::getNonLostContext(); 8330 8331 if (context) 8332 { 8333 if (context->getClientVersion() < 3) 8334 { 8335 return gl::error(GL_INVALID_OPERATION, GL_INVALID_INDEX); 8336 } 8337 8338 gl::Program *programObject = context->getProgram(program); 8339 8340 if (!programObject) 8341 { 8342 if (context->getShader(program)) 8343 { 8344 return gl::error(GL_INVALID_OPERATION, GL_INVALID_INDEX); 8345 } 8346 else 8347 { 8348 return gl::error(GL_INVALID_VALUE, GL_INVALID_INDEX); 8349 } 8350 } 8351 8352 gl::ProgramBinary *programBinary = programObject->getProgramBinary(); 8353 if (!programBinary) 8354 { 8355 return GL_INVALID_INDEX; 8356 } 8357 8358 return programBinary->getUniformBlockIndex(uniformBlockName); 8359 } 8360 } 8361 catch (...) 8362 { 8363 return gl::error(GL_OUT_OF_MEMORY, 0); 8364 } 8365 8366 return 0; 8367} 8368 8369void __stdcall glGetActiveUniformBlockiv(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint* params) 8370{ 8371 EVENT("(GLuint program = %u, GLuint uniformBlockIndex = %u, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", 8372 program, uniformBlockIndex, pname, params); 8373 8374 try 8375 { 8376 gl::Context *context = gl::getNonLostContext(); 8377 8378 if (context) 8379 { 8380 if (context->getClientVersion() < 3) 8381 { 8382 return gl::error(GL_INVALID_OPERATION); 8383 } 8384 gl::Program *programObject = context->getProgram(program); 8385 8386 if (!programObject) 8387 { 8388 if (context->getShader(program)) 8389 { 8390 return gl::error(GL_INVALID_OPERATION); 8391 } 8392 else 8393 { 8394 return gl::error(GL_INVALID_VALUE); 8395 } 8396 } 8397 8398 gl::ProgramBinary *programBinary = programObject->getProgramBinary(); 8399 8400 if (!programBinary || uniformBlockIndex >= programBinary->getActiveUniformBlockCount()) 8401 { 8402 return gl::error(GL_INVALID_VALUE); 8403 } 8404 8405 switch (pname) 8406 { 8407 case GL_UNIFORM_BLOCK_BINDING: 8408 *params = static_cast<GLint>(programObject->getUniformBlockBinding(uniformBlockIndex)); 8409 break; 8410 8411 case GL_UNIFORM_BLOCK_DATA_SIZE: 8412 case GL_UNIFORM_BLOCK_NAME_LENGTH: 8413 case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS: 8414 case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES: 8415 case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER: 8416 case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER: 8417 programBinary->getActiveUniformBlockiv(uniformBlockIndex, pname, params); 8418 break; 8419 8420 default: 8421 return gl::error(GL_INVALID_ENUM); 8422 } 8423 } 8424 } 8425 catch (...) 8426 { 8427 return gl::error(GL_OUT_OF_MEMORY); 8428 } 8429} 8430 8431void __stdcall glGetActiveUniformBlockName(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformBlockName) 8432{ 8433 EVENT("(GLuint program = %u, GLuint uniformBlockIndex = %u, GLsizei bufSize = %d, GLsizei* length = 0x%0.8p, GLchar* uniformBlockName = 0x%0.8p)", 8434 program, uniformBlockIndex, bufSize, length, uniformBlockName); 8435 8436 try 8437 { 8438 gl::Context *context = gl::getNonLostContext(); 8439 8440 if (context) 8441 { 8442 if (context->getClientVersion() < 3) 8443 { 8444 return gl::error(GL_INVALID_OPERATION); 8445 } 8446 8447 gl::Program *programObject = context->getProgram(program); 8448 8449 if (!programObject) 8450 { 8451 if (context->getShader(program)) 8452 { 8453 return gl::error(GL_INVALID_OPERATION); 8454 } 8455 else 8456 { 8457 return gl::error(GL_INVALID_VALUE); 8458 } 8459 } 8460 8461 gl::ProgramBinary *programBinary = programObject->getProgramBinary(); 8462 8463 if (!programBinary || uniformBlockIndex >= programBinary->getActiveUniformBlockCount()) 8464 { 8465 return gl::error(GL_INVALID_VALUE); 8466 } 8467 8468 programBinary->getActiveUniformBlockName(uniformBlockIndex, bufSize, length, uniformBlockName); 8469 } 8470 } 8471 catch (...) 8472 { 8473 return gl::error(GL_OUT_OF_MEMORY); 8474 } 8475} 8476 8477void __stdcall glUniformBlockBinding(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding) 8478{ 8479 EVENT("(GLuint program = %u, GLuint uniformBlockIndex = %u, GLuint uniformBlockBinding = %u)", 8480 program, uniformBlockIndex, uniformBlockBinding); 8481 8482 try 8483 { 8484 gl::Context *context = gl::getNonLostContext(); 8485 8486 if (context) 8487 { 8488 if (context->getClientVersion() < 3) 8489 { 8490 return gl::error(GL_INVALID_OPERATION); 8491 } 8492 8493 if (uniformBlockBinding >= context->getMaximumCombinedUniformBufferBindings()) 8494 { 8495 return gl::error(GL_INVALID_VALUE); 8496 } 8497 8498 gl::Program *programObject = context->getProgram(program); 8499 8500 if (!programObject) 8501 { 8502 if (context->getShader(program)) 8503 { 8504 return gl::error(GL_INVALID_OPERATION); 8505 } 8506 else 8507 { 8508 return gl::error(GL_INVALID_VALUE); 8509 } 8510 } 8511 8512 gl::ProgramBinary *programBinary = programObject->getProgramBinary(); 8513 8514 // if never linked, there won't be any uniform blocks 8515 if (!programBinary || uniformBlockIndex >= programBinary->getActiveUniformBlockCount()) 8516 { 8517 return gl::error(GL_INVALID_VALUE); 8518 } 8519 8520 programObject->bindUniformBlock(uniformBlockIndex, uniformBlockBinding); 8521 } 8522 } 8523 catch (...) 8524 { 8525 return gl::error(GL_OUT_OF_MEMORY); 8526 } 8527} 8528 8529void __stdcall glDrawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount) 8530{ 8531 EVENT("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d, GLsizei instanceCount = %d)", 8532 mode, first, count, instanceCount); 8533 8534 try 8535 { 8536 gl::Context *context = gl::getNonLostContext(); 8537 8538 if (context) 8539 { 8540 if (context->getClientVersion() < 3) 8541 { 8542 return gl::error(GL_INVALID_OPERATION); 8543 } 8544 8545 // glDrawArraysInstanced 8546 UNIMPLEMENTED(); 8547 } 8548 } 8549 catch (...) 8550 { 8551 return gl::error(GL_OUT_OF_MEMORY); 8552 } 8553} 8554 8555void __stdcall glDrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices, GLsizei instanceCount) 8556{ 8557 EVENT("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = 0x%0.8p, GLsizei instanceCount = %d)", 8558 mode, count, type, indices, instanceCount); 8559 8560 try 8561 { 8562 gl::Context *context = gl::getNonLostContext(); 8563 8564 if (context) 8565 { 8566 if (context->getClientVersion() < 3) 8567 { 8568 return gl::error(GL_INVALID_OPERATION); 8569 } 8570 8571 // glDrawElementsInstanced 8572 UNIMPLEMENTED(); 8573 } 8574 } 8575 catch (...) 8576 { 8577 return gl::error(GL_OUT_OF_MEMORY); 8578 } 8579} 8580 8581GLsync __stdcall glFenceSync(GLenum condition, GLbitfield flags) 8582{ 8583 EVENT("(GLenum condition = 0x%X, GLbitfield flags = 0x%X)", condition, flags); 8584 8585 try 8586 { 8587 gl::Context *context = gl::getNonLostContext(); 8588 8589 if (context) 8590 { 8591 if (context->getClientVersion() < 3) 8592 { 8593 return gl::error(GL_INVALID_OPERATION, reinterpret_cast<GLsync>(0)); 8594 } 8595 8596 if (condition != GL_SYNC_GPU_COMMANDS_COMPLETE) 8597 { 8598 return gl::error(GL_INVALID_ENUM, reinterpret_cast<GLsync>(0)); 8599 } 8600 8601 if (flags != 0) 8602 { 8603 return gl::error(GL_INVALID_VALUE, reinterpret_cast<GLsync>(0)); 8604 } 8605 8606 return context->createFenceSync(condition); 8607 } 8608 } 8609 catch (...) 8610 { 8611 return gl::error(GL_OUT_OF_MEMORY, reinterpret_cast<GLsync>(NULL)); 8612 } 8613 8614 return NULL; 8615} 8616 8617GLboolean __stdcall glIsSync(GLsync sync) 8618{ 8619 EVENT("(GLsync sync = 0x%0.8p)", sync); 8620 8621 try 8622 { 8623 gl::Context *context = gl::getNonLostContext(); 8624 8625 if (context) 8626 { 8627 if (context->getClientVersion() < 3) 8628 { 8629 return gl::error(GL_INVALID_OPERATION, GL_FALSE); 8630 } 8631 8632 return (context->getFenceSync(sync) != NULL); 8633 } 8634 } 8635 catch (...) 8636 { 8637 return gl::error(GL_OUT_OF_MEMORY, GL_FALSE); 8638 } 8639 8640 return GL_FALSE; 8641} 8642 8643void __stdcall glDeleteSync(GLsync sync) 8644{ 8645 EVENT("(GLsync sync = 0x%0.8p)", sync); 8646 8647 try 8648 { 8649 gl::Context *context = gl::getNonLostContext(); 8650 8651 if (context) 8652 { 8653 if (context->getClientVersion() < 3) 8654 { 8655 return gl::error(GL_INVALID_OPERATION); 8656 } 8657 8658 if (sync != static_cast<GLsync>(0) && !context->getFenceSync(sync)) 8659 { 8660 return gl::error(GL_INVALID_VALUE); 8661 } 8662 8663 context->deleteFenceSync(sync); 8664 } 8665 } 8666 catch (...) 8667 { 8668 return gl::error(GL_OUT_OF_MEMORY); 8669 } 8670} 8671 8672GLenum __stdcall glClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) 8673{ 8674 EVENT("(GLsync sync = 0x%0.8p, GLbitfield flags = 0x%X, GLuint64 timeout = %llu)", 8675 sync, flags, timeout); 8676 8677 try 8678 { 8679 gl::Context *context = gl::getNonLostContext(); 8680 8681 if (context) 8682 { 8683 if (context->getClientVersion() < 3) 8684 { 8685 return gl::error(GL_INVALID_OPERATION, GL_WAIT_FAILED); 8686 } 8687 8688 if ((flags & ~(GL_SYNC_FLUSH_COMMANDS_BIT)) != 0) 8689 { 8690 return gl::error(GL_INVALID_VALUE, GL_WAIT_FAILED); 8691 } 8692 8693 gl::FenceSync *fenceSync = context->getFenceSync(sync); 8694 8695 if (!fenceSync) 8696 { 8697 return gl::error(GL_INVALID_VALUE, GL_WAIT_FAILED); 8698 } 8699 8700 return fenceSync->clientWait(flags, timeout); 8701 } 8702 } 8703 catch (...) 8704 { 8705 return gl::error(GL_OUT_OF_MEMORY, GL_FALSE); 8706 } 8707 8708 return GL_FALSE; 8709} 8710 8711void __stdcall glWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) 8712{ 8713 EVENT("(GLsync sync = 0x%0.8p, GLbitfield flags = 0x%X, GLuint64 timeout = %llu)", 8714 sync, flags, timeout); 8715 8716 try 8717 { 8718 gl::Context *context = gl::getNonLostContext(); 8719 8720 if (context) 8721 { 8722 if (context->getClientVersion() < 3) 8723 { 8724 return gl::error(GL_INVALID_OPERATION); 8725 } 8726 8727 if (flags != 0) 8728 { 8729 return gl::error(GL_INVALID_VALUE); 8730 } 8731 8732 if (timeout != GL_TIMEOUT_IGNORED) 8733 { 8734 return gl::error(GL_INVALID_VALUE); 8735 } 8736 8737 gl::FenceSync *fenceSync = context->getFenceSync(sync); 8738 8739 if (!fenceSync) 8740 { 8741 return gl::error(GL_INVALID_VALUE); 8742 } 8743 8744 fenceSync->serverWait(); 8745 } 8746 } 8747 catch (...) 8748 { 8749 return gl::error(GL_OUT_OF_MEMORY); 8750 } 8751} 8752 8753void __stdcall glGetInteger64v(GLenum pname, GLint64* params) 8754{ 8755 EVENT("(GLenum pname = 0x%X, GLint64* params = 0x%0.8p)", 8756 pname, params); 8757 8758 try 8759 { 8760 gl::Context *context = gl::getNonLostContext(); 8761 8762 if (context) 8763 { 8764 if (context->getClientVersion() < 3) 8765 { 8766 return gl::error(GL_INVALID_OPERATION); 8767 } 8768 8769 GLenum nativeType; 8770 unsigned int numParams = 0; 8771 if (!ValidateStateQuery(context, pname, &nativeType, &numParams)) 8772 { 8773 return; 8774 } 8775 8776 if (nativeType == GL_INT_64_ANGLEX) 8777 { 8778 context->getInteger64v(pname, params); 8779 } 8780 else 8781 { 8782 CastStateValues(context, nativeType, pname, numParams, params); 8783 } 8784 } 8785 } 8786 catch (...) 8787 { 8788 return gl::error(GL_OUT_OF_MEMORY); 8789 } 8790} 8791 8792void __stdcall glGetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei* length, GLint* values) 8793{ 8794 EVENT("(GLsync sync = 0x%0.8p, GLenum pname = 0x%X, GLsizei bufSize = %d, GLsizei* length = 0x%0.8p, GLint* values = 0x%0.8p)", 8795 sync, pname, bufSize, length, values); 8796 8797 try 8798 { 8799 gl::Context *context = gl::getNonLostContext(); 8800 8801 if (context) 8802 { 8803 if (context->getClientVersion() < 3) 8804 { 8805 return gl::error(GL_INVALID_OPERATION); 8806 } 8807 8808 if (bufSize < 0) 8809 { 8810 return gl::error(GL_INVALID_VALUE); 8811 } 8812 8813 gl::FenceSync *fenceSync = context->getFenceSync(sync); 8814 8815 if (!fenceSync) 8816 { 8817 return gl::error(GL_INVALID_VALUE); 8818 } 8819 8820 switch (pname) 8821 { 8822 case GL_OBJECT_TYPE: values[0] = static_cast<GLint>(GL_SYNC_FENCE); break; 8823 case GL_SYNC_STATUS: values[0] = static_cast<GLint>(fenceSync->getStatus()); break; 8824 case GL_SYNC_CONDITION: values[0] = static_cast<GLint>(fenceSync->getCondition()); break; 8825 case GL_SYNC_FLAGS: values[0] = 0; break; 8826 8827 default: 8828 return gl::error(GL_INVALID_ENUM); 8829 } 8830 } 8831 } 8832 catch (...) 8833 { 8834 return gl::error(GL_OUT_OF_MEMORY); 8835 } 8836} 8837 8838void __stdcall glGetInteger64i_v(GLenum target, GLuint index, GLint64* data) 8839{ 8840 EVENT("(GLenum target = 0x%X, GLuint index = %u, GLint64* data = 0x%0.8p)", 8841 target, index, data); 8842 8843 try 8844 { 8845 gl::Context *context = gl::getNonLostContext(); 8846 8847 if (context) 8848 { 8849 if (context->getClientVersion() < 3) 8850 { 8851 return gl::error(GL_INVALID_OPERATION); 8852 } 8853 8854 switch (target) 8855 { 8856 case GL_TRANSFORM_FEEDBACK_BUFFER_START: 8857 case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE: 8858 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: 8859 if (index >= context->getMaxTransformFeedbackBufferBindings()) 8860 return gl::error(GL_INVALID_VALUE); 8861 break; 8862 case GL_UNIFORM_BUFFER_START: 8863 case GL_UNIFORM_BUFFER_SIZE: 8864 case GL_UNIFORM_BUFFER_BINDING: 8865 if (index >= context->getMaximumCombinedUniformBufferBindings()) 8866 return gl::error(GL_INVALID_VALUE); 8867 break; 8868 default: 8869 return gl::error(GL_INVALID_ENUM); 8870 } 8871 8872 if (!(context->getIndexedInteger64v(target, index, data))) 8873 { 8874 GLenum nativeType; 8875 unsigned int numParams = 0; 8876 if (!context->getIndexedQueryParameterInfo(target, &nativeType, &numParams)) 8877 return gl::error(GL_INVALID_ENUM); 8878 8879 if (numParams == 0) 8880 return; // it is known that pname is valid, but there are no parameters to return 8881 8882 if (nativeType == GL_INT) 8883 { 8884 GLint *intParams = new GLint[numParams]; 8885 8886 context->getIndexedIntegerv(target, index, intParams); 8887 8888 for (unsigned int i = 0; i < numParams; ++i) 8889 { 8890 data[i] = static_cast<GLint64>(intParams[i]); 8891 } 8892 8893 delete [] intParams; 8894 } 8895 else 8896 { 8897 UNREACHABLE(); 8898 } 8899 } 8900 } 8901 } 8902 catch (...) 8903 { 8904 return gl::error(GL_OUT_OF_MEMORY); 8905 } 8906} 8907 8908void __stdcall glGetBufferParameteri64v(GLenum target, GLenum pname, GLint64* params) 8909{ 8910 EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint64* params = 0x%0.8p)", 8911 target, pname, params); 8912 8913 try 8914 { 8915 gl::Context *context = gl::getNonLostContext(); 8916 8917 if (context) 8918 { 8919 if (context->getClientVersion() < 3) 8920 { 8921 return gl::error(GL_INVALID_OPERATION); 8922 } 8923 8924 if (!gl::ValidBufferTarget(context, target)) 8925 { 8926 return gl::error(GL_INVALID_ENUM); 8927 } 8928 8929 if (!gl::ValidBufferParameter(context, pname)) 8930 { 8931 return gl::error(GL_INVALID_ENUM); 8932 } 8933 8934 gl::Buffer *buffer = context->getTargetBuffer(target); 8935 8936 if (!buffer) 8937 { 8938 // A null buffer means that "0" is bound to the requested buffer target 8939 return gl::error(GL_INVALID_OPERATION); 8940 } 8941 8942 switch (pname) 8943 { 8944 case GL_BUFFER_USAGE: 8945 *params = static_cast<GLint64>(buffer->usage()); 8946 break; 8947 case GL_BUFFER_SIZE: 8948 *params = buffer->size(); 8949 break; 8950 case GL_BUFFER_ACCESS_FLAGS: 8951 *params = static_cast<GLint64>(buffer->accessFlags()); 8952 break; 8953 case GL_BUFFER_MAPPED: 8954 *params = static_cast<GLint64>(buffer->mapped()); 8955 break; 8956 case GL_BUFFER_MAP_OFFSET: 8957 *params = buffer->mapOffset(); 8958 break; 8959 case GL_BUFFER_MAP_LENGTH: 8960 *params = buffer->mapLength(); 8961 break; 8962 default: UNREACHABLE(); break; 8963 } 8964 } 8965 } 8966 catch (...) 8967 { 8968 return gl::error(GL_OUT_OF_MEMORY); 8969 } 8970} 8971 8972void __stdcall glGenSamplers(GLsizei count, GLuint* samplers) 8973{ 8974 EVENT("(GLsizei count = %d, GLuint* samplers = 0x%0.8p)", count, samplers); 8975 8976 try 8977 { 8978 gl::Context *context = gl::getNonLostContext(); 8979 8980 if (context) 8981 { 8982 if (context->getClientVersion() < 3) 8983 { 8984 return gl::error(GL_INVALID_OPERATION); 8985 } 8986 8987 if (count < 0) 8988 { 8989 return gl::error(GL_INVALID_VALUE); 8990 } 8991 8992 for (int i = 0; i < count; i++) 8993 { 8994 samplers[i] = context->createSampler(); 8995 } 8996 } 8997 } 8998 catch (...) 8999 { 9000 return gl::error(GL_OUT_OF_MEMORY); 9001 } 9002} 9003 9004void __stdcall glDeleteSamplers(GLsizei count, const GLuint* samplers) 9005{ 9006 EVENT("(GLsizei count = %d, const GLuint* samplers = 0x%0.8p)", count, samplers); 9007 9008 try 9009 { 9010 gl::Context *context = gl::getNonLostContext(); 9011 9012 if (context) 9013 { 9014 if (context->getClientVersion() < 3) 9015 { 9016 return gl::error(GL_INVALID_OPERATION); 9017 } 9018 9019 if (count < 0) 9020 { 9021 return gl::error(GL_INVALID_VALUE); 9022 } 9023 9024 for (int i = 0; i < count; i++) 9025 { 9026 context->deleteSampler(samplers[i]); 9027 } 9028 } 9029 } 9030 catch (...) 9031 { 9032 return gl::error(GL_OUT_OF_MEMORY); 9033 } 9034} 9035 9036GLboolean __stdcall glIsSampler(GLuint sampler) 9037{ 9038 EVENT("(GLuint sampler = %u)", sampler); 9039 9040 try 9041 { 9042 gl::Context *context = gl::getNonLostContext(); 9043 9044 if (context) 9045 { 9046 if (context->getClientVersion() < 3) 9047 { 9048 return gl::error(GL_INVALID_OPERATION, GL_FALSE); 9049 } 9050 9051 return context->isSampler(sampler); 9052 } 9053 } 9054 catch (...) 9055 { 9056 return gl::error(GL_OUT_OF_MEMORY, GL_FALSE); 9057 } 9058 9059 return GL_FALSE; 9060} 9061 9062void __stdcall glBindSampler(GLuint unit, GLuint sampler) 9063{ 9064 EVENT("(GLuint unit = %u, GLuint sampler = %u)", unit, sampler); 9065 9066 try 9067 { 9068 gl::Context *context = gl::getNonLostContext(); 9069 9070 if (context) 9071 { 9072 if (context->getClientVersion() < 3) 9073 { 9074 return gl::error(GL_INVALID_OPERATION); 9075 } 9076 9077 if (sampler != 0 && !context->isSampler(sampler)) 9078 { 9079 return gl::error(GL_INVALID_OPERATION); 9080 } 9081 9082 if (unit >= context->getMaximumCombinedTextureImageUnits()) 9083 { 9084 return gl::error(GL_INVALID_VALUE); 9085 } 9086 9087 context->bindSampler(unit, sampler); 9088 } 9089 } 9090 catch (...) 9091 { 9092 return gl::error(GL_OUT_OF_MEMORY); 9093 } 9094} 9095 9096void __stdcall glSamplerParameteri(GLuint sampler, GLenum pname, GLint param) 9097{ 9098 EVENT("(GLuint sampler = %u, GLenum pname = 0x%X, GLint param = %d)", sampler, pname, param); 9099 9100 try 9101 { 9102 gl::Context *context = gl::getNonLostContext(); 9103 9104 if (context) 9105 { 9106 if (context->getClientVersion() < 3) 9107 { 9108 return gl::error(GL_INVALID_OPERATION); 9109 } 9110 9111 if (!gl::ValidateSamplerObjectParameter(pname)) 9112 { 9113 return; 9114 } 9115 9116 if (!gl::ValidateTexParamParameters(context, pname, param)) 9117 { 9118 return; 9119 } 9120 9121 if (!context->isSampler(sampler)) 9122 { 9123 return gl::error(GL_INVALID_OPERATION); 9124 } 9125 9126 context->samplerParameteri(sampler, pname, param); 9127 } 9128 } 9129 catch (...) 9130 { 9131 return gl::error(GL_OUT_OF_MEMORY); 9132 } 9133} 9134 9135void __stdcall glSamplerParameteriv(GLuint sampler, GLenum pname, const GLint* param) 9136{ 9137 glSamplerParameteri(sampler, pname, *param); 9138} 9139 9140void __stdcall glSamplerParameterf(GLuint sampler, GLenum pname, GLfloat param) 9141{ 9142 EVENT("(GLuint sampler = %u, GLenum pname = 0x%X, GLfloat param = %g)", sampler, pname, param); 9143 9144 try 9145 { 9146 gl::Context *context = gl::getNonLostContext(); 9147 9148 if (context) 9149 { 9150 if (context->getClientVersion() < 3) 9151 { 9152 return gl::error(GL_INVALID_OPERATION); 9153 } 9154 9155 if (!gl::ValidateSamplerObjectParameter(pname)) 9156 { 9157 return; 9158 } 9159 9160 if (!gl::ValidateTexParamParameters(context, pname, static_cast<GLint>(param))) 9161 { 9162 return; 9163 } 9164 9165 if (!context->isSampler(sampler)) 9166 { 9167 return gl::error(GL_INVALID_OPERATION); 9168 } 9169 9170 context->samplerParameterf(sampler, pname, param); 9171 } 9172 } 9173 catch (...) 9174 { 9175 return gl::error(GL_OUT_OF_MEMORY); 9176 } 9177} 9178 9179void __stdcall glSamplerParameterfv(GLuint sampler, GLenum pname, const GLfloat* param) 9180{ 9181 glSamplerParameterf(sampler, pname, *param); 9182} 9183 9184void __stdcall glGetSamplerParameteriv(GLuint sampler, GLenum pname, GLint* params) 9185{ 9186 EVENT("(GLuint sampler = %u, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", sampler, pname, params); 9187 9188 try 9189 { 9190 gl::Context *context = gl::getNonLostContext(); 9191 9192 if (context) 9193 { 9194 if (context->getClientVersion() < 3) 9195 { 9196 return gl::error(GL_INVALID_OPERATION); 9197 } 9198 9199 if (!gl::ValidateSamplerObjectParameter(pname)) 9200 { 9201 return; 9202 } 9203 9204 if (!context->isSampler(sampler)) 9205 { 9206 return gl::error(GL_INVALID_OPERATION); 9207 } 9208 9209 *params = context->getSamplerParameteri(sampler, pname); 9210 } 9211 } 9212 catch (...) 9213 { 9214 return gl::error(GL_OUT_OF_MEMORY); 9215 } 9216} 9217 9218void __stdcall glGetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat* params) 9219{ 9220 EVENT("(GLuint sample = %ur, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", sampler, pname, params); 9221 9222 try 9223 { 9224 gl::Context *context = gl::getNonLostContext(); 9225 9226 if (context) 9227 { 9228 if (context->getClientVersion() < 3) 9229 { 9230 return gl::error(GL_INVALID_OPERATION); 9231 } 9232 9233 if (!gl::ValidateSamplerObjectParameter(pname)) 9234 { 9235 return; 9236 } 9237 9238 if (!context->isSampler(sampler)) 9239 { 9240 return gl::error(GL_INVALID_OPERATION); 9241 } 9242 9243 *params = context->getSamplerParameterf(sampler, pname); 9244 } 9245 } 9246 catch (...) 9247 { 9248 return gl::error(GL_OUT_OF_MEMORY); 9249 } 9250} 9251 9252void __stdcall glVertexAttribDivisor(GLuint index, GLuint divisor) 9253{ 9254 EVENT("(GLuint index = %u, GLuint divisor = %u)", index, divisor); 9255 9256 try 9257 { 9258 if (index >= gl::MAX_VERTEX_ATTRIBS) 9259 { 9260 return gl::error(GL_INVALID_VALUE); 9261 } 9262 9263 gl::Context *context = gl::getNonLostContext(); 9264 9265 if (context) 9266 { 9267 if (context->getClientVersion() < 3) 9268 { 9269 return gl::error(GL_INVALID_OPERATION); 9270 } 9271 9272 context->setVertexAttribDivisor(index, divisor); 9273 } 9274 } 9275 catch (...) 9276 { 9277 return gl::error(GL_OUT_OF_MEMORY); 9278 } 9279} 9280 9281void __stdcall glBindTransformFeedback(GLenum target, GLuint id) 9282{ 9283 EVENT("(GLenum target = 0x%X, GLuint id = %u)", target, id); 9284 9285 try 9286 { 9287 gl::Context *context = gl::getNonLostContext(); 9288 9289 if (context) 9290 { 9291 if (context->getClientVersion() < 3) 9292 { 9293 return gl::error(GL_INVALID_OPERATION); 9294 } 9295 9296 switch (target) 9297 { 9298 case GL_TRANSFORM_FEEDBACK: 9299 { 9300 // Cannot bind a transform feedback object if the current one is started and not paused (3.0.2 pg 85 section 2.14.1) 9301 gl::TransformFeedback *curTransformFeedback = context->getCurrentTransformFeedback(); 9302 if (curTransformFeedback && curTransformFeedback->isStarted() && !curTransformFeedback->isPaused()) 9303 { 9304 return gl::error(GL_INVALID_OPERATION); 9305 } 9306 9307 // Cannot bind a transform feedback object that does not exist (3.0.2 pg 85 section 2.14.1) 9308 if (context->getTransformFeedback(id) == NULL) 9309 { 9310 return gl::error(GL_INVALID_OPERATION); 9311 } 9312 9313 context->bindTransformFeedback(id); 9314 } 9315 break; 9316 9317 default: 9318 return gl::error(GL_INVALID_ENUM); 9319 } 9320 } 9321 } 9322 catch (...) 9323 { 9324 return gl::error(GL_OUT_OF_MEMORY); 9325 } 9326} 9327 9328void __stdcall glDeleteTransformFeedbacks(GLsizei n, const GLuint* ids) 9329{ 9330 EVENT("(GLsizei n = %d, const GLuint* ids = 0x%0.8p)", n, ids); 9331 9332 try 9333 { 9334 gl::Context *context = gl::getNonLostContext(); 9335 9336 if (context) 9337 { 9338 if (context->getClientVersion() < 3) 9339 { 9340 return gl::error(GL_INVALID_OPERATION); 9341 } 9342 9343 for (int i = 0; i < n; i++) 9344 { 9345 context->deleteTransformFeedback(ids[i]); 9346 } 9347 } 9348 } 9349 catch (...) 9350 { 9351 return gl::error(GL_OUT_OF_MEMORY); 9352 } 9353} 9354 9355void __stdcall glGenTransformFeedbacks(GLsizei n, GLuint* ids) 9356{ 9357 EVENT("(GLsizei n = %d, GLuint* ids = 0x%0.8p)", n, ids); 9358 9359 try 9360 { 9361 gl::Context *context = gl::getNonLostContext(); 9362 9363 if (context) 9364 { 9365 if (context->getClientVersion() < 3) 9366 { 9367 return gl::error(GL_INVALID_OPERATION); 9368 } 9369 9370 for (int i = 0; i < n; i++) 9371 { 9372 ids[i] = context->createTransformFeedback(); 9373 } 9374 } 9375 } 9376 catch (...) 9377 { 9378 return gl::error(GL_OUT_OF_MEMORY); 9379 } 9380} 9381 9382GLboolean __stdcall glIsTransformFeedback(GLuint id) 9383{ 9384 EVENT("(GLuint id = %u)", id); 9385 9386 try 9387 { 9388 gl::Context *context = gl::getNonLostContext(); 9389 9390 if (context) 9391 { 9392 if (context->getClientVersion() < 3) 9393 { 9394 return gl::error(GL_INVALID_OPERATION, GL_FALSE); 9395 } 9396 9397 return ((context->getTransformFeedback(id) != NULL) ? GL_TRUE : GL_FALSE); 9398 } 9399 } 9400 catch (...) 9401 { 9402 return gl::error(GL_OUT_OF_MEMORY, GL_FALSE); 9403 } 9404 9405 return GL_FALSE; 9406} 9407 9408void __stdcall glPauseTransformFeedback(void) 9409{ 9410 EVENT("(void)"); 9411 9412 try 9413 { 9414 gl::Context *context = gl::getNonLostContext(); 9415 9416 if (context) 9417 { 9418 if (context->getClientVersion() < 3) 9419 { 9420 return gl::error(GL_INVALID_OPERATION); 9421 } 9422 9423 gl::TransformFeedback *transformFeedback = context->getCurrentTransformFeedback(); 9424 ASSERT(transformFeedback != NULL); 9425 9426 // Current transform feedback must be started and not paused in order to pause (3.0.2 pg 86) 9427 if (!transformFeedback->isStarted() || transformFeedback->isPaused()) 9428 { 9429 return gl::error(GL_INVALID_OPERATION); 9430 } 9431 9432 transformFeedback->pause(); 9433 } 9434 } 9435 catch (...) 9436 { 9437 return gl::error(GL_OUT_OF_MEMORY); 9438 } 9439} 9440 9441void __stdcall glResumeTransformFeedback(void) 9442{ 9443 EVENT("(void)"); 9444 9445 try 9446 { 9447 gl::Context *context = gl::getNonLostContext(); 9448 9449 if (context) 9450 { 9451 if (context->getClientVersion() < 3) 9452 { 9453 return gl::error(GL_INVALID_OPERATION); 9454 } 9455 9456 gl::TransformFeedback *transformFeedback = context->getCurrentTransformFeedback(); 9457 ASSERT(transformFeedback != NULL); 9458 9459 // Current transform feedback must be started and paused in order to resume (3.0.2 pg 86) 9460 if (!transformFeedback->isStarted() || !transformFeedback->isPaused()) 9461 { 9462 return gl::error(GL_INVALID_OPERATION); 9463 } 9464 9465 transformFeedback->resume(); 9466 } 9467 } 9468 catch (...) 9469 { 9470 return gl::error(GL_OUT_OF_MEMORY); 9471 } 9472} 9473 9474void __stdcall glGetProgramBinary(GLuint program, GLsizei bufSize, GLsizei* length, GLenum* binaryFormat, GLvoid* binary) 9475{ 9476 EVENT("(GLuint program = %u, GLsizei bufSize = %d, GLsizei* length = 0x%0.8p, GLenum* binaryFormat = 0x%0.8p, GLvoid* binary = 0x%0.8p)", 9477 program, bufSize, length, binaryFormat, binary); 9478 9479 try 9480 { 9481 gl::Context *context = gl::getNonLostContext(); 9482 9483 if (context) 9484 { 9485 if (context->getClientVersion() < 3) 9486 { 9487 return gl::error(GL_INVALID_OPERATION); 9488 } 9489 9490 // glGetProgramBinary 9491 UNIMPLEMENTED(); 9492 } 9493 } 9494 catch (...) 9495 { 9496 return gl::error(GL_OUT_OF_MEMORY); 9497 } 9498} 9499 9500void __stdcall glProgramBinary(GLuint program, GLenum binaryFormat, const GLvoid* binary, GLsizei length) 9501{ 9502 EVENT("(GLuint program = %u, GLenum binaryFormat = 0x%X, const GLvoid* binary = 0x%0.8p, GLsizei length = %d)", 9503 program, binaryFormat, binary, length); 9504 9505 try 9506 { 9507 gl::Context *context = gl::getNonLostContext(); 9508 9509 if (context) 9510 { 9511 if (context->getClientVersion() < 3) 9512 { 9513 return gl::error(GL_INVALID_OPERATION); 9514 } 9515 9516 // glProgramBinary 9517 UNIMPLEMENTED(); 9518 } 9519 } 9520 catch (...) 9521 { 9522 return gl::error(GL_OUT_OF_MEMORY); 9523 } 9524} 9525 9526void __stdcall glProgramParameteri(GLuint program, GLenum pname, GLint value) 9527{ 9528 EVENT("(GLuint program = %u, GLenum pname = 0x%X, GLint value = %d)", 9529 program, pname, value); 9530 9531 try 9532 { 9533 gl::Context *context = gl::getNonLostContext(); 9534 9535 if (context) 9536 { 9537 if (context->getClientVersion() < 3) 9538 { 9539 return gl::error(GL_INVALID_OPERATION); 9540 } 9541 9542 // glProgramParameteri 9543 UNIMPLEMENTED(); 9544 } 9545 } 9546 catch (...) 9547 { 9548 return gl::error(GL_OUT_OF_MEMORY); 9549 } 9550} 9551 9552void __stdcall glInvalidateFramebuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments) 9553{ 9554 EVENT("(GLenum target = 0x%X, GLsizei numAttachments = %d, const GLenum* attachments = 0x%0.8p)", 9555 target, numAttachments, attachments); 9556 9557 try 9558 { 9559 gl::Context *context = gl::getNonLostContext(); 9560 9561 if (context) 9562 { 9563 if (context->getClientVersion() < 3) 9564 { 9565 return gl::error(GL_INVALID_OPERATION); 9566 } 9567 9568 if (!ValidateInvalidateFramebufferParameters(context, target, numAttachments, attachments)) 9569 { 9570 return; 9571 } 9572 9573 int maxDimension = context->getMaximumRenderbufferDimension(); 9574 context->invalidateFrameBuffer(target, numAttachments, attachments, 0, 0, maxDimension, maxDimension); 9575 } 9576 } 9577 catch (...) 9578 { 9579 return gl::error(GL_OUT_OF_MEMORY); 9580 } 9581} 9582 9583void __stdcall glInvalidateSubFramebuffer(GLenum target, GLsizei numAttachments, const GLenum* attachments, GLint x, GLint y, GLsizei width, GLsizei height) 9584{ 9585 EVENT("(GLenum target = 0x%X, GLsizei numAttachments = %d, const GLenum* attachments = 0x%0.8p, GLint x = %d, " 9586 "GLint y = %d, GLsizei width = %d, GLsizei height = %d)", 9587 target, numAttachments, attachments, x, y, width, height); 9588 9589 try 9590 { 9591 gl::Context *context = gl::getNonLostContext(); 9592 9593 if (context) 9594 { 9595 if (context->getClientVersion() < 3) 9596 { 9597 return gl::error(GL_INVALID_OPERATION); 9598 } 9599 9600 if (!ValidateInvalidateFramebufferParameters(context, target, numAttachments, attachments)) 9601 { 9602 return; 9603 } 9604 9605 context->invalidateFrameBuffer(target, numAttachments, attachments, x, y, width, height); 9606 } 9607 } 9608 catch (...) 9609 { 9610 return gl::error(GL_OUT_OF_MEMORY); 9611 } 9612} 9613 9614void __stdcall glTexStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) 9615{ 9616 EVENT("(GLenum target = 0x%X, GLsizei levels = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)", 9617 target, levels, internalformat, width, height); 9618 9619 try 9620 { 9621 gl::Context *context = gl::getNonLostContext(); 9622 9623 if (context) 9624 { 9625 if (context->getClientVersion() < 3) 9626 { 9627 return gl::error(GL_INVALID_OPERATION); 9628 } 9629 9630 if (!ValidateES3TexStorageParameters(context, target, levels, internalformat, width, height, 1)) 9631 { 9632 return; 9633 } 9634 9635 switch (target) 9636 { 9637 case GL_TEXTURE_2D: 9638 { 9639 gl::Texture2D *texture2d = context->getTexture2D(); 9640 texture2d->storage(levels, internalformat, width, height); 9641 } 9642 break; 9643 9644 case GL_TEXTURE_CUBE_MAP: 9645 { 9646 gl::TextureCubeMap *textureCube = context->getTextureCubeMap(); 9647 textureCube->storage(levels, internalformat, width); 9648 } 9649 break; 9650 9651 default: 9652 return gl::error(GL_INVALID_ENUM); 9653 } 9654 } 9655 } 9656 catch (...) 9657 { 9658 return gl::error(GL_OUT_OF_MEMORY); 9659 } 9660} 9661 9662void __stdcall glTexStorage3D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) 9663{ 9664 EVENT("(GLenum target = 0x%X, GLsizei levels = %d, GLenum internalformat = 0x%X, GLsizei width = %d, " 9665 "GLsizei height = %d, GLsizei depth = %d)", 9666 target, levels, internalformat, width, height, depth); 9667 9668 try 9669 { 9670 gl::Context *context = gl::getNonLostContext(); 9671 9672 if (context) 9673 { 9674 if (context->getClientVersion() < 3) 9675 { 9676 return gl::error(GL_INVALID_OPERATION); 9677 } 9678 9679 if (!ValidateES3TexStorageParameters(context, target, levels, internalformat, width, height, depth)) 9680 { 9681 return; 9682 } 9683 9684 switch (target) 9685 { 9686 case GL_TEXTURE_3D: 9687 { 9688 gl::Texture3D *texture3d = context->getTexture3D(); 9689 texture3d->storage(levels, internalformat, width, height, depth); 9690 } 9691 break; 9692 9693 case GL_TEXTURE_2D_ARRAY: 9694 { 9695 gl::Texture2DArray *texture2darray = context->getTexture2DArray(); 9696 texture2darray->storage(levels, internalformat, width, height, depth); 9697 } 9698 break; 9699 9700 default: 9701 UNREACHABLE(); 9702 } 9703 } 9704 } 9705 catch (...) 9706 { 9707 return gl::error(GL_OUT_OF_MEMORY); 9708 } 9709} 9710 9711void __stdcall glGetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint* params) 9712{ 9713 EVENT("(GLenum target = 0x%X, GLenum internalformat = 0x%X, GLenum pname = 0x%X, GLsizei bufSize = %d, " 9714 "GLint* params = 0x%0.8p)", 9715 target, internalformat, pname, bufSize, params); 9716 9717 try 9718 { 9719 gl::Context *context = gl::getNonLostContext(); 9720 9721 if (context) 9722 { 9723 if (context->getClientVersion() < 3) 9724 { 9725 return gl::error(GL_INVALID_OPERATION); 9726 } 9727 9728 if (!gl::IsColorRenderingSupported(internalformat, context) && 9729 !gl::IsDepthRenderingSupported(internalformat, context) && 9730 !gl::IsStencilRenderingSupported(internalformat, context)) 9731 { 9732 return gl::error(GL_INVALID_ENUM); 9733 } 9734 9735 if (target != GL_RENDERBUFFER) 9736 { 9737 return gl::error(GL_INVALID_ENUM); 9738 } 9739 9740 if (bufSize < 0) 9741 { 9742 return gl::error(GL_INVALID_VALUE); 9743 } 9744 9745 switch (pname) 9746 { 9747 case GL_NUM_SAMPLE_COUNTS: 9748 if (bufSize != 0) 9749 *params = context->getNumSampleCounts(internalformat); 9750 break; 9751 case GL_SAMPLES: 9752 context->getSampleCounts(internalformat, bufSize, params); 9753 break; 9754 default: 9755 return gl::error(GL_INVALID_ENUM); 9756 } 9757 } 9758 } 9759 catch (...) 9760 { 9761 return gl::error(GL_OUT_OF_MEMORY); 9762 } 9763} 9764 9765// Extension functions 9766 9767void __stdcall glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, 9768 GLbitfield mask, GLenum filter) 9769{ 9770 EVENT("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, " 9771 "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, " 9772 "GLbitfield mask = 0x%X, GLenum filter = 0x%X)", 9773 srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter); 9774 9775 try 9776 { 9777 gl::Context *context = gl::getNonLostContext(); 9778 9779 if (context) 9780 { 9781 if (!ValidateBlitFramebufferParameters(context, srcX0, srcY0, srcX1, srcY1, 9782 dstX0, dstY0, dstX1, dstY1, mask, filter, 9783 true)) 9784 { 9785 return; 9786 } 9787 9788 context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, 9789 mask, filter); 9790 } 9791 } 9792 catch (...) 9793 { 9794 return gl::error(GL_OUT_OF_MEMORY); 9795 } 9796} 9797 9798void __stdcall glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, 9799 GLint border, GLenum format, GLenum type, const GLvoid* pixels) 9800{ 9801 EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, " 9802 "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, " 9803 "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = 0x%0.8p)", 9804 target, level, internalformat, width, height, depth, border, format, type, pixels); 9805 9806 try 9807 { 9808 UNIMPLEMENTED(); // FIXME 9809 } 9810 catch (...) 9811 { 9812 return gl::error(GL_OUT_OF_MEMORY); 9813 } 9814} 9815 9816void __stdcall glGetProgramBinaryOES(GLuint program, GLsizei bufSize, GLsizei *length, 9817 GLenum *binaryFormat, void *binary) 9818{ 9819 EVENT("(GLenum program = 0x%X, bufSize = %d, length = 0x%0.8p, binaryFormat = 0x%0.8p, binary = 0x%0.8p)", 9820 program, bufSize, length, binaryFormat, binary); 9821 9822 try 9823 { 9824 gl::Context *context = gl::getNonLostContext(); 9825 9826 if (context) 9827 { 9828 gl::Program *programObject = context->getProgram(program); 9829 9830 if (!programObject || !programObject->isLinked()) 9831 { 9832 return gl::error(GL_INVALID_OPERATION); 9833 } 9834 9835 gl::ProgramBinary *programBinary = programObject->getProgramBinary(); 9836 9837 if (!programBinary) 9838 { 9839 return gl::error(GL_INVALID_OPERATION); 9840 } 9841 9842 if (!programBinary->save(binary, bufSize, length)) 9843 { 9844 return gl::error(GL_INVALID_OPERATION); 9845 } 9846 9847 *binaryFormat = GL_PROGRAM_BINARY_ANGLE; 9848 } 9849 } 9850 catch (...) 9851 { 9852 return gl::error(GL_OUT_OF_MEMORY); 9853 } 9854} 9855 9856void __stdcall glProgramBinaryOES(GLuint program, GLenum binaryFormat, 9857 const void *binary, GLint length) 9858{ 9859 EVENT("(GLenum program = 0x%X, binaryFormat = 0x%x, binary = 0x%0.8p, length = %d)", 9860 program, binaryFormat, binary, length); 9861 9862 try 9863 { 9864 gl::Context *context = gl::getNonLostContext(); 9865 9866 if (context) 9867 { 9868 if (binaryFormat != GL_PROGRAM_BINARY_ANGLE) 9869 { 9870 return gl::error(GL_INVALID_ENUM); 9871 } 9872 9873 gl::Program *programObject = context->getProgram(program); 9874 9875 if (!programObject) 9876 { 9877 return gl::error(GL_INVALID_OPERATION); 9878 } 9879 9880 context->setProgramBinary(program, binary, length); 9881 } 9882 } 9883 catch (...) 9884 { 9885 return gl::error(GL_OUT_OF_MEMORY); 9886 } 9887} 9888 9889void __stdcall glDrawBuffersEXT(GLsizei n, const GLenum *bufs) 9890{ 9891 EVENT("(GLenum n = %d, bufs = 0x%0.8p)", n, bufs); 9892 9893 try 9894 { 9895 gl::Context *context = gl::getNonLostContext(); 9896 9897 if (context) 9898 { 9899 if (n < 0 || (unsigned int)n > context->getMaximumRenderTargets()) 9900 { 9901 return gl::error(GL_INVALID_VALUE); 9902 } 9903 9904 if (context->getDrawFramebufferHandle() == 0) 9905 { 9906 if (n != 1) 9907 { 9908 return gl::error(GL_INVALID_OPERATION); 9909 } 9910 9911 if (bufs[0] != GL_NONE && bufs[0] != GL_BACK) 9912 { 9913 return gl::error(GL_INVALID_OPERATION); 9914 } 9915 } 9916 else 9917 { 9918 for (int colorAttachment = 0; colorAttachment < n; colorAttachment++) 9919 { 9920 const GLenum attachment = GL_COLOR_ATTACHMENT0_EXT + colorAttachment; 9921 if (bufs[colorAttachment] != GL_NONE && bufs[colorAttachment] != attachment) 9922 { 9923 return gl::error(GL_INVALID_OPERATION); 9924 } 9925 } 9926 } 9927 9928 gl::Framebuffer *framebuffer = context->getDrawFramebuffer(); 9929 9930 for (int colorAttachment = 0; colorAttachment < n; colorAttachment++) 9931 { 9932 framebuffer->setDrawBufferState(colorAttachment, bufs[colorAttachment]); 9933 } 9934 9935 for (int colorAttachment = n; colorAttachment < (int)context->getMaximumRenderTargets(); colorAttachment++) 9936 { 9937 framebuffer->setDrawBufferState(colorAttachment, GL_NONE); 9938 } 9939 } 9940 } 9941 catch (...) 9942 { 9943 return gl::error(GL_OUT_OF_MEMORY); 9944 } 9945} 9946 9947void __stdcall glGetBufferPointervOES(GLenum target, GLenum pname, void** params) 9948{ 9949 EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLvoid** params = 0x%0.8p)", target, pname, params); 9950 9951 try 9952 { 9953 gl::Context *context = gl::getNonLostContext(); 9954 9955 if (context) 9956 { 9957 if (!context->supportsPBOs()) 9958 { 9959 return gl::error(GL_INVALID_OPERATION); 9960 } 9961 9962 if (!gl::ValidBufferTarget(context, target)) 9963 { 9964 return gl::error(GL_INVALID_ENUM); 9965 } 9966 9967 if (pname != GL_BUFFER_MAP_POINTER) 9968 { 9969 return gl::error(GL_INVALID_ENUM); 9970 } 9971 9972 gl::Buffer *buffer = context->getTargetBuffer(target); 9973 9974 if (!buffer || !buffer->mapped()) 9975 { 9976 *params = NULL; 9977 } 9978 9979 *params = buffer->mapPointer(); 9980 } 9981 } 9982 catch (...) 9983 { 9984 return gl::error(GL_OUT_OF_MEMORY); 9985 } 9986} 9987 9988void * __stdcall glMapBufferOES(GLenum target, GLenum access) 9989{ 9990 EVENT("(GLenum target = 0x%X, GLbitfield access = 0x%X)", target, access); 9991 9992 try 9993 { 9994 gl::Context *context = gl::getNonLostContext(); 9995 9996 if (context) 9997 { 9998 if (!gl::ValidBufferTarget(context, target)) 9999 { 10000 return gl::error(GL_INVALID_ENUM, reinterpret_cast<GLvoid*>(NULL)); 10001 } 10002 10003 gl::Buffer *buffer = context->getTargetBuffer(target); 10004 10005 if (buffer == NULL) 10006 { 10007 return gl::error(GL_INVALID_OPERATION, reinterpret_cast<GLvoid*>(NULL)); 10008 } 10009 10010 if (access != GL_WRITE_ONLY_OES) 10011 { 10012 return gl::error(GL_INVALID_ENUM, reinterpret_cast<GLvoid*>(NULL)); 10013 } 10014 10015 if (buffer->mapped()) 10016 { 10017 return gl::error(GL_INVALID_OPERATION, reinterpret_cast<GLvoid*>(NULL)); 10018 } 10019 10020 return buffer->mapRange(0, buffer->size(), GL_MAP_WRITE_BIT); 10021 } 10022 } 10023 catch (...) 10024 { 10025 return gl::error(GL_OUT_OF_MEMORY, reinterpret_cast<GLvoid*>(NULL)); 10026 } 10027 10028 return NULL; 10029} 10030 10031GLboolean __stdcall glUnmapBufferOES(GLenum target) 10032{ 10033 EVENT("(GLenum target = 0x%X)", target); 10034 10035 try 10036 { 10037 gl::Context *context = gl::getNonLostContext(); 10038 10039 if (context) 10040 { 10041 if (!gl::ValidBufferTarget(context, target)) 10042 { 10043 return gl::error(GL_INVALID_ENUM, GL_FALSE); 10044 } 10045 10046 gl::Buffer *buffer = context->getTargetBuffer(target); 10047 10048 if (buffer == NULL || !buffer->mapped()) 10049 { 10050 return gl::error(GL_INVALID_OPERATION, GL_FALSE); 10051 } 10052 10053 // TODO: detect if we had corruption. if so, throw an error and return false. 10054 10055 buffer->unmap(); 10056 10057 return GL_TRUE; 10058 } 10059 } 10060 catch (...) 10061 { 10062 return gl::error(GL_OUT_OF_MEMORY, GL_FALSE); 10063 } 10064 10065 return GL_FALSE; 10066} 10067 10068void* __stdcall glMapBufferRangeEXT (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access) 10069{ 10070 EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr length = %d, GLbitfield access = 0x%X)", 10071 target, offset, length, access); 10072 10073 try 10074 { 10075 gl::Context *context = gl::getNonLostContext(); 10076 10077 if (context) 10078 { 10079 if (!gl::ValidBufferTarget(context, target)) 10080 { 10081 return gl::error(GL_INVALID_ENUM, reinterpret_cast<GLvoid*>(NULL)); 10082 } 10083 10084 if (offset < 0 || length < 0) 10085 { 10086 return gl::error(GL_INVALID_VALUE, reinterpret_cast<GLvoid*>(NULL)); 10087 } 10088 10089 gl::Buffer *buffer = context->getTargetBuffer(target); 10090 10091 if (buffer == NULL) 10092 { 10093 return gl::error(GL_INVALID_OPERATION, reinterpret_cast<GLvoid*>(NULL)); 10094 } 10095 10096 // Check for buffer overflow 10097 size_t offsetSize = static_cast<size_t>(offset); 10098 size_t lengthSize = static_cast<size_t>(length); 10099 10100 if (!rx::IsUnsignedAdditionSafe(offsetSize, lengthSize) || 10101 offsetSize + lengthSize > static_cast<size_t>(buffer->size())) 10102 { 10103 return gl::error(GL_INVALID_VALUE, reinterpret_cast<GLvoid*>(NULL)); 10104 } 10105 10106 // Check for invalid bits in the mask 10107 GLbitfield allAccessBits = GL_MAP_READ_BIT | 10108 GL_MAP_WRITE_BIT | 10109 GL_MAP_INVALIDATE_RANGE_BIT | 10110 GL_MAP_INVALIDATE_BUFFER_BIT | 10111 GL_MAP_FLUSH_EXPLICIT_BIT | 10112 GL_MAP_UNSYNCHRONIZED_BIT; 10113 10114 if (access & ~(allAccessBits)) 10115 { 10116 return gl::error(GL_INVALID_VALUE, reinterpret_cast<GLvoid*>(NULL)); 10117 } 10118 10119 if (length == 0 || buffer->mapped()) 10120 { 10121 return gl::error(GL_INVALID_OPERATION, reinterpret_cast<GLvoid*>(NULL)); 10122 } 10123 10124 // Check for invalid bit combinations 10125 if ((access & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)) == 0) 10126 { 10127 return gl::error(GL_INVALID_OPERATION, reinterpret_cast<GLvoid*>(NULL)); 10128 } 10129 10130 GLbitfield writeOnlyBits = GL_MAP_INVALIDATE_RANGE_BIT | 10131 GL_MAP_INVALIDATE_BUFFER_BIT | 10132 GL_MAP_UNSYNCHRONIZED_BIT; 10133 10134 if ((access & GL_MAP_READ_BIT) != 0 && (access & writeOnlyBits) != 0) 10135 { 10136 return gl::error(GL_INVALID_OPERATION, reinterpret_cast<GLvoid*>(NULL)); 10137 } 10138 10139 if ((access & GL_MAP_WRITE_BIT) == 0 && (access & GL_MAP_FLUSH_EXPLICIT_BIT) != 0) 10140 { 10141 return gl::error(GL_INVALID_OPERATION, reinterpret_cast<GLvoid*>(NULL)); 10142 } 10143 10144 return buffer->mapRange(offset, length, access); 10145 } 10146 } 10147 catch (...) 10148 { 10149 return gl::error(GL_OUT_OF_MEMORY, reinterpret_cast<GLvoid*>(NULL)); 10150 } 10151 10152 return NULL; 10153} 10154 10155void __stdcall glFlushMappedBufferRangeEXT (GLenum target, GLintptr offset, GLsizeiptr length) 10156{ 10157 EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr length = %d)", target, offset, length); 10158 10159 try 10160 { 10161 gl::Context *context = gl::getNonLostContext(); 10162 10163 if (context) 10164 { 10165 if (offset < 0 || length < 0) 10166 { 10167 return gl::error(GL_INVALID_VALUE); 10168 } 10169 10170 if (!gl::ValidBufferTarget(context, target)) 10171 { 10172 return gl::error(GL_INVALID_ENUM); 10173 } 10174 10175 gl::Buffer *buffer = context->getTargetBuffer(target); 10176 10177 if (buffer == NULL) 10178 { 10179 return gl::error(GL_INVALID_OPERATION); 10180 } 10181 10182 if (!buffer->mapped() || (buffer->accessFlags() & GL_MAP_FLUSH_EXPLICIT_BIT) == 0) 10183 { 10184 return gl::error(GL_INVALID_OPERATION); 10185 } 10186 10187 // Check for buffer overflow 10188 size_t offsetSize = static_cast<size_t>(offset); 10189 size_t lengthSize = static_cast<size_t>(length); 10190 10191 if (!rx::IsUnsignedAdditionSafe(offsetSize, lengthSize) || 10192 offsetSize + lengthSize > static_cast<size_t>(buffer->mapLength())) 10193 { 10194 return gl::error(GL_INVALID_VALUE); 10195 } 10196 10197 // We do not currently support a non-trivial implementation of FlushMappedBufferRange 10198 } 10199 } 10200 catch (...) 10201 { 10202 return gl::error(GL_OUT_OF_MEMORY); 10203 } 10204} 10205 10206__eglMustCastToProperFunctionPointerType __stdcall glGetProcAddress(const char *procname) 10207{ 10208 struct Extension 10209 { 10210 const char *name; 10211 __eglMustCastToProperFunctionPointerType address; 10212 }; 10213 10214 static const Extension glExtensions[] = 10215 { 10216 {"glTexImage3DOES", (__eglMustCastToProperFunctionPointerType)glTexImage3DOES}, 10217 {"glBlitFramebufferANGLE", (__eglMustCastToProperFunctionPointerType)glBlitFramebufferANGLE}, 10218 {"glRenderbufferStorageMultisampleANGLE", (__eglMustCastToProperFunctionPointerType)glRenderbufferStorageMultisampleANGLE}, 10219 {"glDeleteFencesNV", (__eglMustCastToProperFunctionPointerType)glDeleteFencesNV}, 10220 {"glGenFencesNV", (__eglMustCastToProperFunctionPointerType)glGenFencesNV}, 10221 {"glIsFenceNV", (__eglMustCastToProperFunctionPointerType)glIsFenceNV}, 10222 {"glTestFenceNV", (__eglMustCastToProperFunctionPointerType)glTestFenceNV}, 10223 {"glGetFenceivNV", (__eglMustCastToProperFunctionPointerType)glGetFenceivNV}, 10224 {"glFinishFenceNV", (__eglMustCastToProperFunctionPointerType)glFinishFenceNV}, 10225 {"glSetFenceNV", (__eglMustCastToProperFunctionPointerType)glSetFenceNV}, 10226 {"glGetTranslatedShaderSourceANGLE", (__eglMustCastToProperFunctionPointerType)glGetTranslatedShaderSourceANGLE}, 10227 {"glTexStorage2DEXT", (__eglMustCastToProperFunctionPointerType)glTexStorage2DEXT}, 10228 {"glGetGraphicsResetStatusEXT", (__eglMustCastToProperFunctionPointerType)glGetGraphicsResetStatusEXT}, 10229 {"glReadnPixelsEXT", (__eglMustCastToProperFunctionPointerType)glReadnPixelsEXT}, 10230 {"glGetnUniformfvEXT", (__eglMustCastToProperFunctionPointerType)glGetnUniformfvEXT}, 10231 {"glGetnUniformivEXT", (__eglMustCastToProperFunctionPointerType)glGetnUniformivEXT}, 10232 {"glGenQueriesEXT", (__eglMustCastToProperFunctionPointerType)glGenQueriesEXT}, 10233 {"glDeleteQueriesEXT", (__eglMustCastToProperFunctionPointerType)glDeleteQueriesEXT}, 10234 {"glIsQueryEXT", (__eglMustCastToProperFunctionPointerType)glIsQueryEXT}, 10235 {"glBeginQueryEXT", (__eglMustCastToProperFunctionPointerType)glBeginQueryEXT}, 10236 {"glEndQueryEXT", (__eglMustCastToProperFunctionPointerType)glEndQueryEXT}, 10237 {"glGetQueryivEXT", (__eglMustCastToProperFunctionPointerType)glGetQueryivEXT}, 10238 {"glGetQueryObjectuivEXT", (__eglMustCastToProperFunctionPointerType)glGetQueryObjectuivEXT}, 10239 {"glDrawBuffersEXT", (__eglMustCastToProperFunctionPointerType)glDrawBuffersEXT}, 10240 {"glVertexAttribDivisorANGLE", (__eglMustCastToProperFunctionPointerType)glVertexAttribDivisorANGLE}, 10241 {"glDrawArraysInstancedANGLE", (__eglMustCastToProperFunctionPointerType)glDrawArraysInstancedANGLE}, 10242 {"glDrawElementsInstancedANGLE", (__eglMustCastToProperFunctionPointerType)glDrawElementsInstancedANGLE}, 10243 {"glGetProgramBinaryOES", (__eglMustCastToProperFunctionPointerType)glGetProgramBinaryOES}, 10244 {"glProgramBinaryOES", (__eglMustCastToProperFunctionPointerType)glProgramBinaryOES}, 10245 {"glGetBufferPointervOES", (__eglMustCastToProperFunctionPointerType)glGetBufferPointervOES}, 10246 {"glMapBufferOES", (__eglMustCastToProperFunctionPointerType)glMapBufferOES}, 10247 {"glUnmapBufferOES", (__eglMustCastToProperFunctionPointerType)glUnmapBufferOES}, 10248 {"glMapBufferRangeEXT", (__eglMustCastToProperFunctionPointerType)glMapBufferRangeEXT}, 10249 {"glFlushMappedBufferRangeEXT", (__eglMustCastToProperFunctionPointerType)glFlushMappedBufferRangeEXT}, }; 10250 10251 for (unsigned int ext = 0; ext < ArraySize(glExtensions); ext++) 10252 { 10253 if (strcmp(procname, glExtensions[ext].name) == 0) 10254 { 10255 return (__eglMustCastToProperFunctionPointerType)glExtensions[ext].address; 10256 } 10257 } 10258 10259 return NULL; 10260} 10261 10262// Non-public functions used by EGL 10263 10264bool __stdcall glBindTexImage(egl::Surface *surface) 10265{ 10266 EVENT("(egl::Surface* surface = 0x%0.8p)", 10267 surface); 10268 10269 try 10270 { 10271 gl::Context *context = gl::getNonLostContext(); 10272 10273 if (context) 10274 { 10275 gl::Texture2D *textureObject = context->getTexture2D(); 10276 ASSERT(textureObject != NULL); 10277 10278 if (textureObject->isImmutable()) 10279 { 10280 return false; 10281 } 10282 10283 textureObject->bindTexImage(surface); 10284 } 10285 } 10286 catch (...) 10287 { 10288 return gl::error(GL_OUT_OF_MEMORY, false); 10289 } 10290 10291 return true; 10292} 10293 10294} 10295