1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // Context.cpp: Implements the gl::Context class, managing all GL state and performing 16 // rendering operations. 17 18 #include "Context.h" 19 20 #include "main.h" 21 #include "mathutil.h" 22 #include "utilities.h" 23 #include "ResourceManager.h" 24 #include "Buffer.h" 25 #include "Fence.h" 26 #include "Framebuffer.h" 27 #include "Program.h" 28 #include "Query.h" 29 #include "Renderbuffer.h" 30 #include "Shader.h" 31 #include "Texture.h" 32 #include "VertexDataManager.h" 33 #include "IndexDataManager.h" 34 #include "Display.h" 35 #include "Surface.h" 36 #include "Common/Half.hpp" 37 38 #define _GDI32_ 39 #include <windows.h> 40 #include <GL/GL.h> 41 #include <GL/glext.h> 42 43 namespace gl 44 { 45 Context::Context(const Context *shareContext) 46 : modelView(32), 47 projection(2) 48 { 49 sw::Context *context = new sw::Context(); 50 device = new gl::Device(context); 51 52 setClearColor(0.0f, 0.0f, 0.0f, 0.0f); 53 54 mState.depthClearValue = 1.0f; 55 mState.stencilClearValue = 0; 56 57 mState.cullFaceEnabled = false; 58 mState.cullMode = GL_BACK; 59 mState.frontFace = GL_CCW; 60 mState.depthTestEnabled = false; 61 mState.depthFunc = GL_LESS; 62 mState.blendEnabled = false; 63 mState.sourceBlendRGB = GL_ONE; 64 mState.sourceBlendAlpha = GL_ONE; 65 mState.destBlendRGB = GL_ZERO; 66 mState.destBlendAlpha = GL_ZERO; 67 mState.blendEquationRGB = GL_FUNC_ADD; 68 mState.blendEquationAlpha = GL_FUNC_ADD; 69 mState.blendColor.red = 0; 70 mState.blendColor.green = 0; 71 mState.blendColor.blue = 0; 72 mState.blendColor.alpha = 0; 73 mState.stencilTestEnabled = false; 74 mState.stencilFunc = GL_ALWAYS; 75 mState.stencilRef = 0; 76 mState.stencilMask = -1; 77 mState.stencilWritemask = -1; 78 mState.stencilBackFunc = GL_ALWAYS; 79 mState.stencilBackRef = 0; 80 mState.stencilBackMask = - 1; 81 mState.stencilBackWritemask = -1; 82 mState.stencilFail = GL_KEEP; 83 mState.stencilPassDepthFail = GL_KEEP; 84 mState.stencilPassDepthPass = GL_KEEP; 85 mState.stencilBackFail = GL_KEEP; 86 mState.stencilBackPassDepthFail = GL_KEEP; 87 mState.stencilBackPassDepthPass = GL_KEEP; 88 mState.polygonOffsetFillEnabled = false; 89 mState.polygonOffsetFactor = 0.0f; 90 mState.polygonOffsetUnits = 0.0f; 91 mState.sampleAlphaToCoverageEnabled = false; 92 mState.sampleCoverageEnabled = false; 93 mState.sampleCoverageValue = 1.0f; 94 mState.sampleCoverageInvert = false; 95 mState.scissorTestEnabled = false; 96 mState.ditherEnabled = true; 97 mState.generateMipmapHint = GL_DONT_CARE; 98 mState.fragmentShaderDerivativeHint = GL_DONT_CARE; 99 mState.colorLogicOpEnabled = false; 100 mState.logicalOperation = GL_COPY; 101 102 mState.lineWidth = 1.0f; 103 104 mState.viewportX = 0; 105 mState.viewportY = 0; 106 mState.viewportWidth = 0; 107 mState.viewportHeight = 0; 108 mState.zNear = 0.0f; 109 mState.zFar = 1.0f; 110 111 mState.scissorX = 0; 112 mState.scissorY = 0; 113 mState.scissorWidth = 0; 114 mState.scissorHeight = 0; 115 116 mState.colorMaskRed = true; 117 mState.colorMaskGreen = true; 118 mState.colorMaskBlue = true; 119 mState.colorMaskAlpha = true; 120 mState.depthMask = true; 121 122 if(shareContext) 123 { 124 mResourceManager = shareContext->mResourceManager; 125 mResourceManager->addRef(); 126 } 127 else 128 { 129 mResourceManager = new ResourceManager(); 130 } 131 132 // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional 133 // and cube map texture state vectors respectively associated with them. 134 // In order that access to these initial textures not be lost, they are treated as texture 135 // objects all of whose names are 0. 136 137 mTexture2DZero = new Texture2D(0); 138 mProxyTexture2DZero = new Texture2D(0); 139 mTextureCubeMapZero = new TextureCubeMap(0); 140 141 mState.activeSampler = 0; 142 bindArrayBuffer(0); 143 bindElementArrayBuffer(0); 144 bindTextureCubeMap(0); 145 bindTexture2D(0); 146 bindReadFramebuffer(0); 147 bindDrawFramebuffer(0); 148 bindRenderbuffer(0); 149 150 mState.currentProgram = 0; 151 152 mState.packAlignment = 4; 153 mState.unpackAlignment = 4; 154 155 mVertexDataManager = nullptr; 156 mIndexDataManager = nullptr; 157 158 mInvalidEnum = false; 159 mInvalidValue = false; 160 mInvalidOperation = false; 161 mOutOfMemory = false; 162 mInvalidFramebufferOperation = false; 163 164 mHasBeenCurrent = false; 165 166 markAllStateDirty(); 167 168 matrixMode = GL_MODELVIEW; 169 170 listMode = 0; 171 //memset(displayList, 0, sizeof(displayList)); 172 listIndex = 0; 173 list = 0; 174 firstFreeIndex = 1; 175 176 clientTexture = GL_TEXTURE0; 177 178 drawing = false; 179 drawMode = 0; // FIXME 180 181 mState.vertexAttribute[sw::Color0].mCurrentValue[0] = 1.0f; 182 mState.vertexAttribute[sw::Color0].mCurrentValue[1] = 1.0f; 183 mState.vertexAttribute[sw::Color0].mCurrentValue[2] = 1.0f; 184 mState.vertexAttribute[sw::Color0].mCurrentValue[3] = 1.0f; 185 mState.vertexAttribute[sw::Normal].mCurrentValue[0] = 0.0f; 186 mState.vertexAttribute[sw::Normal].mCurrentValue[1] = 0.0f; 187 mState.vertexAttribute[sw::Normal].mCurrentValue[2] = 1.0f; 188 mState.vertexAttribute[sw::Normal].mCurrentValue[3] = 0.0f; 189 mState.vertexAttribute[sw::TexCoord0].mCurrentValue[0] = 0.0f; 190 mState.vertexAttribute[sw::TexCoord0].mCurrentValue[1] = 0.0f; 191 mState.vertexAttribute[sw::TexCoord0].mCurrentValue[2] = 0.0f; 192 mState.vertexAttribute[sw::TexCoord0].mCurrentValue[3] = 1.0f; 193 mState.vertexAttribute[sw::TexCoord1].mCurrentValue[0] = 0.0f; 194 mState.vertexAttribute[sw::TexCoord1].mCurrentValue[1] = 0.0f; 195 mState.vertexAttribute[sw::TexCoord1].mCurrentValue[2] = 0.0f; 196 mState.vertexAttribute[sw::TexCoord1].mCurrentValue[3] = 1.0f; 197 198 for(int i = 0; i < 8; i++) 199 { 200 envEnable[i] = true; 201 } 202 } 203 204 Context::~Context() 205 { 206 if(mState.currentProgram != 0) 207 { 208 Program *programObject = mResourceManager->getProgram(mState.currentProgram); 209 if(programObject) 210 { 211 programObject->release(); 212 } 213 mState.currentProgram = 0; 214 } 215 216 while(!mFramebufferNameSpace.empty()) 217 { 218 deleteFramebuffer(mFramebufferNameSpace.firstName()); 219 } 220 221 while(!mFenceNameSpace.empty()) 222 { 223 deleteFence(mFenceNameSpace.firstName()); 224 } 225 226 while(!mQueryNameSpace.empty()) 227 { 228 deleteQuery(mQueryNameSpace.firstName()); 229 } 230 231 for(int type = 0; type < TEXTURE_TYPE_COUNT; type++) 232 { 233 for(int sampler = 0; sampler < MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++) 234 { 235 mState.samplerTexture[type][sampler] = nullptr; 236 } 237 } 238 239 for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++) 240 { 241 mState.vertexAttribute[i].mBoundBuffer = nullptr; 242 } 243 244 for(int i = 0; i < QUERY_TYPE_COUNT; i++) 245 { 246 mState.activeQuery[i] = nullptr; 247 } 248 249 mState.arrayBuffer = nullptr; 250 mState.elementArrayBuffer = nullptr; 251 mState.renderbuffer = nullptr; 252 253 mTexture2DZero = nullptr; 254 mProxyTexture2DZero = nullptr; 255 mTextureCubeMapZero = nullptr; 256 257 delete mVertexDataManager; 258 delete mIndexDataManager; 259 260 mResourceManager->release(); 261 delete device; 262 } 263 264 void Context::makeCurrent(Surface *surface) 265 { 266 if(!mHasBeenCurrent) 267 { 268 mVertexDataManager = new VertexDataManager(this); 269 mIndexDataManager = new IndexDataManager(); 270 271 mState.viewportX = 0; 272 mState.viewportY = 0; 273 mState.viewportWidth = surface->getWidth(); 274 mState.viewportHeight = surface->getHeight(); 275 276 mState.scissorX = 0; 277 mState.scissorY = 0; 278 mState.scissorWidth = surface->getWidth(); 279 mState.scissorHeight = surface->getHeight(); 280 281 mHasBeenCurrent = true; 282 } 283 284 // Wrap the existing resources into GL objects and assign them to the '0' names 285 Image *defaultRenderTarget = surface->getRenderTarget(); 286 Image *depthStencil = surface->getDepthStencil(); 287 288 Colorbuffer *colorbufferZero = new Colorbuffer(defaultRenderTarget); 289 DepthStencilbuffer *depthStencilbufferZero = new DepthStencilbuffer(depthStencil); 290 Framebuffer *framebufferZero = new DefaultFramebuffer(colorbufferZero, depthStencilbufferZero); 291 292 setFramebufferZero(framebufferZero); 293 294 if(defaultRenderTarget) 295 { 296 defaultRenderTarget->release(); 297 } 298 299 if(depthStencil) 300 { 301 depthStencil->release(); 302 } 303 304 markAllStateDirty(); 305 } 306 307 // This function will set all of the state-related dirty flags, so that all state is set during next pre-draw. 308 void Context::markAllStateDirty() 309 { 310 mAppliedProgramSerial = 0; 311 312 mDepthStateDirty = true; 313 mMaskStateDirty = true; 314 mBlendStateDirty = true; 315 mStencilStateDirty = true; 316 mPolygonOffsetStateDirty = true; 317 mSampleStateDirty = true; 318 mDitherStateDirty = true; 319 mFrontFaceDirty = true; 320 mColorLogicOperatorDirty = true; 321 } 322 323 void Context::setClearColor(float red, float green, float blue, float alpha) 324 { 325 mState.colorClearValue.red = red; 326 mState.colorClearValue.green = green; 327 mState.colorClearValue.blue = blue; 328 mState.colorClearValue.alpha = alpha; 329 } 330 331 void Context::setClearDepth(float depth) 332 { 333 mState.depthClearValue = depth; 334 } 335 336 void Context::setClearStencil(int stencil) 337 { 338 mState.stencilClearValue = stencil; 339 } 340 341 void Context::setCullFaceEnabled(bool enabled) 342 { 343 mState.cullFaceEnabled = enabled; 344 } 345 346 bool Context::isCullFaceEnabled() const 347 { 348 return mState.cullFaceEnabled; 349 } 350 351 void Context::setCullMode(GLenum mode) 352 { 353 mState.cullMode = mode; 354 } 355 356 void Context::setFrontFace(GLenum front) 357 { 358 if(mState.frontFace != front) 359 { 360 mState.frontFace = front; 361 mFrontFaceDirty = true; 362 } 363 } 364 365 void Context::setDepthTestEnabled(bool enabled) 366 { 367 if(mState.depthTestEnabled != enabled) 368 { 369 mState.depthTestEnabled = enabled; 370 mDepthStateDirty = true; 371 } 372 } 373 374 bool Context::isDepthTestEnabled() const 375 { 376 return mState.depthTestEnabled; 377 } 378 379 void Context::setDepthFunc(GLenum depthFunc) 380 { 381 if(mState.depthFunc != depthFunc) 382 { 383 mState.depthFunc = depthFunc; 384 mDepthStateDirty = true; 385 } 386 } 387 388 void Context::setDepthRange(float zNear, float zFar) 389 { 390 mState.zNear = zNear; 391 mState.zFar = zFar; 392 } 393 394 void Context::setBlendEnabled(bool enabled) 395 { 396 if(mState.blendEnabled != enabled) 397 { 398 mState.blendEnabled = enabled; 399 mBlendStateDirty = true; 400 } 401 } 402 403 bool Context::isBlendEnabled() const 404 { 405 return mState.blendEnabled; 406 } 407 408 void Context::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha) 409 { 410 if(mState.sourceBlendRGB != sourceRGB || 411 mState.sourceBlendAlpha != sourceAlpha || 412 mState.destBlendRGB != destRGB || 413 mState.destBlendAlpha != destAlpha) 414 { 415 mState.sourceBlendRGB = sourceRGB; 416 mState.destBlendRGB = destRGB; 417 mState.sourceBlendAlpha = sourceAlpha; 418 mState.destBlendAlpha = destAlpha; 419 mBlendStateDirty = true; 420 } 421 } 422 423 void Context::setBlendColor(float red, float green, float blue, float alpha) 424 { 425 if(mState.blendColor.red != red || 426 mState.blendColor.green != green || 427 mState.blendColor.blue != blue || 428 mState.blendColor.alpha != alpha) 429 { 430 mState.blendColor.red = red; 431 mState.blendColor.green = green; 432 mState.blendColor.blue = blue; 433 mState.blendColor.alpha = alpha; 434 mBlendStateDirty = true; 435 } 436 } 437 438 void Context::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation) 439 { 440 if(mState.blendEquationRGB != rgbEquation || 441 mState.blendEquationAlpha != alphaEquation) 442 { 443 mState.blendEquationRGB = rgbEquation; 444 mState.blendEquationAlpha = alphaEquation; 445 mBlendStateDirty = true; 446 } 447 } 448 449 void Context::setStencilTestEnabled(bool enabled) 450 { 451 if(mState.stencilTestEnabled != enabled) 452 { 453 mState.stencilTestEnabled = enabled; 454 mStencilStateDirty = true; 455 } 456 } 457 458 bool Context::isStencilTestEnabled() const 459 { 460 return mState.stencilTestEnabled; 461 } 462 463 void Context::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask) 464 { 465 if(mState.stencilFunc != stencilFunc || 466 mState.stencilRef != stencilRef || 467 mState.stencilMask != stencilMask) 468 { 469 mState.stencilFunc = stencilFunc; 470 mState.stencilRef = (stencilRef > 0) ? stencilRef : 0; 471 mState.stencilMask = stencilMask; 472 mStencilStateDirty = true; 473 } 474 } 475 476 void Context::setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask) 477 { 478 if(mState.stencilBackFunc != stencilBackFunc || 479 mState.stencilBackRef != stencilBackRef || 480 mState.stencilBackMask != stencilBackMask) 481 { 482 mState.stencilBackFunc = stencilBackFunc; 483 mState.stencilBackRef = (stencilBackRef > 0) ? stencilBackRef : 0; 484 mState.stencilBackMask = stencilBackMask; 485 mStencilStateDirty = true; 486 } 487 } 488 489 void Context::setStencilWritemask(GLuint stencilWritemask) 490 { 491 if(mState.stencilWritemask != stencilWritemask) 492 { 493 mState.stencilWritemask = stencilWritemask; 494 mStencilStateDirty = true; 495 } 496 } 497 498 void Context::setStencilBackWritemask(GLuint stencilBackWritemask) 499 { 500 if(mState.stencilBackWritemask != stencilBackWritemask) 501 { 502 mState.stencilBackWritemask = stencilBackWritemask; 503 mStencilStateDirty = true; 504 } 505 } 506 507 void Context::setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass) 508 { 509 if(mState.stencilFail != stencilFail || 510 mState.stencilPassDepthFail != stencilPassDepthFail || 511 mState.stencilPassDepthPass != stencilPassDepthPass) 512 { 513 mState.stencilFail = stencilFail; 514 mState.stencilPassDepthFail = stencilPassDepthFail; 515 mState.stencilPassDepthPass = stencilPassDepthPass; 516 mStencilStateDirty = true; 517 } 518 } 519 520 void Context::setStencilBackOperations(GLenum stencilBackFail, GLenum stencilBackPassDepthFail, GLenum stencilBackPassDepthPass) 521 { 522 if(mState.stencilBackFail != stencilBackFail || 523 mState.stencilBackPassDepthFail != stencilBackPassDepthFail || 524 mState.stencilBackPassDepthPass != stencilBackPassDepthPass) 525 { 526 mState.stencilBackFail = stencilBackFail; 527 mState.stencilBackPassDepthFail = stencilBackPassDepthFail; 528 mState.stencilBackPassDepthPass = stencilBackPassDepthPass; 529 mStencilStateDirty = true; 530 } 531 } 532 533 void Context::setPolygonOffsetFillEnabled(bool enabled) 534 { 535 if(mState.polygonOffsetFillEnabled != enabled) 536 { 537 mState.polygonOffsetFillEnabled = enabled; 538 mPolygonOffsetStateDirty = true; 539 } 540 } 541 542 bool Context::isPolygonOffsetFillEnabled() const 543 { 544 return mState.polygonOffsetFillEnabled; 545 } 546 547 void Context::setPolygonOffsetParams(GLfloat factor, GLfloat units) 548 { 549 if(mState.polygonOffsetFactor != factor || 550 mState.polygonOffsetUnits != units) 551 { 552 mState.polygonOffsetFactor = factor; 553 mState.polygonOffsetUnits = units; 554 mPolygonOffsetStateDirty = true; 555 } 556 } 557 558 void Context::setSampleAlphaToCoverageEnabled(bool enabled) 559 { 560 if(mState.sampleAlphaToCoverageEnabled != enabled) 561 { 562 mState.sampleAlphaToCoverageEnabled = enabled; 563 mSampleStateDirty = true; 564 } 565 } 566 567 bool Context::isSampleAlphaToCoverageEnabled() const 568 { 569 return mState.sampleAlphaToCoverageEnabled; 570 } 571 572 void Context::setSampleCoverageEnabled(bool enabled) 573 { 574 if(mState.sampleCoverageEnabled != enabled) 575 { 576 mState.sampleCoverageEnabled = enabled; 577 mSampleStateDirty = true; 578 } 579 } 580 581 bool Context::isSampleCoverageEnabled() const 582 { 583 return mState.sampleCoverageEnabled; 584 } 585 586 void Context::setSampleCoverageParams(GLclampf value, bool invert) 587 { 588 if(mState.sampleCoverageValue != value || 589 mState.sampleCoverageInvert != invert) 590 { 591 mState.sampleCoverageValue = value; 592 mState.sampleCoverageInvert = invert; 593 mSampleStateDirty = true; 594 } 595 } 596 597 void Context::setScissorTestEnabled(bool enabled) 598 { 599 mState.scissorTestEnabled = enabled; 600 } 601 602 bool Context::isScissorTestEnabled() const 603 { 604 return mState.scissorTestEnabled; 605 } 606 607 void Context::setDitherEnabled(bool enabled) 608 { 609 if(mState.ditherEnabled != enabled) 610 { 611 mState.ditherEnabled = enabled; 612 mDitherStateDirty = true; 613 } 614 } 615 616 bool Context::isDitherEnabled() const 617 { 618 return mState.ditherEnabled; 619 } 620 621 void Context::setLineWidth(GLfloat width) 622 { 623 mState.lineWidth = width; 624 device->setLineWidth(clamp(width, ALIASED_LINE_WIDTH_RANGE_MIN, ALIASED_LINE_WIDTH_RANGE_MAX)); 625 } 626 627 void Context::setGenerateMipmapHint(GLenum hint) 628 { 629 mState.generateMipmapHint = hint; 630 } 631 632 void Context::setFragmentShaderDerivativeHint(GLenum hint) 633 { 634 mState.fragmentShaderDerivativeHint = hint; 635 // TODO: Propagate the hint to shader translator so we can write 636 // ddx, ddx_coarse, or ddx_fine depending on the hint. 637 // Ignore for now. It is valid for implementations to ignore hint. 638 } 639 640 void Context::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height) 641 { 642 mState.viewportX = x; 643 mState.viewportY = y; 644 mState.viewportWidth = width; 645 mState.viewportHeight = height; 646 } 647 648 void Context::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height) 649 { 650 mState.scissorX = x; 651 mState.scissorY = y; 652 mState.scissorWidth = width; 653 mState.scissorHeight = height; 654 } 655 656 void Context::setColorMask(bool red, bool green, bool blue, bool alpha) 657 { 658 if(mState.colorMaskRed != red || mState.colorMaskGreen != green || 659 mState.colorMaskBlue != blue || mState.colorMaskAlpha != alpha) 660 { 661 mState.colorMaskRed = red; 662 mState.colorMaskGreen = green; 663 mState.colorMaskBlue = blue; 664 mState.colorMaskAlpha = alpha; 665 mMaskStateDirty = true; 666 } 667 } 668 669 void Context::setDepthMask(bool mask) 670 { 671 if(mState.depthMask != mask) 672 { 673 mState.depthMask = mask; 674 mMaskStateDirty = true; 675 } 676 } 677 678 void Context::setActiveSampler(unsigned int active) 679 { 680 mState.activeSampler = active; 681 } 682 683 GLuint Context::getReadFramebufferName() const 684 { 685 return mState.readFramebuffer; 686 } 687 688 GLuint Context::getDrawFramebufferName() const 689 { 690 return mState.drawFramebuffer; 691 } 692 693 GLuint Context::getRenderbufferName() const 694 { 695 return mState.renderbuffer.name(); 696 } 697 698 GLuint Context::getArrayBufferName() const 699 { 700 return mState.arrayBuffer.name(); 701 } 702 703 GLuint Context::getActiveQuery(GLenum target) const 704 { 705 Query *queryObject = nullptr; 706 707 switch(target) 708 { 709 case GL_ANY_SAMPLES_PASSED: 710 queryObject = mState.activeQuery[QUERY_ANY_SAMPLES_PASSED]; 711 break; 712 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE: 713 queryObject = mState.activeQuery[QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE]; 714 break; 715 default: 716 ASSERT(false); 717 } 718 719 if(queryObject) 720 { 721 return queryObject->name; 722 } 723 724 return 0; 725 } 726 727 void Context::setVertexAttribArrayEnabled(unsigned int attribNum, bool enabled) 728 { 729 mState.vertexAttribute[attribNum].mArrayEnabled = enabled; 730 } 731 732 const VertexAttribute &Context::getVertexAttribState(unsigned int attribNum) 733 { 734 return mState.vertexAttribute[attribNum]; 735 } 736 737 void Context::setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type, bool normalized, 738 GLsizei stride, const void *pointer) 739 { 740 mState.vertexAttribute[attribNum].mBoundBuffer = boundBuffer; 741 mState.vertexAttribute[attribNum].mSize = size; 742 mState.vertexAttribute[attribNum].mType = type; 743 mState.vertexAttribute[attribNum].mNormalized = normalized; 744 mState.vertexAttribute[attribNum].mStride = stride; 745 mState.vertexAttribute[attribNum].mPointer = pointer; 746 } 747 748 const void *Context::getVertexAttribPointer(unsigned int attribNum) const 749 { 750 return mState.vertexAttribute[attribNum].mPointer; 751 } 752 753 const VertexAttributeArray &Context::getVertexAttributes() 754 { 755 return mState.vertexAttribute; 756 } 757 758 void Context::setPackAlignment(GLint alignment) 759 { 760 mState.packAlignment = alignment; 761 } 762 763 GLint Context::getPackAlignment() const 764 { 765 return mState.packAlignment; 766 } 767 768 void Context::setUnpackAlignment(GLint alignment) 769 { 770 mState.unpackAlignment = alignment; 771 } 772 773 GLint Context::getUnpackAlignment() const 774 { 775 return mState.unpackAlignment; 776 } 777 778 GLuint Context::createBuffer() 779 { 780 return mResourceManager->createBuffer(); 781 } 782 783 GLuint Context::createProgram() 784 { 785 return mResourceManager->createProgram(); 786 } 787 788 GLuint Context::createShader(GLenum type) 789 { 790 return mResourceManager->createShader(type); 791 } 792 793 GLuint Context::createTexture() 794 { 795 return mResourceManager->createTexture(); 796 } 797 798 GLuint Context::createRenderbuffer() 799 { 800 return mResourceManager->createRenderbuffer(); 801 } 802 803 // Returns an unused framebuffer name 804 GLuint Context::createFramebuffer() 805 { 806 return mFramebufferNameSpace.allocate(); 807 } 808 809 GLuint Context::createFence() 810 { 811 return mFenceNameSpace.allocate(new Fence()); 812 } 813 814 // Returns an unused query name 815 GLuint Context::createQuery() 816 { 817 return mQueryNameSpace.allocate(); 818 } 819 820 void Context::deleteBuffer(GLuint buffer) 821 { 822 if(mResourceManager->getBuffer(buffer)) 823 { 824 detachBuffer(buffer); 825 } 826 827 mResourceManager->deleteBuffer(buffer); 828 } 829 830 void Context::deleteShader(GLuint shader) 831 { 832 mResourceManager->deleteShader(shader); 833 } 834 835 void Context::deleteProgram(GLuint program) 836 { 837 mResourceManager->deleteProgram(program); 838 } 839 840 void Context::deleteTexture(GLuint texture) 841 { 842 if(mResourceManager->getTexture(texture)) 843 { 844 detachTexture(texture); 845 } 846 847 mResourceManager->deleteTexture(texture); 848 } 849 850 void Context::deleteRenderbuffer(GLuint renderbuffer) 851 { 852 if(mResourceManager->getRenderbuffer(renderbuffer)) 853 { 854 detachRenderbuffer(renderbuffer); 855 } 856 857 mResourceManager->deleteRenderbuffer(renderbuffer); 858 } 859 860 void Context::deleteFramebuffer(GLuint framebuffer) 861 { 862 Framebuffer *framebufferObject = mFramebufferNameSpace.remove(framebuffer); 863 864 if(framebufferObject) 865 { 866 detachFramebuffer(framebuffer); 867 868 delete framebufferObject; 869 } 870 } 871 872 void Context::deleteFence(GLuint fence) 873 { 874 Fence *fenceObject = mFenceNameSpace.remove(fence); 875 876 if(fenceObject) 877 { 878 delete fenceObject; 879 } 880 } 881 882 void Context::deleteQuery(GLuint query) 883 { 884 Query *queryObject = mQueryNameSpace.remove(query); 885 886 if(queryObject) 887 { 888 queryObject->release(); 889 } 890 } 891 892 Buffer *Context::getBuffer(GLuint handle) 893 { 894 return mResourceManager->getBuffer(handle); 895 } 896 897 Shader *Context::getShader(GLuint handle) 898 { 899 return mResourceManager->getShader(handle); 900 } 901 902 Program *Context::getProgram(GLuint handle) 903 { 904 return mResourceManager->getProgram(handle); 905 } 906 907 Texture *Context::getTexture(GLuint handle) 908 { 909 return mResourceManager->getTexture(handle); 910 } 911 912 Renderbuffer *Context::getRenderbuffer(GLuint handle) 913 { 914 return mResourceManager->getRenderbuffer(handle); 915 } 916 917 Framebuffer *Context::getReadFramebuffer() 918 { 919 return getFramebuffer(mState.readFramebuffer); 920 } 921 922 Framebuffer *Context::getDrawFramebuffer() 923 { 924 return getFramebuffer(mState.drawFramebuffer); 925 } 926 927 void Context::bindArrayBuffer(unsigned int buffer) 928 { 929 mResourceManager->checkBufferAllocation(buffer); 930 931 mState.arrayBuffer = getBuffer(buffer); 932 } 933 934 void Context::bindElementArrayBuffer(unsigned int buffer) 935 { 936 mResourceManager->checkBufferAllocation(buffer); 937 938 mState.elementArrayBuffer = getBuffer(buffer); 939 } 940 941 void Context::bindTexture2D(GLuint texture) 942 { 943 mResourceManager->checkTextureAllocation(texture, TEXTURE_2D); 944 945 mState.samplerTexture[TEXTURE_2D][mState.activeSampler] = getTexture(texture); 946 } 947 948 void Context::bindTextureCubeMap(GLuint texture) 949 { 950 mResourceManager->checkTextureAllocation(texture, TEXTURE_CUBE); 951 952 mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler] = getTexture(texture); 953 } 954 955 void Context::bindReadFramebuffer(GLuint framebuffer) 956 { 957 if(!getFramebuffer(framebuffer)) 958 { 959 mFramebufferNameSpace.insert(framebuffer, new Framebuffer()); 960 } 961 962 mState.readFramebuffer = framebuffer; 963 } 964 965 void Context::bindDrawFramebuffer(GLuint framebuffer) 966 { 967 if(!getFramebuffer(framebuffer)) 968 { 969 mFramebufferNameSpace.insert(framebuffer, new Framebuffer()); 970 } 971 972 mState.drawFramebuffer = framebuffer; 973 } 974 975 void Context::bindRenderbuffer(GLuint renderbuffer) 976 { 977 mResourceManager->checkRenderbufferAllocation(renderbuffer); 978 979 mState.renderbuffer = getRenderbuffer(renderbuffer); 980 } 981 982 void Context::useProgram(GLuint program) 983 { 984 GLuint priorProgram = mState.currentProgram; 985 mState.currentProgram = program; // Must switch before trying to delete, otherwise it only gets flagged. 986 987 if(priorProgram != program) 988 { 989 Program *newProgram = mResourceManager->getProgram(program); 990 Program *oldProgram = mResourceManager->getProgram(priorProgram); 991 992 if(newProgram) 993 { 994 newProgram->addRef(); 995 } 996 997 if(oldProgram) 998 { 999 oldProgram->release(); 1000 } 1001 } 1002 } 1003 1004 void Context::beginQuery(GLenum target, GLuint query) 1005 { 1006 // From EXT_occlusion_query_boolean: If BeginQueryEXT is called with an <id> 1007 // of zero, if the active query object name for <target> is non-zero (for the 1008 // targets ANY_SAMPLES_PASSED_EXT and ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, if 1009 // the active query for either target is non-zero), if <id> is the name of an 1010 // existing query object whose type does not match <target>, or if <id> is the 1011 // active query object name for any query type, the error INVALID_OPERATION is 1012 // generated. 1013 1014 // Ensure no other queries are active 1015 // NOTE: If other queries than occlusion are supported, we will need to check 1016 // separately that: 1017 // a) The query ID passed is not the current active query for any target/type 1018 // b) There are no active queries for the requested target (and in the case 1019 // of GL_ANY_SAMPLES_PASSED_EXT and GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, 1020 // no query may be active for either if glBeginQuery targets either. 1021 for(int i = 0; i < QUERY_TYPE_COUNT; i++) 1022 { 1023 if(mState.activeQuery[i]) 1024 { 1025 return error(GL_INVALID_OPERATION); 1026 } 1027 } 1028 1029 QueryType qType; 1030 switch(target) 1031 { 1032 case GL_ANY_SAMPLES_PASSED: 1033 qType = QUERY_ANY_SAMPLES_PASSED; 1034 break; 1035 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE: 1036 qType = QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE; 1037 break; 1038 default: 1039 ASSERT(false); 1040 } 1041 1042 Query *queryObject = getQuery(query, true, target); 1043 1044 // Check that name was obtained with glGenQueries 1045 if(!queryObject) 1046 { 1047 return error(GL_INVALID_OPERATION); 1048 } 1049 1050 // Check for type mismatch 1051 if(queryObject->getType() != target) 1052 { 1053 return error(GL_INVALID_OPERATION); 1054 } 1055 1056 // Set query as active for specified target 1057 mState.activeQuery[qType] = queryObject; 1058 1059 // Begin query 1060 queryObject->begin(); 1061 } 1062 1063 void Context::endQuery(GLenum target) 1064 { 1065 QueryType qType; 1066 1067 switch(target) 1068 { 1069 case GL_ANY_SAMPLES_PASSED: 1070 qType = QUERY_ANY_SAMPLES_PASSED; 1071 break; 1072 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE: 1073 qType = QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE; 1074 break; 1075 default: 1076 ASSERT(false); 1077 } 1078 1079 Query *queryObject = mState.activeQuery[qType]; 1080 1081 if(!queryObject) 1082 { 1083 return error(GL_INVALID_OPERATION); 1084 } 1085 1086 queryObject->end(); 1087 1088 mState.activeQuery[qType] = nullptr; 1089 } 1090 1091 void Context::setFramebufferZero(Framebuffer *buffer) 1092 { 1093 delete mFramebufferNameSpace.remove(0); 1094 mFramebufferNameSpace.insert(0, buffer); 1095 } 1096 1097 void Context::setRenderbufferStorage(RenderbufferStorage *renderbuffer) 1098 { 1099 Renderbuffer *renderbufferObject = mState.renderbuffer; 1100 renderbufferObject->setStorage(renderbuffer); 1101 } 1102 1103 Framebuffer *Context::getFramebuffer(unsigned int handle) 1104 { 1105 return mFramebufferNameSpace.find(handle); 1106 } 1107 1108 Fence *Context::getFence(unsigned int handle) 1109 { 1110 return mFenceNameSpace.find(handle); 1111 } 1112 1113 Query *Context::getQuery(unsigned int handle, bool create, GLenum type) 1114 { 1115 if(!mQueryNameSpace.isReserved(handle)) 1116 { 1117 return nullptr; 1118 } 1119 else 1120 { 1121 Query *query = mQueryNameSpace.find(handle); 1122 if(!query && create) 1123 { 1124 query = new Query(handle, type); 1125 query->addRef(); 1126 mQueryNameSpace.insert(handle, query); 1127 } 1128 1129 return query; 1130 } 1131 } 1132 1133 Buffer *Context::getArrayBuffer() 1134 { 1135 return mState.arrayBuffer; 1136 } 1137 1138 Buffer *Context::getElementArrayBuffer() 1139 { 1140 return mState.elementArrayBuffer; 1141 } 1142 1143 Program *Context::getCurrentProgram() 1144 { 1145 return mResourceManager->getProgram(mState.currentProgram); 1146 } 1147 1148 Texture2D *Context::getTexture2D(GLenum target) 1149 { 1150 if(target == GL_TEXTURE_2D) 1151 { 1152 return static_cast<Texture2D*>(getSamplerTexture(mState.activeSampler, TEXTURE_2D)); 1153 } 1154 else if(target == GL_PROXY_TEXTURE_2D) 1155 { 1156 return static_cast<Texture2D*>(getSamplerTexture(mState.activeSampler, PROXY_TEXTURE_2D)); 1157 } 1158 else UNREACHABLE(target); 1159 1160 return nullptr; 1161 } 1162 1163 TextureCubeMap *Context::getTextureCubeMap() 1164 { 1165 return static_cast<TextureCubeMap*>(getSamplerTexture(mState.activeSampler, TEXTURE_CUBE)); 1166 } 1167 1168 Texture *Context::getSamplerTexture(unsigned int sampler, TextureType type) 1169 { 1170 GLuint texid = mState.samplerTexture[type][sampler].name(); 1171 1172 if(texid == 0) // Special case: 0 refers to different initial textures based on the target 1173 { 1174 switch(type) 1175 { 1176 case TEXTURE_2D: return mTexture2DZero; 1177 case PROXY_TEXTURE_2D: return mProxyTexture2DZero; 1178 case TEXTURE_CUBE: return mTextureCubeMapZero; 1179 default: UNREACHABLE(type); 1180 } 1181 } 1182 1183 return mState.samplerTexture[type][sampler]; 1184 } 1185 1186 bool Context::getBooleanv(GLenum pname, GLboolean *params) 1187 { 1188 switch(pname) 1189 { 1190 case GL_SHADER_COMPILER: *params = GL_TRUE; break; 1191 case GL_SAMPLE_COVERAGE_INVERT: *params = mState.sampleCoverageInvert; break; 1192 case GL_DEPTH_WRITEMASK: *params = mState.depthMask; break; 1193 case GL_COLOR_WRITEMASK: 1194 params[0] = mState.colorMaskRed; 1195 params[1] = mState.colorMaskGreen; 1196 params[2] = mState.colorMaskBlue; 1197 params[3] = mState.colorMaskAlpha; 1198 break; 1199 case GL_CULL_FACE: *params = mState.cullFaceEnabled; break; 1200 case GL_POLYGON_OFFSET_FILL: *params = mState.polygonOffsetFillEnabled; break; 1201 case GL_SAMPLE_ALPHA_TO_COVERAGE: *params = mState.sampleAlphaToCoverageEnabled; break; 1202 case GL_SAMPLE_COVERAGE: *params = mState.sampleCoverageEnabled; break; 1203 case GL_SCISSOR_TEST: *params = mState.scissorTestEnabled; break; 1204 case GL_STENCIL_TEST: *params = mState.stencilTestEnabled; break; 1205 case GL_DEPTH_TEST: *params = mState.depthTestEnabled; break; 1206 case GL_BLEND: *params = mState.blendEnabled; break; 1207 case GL_DITHER: *params = mState.ditherEnabled; break; 1208 default: 1209 return false; 1210 } 1211 1212 return true; 1213 } 1214 1215 bool Context::getFloatv(GLenum pname, GLfloat *params) 1216 { 1217 // Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation 1218 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names 1219 // GetIntegerv as its native query function. As it would require conversion in any 1220 // case, this should make no difference to the calling application. 1221 switch(pname) 1222 { 1223 case GL_LINE_WIDTH: *params = mState.lineWidth; break; 1224 case GL_SAMPLE_COVERAGE_VALUE: *params = mState.sampleCoverageValue; break; 1225 case GL_DEPTH_CLEAR_VALUE: *params = mState.depthClearValue; break; 1226 case GL_POLYGON_OFFSET_FACTOR: *params = mState.polygonOffsetFactor; break; 1227 case GL_POLYGON_OFFSET_UNITS: *params = mState.polygonOffsetUnits; break; 1228 case GL_ALIASED_LINE_WIDTH_RANGE: 1229 params[0] = ALIASED_LINE_WIDTH_RANGE_MIN; 1230 params[1] = ALIASED_LINE_WIDTH_RANGE_MAX; 1231 break; 1232 case GL_ALIASED_POINT_SIZE_RANGE: 1233 params[0] = ALIASED_POINT_SIZE_RANGE_MIN; 1234 params[1] = ALIASED_POINT_SIZE_RANGE_MAX; 1235 break; 1236 case GL_DEPTH_RANGE: 1237 params[0] = mState.zNear; 1238 params[1] = mState.zFar; 1239 break; 1240 case GL_COLOR_CLEAR_VALUE: 1241 params[0] = mState.colorClearValue.red; 1242 params[1] = mState.colorClearValue.green; 1243 params[2] = mState.colorClearValue.blue; 1244 params[3] = mState.colorClearValue.alpha; 1245 break; 1246 case GL_BLEND_COLOR: 1247 params[0] = mState.blendColor.red; 1248 params[1] = mState.blendColor.green; 1249 params[2] = mState.blendColor.blue; 1250 params[3] = mState.blendColor.alpha; 1251 break; 1252 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT: 1253 *params = MAX_TEXTURE_MAX_ANISOTROPY; 1254 break; 1255 case GL_MODELVIEW_MATRIX: 1256 for(int i = 0; i < 16; i++) 1257 { 1258 params[i] = modelView.current()[i % 4][i / 4]; 1259 } 1260 break; 1261 case GL_PROJECTION_MATRIX: 1262 for(int i = 0; i < 16; i++) 1263 { 1264 params[i] = projection.current()[i % 4][i / 4]; 1265 } 1266 break; 1267 default: 1268 return false; 1269 } 1270 1271 return true; 1272 } 1273 1274 bool Context::getIntegerv(GLenum pname, GLint *params) 1275 { 1276 // Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation 1277 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names 1278 // GetIntegerv as its native query function. As it would require conversion in any 1279 // case, this should make no difference to the calling application. You may find it in 1280 // Context::getFloatv. 1281 switch(pname) 1282 { 1283 case GL_MAX_VERTEX_ATTRIBS: *params = MAX_VERTEX_ATTRIBS; break; 1284 case GL_MAX_VERTEX_UNIFORM_VECTORS: *params = MAX_VERTEX_UNIFORM_VECTORS; break; 1285 case GL_MAX_VERTEX_UNIFORM_COMPONENTS: *params = MAX_VERTEX_UNIFORM_VECTORS * 4; break; // FIXME: Verify 1286 case GL_MAX_VARYING_VECTORS: *params = MAX_VARYING_VECTORS; break; 1287 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = MAX_COMBINED_TEXTURE_IMAGE_UNITS; break; 1288 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = MAX_VERTEX_TEXTURE_IMAGE_UNITS; break; 1289 case GL_MAX_TEXTURE_IMAGE_UNITS: *params = MAX_TEXTURE_IMAGE_UNITS; break; 1290 case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = MAX_FRAGMENT_UNIFORM_VECTORS; break; 1291 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: *params = MAX_VERTEX_UNIFORM_VECTORS * 4; break; // FIXME: Verify 1292 case GL_MAX_RENDERBUFFER_SIZE: *params = IMPLEMENTATION_MAX_RENDERBUFFER_SIZE; break; 1293 case GL_NUM_SHADER_BINARY_FORMATS: *params = 0; break; 1294 case GL_SHADER_BINARY_FORMATS: /* no shader binary formats are supported */ break; 1295 case GL_ARRAY_BUFFER_BINDING: *params = mState.arrayBuffer.name(); break; 1296 case GL_ELEMENT_ARRAY_BUFFER_BINDING: *params = mState.elementArrayBuffer.name(); break; 1297 // case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE 1298 case GL_DRAW_FRAMEBUFFER_BINDING: *params = mState.drawFramebuffer; break; 1299 case GL_READ_FRAMEBUFFER_BINDING: *params = mState.readFramebuffer; break; 1300 case GL_RENDERBUFFER_BINDING: *params = mState.renderbuffer.name(); break; 1301 case GL_CURRENT_PROGRAM: *params = mState.currentProgram; break; 1302 case GL_PACK_ALIGNMENT: *params = mState.packAlignment; break; 1303 case GL_UNPACK_ALIGNMENT: *params = mState.unpackAlignment; break; 1304 case GL_GENERATE_MIPMAP_HINT: *params = mState.generateMipmapHint; break; 1305 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT: *params = mState.fragmentShaderDerivativeHint; break; 1306 case GL_ACTIVE_TEXTURE: *params = (mState.activeSampler + GL_TEXTURE0); break; 1307 case GL_STENCIL_FUNC: *params = mState.stencilFunc; break; 1308 case GL_STENCIL_REF: *params = mState.stencilRef; break; 1309 case GL_STENCIL_VALUE_MASK: *params = mState.stencilMask; break; 1310 case GL_STENCIL_BACK_FUNC: *params = mState.stencilBackFunc; break; 1311 case GL_STENCIL_BACK_REF: *params = mState.stencilBackRef; break; 1312 case GL_STENCIL_BACK_VALUE_MASK: *params = mState.stencilBackMask; break; 1313 case GL_STENCIL_FAIL: *params = mState.stencilFail; break; 1314 case GL_STENCIL_PASS_DEPTH_FAIL: *params = mState.stencilPassDepthFail; break; 1315 case GL_STENCIL_PASS_DEPTH_PASS: *params = mState.stencilPassDepthPass; break; 1316 case GL_STENCIL_BACK_FAIL: *params = mState.stencilBackFail; break; 1317 case GL_STENCIL_BACK_PASS_DEPTH_FAIL: *params = mState.stencilBackPassDepthFail; break; 1318 case GL_STENCIL_BACK_PASS_DEPTH_PASS: *params = mState.stencilBackPassDepthPass; break; 1319 case GL_DEPTH_FUNC: *params = mState.depthFunc; break; 1320 case GL_BLEND_SRC_RGB: *params = mState.sourceBlendRGB; break; 1321 case GL_BLEND_SRC_ALPHA: *params = mState.sourceBlendAlpha; break; 1322 case GL_BLEND_DST_RGB: *params = mState.destBlendRGB; break; 1323 case GL_BLEND_DST_ALPHA: *params = mState.destBlendAlpha; break; 1324 case GL_BLEND_EQUATION_RGB: *params = mState.blendEquationRGB; break; 1325 case GL_BLEND_EQUATION_ALPHA: *params = mState.blendEquationAlpha; break; 1326 case GL_STENCIL_WRITEMASK: *params = mState.stencilWritemask; break; 1327 case GL_STENCIL_BACK_WRITEMASK: *params = mState.stencilBackWritemask; break; 1328 case GL_STENCIL_CLEAR_VALUE: *params = mState.stencilClearValue; break; 1329 case GL_SUBPIXEL_BITS: *params = 4; break; 1330 case GL_MAX_TEXTURE_SIZE: *params = IMPLEMENTATION_MAX_TEXTURE_SIZE; break; 1331 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: *params = IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE; break; 1332 case GL_MAX_ARRAY_TEXTURE_LAYERS: *params = 0; break; 1333 case GL_NUM_COMPRESSED_TEXTURE_FORMATS: *params = NUM_COMPRESSED_TEXTURE_FORMATS; break; 1334 case GL_MAX_SAMPLES: *params = IMPLEMENTATION_MAX_SAMPLES; break; 1335 case GL_SAMPLE_BUFFERS: 1336 case GL_SAMPLES: 1337 { 1338 Framebuffer *framebuffer = getDrawFramebuffer(); 1339 int width, height, samples; 1340 1341 if(framebuffer->completeness(width, height, samples) == GL_FRAMEBUFFER_COMPLETE) 1342 { 1343 switch(pname) 1344 { 1345 case GL_SAMPLE_BUFFERS: 1346 if(samples > 1) 1347 { 1348 *params = 1; 1349 } 1350 else 1351 { 1352 *params = 0; 1353 } 1354 break; 1355 case GL_SAMPLES: 1356 *params = samples; 1357 break; 1358 } 1359 } 1360 else 1361 { 1362 *params = 0; 1363 } 1364 } 1365 break; 1366 case GL_IMPLEMENTATION_COLOR_READ_TYPE: *params = IMPLEMENTATION_COLOR_READ_TYPE; break; 1367 case GL_IMPLEMENTATION_COLOR_READ_FORMAT: *params = IMPLEMENTATION_COLOR_READ_FORMAT; break; 1368 case GL_MAX_VIEWPORT_DIMS: 1369 { 1370 int maxDimension = IMPLEMENTATION_MAX_RENDERBUFFER_SIZE; 1371 params[0] = maxDimension; 1372 params[1] = maxDimension; 1373 } 1374 break; 1375 case GL_COMPRESSED_TEXTURE_FORMATS: 1376 { 1377 for(int i = 0; i < NUM_COMPRESSED_TEXTURE_FORMATS; i++) 1378 { 1379 params[i] = compressedTextureFormats[i]; 1380 } 1381 } 1382 break; 1383 case GL_VIEWPORT: 1384 params[0] = mState.viewportX; 1385 params[1] = mState.viewportY; 1386 params[2] = mState.viewportWidth; 1387 params[3] = mState.viewportHeight; 1388 break; 1389 case GL_SCISSOR_BOX: 1390 params[0] = mState.scissorX; 1391 params[1] = mState.scissorY; 1392 params[2] = mState.scissorWidth; 1393 params[3] = mState.scissorHeight; 1394 break; 1395 case GL_CULL_FACE_MODE: *params = mState.cullMode; break; 1396 case GL_FRONT_FACE: *params = mState.frontFace; break; 1397 case GL_RED_BITS: 1398 case GL_GREEN_BITS: 1399 case GL_BLUE_BITS: 1400 case GL_ALPHA_BITS: 1401 { 1402 Framebuffer *framebuffer = getDrawFramebuffer(); 1403 Renderbuffer *colorbuffer = framebuffer->getColorbuffer(); 1404 1405 if(colorbuffer) 1406 { 1407 switch(pname) 1408 { 1409 case GL_RED_BITS: *params = colorbuffer->getRedSize(); break; 1410 case GL_GREEN_BITS: *params = colorbuffer->getGreenSize(); break; 1411 case GL_BLUE_BITS: *params = colorbuffer->getBlueSize(); break; 1412 case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize(); break; 1413 } 1414 } 1415 else 1416 { 1417 *params = 0; 1418 } 1419 } 1420 break; 1421 case GL_DEPTH_BITS: 1422 { 1423 Framebuffer *framebuffer = getDrawFramebuffer(); 1424 Renderbuffer *depthbuffer = framebuffer->getDepthbuffer(); 1425 1426 if(depthbuffer) 1427 { 1428 *params = depthbuffer->getDepthSize(); 1429 } 1430 else 1431 { 1432 *params = 0; 1433 } 1434 } 1435 break; 1436 case GL_STENCIL_BITS: 1437 { 1438 Framebuffer *framebuffer = getDrawFramebuffer(); 1439 Renderbuffer *stencilbuffer = framebuffer->getStencilbuffer(); 1440 1441 if(stencilbuffer) 1442 { 1443 *params = stencilbuffer->getStencilSize(); 1444 } 1445 else 1446 { 1447 *params = 0; 1448 } 1449 } 1450 break; 1451 case GL_TEXTURE_BINDING_2D: 1452 { 1453 if(mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1) 1454 { 1455 error(GL_INVALID_OPERATION); 1456 return false; 1457 } 1458 1459 *params = mState.samplerTexture[TEXTURE_2D][mState.activeSampler].name(); 1460 } 1461 break; 1462 case GL_TEXTURE_BINDING_CUBE_MAP: 1463 { 1464 if(mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1) 1465 { 1466 error(GL_INVALID_OPERATION); 1467 return false; 1468 } 1469 1470 *params = mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler].name(); 1471 } 1472 break; 1473 default: 1474 return false; 1475 } 1476 1477 return true; 1478 } 1479 1480 bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams) 1481 { 1482 // Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation 1483 // is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due 1484 // to the fact that it is stored internally as a float, and so would require conversion 1485 // if returned from Context::getIntegerv. Since this conversion is already implemented 1486 // in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we 1487 // place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling 1488 // application. 1489 switch(pname) 1490 { 1491 case GL_COMPRESSED_TEXTURE_FORMATS: 1492 { 1493 *type = GL_INT; 1494 *numParams = NUM_COMPRESSED_TEXTURE_FORMATS; 1495 } 1496 break; 1497 case GL_SHADER_BINARY_FORMATS: 1498 { 1499 *type = GL_INT; 1500 *numParams = 0; 1501 } 1502 break; 1503 case GL_MAX_VERTEX_ATTRIBS: 1504 case GL_MAX_VERTEX_UNIFORM_VECTORS: 1505 case GL_MAX_VARYING_VECTORS: 1506 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: 1507 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: 1508 case GL_MAX_TEXTURE_IMAGE_UNITS: 1509 case GL_MAX_FRAGMENT_UNIFORM_VECTORS: 1510 case GL_MAX_RENDERBUFFER_SIZE: 1511 case GL_NUM_SHADER_BINARY_FORMATS: 1512 case GL_NUM_COMPRESSED_TEXTURE_FORMATS: 1513 case GL_ARRAY_BUFFER_BINDING: 1514 case GL_FRAMEBUFFER_BINDING: 1515 case GL_RENDERBUFFER_BINDING: 1516 case GL_CURRENT_PROGRAM: 1517 case GL_PACK_ALIGNMENT: 1518 case GL_UNPACK_ALIGNMENT: 1519 case GL_GENERATE_MIPMAP_HINT: 1520 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT: 1521 case GL_RED_BITS: 1522 case GL_GREEN_BITS: 1523 case GL_BLUE_BITS: 1524 case GL_ALPHA_BITS: 1525 case GL_DEPTH_BITS: 1526 case GL_STENCIL_BITS: 1527 case GL_ELEMENT_ARRAY_BUFFER_BINDING: 1528 case GL_CULL_FACE_MODE: 1529 case GL_FRONT_FACE: 1530 case GL_ACTIVE_TEXTURE: 1531 case GL_STENCIL_FUNC: 1532 case GL_STENCIL_VALUE_MASK: 1533 case GL_STENCIL_REF: 1534 case GL_STENCIL_FAIL: 1535 case GL_STENCIL_PASS_DEPTH_FAIL: 1536 case GL_STENCIL_PASS_DEPTH_PASS: 1537 case GL_STENCIL_BACK_FUNC: 1538 case GL_STENCIL_BACK_VALUE_MASK: 1539 case GL_STENCIL_BACK_REF: 1540 case GL_STENCIL_BACK_FAIL: 1541 case GL_STENCIL_BACK_PASS_DEPTH_FAIL: 1542 case GL_STENCIL_BACK_PASS_DEPTH_PASS: 1543 case GL_DEPTH_FUNC: 1544 case GL_BLEND_SRC_RGB: 1545 case GL_BLEND_SRC_ALPHA: 1546 case GL_BLEND_DST_RGB: 1547 case GL_BLEND_DST_ALPHA: 1548 case GL_BLEND_EQUATION_RGB: 1549 case GL_BLEND_EQUATION_ALPHA: 1550 case GL_STENCIL_WRITEMASK: 1551 case GL_STENCIL_BACK_WRITEMASK: 1552 case GL_STENCIL_CLEAR_VALUE: 1553 case GL_SUBPIXEL_BITS: 1554 case GL_MAX_TEXTURE_SIZE: 1555 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: 1556 case GL_SAMPLE_BUFFERS: 1557 case GL_SAMPLES: 1558 case GL_IMPLEMENTATION_COLOR_READ_TYPE: 1559 case GL_IMPLEMENTATION_COLOR_READ_FORMAT: 1560 case GL_TEXTURE_BINDING_2D: 1561 case GL_TEXTURE_BINDING_CUBE_MAP: 1562 case GL_MAX_VERTEX_UNIFORM_COMPONENTS: 1563 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: 1564 case GL_MAX_ARRAY_TEXTURE_LAYERS: 1565 { 1566 *type = GL_INT; 1567 *numParams = 1; 1568 } 1569 break; 1570 case GL_MAX_SAMPLES: 1571 { 1572 *type = GL_INT; 1573 *numParams = 1; 1574 } 1575 break; 1576 case GL_MAX_VIEWPORT_DIMS: 1577 { 1578 *type = GL_INT; 1579 *numParams = 2; 1580 } 1581 break; 1582 case GL_VIEWPORT: 1583 case GL_SCISSOR_BOX: 1584 { 1585 *type = GL_INT; 1586 *numParams = 4; 1587 } 1588 break; 1589 case GL_SHADER_COMPILER: 1590 case GL_SAMPLE_COVERAGE_INVERT: 1591 case GL_DEPTH_WRITEMASK: 1592 case GL_CULL_FACE: // CULL_FACE through DITHER are natural to IsEnabled, 1593 case GL_POLYGON_OFFSET_FILL: // but can be retrieved through the Get{Type}v queries. 1594 case GL_SAMPLE_ALPHA_TO_COVERAGE: // For this purpose, they are treated here as bool-natural 1595 case GL_SAMPLE_COVERAGE: 1596 case GL_SCISSOR_TEST: 1597 case GL_STENCIL_TEST: 1598 case GL_DEPTH_TEST: 1599 case GL_BLEND: 1600 case GL_DITHER: 1601 { 1602 *type = GL_BOOL; 1603 *numParams = 1; 1604 } 1605 break; 1606 case GL_COLOR_WRITEMASK: 1607 { 1608 *type = GL_BOOL; 1609 *numParams = 4; 1610 } 1611 break; 1612 case GL_POLYGON_OFFSET_FACTOR: 1613 case GL_POLYGON_OFFSET_UNITS: 1614 case GL_SAMPLE_COVERAGE_VALUE: 1615 case GL_DEPTH_CLEAR_VALUE: 1616 case GL_LINE_WIDTH: 1617 { 1618 *type = GL_FLOAT; 1619 *numParams = 1; 1620 } 1621 break; 1622 case GL_ALIASED_LINE_WIDTH_RANGE: 1623 case GL_ALIASED_POINT_SIZE_RANGE: 1624 case GL_DEPTH_RANGE: 1625 { 1626 *type = GL_FLOAT; 1627 *numParams = 2; 1628 } 1629 break; 1630 case GL_COLOR_CLEAR_VALUE: 1631 case GL_BLEND_COLOR: 1632 { 1633 *type = GL_FLOAT; 1634 *numParams = 4; 1635 } 1636 break; 1637 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT: 1638 *type = GL_FLOAT; 1639 *numParams = 1; 1640 break; 1641 default: 1642 return false; 1643 } 1644 1645 return true; 1646 } 1647 1648 // Applies the render target surface, depth stencil surface, viewport rectangle and scissor rectangle 1649 bool Context::applyRenderTarget() 1650 { 1651 Framebuffer *framebuffer = getDrawFramebuffer(); 1652 int width, height, samples; 1653 1654 if(!framebuffer || framebuffer->completeness(width, height, samples) != GL_FRAMEBUFFER_COMPLETE) 1655 { 1656 return error(GL_INVALID_FRAMEBUFFER_OPERATION, false); 1657 } 1658 1659 Image *renderTarget = framebuffer->getRenderTarget(); 1660 device->setRenderTarget(0, renderTarget); 1661 if(renderTarget) renderTarget->release(); 1662 1663 Image *depthStencil = framebuffer->getDepthStencil(); 1664 device->setDepthStencilSurface(depthStencil); 1665 if(depthStencil) depthStencil->release(); 1666 1667 Viewport viewport; 1668 float zNear = clamp01(mState.zNear); 1669 float zFar = clamp01(mState.zFar); 1670 1671 viewport.x0 = mState.viewportX; 1672 viewport.y0 = mState.viewportY; 1673 viewport.width = mState.viewportWidth; 1674 viewport.height = mState.viewportHeight; 1675 viewport.minZ = zNear; 1676 viewport.maxZ = zFar; 1677 1678 device->setViewport(viewport); 1679 1680 if(mState.scissorTestEnabled) 1681 { 1682 sw::Rect scissor = {mState.scissorX, mState.scissorY, mState.scissorX + mState.scissorWidth, mState.scissorY + mState.scissorHeight}; 1683 scissor.clip(0, 0, width, height); 1684 1685 device->setScissorRect(scissor); 1686 device->setScissorEnable(true); 1687 } 1688 else 1689 { 1690 device->setScissorEnable(false); 1691 } 1692 1693 Program *program = getCurrentProgram(); 1694 1695 if(program) 1696 { 1697 GLfloat nearFarDiff[3] = {zNear, zFar, zFar - zNear}; 1698 program->setUniform1fv(program->getUniformLocation("gl_DepthRange.near"), 1, &nearFarDiff[0]); 1699 program->setUniform1fv(program->getUniformLocation("gl_DepthRange.far"), 1, &nearFarDiff[1]); 1700 program->setUniform1fv(program->getUniformLocation("gl_DepthRange.diff"), 1, &nearFarDiff[2]); 1701 } 1702 1703 return true; 1704 } 1705 1706 // Applies the fixed-function state (culling, depth test, alpha blending, stenciling, etc) 1707 void Context::applyState(GLenum drawMode) 1708 { 1709 Framebuffer *framebuffer = getDrawFramebuffer(); 1710 1711 if(mState.cullFaceEnabled) 1712 { 1713 device->setCullMode(es2sw::ConvertCullMode(mState.cullMode, mState.frontFace)); 1714 } 1715 else 1716 { 1717 device->setCullMode(sw::CULL_NONE); 1718 } 1719 1720 if(mDepthStateDirty) 1721 { 1722 if(mState.depthTestEnabled) 1723 { 1724 device->setDepthBufferEnable(true); 1725 device->setDepthCompare(es2sw::ConvertDepthComparison(mState.depthFunc)); 1726 } 1727 else 1728 { 1729 device->setDepthBufferEnable(false); 1730 } 1731 1732 mDepthStateDirty = false; 1733 } 1734 1735 if(mBlendStateDirty) 1736 { 1737 if(mState.blendEnabled) 1738 { 1739 device->setAlphaBlendEnable(true); 1740 device->setSeparateAlphaBlendEnable(true); 1741 1742 device->setBlendConstant(es2sw::ConvertColor(mState.blendColor)); 1743 1744 device->setSourceBlendFactor(es2sw::ConvertBlendFunc(mState.sourceBlendRGB)); 1745 device->setDestBlendFactor(es2sw::ConvertBlendFunc(mState.destBlendRGB)); 1746 device->setBlendOperation(es2sw::ConvertBlendOp(mState.blendEquationRGB)); 1747 1748 device->setSourceBlendFactorAlpha(es2sw::ConvertBlendFunc(mState.sourceBlendAlpha)); 1749 device->setDestBlendFactorAlpha(es2sw::ConvertBlendFunc(mState.destBlendAlpha)); 1750 device->setBlendOperationAlpha(es2sw::ConvertBlendOp(mState.blendEquationAlpha)); 1751 } 1752 else 1753 { 1754 device->setAlphaBlendEnable(false); 1755 } 1756 1757 mBlendStateDirty = false; 1758 } 1759 1760 if(mColorLogicOperatorDirty) 1761 { 1762 if(mState.colorLogicOpEnabled) 1763 { 1764 device->setColorLogicOpEnabled(true); 1765 device->setLogicalOperation(es2sw::ConvertLogicalOperation(mState.logicalOperation)); 1766 } 1767 else 1768 { 1769 device->setColorLogicOpEnabled(false); 1770 } 1771 1772 mColorLogicOperatorDirty = false; 1773 } 1774 1775 if(mStencilStateDirty || mFrontFaceDirty) 1776 { 1777 if(mState.stencilTestEnabled && framebuffer->hasStencil()) 1778 { 1779 device->setStencilEnable(true); 1780 device->setTwoSidedStencil(true); 1781 1782 if(mState.stencilWritemask != mState.stencilBackWritemask || 1783 mState.stencilRef != mState.stencilBackRef || 1784 mState.stencilMask != mState.stencilBackMask) 1785 { 1786 ERR("Separate front/back stencil writemasks, reference values, or stencil mask values are invalid under WebGL."); 1787 return error(GL_INVALID_OPERATION); 1788 } 1789 1790 // get the maximum size of the stencil ref 1791 Renderbuffer *stencilbuffer = framebuffer->getStencilbuffer(); 1792 GLuint maxStencil = (1 << stencilbuffer->getStencilSize()) - 1; 1793 1794 if(mState.frontFace == GL_CCW) 1795 { 1796 device->setStencilWriteMask(mState.stencilWritemask); 1797 device->setStencilCompare(es2sw::ConvertStencilComparison(mState.stencilFunc)); 1798 1799 device->setStencilReference((mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil); 1800 device->setStencilMask(mState.stencilMask); 1801 1802 device->setStencilFailOperation(es2sw::ConvertStencilOp(mState.stencilFail)); 1803 device->setStencilZFailOperation(es2sw::ConvertStencilOp(mState.stencilPassDepthFail)); 1804 device->setStencilPassOperation(es2sw::ConvertStencilOp(mState.stencilPassDepthPass)); 1805 1806 device->setStencilWriteMaskCCW(mState.stencilBackWritemask); 1807 device->setStencilCompareCCW(es2sw::ConvertStencilComparison(mState.stencilBackFunc)); 1808 1809 device->setStencilReferenceCCW((mState.stencilBackRef < (GLint)maxStencil) ? mState.stencilBackRef : maxStencil); 1810 device->setStencilMaskCCW(mState.stencilBackMask); 1811 1812 device->setStencilFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilBackFail)); 1813 device->setStencilZFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilBackPassDepthFail)); 1814 device->setStencilPassOperationCCW(es2sw::ConvertStencilOp(mState.stencilBackPassDepthPass)); 1815 } 1816 else 1817 { 1818 device->setStencilWriteMaskCCW(mState.stencilWritemask); 1819 device->setStencilCompareCCW(es2sw::ConvertStencilComparison(mState.stencilFunc)); 1820 1821 device->setStencilReferenceCCW((mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil); 1822 device->setStencilMaskCCW(mState.stencilMask); 1823 1824 device->setStencilFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilFail)); 1825 device->setStencilZFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilPassDepthFail)); 1826 device->setStencilPassOperationCCW(es2sw::ConvertStencilOp(mState.stencilPassDepthPass)); 1827 1828 device->setStencilWriteMask(mState.stencilBackWritemask); 1829 device->setStencilCompare(es2sw::ConvertStencilComparison(mState.stencilBackFunc)); 1830 1831 device->setStencilReference((mState.stencilBackRef < (GLint)maxStencil) ? mState.stencilBackRef : maxStencil); 1832 device->setStencilMask(mState.stencilBackMask); 1833 1834 device->setStencilFailOperation(es2sw::ConvertStencilOp(mState.stencilBackFail)); 1835 device->setStencilZFailOperation(es2sw::ConvertStencilOp(mState.stencilBackPassDepthFail)); 1836 device->setStencilPassOperation(es2sw::ConvertStencilOp(mState.stencilBackPassDepthPass)); 1837 } 1838 } 1839 else 1840 { 1841 device->setStencilEnable(false); 1842 } 1843 1844 mStencilStateDirty = false; 1845 mFrontFaceDirty = false; 1846 } 1847 1848 if(mMaskStateDirty) 1849 { 1850 device->setColorWriteMask(0, es2sw::ConvertColorMask(mState.colorMaskRed, mState.colorMaskGreen, mState.colorMaskBlue, mState.colorMaskAlpha)); 1851 device->setDepthWriteEnable(mState.depthMask); 1852 1853 mMaskStateDirty = false; 1854 } 1855 1856 if(mPolygonOffsetStateDirty) 1857 { 1858 if(mState.polygonOffsetFillEnabled) 1859 { 1860 Renderbuffer *depthbuffer = framebuffer->getDepthbuffer(); 1861 if(depthbuffer) 1862 { 1863 device->setSlopeDepthBias(mState.polygonOffsetFactor); 1864 float depthBias = ldexp(mState.polygonOffsetUnits, -(int)(depthbuffer->getDepthSize())); 1865 device->setDepthBias(depthBias); 1866 } 1867 } 1868 else 1869 { 1870 device->setSlopeDepthBias(0); 1871 device->setDepthBias(0); 1872 } 1873 1874 mPolygonOffsetStateDirty = false; 1875 } 1876 1877 if(mSampleStateDirty) 1878 { 1879 if(mState.sampleAlphaToCoverageEnabled) 1880 { 1881 device->setTransparencyAntialiasing(sw::TRANSPARENCY_ALPHA_TO_COVERAGE); 1882 } 1883 else 1884 { 1885 device->setTransparencyAntialiasing(sw::TRANSPARENCY_NONE); 1886 } 1887 1888 if(mState.sampleCoverageEnabled) 1889 { 1890 unsigned int mask = 0; 1891 if(mState.sampleCoverageValue != 0) 1892 { 1893 int width, height, samples; 1894 framebuffer->completeness(width, height, samples); 1895 1896 float threshold = 0.5f; 1897 1898 for(int i = 0; i < samples; i++) 1899 { 1900 mask <<= 1; 1901 1902 if((i + 1) * mState.sampleCoverageValue >= threshold) 1903 { 1904 threshold += 1.0f; 1905 mask |= 1; 1906 } 1907 } 1908 } 1909 1910 if(mState.sampleCoverageInvert) 1911 { 1912 mask = ~mask; 1913 } 1914 1915 device->setMultiSampleMask(mask); 1916 } 1917 else 1918 { 1919 device->setMultiSampleMask(0xFFFFFFFF); 1920 } 1921 1922 mSampleStateDirty = false; 1923 } 1924 1925 if(mDitherStateDirty) 1926 { 1927 // UNIMPLEMENTED(); // FIXME 1928 1929 mDitherStateDirty = false; 1930 } 1931 } 1932 1933 GLenum Context::applyVertexBuffer(GLint base, GLint first, GLsizei count) 1934 { 1935 TranslatedAttribute attributes[MAX_VERTEX_ATTRIBS]; 1936 1937 GLenum err = mVertexDataManager->prepareVertexData(first, count, attributes); 1938 if(err != GL_NO_ERROR) 1939 { 1940 return err; 1941 } 1942 1943 Program *program = getCurrentProgram(); 1944 1945 device->resetInputStreams(false); 1946 1947 for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++) 1948 { 1949 if(program && program->getAttributeStream(i) == -1) 1950 { 1951 continue; 1952 } 1953 1954 sw::Resource *resource = attributes[i].vertexBuffer; 1955 const void *buffer = (char*)resource->data() + attributes[i].offset; 1956 1957 int stride = attributes[i].stride; 1958 1959 buffer = (char*)buffer + stride * base; 1960 1961 sw::Stream attribute(resource, buffer, stride); 1962 1963 attribute.type = attributes[i].type; 1964 attribute.count = attributes[i].count; 1965 attribute.normalized = attributes[i].normalized; 1966 1967 int stream = program ? program->getAttributeStream(i) : i; 1968 device->setInputStream(stream, attribute); 1969 } 1970 1971 return GL_NO_ERROR; 1972 } 1973 1974 // Applies the indices and element array bindings 1975 GLenum Context::applyIndexBuffer(const void *indices, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo) 1976 { 1977 GLenum err = mIndexDataManager->prepareIndexData(type, count, mState.elementArrayBuffer, indices, indexInfo); 1978 1979 if(err == GL_NO_ERROR) 1980 { 1981 device->setIndexBuffer(indexInfo->indexBuffer); 1982 } 1983 1984 return err; 1985 } 1986 1987 // Applies the shaders and shader constants 1988 void Context::applyShaders() 1989 { 1990 Program *programObject = getCurrentProgram(); 1991 if(!programObject) 1992 { 1993 device->setVertexShader(0); 1994 device->setPixelShader(0); 1995 return; 1996 } 1997 sw::VertexShader *vertexShader = programObject->getVertexShader(); 1998 sw::PixelShader *pixelShader = programObject->getPixelShader(); 1999 2000 device->setVertexShader(vertexShader); 2001 device->setPixelShader(pixelShader); 2002 2003 if(programObject->getSerial() != mAppliedProgramSerial) 2004 { 2005 programObject->dirtyAllUniforms(); 2006 mAppliedProgramSerial = programObject->getSerial(); 2007 } 2008 2009 programObject->applyUniforms(); 2010 } 2011 2012 void Context::applyTextures() 2013 { 2014 applyTextures(sw::SAMPLER_PIXEL); 2015 //applyTextures(sw::SAMPLER_VERTEX); 2016 } 2017 2018 void Context::applyTextures(sw::SamplerType samplerType) 2019 { 2020 Program *programObject = getCurrentProgram(); 2021 2022 int samplerCount = (samplerType == sw::SAMPLER_PIXEL) ? MAX_TEXTURE_IMAGE_UNITS : MAX_VERTEX_TEXTURE_IMAGE_UNITS; // Range of samplers of given sampler type 2023 2024 for(int samplerIndex = 0; samplerIndex < samplerCount; samplerIndex++) 2025 { 2026 int textureUnit = programObject ? programObject->getSamplerMapping(samplerType, samplerIndex) : samplerIndex; // OpenGL texture image unit index 2027 2028 if(textureUnit != -1) 2029 { 2030 TextureType textureType = programObject ? programObject->getSamplerTextureType(samplerType, samplerIndex) : TEXTURE_2D; 2031 2032 Texture *texture = getSamplerTexture(textureUnit, textureType); 2033 2034 if(envEnable[samplerIndex] && texture->isSamplerComplete()) 2035 { 2036 GLenum wrapS = texture->getWrapS(); 2037 GLenum wrapT = texture->getWrapT(); 2038 GLenum minFilter = texture->getMinFilter(); 2039 GLenum magFilter = texture->getMagFilter(); 2040 GLfloat maxAnisotropy = texture->getMaxAnisotropy(); 2041 2042 device->setAddressingModeU(samplerType, samplerIndex, es2sw::ConvertTextureWrap(wrapS)); 2043 device->setAddressingModeV(samplerType, samplerIndex, es2sw::ConvertTextureWrap(wrapT)); 2044 2045 device->setTextureFilter(samplerType, samplerIndex, es2sw::ConvertTextureFilter(minFilter, magFilter, maxAnisotropy)); 2046 device->setMipmapFilter(samplerType, samplerIndex, es2sw::ConvertMipMapFilter(minFilter)); 2047 device->setMaxAnisotropy(samplerType, samplerIndex, maxAnisotropy); 2048 2049 applyTexture(samplerType, samplerIndex, texture); 2050 2051 device->setStageOperation(samplerIndex, sw::TextureStage::STAGE_MODULATE); 2052 device->setFirstArgument(samplerIndex, sw::TextureStage::SOURCE_TEXTURE); 2053 device->setSecondArgument(samplerIndex, sw::TextureStage::SOURCE_CURRENT); 2054 //device->setThirdArgument(samplerIndex, sw::TextureStage::SOURCE_CONSTANT); 2055 2056 device->setStageOperationAlpha(samplerIndex, sw::TextureStage::STAGE_MODULATE); 2057 device->setFirstArgumentAlpha(samplerIndex, sw::TextureStage::SOURCE_TEXTURE); 2058 device->setSecondArgumentAlpha(samplerIndex, sw::TextureStage::SOURCE_CURRENT); 2059 //device->setThirdArgumentAlpha(samplerIndex, sw::TextureStage::SOURCE_CONSTANT); 2060 2061 //device->setConstantColor(0, sw::Color<float>(0.0f, 0.0f, 0.0f, 0.0f)); 2062 } 2063 else 2064 { 2065 applyTexture(samplerType, samplerIndex, nullptr); 2066 2067 device->setStageOperation(samplerIndex, sw::TextureStage::STAGE_SELECTARG1); 2068 device->setFirstArgument(samplerIndex, sw::TextureStage::SOURCE_CURRENT); 2069 device->setSecondArgument(samplerIndex, sw::TextureStage::SOURCE_CURRENT); 2070 //device->setThirdArgument(samplerIndex, sw::TextureStage::SOURCE_CONSTANT); 2071 2072 device->setStageOperationAlpha(samplerIndex, sw::TextureStage::STAGE_SELECTARG1); 2073 device->setFirstArgumentAlpha(samplerIndex, sw::TextureStage::SOURCE_CURRENT); 2074 device->setSecondArgumentAlpha(samplerIndex, sw::TextureStage::SOURCE_CURRENT); 2075 //device->setThirdArgumentAlpha(samplerIndex, sw::TextureStage::SOURCE_CONSTANT); 2076 } 2077 } 2078 else 2079 { 2080 applyTexture(samplerType, samplerIndex, nullptr); 2081 } 2082 } 2083 } 2084 2085 void Context::applyTexture(sw::SamplerType type, int index, Texture *baseTexture) 2086 { 2087 Program *program = getCurrentProgram(); 2088 int sampler = (type == sw::SAMPLER_PIXEL) ? index : 16 + index; 2089 bool textureUsed = false; 2090 2091 if(type == sw::SAMPLER_PIXEL) 2092 { 2093 textureUsed = program ? program->getPixelShader()->usesSampler(index) : true; 2094 } 2095 else if(type == sw::SAMPLER_VERTEX) 2096 { 2097 textureUsed = program ? program->getVertexShader()->usesSampler(index) : false; 2098 } 2099 else UNREACHABLE(type); 2100 2101 sw::Resource *resource = nullptr; 2102 2103 if(baseTexture && textureUsed) 2104 { 2105 resource = baseTexture->getResource(); 2106 } 2107 2108 device->setTextureResource(sampler, resource); 2109 2110 if(baseTexture && textureUsed) 2111 { 2112 int topLevel = baseTexture->getTopLevel(); 2113 2114 if(baseTexture->getTarget() == GL_TEXTURE_2D) 2115 { 2116 Texture2D *texture = static_cast<Texture2D*>(baseTexture); 2117 2118 for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++) 2119 { 2120 int surfaceLevel = mipmapLevel; 2121 2122 if(surfaceLevel < 0) 2123 { 2124 surfaceLevel = 0; 2125 } 2126 else if(surfaceLevel > topLevel) 2127 { 2128 surfaceLevel = topLevel; 2129 } 2130 2131 Image *surface = texture->getImage(surfaceLevel); 2132 device->setTextureLevel(sampler, 0, mipmapLevel, surface, sw::TEXTURE_2D); 2133 } 2134 } 2135 else if(baseTexture->getTarget() == GL_TEXTURE_CUBE_MAP) 2136 { 2137 for(int face = 0; face < 6; face++) 2138 { 2139 TextureCubeMap *cubeTexture = static_cast<TextureCubeMap*>(baseTexture); 2140 2141 for(int mipmapLevel = 0; mipmapLevel < sw::MIPMAP_LEVELS; mipmapLevel++) 2142 { 2143 int surfaceLevel = mipmapLevel; 2144 2145 if(surfaceLevel < 0) 2146 { 2147 surfaceLevel = 0; 2148 } 2149 else if(surfaceLevel > topLevel) 2150 { 2151 surfaceLevel = topLevel; 2152 } 2153 2154 Image *surface = cubeTexture->getImage(face, surfaceLevel); 2155 device->setTextureLevel(sampler, face, mipmapLevel, surface, sw::TEXTURE_CUBE); 2156 } 2157 } 2158 } 2159 else UNIMPLEMENTED(); 2160 } 2161 else 2162 { 2163 device->setTextureLevel(sampler, 0, 0, 0, sw::TEXTURE_NULL); 2164 } 2165 } 2166 2167 void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, 2168 GLenum format, GLenum type, GLsizei *bufSize, void* pixels) 2169 { 2170 Framebuffer *framebuffer = getReadFramebuffer(); 2171 int framebufferWidth, framebufferHeight, framebufferSamples; 2172 2173 if(framebuffer->completeness(framebufferWidth, framebufferHeight, framebufferSamples) != GL_FRAMEBUFFER_COMPLETE) 2174 { 2175 return error(GL_INVALID_FRAMEBUFFER_OPERATION); 2176 } 2177 2178 if(getReadFramebufferName() != 0 && framebufferSamples != 0) 2179 { 2180 return error(GL_INVALID_OPERATION); 2181 } 2182 2183 GLsizei outputPitch = ComputePitch(width, format, type, mState.packAlignment); 2184 2185 // Sized query sanity check 2186 if(bufSize) 2187 { 2188 int requiredSize = outputPitch * height; 2189 if(requiredSize > *bufSize) 2190 { 2191 return error(GL_INVALID_OPERATION); 2192 } 2193 } 2194 2195 Image *renderTarget = framebuffer->getRenderTarget(); 2196 2197 if(!renderTarget) 2198 { 2199 return error(GL_OUT_OF_MEMORY); 2200 } 2201 2202 sw::Rect rect = {x, y, x + width, y + height}; 2203 rect.clip(0, 0, renderTarget->getWidth(), renderTarget->getHeight()); 2204 2205 unsigned char *source = (unsigned char*)renderTarget->lock(rect.x0, rect.y0, sw::LOCK_READONLY); 2206 unsigned char *dest = (unsigned char*)pixels; 2207 unsigned short *dest16 = (unsigned short*)pixels; 2208 int inputPitch = (int)renderTarget->getPitch(); 2209 2210 for(int j = 0; j < rect.y1 - rect.y0; j++) 2211 { 2212 if(renderTarget->getInternalFormat() == sw::FORMAT_A8R8G8B8 && 2213 format == GL_BGRA_EXT && type == GL_UNSIGNED_BYTE) 2214 { 2215 // Fast path for EXT_read_format_bgra, given an RGBA source buffer 2216 // Note that buffers with no alpha go through the slow path below 2217 memcpy(dest + j * outputPitch, source + j * inputPitch, (rect.x1 - rect.x0) * 4); 2218 } 2219 else 2220 { 2221 for(int i = 0; i < rect.x1 - rect.x0; i++) 2222 { 2223 float r; 2224 float g; 2225 float b; 2226 float a; 2227 2228 switch(renderTarget->getInternalFormat()) 2229 { 2230 case sw::FORMAT_R5G6B5: 2231 { 2232 unsigned short rgb = *(unsigned short*)(source + 2 * i + j * inputPitch); 2233 2234 a = 1.0f; 2235 b = (rgb & 0x001F) * (1.0f / 0x001F); 2236 g = (rgb & 0x07E0) * (1.0f / 0x07E0); 2237 r = (rgb & 0xF800) * (1.0f / 0xF800); 2238 } 2239 break; 2240 case sw::FORMAT_A1R5G5B5: 2241 { 2242 unsigned short argb = *(unsigned short*)(source + 2 * i + j * inputPitch); 2243 2244 a = (argb & 0x8000) ? 1.0f : 0.0f; 2245 b = (argb & 0x001F) * (1.0f / 0x001F); 2246 g = (argb & 0x03E0) * (1.0f / 0x03E0); 2247 r = (argb & 0x7C00) * (1.0f / 0x7C00); 2248 } 2249 break; 2250 case sw::FORMAT_A8R8G8B8: 2251 { 2252 unsigned int argb = *(unsigned int*)(source + 4 * i + j * inputPitch); 2253 2254 a = (argb & 0xFF000000) * (1.0f / 0xFF000000); 2255 b = (argb & 0x000000FF) * (1.0f / 0x000000FF); 2256 g = (argb & 0x0000FF00) * (1.0f / 0x0000FF00); 2257 r = (argb & 0x00FF0000) * (1.0f / 0x00FF0000); 2258 } 2259 break; 2260 case sw::FORMAT_X8R8G8B8: 2261 { 2262 unsigned int xrgb = *(unsigned int*)(source + 4 * i + j * inputPitch); 2263 2264 a = 1.0f; 2265 b = (xrgb & 0x000000FF) * (1.0f / 0x000000FF); 2266 g = (xrgb & 0x0000FF00) * (1.0f / 0x0000FF00); 2267 r = (xrgb & 0x00FF0000) * (1.0f / 0x00FF0000); 2268 } 2269 break; 2270 case sw::FORMAT_A2R10G10B10: 2271 { 2272 unsigned int argb = *(unsigned int*)(source + 4 * i + j * inputPitch); 2273 2274 a = (argb & 0xC0000000) * (1.0f / 0xC0000000); 2275 b = (argb & 0x000003FF) * (1.0f / 0x000003FF); 2276 g = (argb & 0x000FFC00) * (1.0f / 0x000FFC00); 2277 r = (argb & 0x3FF00000) * (1.0f / 0x3FF00000); 2278 } 2279 break; 2280 case sw::FORMAT_A32B32G32R32F: 2281 { 2282 r = *((float*)(source + 16 * i + j * inputPitch) + 0); 2283 g = *((float*)(source + 16 * i + j * inputPitch) + 1); 2284 b = *((float*)(source + 16 * i + j * inputPitch) + 2); 2285 a = *((float*)(source + 16 * i + j * inputPitch) + 3); 2286 } 2287 break; 2288 case sw::FORMAT_A16B16G16R16F: 2289 { 2290 r = (float)*((sw::half*)(source + 8 * i + j * inputPitch) + 0); 2291 g = (float)*((sw::half*)(source + 8 * i + j * inputPitch) + 1); 2292 b = (float)*((sw::half*)(source + 8 * i + j * inputPitch) + 2); 2293 a = (float)*((sw::half*)(source + 8 * i + j * inputPitch) + 3); 2294 } 2295 break; 2296 default: 2297 UNIMPLEMENTED(); // FIXME 2298 UNREACHABLE(renderTarget->getInternalFormat()); 2299 } 2300 2301 switch(format) 2302 { 2303 case GL_RGBA: 2304 switch(type) 2305 { 2306 case GL_UNSIGNED_BYTE: 2307 dest[4 * i + j * outputPitch + 0] = (unsigned char)(255 * r + 0.5f); 2308 dest[4 * i + j * outputPitch + 1] = (unsigned char)(255 * g + 0.5f); 2309 dest[4 * i + j * outputPitch + 2] = (unsigned char)(255 * b + 0.5f); 2310 dest[4 * i + j * outputPitch + 3] = (unsigned char)(255 * a + 0.5f); 2311 break; 2312 default: UNREACHABLE(type); 2313 } 2314 break; 2315 case GL_BGRA_EXT: 2316 switch(type) 2317 { 2318 case GL_UNSIGNED_BYTE: 2319 dest[4 * i + j * outputPitch + 0] = (unsigned char)(255 * b + 0.5f); 2320 dest[4 * i + j * outputPitch + 1] = (unsigned char)(255 * g + 0.5f); 2321 dest[4 * i + j * outputPitch + 2] = (unsigned char)(255 * r + 0.5f); 2322 dest[4 * i + j * outputPitch + 3] = (unsigned char)(255 * a + 0.5f); 2323 break; 2324 case GL_UNSIGNED_SHORT_4_4_4_4_REV: 2325 // According to the desktop GL spec in the "Transfer of Pixel Rectangles" section 2326 // this type is packed as follows: 2327 // 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 2328 // -------------------------------------------------------------------------------- 2329 // | 4th | 3rd | 2nd | 1st component | 2330 // -------------------------------------------------------------------------------- 2331 // in the case of BGRA_EXT, B is the first component, G the second, and so forth. 2332 dest16[i + j * outputPitch / sizeof(unsigned short)] = 2333 ((unsigned short)(15 * a + 0.5f) << 12)| 2334 ((unsigned short)(15 * r + 0.5f) << 8) | 2335 ((unsigned short)(15 * g + 0.5f) << 4) | 2336 ((unsigned short)(15 * b + 0.5f) << 0); 2337 break; 2338 case GL_UNSIGNED_SHORT_1_5_5_5_REV: 2339 // According to the desktop GL spec in the "Transfer of Pixel Rectangles" section 2340 // this type is packed as follows: 2341 // 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 2342 // -------------------------------------------------------------------------------- 2343 // | 4th | 3rd | 2nd | 1st component | 2344 // -------------------------------------------------------------------------------- 2345 // in the case of BGRA_EXT, B is the first component, G the second, and so forth. 2346 dest16[i + j * outputPitch / sizeof(unsigned short)] = 2347 ((unsigned short)( a + 0.5f) << 15) | 2348 ((unsigned short)(31 * r + 0.5f) << 10) | 2349 ((unsigned short)(31 * g + 0.5f) << 5) | 2350 ((unsigned short)(31 * b + 0.5f) << 0); 2351 break; 2352 default: UNREACHABLE(type); 2353 } 2354 break; 2355 case GL_RGB: // IMPLEMENTATION_COLOR_READ_FORMAT 2356 switch(type) 2357 { 2358 case GL_UNSIGNED_SHORT_5_6_5: // IMPLEMENTATION_COLOR_READ_TYPE 2359 dest16[i + j * outputPitch / sizeof(unsigned short)] = 2360 ((unsigned short)(31 * b + 0.5f) << 0) | 2361 ((unsigned short)(63 * g + 0.5f) << 5) | 2362 ((unsigned short)(31 * r + 0.5f) << 11); 2363 break; 2364 default: UNREACHABLE(type); 2365 } 2366 break; 2367 default: UNREACHABLE(format); 2368 } 2369 } 2370 } 2371 } 2372 2373 renderTarget->unlock(); 2374 renderTarget->release(); 2375 } 2376 2377 void Context::clear(GLbitfield mask) 2378 { 2379 Framebuffer *framebuffer = getDrawFramebuffer(); 2380 2381 if(!framebuffer || framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE) 2382 { 2383 return error(GL_INVALID_FRAMEBUFFER_OPERATION); 2384 } 2385 2386 if(!applyRenderTarget()) 2387 { 2388 return; 2389 } 2390 2391 float depth = clamp01(mState.depthClearValue); 2392 int stencil = mState.stencilClearValue & 0x000000FF; 2393 2394 if(mask & GL_COLOR_BUFFER_BIT) 2395 { 2396 unsigned int rgbaMask = (mState.colorMaskRed ? 0x1 : 0) | 2397 (mState.colorMaskGreen ? 0x2 : 0) | 2398 (mState.colorMaskBlue ? 0x4 : 0) | 2399 (mState.colorMaskAlpha ? 0x8 : 0); 2400 2401 if(rgbaMask != 0) 2402 { 2403 device->clearColor(mState.colorClearValue.red, mState.colorClearValue.green, mState.colorClearValue.blue, mState.colorClearValue.alpha, rgbaMask); 2404 } 2405 } 2406 2407 if(mask & GL_DEPTH_BUFFER_BIT) 2408 { 2409 if(mState.depthMask != 0) 2410 { 2411 device->clearDepth(depth); 2412 } 2413 } 2414 2415 if(mask & GL_STENCIL_BUFFER_BIT) 2416 { 2417 if(mState.stencilWritemask != 0) 2418 { 2419 device->clearStencil(stencil, mState.stencilWritemask); 2420 } 2421 } 2422 } 2423 2424 void Context::drawArrays(GLenum mode, GLint first, GLsizei count) 2425 { 2426 if(!mState.currentProgram) 2427 { 2428 device->setProjectionMatrix(projection.current()); 2429 device->setViewMatrix(modelView.current()); 2430 device->setTextureMatrix(0, texture[0].current()); 2431 device->setTextureMatrix(1, texture[1].current()); 2432 device->setTextureTransform(0, texture[0].isIdentity() ? 0 : 4, false); 2433 device->setTextureTransform(1, texture[1].isIdentity() ? 0 : 4, false); 2434 device->setTexGen(0, sw::TEXGEN_NONE); 2435 device->setTexGen(1, sw::TEXGEN_NONE); 2436 } 2437 2438 PrimitiveType primitiveType; 2439 int primitiveCount; 2440 2441 if(!es2sw::ConvertPrimitiveType(mode, count, primitiveType, primitiveCount)) 2442 return error(GL_INVALID_ENUM); 2443 2444 if(primitiveCount <= 0) 2445 { 2446 return; 2447 } 2448 2449 if(!applyRenderTarget()) 2450 { 2451 return; 2452 } 2453 2454 applyState(mode); 2455 2456 GLenum err = applyVertexBuffer(0, first, count); 2457 if(err != GL_NO_ERROR) 2458 { 2459 return error(err); 2460 } 2461 2462 applyShaders(); 2463 applyTextures(); 2464 2465 if(getCurrentProgram() && !getCurrentProgram()->validateSamplers(false)) 2466 { 2467 return error(GL_INVALID_OPERATION); 2468 } 2469 2470 if(!cullSkipsDraw(mode)) 2471 { 2472 device->drawPrimitive(primitiveType, primitiveCount); 2473 } 2474 } 2475 2476 void Context::drawElements(GLenum mode, GLsizei count, GLenum type, const void *indices) 2477 { 2478 if(!mState.currentProgram) 2479 { 2480 return; 2481 } 2482 2483 if(!indices && !mState.elementArrayBuffer) 2484 { 2485 return error(GL_INVALID_OPERATION); 2486 } 2487 2488 PrimitiveType primitiveType; 2489 int primitiveCount; 2490 2491 if(!es2sw::ConvertPrimitiveType(mode, count, primitiveType, primitiveCount)) 2492 return error(GL_INVALID_ENUM); 2493 2494 if(primitiveCount <= 0) 2495 { 2496 return; 2497 } 2498 2499 if(!applyRenderTarget()) 2500 { 2501 return; 2502 } 2503 2504 applyState(mode); 2505 2506 TranslatedIndexData indexInfo; 2507 GLenum err = applyIndexBuffer(indices, count, mode, type, &indexInfo); 2508 if(err != GL_NO_ERROR) 2509 { 2510 return error(err); 2511 } 2512 2513 GLsizei vertexCount = indexInfo.maxIndex - indexInfo.minIndex + 1; 2514 err = applyVertexBuffer(-(int)indexInfo.minIndex, indexInfo.minIndex, vertexCount); 2515 if(err != GL_NO_ERROR) 2516 { 2517 return error(err); 2518 } 2519 2520 applyShaders(); 2521 applyTextures(); 2522 2523 if(!getCurrentProgram()->validateSamplers(false)) 2524 { 2525 return error(GL_INVALID_OPERATION); 2526 } 2527 2528 if(!cullSkipsDraw(mode)) 2529 { 2530 device->drawIndexedPrimitive(primitiveType, indexInfo.indexOffset, primitiveCount, IndexDataManager::typeSize(type)); 2531 } 2532 } 2533 2534 void Context::finish() 2535 { 2536 device->finish(); 2537 } 2538 2539 void Context::flush() 2540 { 2541 // We don't queue anything without processing it as fast as possible 2542 } 2543 2544 void Context::recordInvalidEnum() 2545 { 2546 mInvalidEnum = true; 2547 } 2548 2549 void Context::recordInvalidValue() 2550 { 2551 mInvalidValue = true; 2552 } 2553 2554 void Context::recordInvalidOperation() 2555 { 2556 mInvalidOperation = true; 2557 } 2558 2559 void Context::recordOutOfMemory() 2560 { 2561 mOutOfMemory = true; 2562 } 2563 2564 void Context::recordInvalidFramebufferOperation() 2565 { 2566 mInvalidFramebufferOperation = true; 2567 } 2568 2569 // Get one of the recorded errors and clear its flag, if any. 2570 GLenum Context::getError() 2571 { 2572 if(mInvalidEnum) 2573 { 2574 mInvalidEnum = false; 2575 2576 return GL_INVALID_ENUM; 2577 } 2578 2579 if(mInvalidValue) 2580 { 2581 mInvalidValue = false; 2582 2583 return GL_INVALID_VALUE; 2584 } 2585 2586 if(mInvalidOperation) 2587 { 2588 mInvalidOperation = false; 2589 2590 return GL_INVALID_OPERATION; 2591 } 2592 2593 if(mOutOfMemory) 2594 { 2595 mOutOfMemory = false; 2596 2597 return GL_OUT_OF_MEMORY; 2598 } 2599 2600 if(mInvalidFramebufferOperation) 2601 { 2602 mInvalidFramebufferOperation = false; 2603 2604 return GL_INVALID_FRAMEBUFFER_OPERATION; 2605 } 2606 2607 return GL_NO_ERROR; 2608 } 2609 2610 int Context::getSupportedMultisampleCount(int requested) 2611 { 2612 int supported = 0; 2613 2614 for(int i = NUM_MULTISAMPLE_COUNTS - 1; i >= 0; i--) 2615 { 2616 if(supported >= requested) 2617 { 2618 return supported; 2619 } 2620 2621 supported = multisampleCount[i]; 2622 } 2623 2624 return supported; 2625 } 2626 2627 void Context::detachBuffer(GLuint buffer) 2628 { 2629 // If a buffer object is deleted while it is bound, all bindings to that object in the current context 2630 // (i.e. in the thread that called Delete-Buffers) are reset to zero. 2631 2632 if(mState.arrayBuffer.name() == buffer) 2633 { 2634 mState.arrayBuffer = nullptr; 2635 } 2636 2637 if(mState.elementArrayBuffer.name() == buffer) 2638 { 2639 mState.elementArrayBuffer = nullptr; 2640 } 2641 2642 for(int attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++) 2643 { 2644 if(mState.vertexAttribute[attribute].mBoundBuffer.name() == buffer) 2645 { 2646 mState.vertexAttribute[attribute].mBoundBuffer = nullptr; 2647 } 2648 } 2649 } 2650 2651 void Context::detachTexture(GLuint texture) 2652 { 2653 // If a texture object is deleted, it is as if all texture units which are bound to that texture object are 2654 // rebound to texture object zero 2655 2656 for(int type = 0; type < TEXTURE_TYPE_COUNT; type++) 2657 { 2658 for(int sampler = 0; sampler < MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++) 2659 { 2660 if(mState.samplerTexture[type][sampler].name() == texture) 2661 { 2662 mState.samplerTexture[type][sampler] = nullptr; 2663 } 2664 } 2665 } 2666 2667 // If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is 2668 // as if FramebufferTexture2D had been called, with a texture of 0, for each attachment point to which this 2669 // image was attached in the currently bound framebuffer. 2670 2671 Framebuffer *readFramebuffer = getReadFramebuffer(); 2672 Framebuffer *drawFramebuffer = getDrawFramebuffer(); 2673 2674 if(readFramebuffer) 2675 { 2676 readFramebuffer->detachTexture(texture); 2677 } 2678 2679 if(drawFramebuffer && drawFramebuffer != readFramebuffer) 2680 { 2681 drawFramebuffer->detachTexture(texture); 2682 } 2683 } 2684 2685 void Context::detachFramebuffer(GLuint framebuffer) 2686 { 2687 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though 2688 // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero. 2689 2690 if(mState.readFramebuffer == framebuffer) 2691 { 2692 bindReadFramebuffer(0); 2693 } 2694 2695 if(mState.drawFramebuffer == framebuffer) 2696 { 2697 bindDrawFramebuffer(0); 2698 } 2699 } 2700 2701 void Context::detachRenderbuffer(GLuint renderbuffer) 2702 { 2703 // If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer 2704 // had been executed with the target RENDERBUFFER and name of zero. 2705 2706 if(mState.renderbuffer.name() == renderbuffer) 2707 { 2708 bindRenderbuffer(0); 2709 } 2710 2711 // If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer, 2712 // then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment 2713 // point to which this image was attached in the currently bound framebuffer. 2714 2715 Framebuffer *readFramebuffer = getReadFramebuffer(); 2716 Framebuffer *drawFramebuffer = getDrawFramebuffer(); 2717 2718 if(readFramebuffer) 2719 { 2720 readFramebuffer->detachRenderbuffer(renderbuffer); 2721 } 2722 2723 if(drawFramebuffer && drawFramebuffer != readFramebuffer) 2724 { 2725 drawFramebuffer->detachRenderbuffer(renderbuffer); 2726 } 2727 } 2728 2729 bool Context::cullSkipsDraw(GLenum drawMode) 2730 { 2731 return mState.cullFaceEnabled && mState.cullMode == GL_FRONT_AND_BACK && isTriangleMode(drawMode); 2732 } 2733 2734 bool Context::isTriangleMode(GLenum drawMode) 2735 { 2736 switch(drawMode) 2737 { 2738 case GL_TRIANGLES: 2739 case GL_TRIANGLE_FAN: 2740 case GL_TRIANGLE_STRIP: 2741 return true; 2742 case GL_POINTS: 2743 case GL_LINES: 2744 case GL_LINE_LOOP: 2745 case GL_LINE_STRIP: 2746 return false; 2747 default: UNREACHABLE(drawMode); 2748 } 2749 2750 return false; 2751 } 2752 2753 void Context::setVertexAttrib(GLuint index, float x, float y, float z, float w) 2754 { 2755 ASSERT(index < MAX_VERTEX_ATTRIBS); 2756 2757 mState.vertexAttribute[index].mCurrentValue[0] = x; 2758 mState.vertexAttribute[index].mCurrentValue[1] = y; 2759 mState.vertexAttribute[index].mCurrentValue[2] = z; 2760 mState.vertexAttribute[index].mCurrentValue[3] = w; 2761 2762 mVertexDataManager->dirtyCurrentValue(index); 2763 } 2764 2765 void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, 2766 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, 2767 GLbitfield mask) 2768 { 2769 Framebuffer *readFramebuffer = getReadFramebuffer(); 2770 Framebuffer *drawFramebuffer = getDrawFramebuffer(); 2771 2772 int readBufferWidth, readBufferHeight, readBufferSamples; 2773 int drawBufferWidth, drawBufferHeight, drawBufferSamples; 2774 2775 if(!readFramebuffer || readFramebuffer->completeness(readBufferWidth, readBufferHeight, readBufferSamples) != GL_FRAMEBUFFER_COMPLETE || 2776 !drawFramebuffer || drawFramebuffer->completeness(drawBufferWidth, drawBufferHeight, drawBufferSamples) != GL_FRAMEBUFFER_COMPLETE) 2777 { 2778 return error(GL_INVALID_FRAMEBUFFER_OPERATION); 2779 } 2780 2781 if(drawBufferSamples > 1) 2782 { 2783 return error(GL_INVALID_OPERATION); 2784 } 2785 2786 sw::SliceRect sourceRect; 2787 sw::SliceRect destRect; 2788 2789 if(srcX0 < srcX1) 2790 { 2791 sourceRect.x0 = srcX0; 2792 sourceRect.x1 = srcX1; 2793 destRect.x0 = dstX0; 2794 destRect.x1 = dstX1; 2795 } 2796 else 2797 { 2798 sourceRect.x0 = srcX1; 2799 destRect.x0 = dstX1; 2800 sourceRect.x1 = srcX0; 2801 destRect.x1 = dstX0; 2802 } 2803 2804 if(srcY0 < srcY1) 2805 { 2806 sourceRect.y0 = srcY0; 2807 destRect.y0 = dstY0; 2808 sourceRect.y1 = srcY1; 2809 destRect.y1 = dstY1; 2810 } 2811 else 2812 { 2813 sourceRect.y0 = srcY1; 2814 destRect.y0 = dstY1; 2815 sourceRect.y1 = srcY0; 2816 destRect.y1 = dstY0; 2817 } 2818 2819 sw::Rect sourceScissoredRect = sourceRect; 2820 sw::Rect destScissoredRect = destRect; 2821 2822 if(mState.scissorTestEnabled) // Only write to parts of the destination framebuffer which pass the scissor test 2823 { 2824 if(destRect.x0 < mState.scissorX) 2825 { 2826 int xDiff = mState.scissorX - destRect.x0; 2827 destScissoredRect.x0 = mState.scissorX; 2828 sourceScissoredRect.x0 += xDiff; 2829 } 2830 2831 if(destRect.x1 > mState.scissorX + mState.scissorWidth) 2832 { 2833 int xDiff = destRect.x1 - (mState.scissorX + mState.scissorWidth); 2834 destScissoredRect.x1 = mState.scissorX + mState.scissorWidth; 2835 sourceScissoredRect.x1 -= xDiff; 2836 } 2837 2838 if(destRect.y0 < mState.scissorY) 2839 { 2840 int yDiff = mState.scissorY - destRect.y0; 2841 destScissoredRect.y0 = mState.scissorY; 2842 sourceScissoredRect.y0 += yDiff; 2843 } 2844 2845 if(destRect.y1 > mState.scissorY + mState.scissorHeight) 2846 { 2847 int yDiff = destRect.y1 - (mState.scissorY + mState.scissorHeight); 2848 destScissoredRect.y1 = mState.scissorY + mState.scissorHeight; 2849 sourceScissoredRect.y1 -= yDiff; 2850 } 2851 } 2852 2853 sw::Rect sourceTrimmedRect = sourceScissoredRect; 2854 sw::Rect destTrimmedRect = destScissoredRect; 2855 2856 // The source & destination rectangles also may need to be trimmed if they fall out of the bounds of 2857 // the actual draw and read surfaces. 2858 if(sourceTrimmedRect.x0 < 0) 2859 { 2860 int xDiff = 0 - sourceTrimmedRect.x0; 2861 sourceTrimmedRect.x0 = 0; 2862 destTrimmedRect.x0 += xDiff; 2863 } 2864 2865 if(sourceTrimmedRect.x1 > readBufferWidth) 2866 { 2867 int xDiff = sourceTrimmedRect.x1 - readBufferWidth; 2868 sourceTrimmedRect.x1 = readBufferWidth; 2869 destTrimmedRect.x1 -= xDiff; 2870 } 2871 2872 if(sourceTrimmedRect.y0 < 0) 2873 { 2874 int yDiff = 0 - sourceTrimmedRect.y0; 2875 sourceTrimmedRect.y0 = 0; 2876 destTrimmedRect.y0 += yDiff; 2877 } 2878 2879 if(sourceTrimmedRect.y1 > readBufferHeight) 2880 { 2881 int yDiff = sourceTrimmedRect.y1 - readBufferHeight; 2882 sourceTrimmedRect.y1 = readBufferHeight; 2883 destTrimmedRect.y1 -= yDiff; 2884 } 2885 2886 if(destTrimmedRect.x0 < 0) 2887 { 2888 int xDiff = 0 - destTrimmedRect.x0; 2889 destTrimmedRect.x0 = 0; 2890 sourceTrimmedRect.x0 += xDiff; 2891 } 2892 2893 if(destTrimmedRect.x1 > drawBufferWidth) 2894 { 2895 int xDiff = destTrimmedRect.x1 - drawBufferWidth; 2896 destTrimmedRect.x1 = drawBufferWidth; 2897 sourceTrimmedRect.x1 -= xDiff; 2898 } 2899 2900 if(destTrimmedRect.y0 < 0) 2901 { 2902 int yDiff = 0 - destTrimmedRect.y0; 2903 destTrimmedRect.y0 = 0; 2904 sourceTrimmedRect.y0 += yDiff; 2905 } 2906 2907 if(destTrimmedRect.y1 > drawBufferHeight) 2908 { 2909 int yDiff = destTrimmedRect.y1 - drawBufferHeight; 2910 destTrimmedRect.y1 = drawBufferHeight; 2911 sourceTrimmedRect.y1 -= yDiff; 2912 } 2913 2914 bool partialBufferCopy = false; 2915 2916 if(sourceTrimmedRect.y1 - sourceTrimmedRect.y0 < readBufferHeight || 2917 sourceTrimmedRect.x1 - sourceTrimmedRect.x0 < readBufferWidth || 2918 destTrimmedRect.y1 - destTrimmedRect.y0 < drawBufferHeight || 2919 destTrimmedRect.x1 - destTrimmedRect.x0 < drawBufferWidth || 2920 sourceTrimmedRect.y0 != 0 || destTrimmedRect.y0 != 0 || sourceTrimmedRect.x0 != 0 || destTrimmedRect.x0 != 0) 2921 { 2922 partialBufferCopy = true; 2923 } 2924 2925 bool blitRenderTarget = false; 2926 bool blitDepthStencil = false; 2927 2928 if(mask & GL_COLOR_BUFFER_BIT) 2929 { 2930 const bool validReadType = readFramebuffer->getColorbufferType() == GL_TEXTURE_2D || 2931 readFramebuffer->getColorbufferType() == GL_RENDERBUFFER; 2932 const bool validDrawType = drawFramebuffer->getColorbufferType() == GL_TEXTURE_2D || 2933 drawFramebuffer->getColorbufferType() == GL_RENDERBUFFER; 2934 if(!validReadType || !validDrawType || 2935 readFramebuffer->getColorbuffer()->getInternalFormat() != drawFramebuffer->getColorbuffer()->getInternalFormat()) 2936 { 2937 ERR("Color buffer format conversion in BlitFramebufferANGLE not supported by this implementation"); 2938 return error(GL_INVALID_OPERATION); 2939 } 2940 2941 if(partialBufferCopy && readBufferSamples > 1) 2942 { 2943 return error(GL_INVALID_OPERATION); 2944 } 2945 2946 blitRenderTarget = true; 2947 } 2948 2949 if(mask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) 2950 { 2951 Renderbuffer *readDSBuffer = nullptr; 2952 Renderbuffer *drawDSBuffer = nullptr; 2953 2954 // We support OES_packed_depth_stencil, and do not support a separately attached depth and stencil buffer, so if we have 2955 // both a depth and stencil buffer, it will be the same buffer. 2956 2957 if(mask & GL_DEPTH_BUFFER_BIT) 2958 { 2959 if(readFramebuffer->getDepthbuffer() && drawFramebuffer->getDepthbuffer()) 2960 { 2961 if(readFramebuffer->getDepthbufferType() != drawFramebuffer->getDepthbufferType() || 2962 readFramebuffer->getDepthbuffer()->getInternalFormat() != drawFramebuffer->getDepthbuffer()->getInternalFormat()) 2963 { 2964 return error(GL_INVALID_OPERATION); 2965 } 2966 2967 blitDepthStencil = true; 2968 readDSBuffer = readFramebuffer->getDepthbuffer(); 2969 drawDSBuffer = drawFramebuffer->getDepthbuffer(); 2970 } 2971 } 2972 2973 if(mask & GL_STENCIL_BUFFER_BIT) 2974 { 2975 if(readFramebuffer->getStencilbuffer() && drawFramebuffer->getStencilbuffer()) 2976 { 2977 if(readFramebuffer->getStencilbufferType() != drawFramebuffer->getStencilbufferType() || 2978 readFramebuffer->getStencilbuffer()->getInternalFormat() != drawFramebuffer->getStencilbuffer()->getInternalFormat()) 2979 { 2980 return error(GL_INVALID_OPERATION); 2981 } 2982 2983 blitDepthStencil = true; 2984 readDSBuffer = readFramebuffer->getStencilbuffer(); 2985 drawDSBuffer = drawFramebuffer->getStencilbuffer(); 2986 } 2987 } 2988 2989 if(partialBufferCopy) 2990 { 2991 ERR("Only whole-buffer depth and stencil blits are supported by this implementation."); 2992 return error(GL_INVALID_OPERATION); // Only whole-buffer copies are permitted 2993 } 2994 2995 if((drawDSBuffer && drawDSBuffer->getSamples() > 1) || 2996 (readDSBuffer && readDSBuffer->getSamples() > 1)) 2997 { 2998 return error(GL_INVALID_OPERATION); 2999 } 3000 } 3001 3002 if(blitRenderTarget || blitDepthStencil) 3003 { 3004 if(blitRenderTarget) 3005 { 3006 Image *readRenderTarget = readFramebuffer->getRenderTarget(); 3007 Image *drawRenderTarget = drawFramebuffer->getRenderTarget(); 3008 3009 bool success = device->stretchRect(readRenderTarget, &sourceRect, drawRenderTarget, &destRect, false); 3010 3011 readRenderTarget->release(); 3012 drawRenderTarget->release(); 3013 3014 if(!success) 3015 { 3016 ERR("BlitFramebufferANGLE failed."); 3017 return; 3018 } 3019 } 3020 3021 if(blitDepthStencil) 3022 { 3023 bool success = device->stretchRect(readFramebuffer->getDepthStencil(), nullptr, drawFramebuffer->getDepthStencil(), nullptr, false); 3024 3025 if(!success) 3026 { 3027 ERR("BlitFramebufferANGLE failed."); 3028 return; 3029 } 3030 } 3031 } 3032 } 3033 3034 void Context::setMatrixMode(GLenum mode) 3035 { 3036 matrixMode = mode; 3037 } 3038 3039 sw::MatrixStack &Context::currentMatrixStack() 3040 { 3041 switch(matrixMode) 3042 { 3043 case GL_MODELVIEW: return modelView; break; 3044 case GL_PROJECTION: return projection; break; 3045 case GL_TEXTURE: return texture[mState.activeSampler]; break; 3046 default: UNREACHABLE(matrixMode); return modelView; break; 3047 } 3048 } 3049 3050 void Context::loadIdentity() 3051 { 3052 if(drawing) 3053 { 3054 return error(GL_INVALID_OPERATION); 3055 } 3056 3057 currentMatrixStack().identity(); 3058 } 3059 3060 void Context::pushMatrix() 3061 { 3062 //if(drawing) 3063 //{ 3064 // return error(GL_INVALID_OPERATION); 3065 //} 3066 3067 if(!currentMatrixStack().push()) 3068 { 3069 return error(GL_STACK_OVERFLOW); 3070 } 3071 } 3072 3073 void Context::popMatrix() 3074 { 3075 //if(drawing) 3076 //{ 3077 // return error(GL_INVALID_OPERATION); 3078 //} 3079 3080 if(!currentMatrixStack().pop()) 3081 { 3082 return error(GL_STACK_OVERFLOW); 3083 } 3084 } 3085 3086 void Context::rotate(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) 3087 { 3088 if(drawing) 3089 { 3090 return error(GL_INVALID_OPERATION); 3091 } 3092 3093 currentMatrixStack().rotate(angle, x, y, z); 3094 } 3095 3096 void Context::translate(GLfloat x, GLfloat y, GLfloat z) 3097 { 3098 if(drawing) 3099 { 3100 return error(GL_INVALID_OPERATION); 3101 } 3102 3103 currentMatrixStack().translate(x, y, z); 3104 } 3105 3106 void Context::scale(GLfloat x, GLfloat y, GLfloat z) 3107 { 3108 if(drawing) 3109 { 3110 return error(GL_INVALID_OPERATION); 3111 } 3112 3113 currentMatrixStack().scale(x, y, z); 3114 } 3115 3116 void Context::multiply(const GLdouble *m) 3117 { 3118 if(drawing) 3119 { 3120 return error(GL_INVALID_OPERATION); 3121 } 3122 3123 currentMatrixStack().multiply(m); 3124 } 3125 3126 void Context::multiply(const GLfloat *m) 3127 { 3128 if(drawing) 3129 { 3130 return error(GL_INVALID_OPERATION); 3131 } 3132 3133 currentMatrixStack().multiply(m); 3134 } 3135 3136 void Context::frustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar) 3137 { 3138 if(drawing) 3139 { 3140 return error(GL_INVALID_OPERATION); 3141 } 3142 3143 currentMatrixStack().frustum(left, right, bottom, top, zNear, zFar); 3144 } 3145 3146 void Context::ortho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar) 3147 { 3148 if(drawing) 3149 { 3150 return error(GL_INVALID_OPERATION); 3151 } 3152 3153 currentMatrixStack().ortho(left, right, bottom, top, zNear, zFar); 3154 } 3155 3156 void Context::setLightingEnabled(bool enable) 3157 { 3158 if(drawing) 3159 { 3160 return error(GL_INVALID_OPERATION); 3161 } 3162 3163 device->setLightingEnable(enable); 3164 } 3165 3166 void Context::setFogEnabled(bool enable) 3167 { 3168 if(drawing) 3169 { 3170 return error(GL_INVALID_OPERATION); 3171 } 3172 3173 device->setFogEnable(enable); 3174 } 3175 3176 void Context::setAlphaTestEnabled(bool enable) 3177 { 3178 if(drawing) 3179 { 3180 return error(GL_INVALID_OPERATION); 3181 } 3182 3183 device->setAlphaTestEnable(enable); 3184 } 3185 3186 void Context::alphaFunc(GLenum func, GLclampf ref) 3187 { 3188 if(drawing) 3189 { 3190 return error(GL_INVALID_OPERATION); 3191 } 3192 3193 switch(func) 3194 { 3195 case GL_NEVER: device->setAlphaCompare(sw::ALPHA_NEVER); break; 3196 case GL_LESS: device->setAlphaCompare(sw::ALPHA_LESS); break; 3197 case GL_EQUAL: device->setAlphaCompare(sw::ALPHA_EQUAL); break; 3198 case GL_LEQUAL: device->setAlphaCompare(sw::ALPHA_LESSEQUAL); break; 3199 case GL_GREATER: device->setAlphaCompare(sw::ALPHA_GREATER); break; 3200 case GL_NOTEQUAL: device->setAlphaCompare(sw::ALPHA_NOTEQUAL); break; 3201 case GL_GEQUAL: device->setAlphaCompare(sw::ALPHA_GREATEREQUAL); break; 3202 case GL_ALWAYS: device->setAlphaCompare(sw::ALPHA_ALWAYS); break; 3203 default: UNREACHABLE(func); 3204 } 3205 3206 device->setAlphaReference(gl::clamp01(ref)); 3207 } 3208 3209 void Context::setTexture2DEnabled(bool enable) 3210 { 3211 if(drawing) 3212 { 3213 return error(GL_INVALID_OPERATION); 3214 } 3215 3216 envEnable[mState.activeSampler] = enable; 3217 } 3218 3219 void Context::setShadeModel(GLenum mode) 3220 { 3221 //if(drawing) 3222 //{ 3223 // return error(GL_INVALID_OPERATION); 3224 //} 3225 3226 switch(mode) 3227 { 3228 case GL_FLAT: device->setShadingMode(sw::SHADING_FLAT); break; 3229 case GL_SMOOTH: device->setShadingMode(sw::SHADING_GOURAUD); break; 3230 default: return error(GL_INVALID_ENUM); 3231 } 3232 } 3233 3234 void Context::setLightEnabled(int index, bool enable) 3235 { 3236 device->setLightEnable(index, enable); 3237 } 3238 3239 void Context::setNormalizeNormalsEnabled(bool enable) 3240 { 3241 device->setNormalizeNormals(enable); 3242 } 3243 3244 GLuint Context::genLists(GLsizei range) 3245 { 3246 if(drawing) 3247 { 3248 return error(GL_INVALID_OPERATION, 0); 3249 } 3250 3251 int firstIndex = std::max(1u, firstFreeIndex); 3252 for(; true; firstIndex++) 3253 { 3254 int empty = 0; 3255 for(; empty < range; empty++) 3256 { 3257 if(displayList[firstIndex + empty] != 0) 3258 { 3259 break; 3260 } 3261 } 3262 3263 if(empty == range) 3264 { 3265 for(int i = firstIndex; i < firstIndex + range; i++) 3266 { 3267 displayList[i] = new DisplayList(); 3268 } 3269 3270 if(firstIndex == firstFreeIndex) 3271 { 3272 firstFreeIndex = firstIndex + range; 3273 } 3274 3275 return firstIndex; 3276 } 3277 } 3278 3279 return 0; 3280 } 3281 3282 void Context::newList(GLuint list, GLenum mode) 3283 { 3284 if(drawing || listIndex != 0) 3285 { 3286 return error(GL_INVALID_OPERATION); 3287 } 3288 3289 ASSERT(!this->list); 3290 this->list = new DisplayList(); 3291 3292 listIndex = list; 3293 listMode = mode; 3294 } 3295 3296 void Context::endList() 3297 { 3298 if(drawing || listIndex == 0) 3299 { 3300 return error(GL_INVALID_OPERATION); 3301 } 3302 3303 ASSERT(list); 3304 delete displayList[listIndex]; 3305 displayList[listIndex] = list; 3306 list = 0; 3307 3308 listIndex = 0; 3309 listMode = 0; 3310 } 3311 3312 void Context::callList(GLuint list) 3313 { 3314 // As per GL specifications, if the list does not exist, it is ignored 3315 if(displayList[list]) 3316 { 3317 displayList[list]->call(); 3318 } 3319 } 3320 3321 void Context::deleteList(GLuint list) 3322 { 3323 delete displayList[list]; 3324 displayList[list] = 0; 3325 displayList.erase(list); 3326 firstFreeIndex = std::min(firstFreeIndex , list); 3327 } 3328 3329 void Context::listCommand(Command *command) 3330 { 3331 ASSERT(list); 3332 list->list.push_back(command); 3333 3334 if(listMode == GL_COMPILE_AND_EXECUTE) 3335 { 3336 listMode = 0; 3337 command->call(); 3338 listMode = GL_COMPILE_AND_EXECUTE; 3339 } 3340 } 3341 3342 void APIENTRY glVertexAttribArray(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr) 3343 { 3344 TRACE("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, " 3345 "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = %p)", 3346 index, size, type, normalized, stride, ptr); 3347 3348 gl::Context *context = gl::getContext(); 3349 3350 if(context) 3351 { 3352 context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr); 3353 context->setVertexAttribArrayEnabled(index, ptr != 0); 3354 } 3355 } 3356 3357 void Context::captureAttribs() 3358 { 3359 memcpy(clientAttribute, mState.vertexAttribute, sizeof(mState.vertexAttribute)); 3360 } 3361 3362 void Context::captureDrawArrays(GLenum mode, GLint first, GLsizei count) 3363 { 3364 ASSERT(first == 0); // FIXME: UNIMPLEMENTED! 3365 3366 for(GLuint i = 0; i < MAX_VERTEX_ATTRIBS; i++) 3367 { 3368 GLint size = mState.vertexAttribute[i].mSize; 3369 GLenum type = mState.vertexAttribute[i].mType; 3370 GLboolean normalized = mState.vertexAttribute[i].mNormalized; 3371 GLsizei stride = mState.vertexAttribute[i].mStride; 3372 const GLvoid *pointer = mState.vertexAttribute[i].mPointer; 3373 3374 size_t length = count * mState.vertexAttribute[i].stride(); 3375 3376 if(mState.vertexAttribute[i].mArrayEnabled) 3377 { 3378 ASSERT(pointer); // FIXME: Add to condition? 3379 const int padding = 1024; // For SIMD processing of vertices // FIXME: Still necessary? 3380 void *buffer = new unsigned char[length + padding]; 3381 memcpy(buffer, pointer, length); 3382 3383 listCommand(gl::newCommand(glVertexAttribArray, i, size, type, normalized, stride, (const void*)buffer)); 3384 } 3385 else 3386 { 3387 listCommand(gl::newCommand(glVertexAttribArray, i, size, type, normalized, stride, (const void*)0)); 3388 } 3389 } 3390 } 3391 3392 void Context::restoreAttribs() 3393 { 3394 memcpy(mState.vertexAttribute, clientAttribute, sizeof(mState.vertexAttribute)); 3395 } 3396 3397 void Context::clientActiveTexture(GLenum texture) 3398 { 3399 clientTexture = texture; 3400 } 3401 3402 GLenum Context::getClientActiveTexture() const 3403 { 3404 return clientTexture; 3405 } 3406 3407 unsigned int Context::getActiveTexture() const 3408 { 3409 return mState.activeSampler; 3410 } 3411 3412 void Context::begin(GLenum mode) 3413 { 3414 if(drawing) 3415 { 3416 return error(GL_INVALID_OPERATION); 3417 } 3418 3419 drawing = true; 3420 drawMode = mode; 3421 3422 vertex.clear(); 3423 } 3424 3425 void Context::position(GLfloat x, GLfloat y, GLfloat z, GLfloat w) 3426 { 3427 InVertex v; 3428 3429 v.P.x = x; 3430 v.P.y = y; 3431 v.P.z = z; 3432 v.P.w = w; 3433 v.C.x = mState.vertexAttribute[sw::Color0].mCurrentValue[0]; 3434 v.C.y = mState.vertexAttribute[sw::Color0].mCurrentValue[1]; 3435 v.C.z = mState.vertexAttribute[sw::Color0].mCurrentValue[2]; 3436 v.C.w = mState.vertexAttribute[sw::Color0].mCurrentValue[3]; 3437 v.N.x = mState.vertexAttribute[sw::Normal].mCurrentValue[0]; 3438 v.N.y = mState.vertexAttribute[sw::Normal].mCurrentValue[1]; 3439 v.N.z = mState.vertexAttribute[sw::Normal].mCurrentValue[2]; 3440 v.N.w = mState.vertexAttribute[sw::Normal].mCurrentValue[3]; 3441 v.T0.x = mState.vertexAttribute[sw::TexCoord0].mCurrentValue[0]; 3442 v.T0.y = mState.vertexAttribute[sw::TexCoord0].mCurrentValue[1]; 3443 v.T0.z = mState.vertexAttribute[sw::TexCoord0].mCurrentValue[2]; 3444 v.T0.w = mState.vertexAttribute[sw::TexCoord0].mCurrentValue[3]; 3445 v.T1.x = mState.vertexAttribute[sw::TexCoord1].mCurrentValue[0]; 3446 v.T1.y = mState.vertexAttribute[sw::TexCoord1].mCurrentValue[1]; 3447 v.T1.z = mState.vertexAttribute[sw::TexCoord1].mCurrentValue[2]; 3448 v.T1.w = mState.vertexAttribute[sw::TexCoord1].mCurrentValue[3]; 3449 3450 vertex.push_back(v); 3451 } 3452 3453 void Context::end() 3454 { 3455 if(!drawing) 3456 { 3457 return error(GL_INVALID_OPERATION); 3458 } 3459 3460 device->setProjectionMatrix(projection.current()); 3461 device->setViewMatrix(modelView.current()); 3462 device->setTextureMatrix(0, texture[0].current()); 3463 device->setTextureMatrix(1, texture[1].current()); 3464 device->setTextureTransform(0, texture[0].isIdentity() ? 0 : 4, false); 3465 device->setTextureTransform(1, texture[1].isIdentity() ? 0 : 4, false); 3466 3467 captureAttribs(); 3468 3469 for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++) 3470 { 3471 mState.vertexAttribute[i].mArrayEnabled = false; 3472 } 3473 3474 setVertexAttribState(sw::Position, 0, 4, GL_FLOAT, false, sizeof(InVertex), &vertex[0].P); 3475 setVertexAttribState(sw::Normal, 0, 4, GL_FLOAT, false, sizeof(InVertex), &vertex[0].N); 3476 setVertexAttribState(sw::Color0, 0, 4, GL_FLOAT, false, sizeof(InVertex), &vertex[0].C); 3477 setVertexAttribState(sw::TexCoord0, 0, 2, GL_FLOAT, false, sizeof(InVertex), &vertex[0].T0); 3478 setVertexAttribState(sw::TexCoord1, 0, 2, GL_FLOAT, false, sizeof(InVertex), &vertex[0].T1); 3479 3480 mState.vertexAttribute[sw::Position].mArrayEnabled = true; 3481 mState.vertexAttribute[sw::Normal].mArrayEnabled = true; 3482 mState.vertexAttribute[sw::Color0].mArrayEnabled = true; 3483 mState.vertexAttribute[sw::TexCoord0].mArrayEnabled = true; 3484 mState.vertexAttribute[sw::TexCoord1].mArrayEnabled = true; 3485 3486 applyState(drawMode); 3487 3488 GLenum err = applyVertexBuffer(0, 0, vertex.size()); 3489 if(err != GL_NO_ERROR) 3490 { 3491 return error(err); 3492 } 3493 3494 applyTextures(); 3495 3496 switch(drawMode) 3497 { 3498 case GL_POINTS: 3499 UNIMPLEMENTED(); 3500 break; 3501 case GL_LINES: 3502 UNIMPLEMENTED(); 3503 break; 3504 case GL_LINE_STRIP: 3505 UNIMPLEMENTED(); 3506 break; 3507 case GL_LINE_LOOP: 3508 UNIMPLEMENTED(); 3509 break; 3510 case GL_TRIANGLES: 3511 UNIMPLEMENTED(); 3512 break; 3513 case GL_TRIANGLE_STRIP: 3514 device->drawPrimitive(DRAW_TRIANGLESTRIP, vertex.size() - 2); 3515 break; 3516 case GL_TRIANGLE_FAN: 3517 UNIMPLEMENTED(); 3518 break; 3519 case GL_QUADS: 3520 UNIMPLEMENTED(); 3521 break; 3522 case GL_QUAD_STRIP: 3523 UNIMPLEMENTED(); 3524 break; 3525 case GL_POLYGON: 3526 UNIMPLEMENTED(); 3527 break; 3528 default: 3529 UNREACHABLE(drawMode); 3530 } 3531 3532 restoreAttribs(); 3533 3534 drawing = false; 3535 } 3536 3537 void Context::setColorLogicOpEnabled(bool colorLogicOpEnabled) 3538 { 3539 if(mState.colorLogicOpEnabled != colorLogicOpEnabled) 3540 { 3541 mState.colorLogicOpEnabled = colorLogicOpEnabled; 3542 mColorLogicOperatorDirty = true; 3543 } 3544 } 3545 3546 bool Context::isColorLogicOpEnabled() 3547 { 3548 return mState.colorLogicOpEnabled; 3549 } 3550 3551 void Context::setLogicalOperation(GLenum logicalOperation) 3552 { 3553 if(mState.logicalOperation != logicalOperation) 3554 { 3555 mState.logicalOperation = logicalOperation; 3556 mColorLogicOperatorDirty = true; 3557 } 3558 } 3559 3560 void Context::setColorMaterialEnabled(bool enable) 3561 { 3562 device->setColorVertexEnable(enable); 3563 } 3564 3565 void Context::setColorMaterialMode(GLenum mode) 3566 { 3567 switch(mode) 3568 { 3569 case GL_EMISSION: 3570 device->setDiffuseMaterialSource(sw::MATERIAL_MATERIAL); 3571 device->setSpecularMaterialSource(sw::MATERIAL_MATERIAL); 3572 device->setAmbientMaterialSource(sw::MATERIAL_MATERIAL); 3573 device->setEmissiveMaterialSource(sw::MATERIAL_COLOR1); 3574 break; 3575 case GL_AMBIENT: 3576 device->setDiffuseMaterialSource(sw::MATERIAL_MATERIAL); 3577 device->setSpecularMaterialSource(sw::MATERIAL_MATERIAL); 3578 device->setAmbientMaterialSource(sw::MATERIAL_COLOR1); 3579 device->setEmissiveMaterialSource(sw::MATERIAL_MATERIAL); 3580 break; 3581 case GL_DIFFUSE: 3582 device->setDiffuseMaterialSource(sw::MATERIAL_COLOR1); 3583 device->setSpecularMaterialSource(sw::MATERIAL_MATERIAL); 3584 device->setAmbientMaterialSource(sw::MATERIAL_MATERIAL); 3585 device->setEmissiveMaterialSource(sw::MATERIAL_MATERIAL); 3586 break; 3587 case GL_SPECULAR: 3588 device->setDiffuseMaterialSource(sw::MATERIAL_MATERIAL); 3589 device->setSpecularMaterialSource(sw::MATERIAL_COLOR1); 3590 device->setAmbientMaterialSource(sw::MATERIAL_MATERIAL); 3591 device->setEmissiveMaterialSource(sw::MATERIAL_MATERIAL); 3592 break; 3593 case GL_AMBIENT_AND_DIFFUSE: 3594 device->setDiffuseMaterialSource(sw::MATERIAL_COLOR1); 3595 device->setSpecularMaterialSource(sw::MATERIAL_MATERIAL); 3596 device->setAmbientMaterialSource(sw::MATERIAL_COLOR1); 3597 device->setEmissiveMaterialSource(sw::MATERIAL_MATERIAL); 3598 break; 3599 default: 3600 UNREACHABLE(mode); 3601 } 3602 } 3603 3604 Device *Context::getDevice() 3605 { 3606 return device; 3607 } 3608 3609 } 3610