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