Context.cpp revision e5a43390eb366d12eb303d75b592e2ed48deb83d
1// SwiftShader Software Renderer 2// 3// Copyright(c) 2005-2013 TransGaming Inc. 4// 5// All rights reserved. No part of this software may be copied, distributed, transmitted, 6// transcribed, stored in a retrieval system, translated into any human or computer 7// language by any means, or disclosed to third parties without the explicit written 8// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express 9// or implied, including but not limited to any patent rights, are granted to you. 10// 11 12// Context.cpp: Implements the es2::Context class, managing all GL state and performing 13// rendering operations. It is the GLES2 specific implementation of EGLContext. 14 15#include "Context.h" 16 17#include "main.h" 18#include "mathutil.h" 19#include "utilities.h" 20#include "ResourceManager.h" 21#include "Buffer.h" 22#include "Fence.h" 23#include "Framebuffer.h" 24#include "Program.h" 25#include "Query.h" 26#include "Renderbuffer.h" 27#include "Sampler.h" 28#include "Shader.h" 29#include "Texture.h" 30#include "TransformFeedback.h" 31#include "VertexArray.h" 32#include "VertexDataManager.h" 33#include "IndexDataManager.h" 34#include "libEGL/Display.h" 35#include "libEGL/Surface.h" 36#include "Common/Half.hpp" 37 38#include <EGL/eglext.h> 39 40#undef near 41#undef far 42 43namespace es2 44{ 45Context::Context(const egl::Config *config, const Context *shareContext, EGLint clientVersion) 46 : mConfig(config), clientVersion(clientVersion) 47{ 48 sw::Context *context = new sw::Context(); 49 device = new es2::Device(context); 50 51 mFenceNameSpace.setBaseHandle(0); 52 53 setClearColor(0.0f, 0.0f, 0.0f, 0.0f); 54 55 mState.depthClearValue = 1.0f; 56 mState.stencilClearValue = 0; 57 58 mState.cullFace = false; 59 mState.cullMode = GL_BACK; 60 mState.frontFace = GL_CCW; 61 mState.depthTest = false; 62 mState.depthFunc = GL_LESS; 63 mState.blend = false; 64 mState.sourceBlendRGB = GL_ONE; 65 mState.sourceBlendAlpha = GL_ONE; 66 mState.destBlendRGB = GL_ZERO; 67 mState.destBlendAlpha = GL_ZERO; 68 mState.blendEquationRGB = GL_FUNC_ADD; 69 mState.blendEquationAlpha = GL_FUNC_ADD; 70 mState.blendColor.red = 0; 71 mState.blendColor.green = 0; 72 mState.blendColor.blue = 0; 73 mState.blendColor.alpha = 0; 74 mState.stencilTest = false; 75 mState.stencilFunc = GL_ALWAYS; 76 mState.stencilRef = 0; 77 mState.stencilMask = -1; 78 mState.stencilWritemask = -1; 79 mState.stencilBackFunc = GL_ALWAYS; 80 mState.stencilBackRef = 0; 81 mState.stencilBackMask = - 1; 82 mState.stencilBackWritemask = -1; 83 mState.stencilFail = GL_KEEP; 84 mState.stencilPassDepthFail = GL_KEEP; 85 mState.stencilPassDepthPass = GL_KEEP; 86 mState.stencilBackFail = GL_KEEP; 87 mState.stencilBackPassDepthFail = GL_KEEP; 88 mState.stencilBackPassDepthPass = GL_KEEP; 89 mState.polygonOffsetFill = false; 90 mState.polygonOffsetFactor = 0.0f; 91 mState.polygonOffsetUnits = 0.0f; 92 mState.sampleAlphaToCoverage = false; 93 mState.sampleCoverage = false; 94 mState.sampleCoverageValue = 1.0f; 95 mState.sampleCoverageInvert = false; 96 mState.scissorTest = false; 97 mState.dither = true; 98 mState.primitiveRestartFixedIndex = false; 99 mState.rasterizerDiscard = false; 100 mState.generateMipmapHint = GL_DONT_CARE; 101 mState.fragmentShaderDerivativeHint = GL_DONT_CARE; 102 103 mState.lineWidth = 1.0f; 104 105 mState.viewportX = 0; 106 mState.viewportY = 0; 107 mState.viewportWidth = config->mDisplayMode.width; 108 mState.viewportHeight = config->mDisplayMode.height; 109 mState.zNear = 0.0f; 110 mState.zFar = 1.0f; 111 112 mState.scissorX = 0; 113 mState.scissorY = 0; 114 mState.scissorWidth = config->mDisplayMode.width; 115 mState.scissorHeight = config->mDisplayMode.height; 116 117 mState.colorMaskRed = true; 118 mState.colorMaskGreen = true; 119 mState.colorMaskBlue = true; 120 mState.colorMaskAlpha = true; 121 mState.depthMask = true; 122 123 if(shareContext != NULL) 124 { 125 mResourceManager = shareContext->mResourceManager; 126 mResourceManager->addRef(); 127 } 128 else 129 { 130 mResourceManager = new ResourceManager(); 131 } 132 133 // [OpenGL ES 2.0.24] section 3.7 page 83: 134 // In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional 135 // and cube map texture state vectors respectively associated with them. 136 // In order that access to these initial textures not be lost, they are treated as texture 137 // objects all of whose names are 0. 138 139 mTexture2DZero = new Texture2D(0); 140 mTexture3DZero = new Texture3D(0); 141 mTexture2DArrayZero = new Texture2DArray(0); 142 mTextureCubeMapZero = new TextureCubeMap(0); 143 mTextureExternalZero = new TextureExternal(0); 144 145 mState.activeSampler = 0; 146 bindVertexArray(0); 147 bindArrayBuffer(0); 148 bindElementArrayBuffer(0); 149 bindTextureCubeMap(0); 150 bindTexture2D(0); 151 bindReadFramebuffer(0); 152 bindDrawFramebuffer(0); 153 bindRenderbuffer(0); 154 bindTransformFeedback(0); 155 156 mState.readFramebufferColorIndex = 0; 157 for(int i = 0; i < MAX_COLOR_ATTACHMENTS; ++i) 158 { 159 mState.drawFramebufferColorIndices[i] = GL_NONE; 160 } 161 162 mState.currentProgram = 0; 163 164 mState.packAlignment = 4; 165 mState.unpackInfo.alignment = 4; 166 mState.packRowLength = 0; 167 mState.packSkipPixels = 0; 168 mState.packSkipRows = 0; 169 mState.unpackInfo.rowLength = 0; 170 mState.unpackInfo.imageHeight = 0; 171 mState.unpackInfo.skipPixels = 0; 172 mState.unpackInfo.skipRows = 0; 173 mState.unpackInfo.skipImages = 0; 174 175 mVertexDataManager = NULL; 176 mIndexDataManager = NULL; 177 178 mInvalidEnum = false; 179 mInvalidValue = false; 180 mInvalidOperation = false; 181 mOutOfMemory = false; 182 mInvalidFramebufferOperation = false; 183 184 mHasBeenCurrent = false; 185 186 markAllStateDirty(); 187} 188 189Context::~Context() 190{ 191 if(mState.currentProgram != 0) 192 { 193 Program *programObject = mResourceManager->getProgram(mState.currentProgram); 194 if(programObject) 195 { 196 programObject->release(); 197 } 198 mState.currentProgram = 0; 199 } 200 201 while(!mFramebufferMap.empty()) 202 { 203 deleteFramebuffer(mFramebufferMap.begin()->first); 204 } 205 206 while(!mFenceMap.empty()) 207 { 208 deleteFence(mFenceMap.begin()->first); 209 } 210 211 while(!mQueryMap.empty()) 212 { 213 deleteQuery(mQueryMap.begin()->first); 214 } 215 216 while(!mVertexArrayMap.empty()) 217 { 218 deleteVertexArray(mVertexArrayMap.begin()->first); 219 } 220 221 while(!mTransformFeedbackMap.empty()) 222 { 223 deleteTransformFeedback(mTransformFeedbackMap.begin()->first); 224 } 225 226 for(int type = 0; type < TEXTURE_TYPE_COUNT; type++) 227 { 228 for(int sampler = 0; sampler < MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++) 229 { 230 mState.samplerTexture[type][sampler] = NULL; 231 } 232 } 233 234 for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++) 235 { 236 mState.vertexAttribute[i].mBoundBuffer = NULL; 237 } 238 239 for(int i = 0; i < QUERY_TYPE_COUNT; i++) 240 { 241 mState.activeQuery[i] = NULL; 242 } 243 244 mState.arrayBuffer = NULL; 245 mState.copyReadBuffer = NULL; 246 mState.copyWriteBuffer = NULL; 247 mState.pixelPackBuffer = NULL; 248 mState.pixelUnpackBuffer = NULL; 249 mState.uniformBuffer = NULL; 250 mState.renderbuffer = NULL; 251 252 for(int i = 0; i < MAX_COMBINED_TEXTURE_IMAGE_UNITS; ++i) 253 { 254 mState.sampler[i] = NULL; 255 } 256 257 mTexture2DZero = NULL; 258 mTexture3DZero = NULL; 259 mTexture2DArrayZero = NULL; 260 mTextureCubeMapZero = NULL; 261 mTextureExternalZero = NULL; 262 263 delete mVertexDataManager; 264 delete mIndexDataManager; 265 266 mResourceManager->release(); 267 delete device; 268} 269 270void Context::makeCurrent(egl::Surface *surface) 271{ 272 if(!mHasBeenCurrent) 273 { 274 mVertexDataManager = new VertexDataManager(this); 275 mIndexDataManager = new IndexDataManager(); 276 277 mState.viewportX = 0; 278 mState.viewportY = 0; 279 mState.viewportWidth = surface->getWidth(); 280 mState.viewportHeight = surface->getHeight(); 281 282 mState.scissorX = 0; 283 mState.scissorY = 0; 284 mState.scissorWidth = surface->getWidth(); 285 mState.scissorHeight = surface->getHeight(); 286 287 mHasBeenCurrent = true; 288 } 289 290 // Wrap the existing resources into GL objects and assign them to the '0' names 291 egl::Image *defaultRenderTarget = surface->getRenderTarget(); 292 egl::Image *depthStencil = surface->getDepthStencil(); 293 294 Colorbuffer *colorbufferZero = new Colorbuffer(defaultRenderTarget); 295 DepthStencilbuffer *depthStencilbufferZero = new DepthStencilbuffer(depthStencil); 296 Framebuffer *framebufferZero = new DefaultFramebuffer(colorbufferZero, depthStencilbufferZero); 297 298 setFramebufferZero(framebufferZero); 299 300 if(defaultRenderTarget) 301 { 302 defaultRenderTarget->release(); 303 } 304 305 if(depthStencil) 306 { 307 depthStencil->release(); 308 } 309 310 markAllStateDirty(); 311} 312 313EGLint Context::getClientVersion() const 314{ 315 return clientVersion; 316} 317 318// This function will set all of the state-related dirty flags, so that all state is set during next pre-draw. 319void Context::markAllStateDirty() 320{ 321 mAppliedProgramSerial = 0; 322 323 mDepthStateDirty = true; 324 mMaskStateDirty = true; 325 mBlendStateDirty = true; 326 mStencilStateDirty = true; 327 mPolygonOffsetStateDirty = true; 328 mSampleStateDirty = true; 329 mDitherStateDirty = true; 330 mFrontFaceDirty = true; 331} 332 333void Context::setClearColor(float red, float green, float blue, float alpha) 334{ 335 mState.colorClearValue.red = red; 336 mState.colorClearValue.green = green; 337 mState.colorClearValue.blue = blue; 338 mState.colorClearValue.alpha = alpha; 339} 340 341void Context::setClearDepth(float depth) 342{ 343 mState.depthClearValue = depth; 344} 345 346void Context::setClearStencil(int stencil) 347{ 348 mState.stencilClearValue = stencil; 349} 350 351void Context::setCullFace(bool enabled) 352{ 353 mState.cullFace = enabled; 354} 355 356bool Context::isCullFaceEnabled() const 357{ 358 return mState.cullFace; 359} 360 361void Context::setCullMode(GLenum mode) 362{ 363 mState.cullMode = mode; 364} 365 366void Context::setFrontFace(GLenum front) 367{ 368 if(mState.frontFace != front) 369 { 370 mState.frontFace = front; 371 mFrontFaceDirty = true; 372 } 373} 374 375void Context::setDepthTest(bool enabled) 376{ 377 if(mState.depthTest != enabled) 378 { 379 mState.depthTest = enabled; 380 mDepthStateDirty = true; 381 } 382} 383 384bool Context::isDepthTestEnabled() const 385{ 386 return mState.depthTest; 387} 388 389void Context::setDepthFunc(GLenum depthFunc) 390{ 391 if(mState.depthFunc != depthFunc) 392 { 393 mState.depthFunc = depthFunc; 394 mDepthStateDirty = true; 395 } 396} 397 398void Context::setDepthRange(float zNear, float zFar) 399{ 400 mState.zNear = zNear; 401 mState.zFar = zFar; 402} 403 404void Context::setBlend(bool enabled) 405{ 406 if(mState.blend != enabled) 407 { 408 mState.blend = enabled; 409 mBlendStateDirty = true; 410 } 411} 412 413bool Context::isBlendEnabled() const 414{ 415 return mState.blend; 416} 417 418void Context::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha) 419{ 420 if(mState.sourceBlendRGB != sourceRGB || 421 mState.sourceBlendAlpha != sourceAlpha || 422 mState.destBlendRGB != destRGB || 423 mState.destBlendAlpha != destAlpha) 424 { 425 mState.sourceBlendRGB = sourceRGB; 426 mState.destBlendRGB = destRGB; 427 mState.sourceBlendAlpha = sourceAlpha; 428 mState.destBlendAlpha = destAlpha; 429 mBlendStateDirty = true; 430 } 431} 432 433void Context::setBlendColor(float red, float green, float blue, float alpha) 434{ 435 if(mState.blendColor.red != red || 436 mState.blendColor.green != green || 437 mState.blendColor.blue != blue || 438 mState.blendColor.alpha != alpha) 439 { 440 mState.blendColor.red = red; 441 mState.blendColor.green = green; 442 mState.blendColor.blue = blue; 443 mState.blendColor.alpha = alpha; 444 mBlendStateDirty = true; 445 } 446} 447 448void Context::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation) 449{ 450 if(mState.blendEquationRGB != rgbEquation || 451 mState.blendEquationAlpha != alphaEquation) 452 { 453 mState.blendEquationRGB = rgbEquation; 454 mState.blendEquationAlpha = alphaEquation; 455 mBlendStateDirty = true; 456 } 457} 458 459void Context::setStencilTest(bool enabled) 460{ 461 if(mState.stencilTest != enabled) 462 { 463 mState.stencilTest = enabled; 464 mStencilStateDirty = true; 465 } 466} 467 468bool Context::isStencilTestEnabled() const 469{ 470 return mState.stencilTest; 471} 472 473void Context::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask) 474{ 475 if(mState.stencilFunc != stencilFunc || 476 mState.stencilRef != stencilRef || 477 mState.stencilMask != stencilMask) 478 { 479 mState.stencilFunc = stencilFunc; 480 mState.stencilRef = (stencilRef > 0) ? stencilRef : 0; 481 mState.stencilMask = stencilMask; 482 mStencilStateDirty = true; 483 } 484} 485 486void Context::setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask) 487{ 488 if(mState.stencilBackFunc != stencilBackFunc || 489 mState.stencilBackRef != stencilBackRef || 490 mState.stencilBackMask != stencilBackMask) 491 { 492 mState.stencilBackFunc = stencilBackFunc; 493 mState.stencilBackRef = (stencilBackRef > 0) ? stencilBackRef : 0; 494 mState.stencilBackMask = stencilBackMask; 495 mStencilStateDirty = true; 496 } 497} 498 499void Context::setStencilWritemask(GLuint stencilWritemask) 500{ 501 if(mState.stencilWritemask != stencilWritemask) 502 { 503 mState.stencilWritemask = stencilWritemask; 504 mStencilStateDirty = true; 505 } 506} 507 508void Context::setStencilBackWritemask(GLuint stencilBackWritemask) 509{ 510 if(mState.stencilBackWritemask != stencilBackWritemask) 511 { 512 mState.stencilBackWritemask = stencilBackWritemask; 513 mStencilStateDirty = true; 514 } 515} 516 517void Context::setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass) 518{ 519 if(mState.stencilFail != stencilFail || 520 mState.stencilPassDepthFail != stencilPassDepthFail || 521 mState.stencilPassDepthPass != stencilPassDepthPass) 522 { 523 mState.stencilFail = stencilFail; 524 mState.stencilPassDepthFail = stencilPassDepthFail; 525 mState.stencilPassDepthPass = stencilPassDepthPass; 526 mStencilStateDirty = true; 527 } 528} 529 530void Context::setStencilBackOperations(GLenum stencilBackFail, GLenum stencilBackPassDepthFail, GLenum stencilBackPassDepthPass) 531{ 532 if(mState.stencilBackFail != stencilBackFail || 533 mState.stencilBackPassDepthFail != stencilBackPassDepthFail || 534 mState.stencilBackPassDepthPass != stencilBackPassDepthPass) 535 { 536 mState.stencilBackFail = stencilBackFail; 537 mState.stencilBackPassDepthFail = stencilBackPassDepthFail; 538 mState.stencilBackPassDepthPass = stencilBackPassDepthPass; 539 mStencilStateDirty = true; 540 } 541} 542 543void Context::setPolygonOffsetFill(bool enabled) 544{ 545 if(mState.polygonOffsetFill != enabled) 546 { 547 mState.polygonOffsetFill = enabled; 548 mPolygonOffsetStateDirty = true; 549 } 550} 551 552bool Context::isPolygonOffsetFillEnabled() const 553{ 554 return mState.polygonOffsetFill; 555} 556 557void Context::setPolygonOffsetParams(GLfloat factor, GLfloat units) 558{ 559 if(mState.polygonOffsetFactor != factor || 560 mState.polygonOffsetUnits != units) 561 { 562 mState.polygonOffsetFactor = factor; 563 mState.polygonOffsetUnits = units; 564 mPolygonOffsetStateDirty = true; 565 } 566} 567 568void Context::setSampleAlphaToCoverage(bool enabled) 569{ 570 if(mState.sampleAlphaToCoverage != enabled) 571 { 572 mState.sampleAlphaToCoverage = enabled; 573 mSampleStateDirty = true; 574 } 575} 576 577bool Context::isSampleAlphaToCoverageEnabled() const 578{ 579 return mState.sampleAlphaToCoverage; 580} 581 582void Context::setSampleCoverage(bool enabled) 583{ 584 if(mState.sampleCoverage != enabled) 585 { 586 mState.sampleCoverage = enabled; 587 mSampleStateDirty = true; 588 } 589} 590 591bool Context::isSampleCoverageEnabled() const 592{ 593 return mState.sampleCoverage; 594} 595 596void Context::setSampleCoverageParams(GLclampf value, bool invert) 597{ 598 if(mState.sampleCoverageValue != value || 599 mState.sampleCoverageInvert != invert) 600 { 601 mState.sampleCoverageValue = value; 602 mState.sampleCoverageInvert = invert; 603 mSampleStateDirty = true; 604 } 605} 606 607void Context::setScissorTest(bool enabled) 608{ 609 mState.scissorTest = enabled; 610} 611 612bool Context::isScissorTestEnabled() const 613{ 614 return mState.scissorTest; 615} 616 617void Context::setDither(bool enabled) 618{ 619 if(mState.dither != enabled) 620 { 621 mState.dither = enabled; 622 mDitherStateDirty = true; 623 } 624} 625 626bool Context::isDitherEnabled() const 627{ 628 return mState.dither; 629} 630 631void Context::setPrimitiveRestartFixedIndex(bool enabled) 632{ 633 UNIMPLEMENTED(); 634 mState.primitiveRestartFixedIndex = enabled; 635} 636 637bool Context::isPrimitiveRestartFixedIndexEnabled() const 638{ 639 return mState.primitiveRestartFixedIndex; 640} 641 642void Context::setRasterizerDiscard(bool enabled) 643{ 644 UNIMPLEMENTED(); 645 mState.rasterizerDiscard = enabled; 646} 647 648bool Context::isRasterizerDiscardEnabled() const 649{ 650 return mState.rasterizerDiscard; 651} 652 653void Context::setLineWidth(GLfloat width) 654{ 655 mState.lineWidth = width; 656 device->setLineWidth(clamp(width, ALIASED_LINE_WIDTH_RANGE_MIN, ALIASED_LINE_WIDTH_RANGE_MAX)); 657} 658 659void Context::setGenerateMipmapHint(GLenum hint) 660{ 661 mState.generateMipmapHint = hint; 662} 663 664void Context::setFragmentShaderDerivativeHint(GLenum hint) 665{ 666 mState.fragmentShaderDerivativeHint = hint; 667 // TODO: Propagate the hint to shader translator so we can write 668 // ddx, ddx_coarse, or ddx_fine depending on the hint. 669 // Ignore for now. It is valid for implementations to ignore hint. 670} 671 672void Context::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height) 673{ 674 mState.viewportX = x; 675 mState.viewportY = y; 676 mState.viewportWidth = width; 677 mState.viewportHeight = height; 678} 679 680void Context::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height) 681{ 682 mState.scissorX = x; 683 mState.scissorY = y; 684 mState.scissorWidth = width; 685 mState.scissorHeight = height; 686} 687 688void Context::setColorMask(bool red, bool green, bool blue, bool alpha) 689{ 690 if(mState.colorMaskRed != red || mState.colorMaskGreen != green || 691 mState.colorMaskBlue != blue || mState.colorMaskAlpha != alpha) 692 { 693 mState.colorMaskRed = red; 694 mState.colorMaskGreen = green; 695 mState.colorMaskBlue = blue; 696 mState.colorMaskAlpha = alpha; 697 mMaskStateDirty = true; 698 } 699} 700 701unsigned int Context::getColorMask() const 702{ 703 return (mState.colorMaskRed ? 0x1 : 0) | 704 (mState.colorMaskGreen ? 0x2 : 0) | 705 (mState.colorMaskBlue ? 0x4 : 0) | 706 (mState.colorMaskAlpha ? 0x8 : 0); 707} 708 709void Context::setDepthMask(bool mask) 710{ 711 if(mState.depthMask != mask) 712 { 713 mState.depthMask = mask; 714 mMaskStateDirty = true; 715 } 716} 717 718void Context::setActiveSampler(unsigned int active) 719{ 720 mState.activeSampler = active; 721} 722 723GLuint Context::getReadFramebufferName() const 724{ 725 return mState.readFramebuffer; 726} 727 728GLuint Context::getDrawFramebufferName() const 729{ 730 return mState.drawFramebuffer; 731} 732 733GLuint Context::getRenderbufferName() const 734{ 735 return mState.renderbuffer.name(); 736} 737 738void Context::setReadFramebufferColorIndex(GLuint index) 739{ 740 mState.readFramebufferColorIndex = index; 741} 742 743void Context::setDrawFramebufferColorIndices(GLsizei n, const GLenum *bufs) 744{ 745 for(int i = 0; i < n; ++i) 746 { 747 mState.drawFramebufferColorIndices[i] = ((bufs[i] == GL_BACK) || (bufs[i] == GL_NONE)) ? bufs[i] : i; 748 } 749} 750 751GLuint Context::getReadFramebufferColorIndex() const 752{ 753 return mState.readFramebufferColorIndex; 754} 755 756GLuint Context::getArrayBufferName() const 757{ 758 return mState.arrayBuffer.name(); 759} 760 761GLuint Context::getElementArrayBufferName() const 762{ 763 Buffer* elementArrayBuffer = getCurrentVertexArray()->getElementArrayBuffer(); 764 return elementArrayBuffer ? elementArrayBuffer->name : 0; 765} 766 767GLuint Context::getActiveQuery(GLenum target) const 768{ 769 Query *queryObject = NULL; 770 771 switch(target) 772 { 773 case GL_ANY_SAMPLES_PASSED_EXT: 774 queryObject = mState.activeQuery[QUERY_ANY_SAMPLES_PASSED]; 775 break; 776 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT: 777 queryObject = mState.activeQuery[QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE]; 778 break; 779 case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN: 780 queryObject = mState.activeQuery[QUERY_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN]; 781 break; 782 default: 783 ASSERT(false); 784 } 785 786 if(queryObject) 787 { 788 return queryObject->name; 789 } 790 791 return 0; 792} 793 794void Context::setEnableVertexAttribArray(unsigned int attribNum, bool enabled) 795{ 796 getCurrentVertexArray()->enableAttribute(attribNum, enabled); 797} 798 799void Context::setVertexAttribDivisor(unsigned int attribNum, GLuint divisor) 800{ 801 getCurrentVertexArray()->setVertexAttribDivisor(attribNum, divisor); 802} 803 804const VertexAttribute &Context::getVertexAttribState(unsigned int attribNum) const 805{ 806 return getCurrentVertexArray()->getVertexAttribute(attribNum); 807} 808 809void Context::setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type, bool normalized, 810 GLsizei stride, const void *pointer) 811{ 812 getCurrentVertexArray()->setAttributeState(attribNum, boundBuffer, size, type, normalized, stride, pointer); 813} 814 815const void *Context::getVertexAttribPointer(unsigned int attribNum) const 816{ 817 return getCurrentVertexArray()->getVertexAttribute(attribNum).mPointer; 818} 819 820const VertexAttributeArray &Context::getVertexArrayAttributes() 821{ 822 return getCurrentVertexArray()->getVertexAttributes(); 823} 824 825const VertexAttributeArray &Context::getCurrentVertexAttributes() 826{ 827 return mState.vertexAttribute; 828} 829 830void Context::setPackAlignment(GLint alignment) 831{ 832 mState.packAlignment = alignment; 833} 834 835void Context::setUnpackAlignment(GLint alignment) 836{ 837 mState.unpackInfo.alignment = alignment; 838} 839 840const egl::Image::UnpackInfo& Context::getUnpackInfo() const 841{ 842 return mState.unpackInfo; 843} 844 845void Context::setPackRowLength(GLint rowLength) 846{ 847 mState.packRowLength = rowLength; 848} 849 850void Context::setPackSkipPixels(GLint skipPixels) 851{ 852 mState.packSkipPixels = skipPixels; 853} 854 855void Context::setPackSkipRows(GLint skipRows) 856{ 857 mState.packSkipRows = skipRows; 858} 859 860void Context::setUnpackRowLength(GLint rowLength) 861{ 862 mState.unpackInfo.rowLength = rowLength; 863} 864 865void Context::setUnpackImageHeight(GLint imageHeight) 866{ 867 mState.unpackInfo.imageHeight = imageHeight; 868} 869 870void Context::setUnpackSkipPixels(GLint skipPixels) 871{ 872 mState.unpackInfo.skipPixels = skipPixels; 873} 874 875void Context::setUnpackSkipRows(GLint skipRows) 876{ 877 mState.unpackInfo.skipRows = skipRows; 878} 879 880void Context::setUnpackSkipImages(GLint skipImages) 881{ 882 mState.unpackInfo.skipImages = skipImages; 883} 884 885GLuint Context::createBuffer() 886{ 887 return mResourceManager->createBuffer(); 888} 889 890GLuint Context::createProgram() 891{ 892 return mResourceManager->createProgram(); 893} 894 895GLuint Context::createShader(GLenum type) 896{ 897 return mResourceManager->createShader(type); 898} 899 900GLuint Context::createTexture() 901{ 902 return mResourceManager->createTexture(); 903} 904 905GLuint Context::createRenderbuffer() 906{ 907 return mResourceManager->createRenderbuffer(); 908} 909 910// Returns an unused framebuffer name 911GLuint Context::createFramebuffer() 912{ 913 GLuint handle = mFramebufferNameSpace.allocate(); 914 915 mFramebufferMap[handle] = NULL; 916 917 return handle; 918} 919 920GLuint Context::createFence() 921{ 922 GLuint handle = mFenceNameSpace.allocate(); 923 924 mFenceMap[handle] = new Fence; 925 926 return handle; 927} 928 929// Returns an unused query name 930GLuint Context::createQuery() 931{ 932 GLuint handle = mQueryNameSpace.allocate(); 933 934 mQueryMap[handle] = NULL; 935 936 return handle; 937} 938 939// Returns an unused vertex array name 940GLuint Context::createVertexArray() 941{ 942 GLuint handle = mVertexArrayNameSpace.allocate(); 943 944 mVertexArrayMap[handle] = NULL; 945 946 return handle; 947} 948 949GLsync Context::createFenceSync(GLenum condition, GLbitfield flags) 950{ 951 GLuint handle = mResourceManager->createFenceSync(condition, flags); 952 953 return reinterpret_cast<GLsync>(static_cast<uintptr_t>(handle)); 954} 955 956// Returns an unused transform feedback name 957GLuint Context::createTransformFeedback() 958{ 959 GLuint handle = mTransformFeedbackNameSpace.allocate(); 960 961 mTransformFeedbackMap[handle] = NULL; 962 963 return handle; 964} 965 966// Returns an unused sampler name 967GLuint Context::createSampler() 968{ 969 return mResourceManager->createSampler(); 970} 971 972void Context::deleteBuffer(GLuint buffer) 973{ 974 if(mResourceManager->getBuffer(buffer)) 975 { 976 detachBuffer(buffer); 977 } 978 979 mResourceManager->deleteBuffer(buffer); 980} 981 982void Context::deleteShader(GLuint shader) 983{ 984 mResourceManager->deleteShader(shader); 985} 986 987void Context::deleteProgram(GLuint program) 988{ 989 mResourceManager->deleteProgram(program); 990} 991 992void Context::deleteTexture(GLuint texture) 993{ 994 if(mResourceManager->getTexture(texture)) 995 { 996 detachTexture(texture); 997 } 998 999 mResourceManager->deleteTexture(texture); 1000} 1001 1002void Context::deleteRenderbuffer(GLuint renderbuffer) 1003{ 1004 if(mResourceManager->getRenderbuffer(renderbuffer)) 1005 { 1006 detachRenderbuffer(renderbuffer); 1007 } 1008 1009 mResourceManager->deleteRenderbuffer(renderbuffer); 1010} 1011 1012void Context::deleteFramebuffer(GLuint framebuffer) 1013{ 1014 FramebufferMap::iterator framebufferObject = mFramebufferMap.find(framebuffer); 1015 1016 if(framebufferObject != mFramebufferMap.end()) 1017 { 1018 detachFramebuffer(framebuffer); 1019 1020 mFramebufferNameSpace.release(framebufferObject->first); 1021 delete framebufferObject->second; 1022 mFramebufferMap.erase(framebufferObject); 1023 } 1024} 1025 1026void Context::deleteFence(GLuint fence) 1027{ 1028 FenceMap::iterator fenceObject = mFenceMap.find(fence); 1029 1030 if(fenceObject != mFenceMap.end()) 1031 { 1032 mFenceNameSpace.release(fenceObject->first); 1033 delete fenceObject->second; 1034 mFenceMap.erase(fenceObject); 1035 } 1036} 1037 1038void Context::deleteQuery(GLuint query) 1039{ 1040 QueryMap::iterator queryObject = mQueryMap.find(query); 1041 1042 if(queryObject != mQueryMap.end()) 1043 { 1044 mQueryNameSpace.release(queryObject->first); 1045 1046 if(queryObject->second) 1047 { 1048 queryObject->second->release(); 1049 } 1050 1051 mQueryMap.erase(queryObject); 1052 } 1053} 1054 1055void Context::deleteVertexArray(GLuint vertexArray) 1056{ 1057 VertexArrayMap::iterator vertexArrayObject = mVertexArrayMap.find(vertexArray); 1058 1059 if(vertexArrayObject != mVertexArrayMap.end()) 1060 { 1061 // Vertex array detachment is handled by Context, because 0 is a valid 1062 // VAO, and a pointer to it must be passed from Context to State at 1063 // binding time. 1064 1065 // [OpenGL ES 3.0.2] section 2.10 page 43: 1066 // If a vertex array object that is currently bound is deleted, the binding 1067 // for that object reverts to zero and the default vertex array becomes current. 1068 if(getCurrentVertexArray()->name == vertexArray) 1069 { 1070 bindVertexArray(0); 1071 } 1072 1073 mVertexArrayNameSpace.release(vertexArrayObject->first); 1074 delete vertexArrayObject->second; 1075 mVertexArrayMap.erase(vertexArrayObject); 1076 } 1077} 1078 1079void Context::deleteFenceSync(GLsync fenceSync) 1080{ 1081 // The spec specifies the underlying Fence object is not deleted until all current 1082 // wait commands finish. However, since the name becomes invalid, we cannot query the fence, 1083 // and since our API is currently designed for being called from a single thread, we can delete 1084 // the fence immediately. 1085 mResourceManager->deleteFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(fenceSync))); 1086} 1087 1088void Context::deleteTransformFeedback(GLuint transformFeedback) 1089{ 1090 TransformFeedbackMap::iterator transformFeedbackObject = mTransformFeedbackMap.find(transformFeedback); 1091 1092 if(transformFeedbackObject != mTransformFeedbackMap.end()) 1093 { 1094 mTransformFeedbackNameSpace.release(transformFeedbackObject->first); 1095 delete transformFeedbackObject->second; 1096 mTransformFeedbackMap.erase(transformFeedbackObject); 1097 } 1098} 1099 1100void Context::deleteSampler(GLuint sampler) 1101{ 1102 if(mResourceManager->getSampler(sampler)) 1103 { 1104 detachSampler(sampler); 1105 } 1106 1107 mResourceManager->deleteSampler(sampler); 1108} 1109 1110Buffer *Context::getBuffer(GLuint handle) const 1111{ 1112 return mResourceManager->getBuffer(handle); 1113} 1114 1115Shader *Context::getShader(GLuint handle) const 1116{ 1117 return mResourceManager->getShader(handle); 1118} 1119 1120Program *Context::getProgram(GLuint handle) const 1121{ 1122 return mResourceManager->getProgram(handle); 1123} 1124 1125Texture *Context::getTexture(GLuint handle) const 1126{ 1127 return mResourceManager->getTexture(handle); 1128} 1129 1130Renderbuffer *Context::getRenderbuffer(GLuint handle) const 1131{ 1132 return mResourceManager->getRenderbuffer(handle); 1133} 1134 1135Framebuffer *Context::getReadFramebuffer() const 1136{ 1137 return getFramebuffer(mState.readFramebuffer); 1138} 1139 1140Framebuffer *Context::getDrawFramebuffer() const 1141{ 1142 return getFramebuffer(mState.drawFramebuffer); 1143} 1144 1145void Context::bindArrayBuffer(unsigned int buffer) 1146{ 1147 mResourceManager->checkBufferAllocation(buffer); 1148 1149 mState.arrayBuffer = getBuffer(buffer); 1150} 1151 1152void Context::bindElementArrayBuffer(unsigned int buffer) 1153{ 1154 mResourceManager->checkBufferAllocation(buffer); 1155 1156 getCurrentVertexArray()->setElementArrayBuffer(getBuffer(buffer)); 1157} 1158 1159void Context::bindCopyReadBuffer(GLuint buffer) 1160{ 1161 mResourceManager->checkBufferAllocation(buffer); 1162 1163 mState.copyReadBuffer = getBuffer(buffer); 1164} 1165 1166void Context::bindCopyWriteBuffer(GLuint buffer) 1167{ 1168 mResourceManager->checkBufferAllocation(buffer); 1169 1170 mState.copyWriteBuffer = getBuffer(buffer); 1171} 1172 1173void Context::bindPixelPackBuffer(GLuint buffer) 1174{ 1175 mResourceManager->checkBufferAllocation(buffer); 1176 1177 mState.pixelPackBuffer = getBuffer(buffer); 1178} 1179 1180void Context::bindPixelUnpackBuffer(GLuint buffer) 1181{ 1182 mResourceManager->checkBufferAllocation(buffer); 1183 1184 mState.pixelUnpackBuffer = getBuffer(buffer); 1185} 1186 1187void Context::bindTransformFeedbackBuffer(GLuint buffer) 1188{ 1189 mResourceManager->checkBufferAllocation(buffer); 1190 1191 TransformFeedback* transformFeedback = getTransformFeedback(mState.transformFeedback); 1192 1193 if(transformFeedback) 1194 { 1195 transformFeedback->setGenericBuffer(getBuffer(buffer)); 1196 } 1197} 1198 1199void Context::bindUniformBuffer(GLuint buffer) 1200{ 1201 mResourceManager->checkBufferAllocation(buffer); 1202 1203 mState.uniformBuffer = getBuffer(buffer); 1204} 1205 1206void Context::bindTexture2D(GLuint texture) 1207{ 1208 mResourceManager->checkTextureAllocation(texture, TEXTURE_2D); 1209 1210 mState.samplerTexture[TEXTURE_2D][mState.activeSampler] = getTexture(texture); 1211} 1212 1213void Context::bindTextureCubeMap(GLuint texture) 1214{ 1215 mResourceManager->checkTextureAllocation(texture, TEXTURE_CUBE); 1216 1217 mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler] = getTexture(texture); 1218} 1219 1220void Context::bindTextureExternal(GLuint texture) 1221{ 1222 mResourceManager->checkTextureAllocation(texture, TEXTURE_EXTERNAL); 1223 1224 mState.samplerTexture[TEXTURE_EXTERNAL][mState.activeSampler] = getTexture(texture); 1225} 1226 1227void Context::bindTexture3D(GLuint texture) 1228{ 1229 mResourceManager->checkTextureAllocation(texture, TEXTURE_3D); 1230 1231 mState.samplerTexture[TEXTURE_3D][mState.activeSampler] = getTexture(texture); 1232} 1233 1234void Context::bindTexture2DArray(GLuint texture) 1235{ 1236 mResourceManager->checkTextureAllocation(texture, TEXTURE_2D_ARRAY); 1237 1238 mState.samplerTexture[TEXTURE_2D_ARRAY][mState.activeSampler] = getTexture(texture); 1239} 1240 1241void Context::bindReadFramebuffer(GLuint framebuffer) 1242{ 1243 if(!getFramebuffer(framebuffer)) 1244 { 1245 mFramebufferMap[framebuffer] = new Framebuffer(); 1246 } 1247 1248 mState.readFramebuffer = framebuffer; 1249} 1250 1251void Context::bindDrawFramebuffer(GLuint framebuffer) 1252{ 1253 if(!getFramebuffer(framebuffer)) 1254 { 1255 mFramebufferMap[framebuffer] = new Framebuffer(); 1256 } 1257 1258 mState.drawFramebuffer = framebuffer; 1259} 1260 1261void Context::bindRenderbuffer(GLuint renderbuffer) 1262{ 1263 mState.renderbuffer = getRenderbuffer(renderbuffer); 1264} 1265 1266bool Context::bindVertexArray(GLuint array) 1267{ 1268 VertexArray* vertexArray = getVertexArray(array); 1269 1270 if(!vertexArray) 1271 { 1272 vertexArray = new VertexArray(array); 1273 mVertexArrayMap[array] = vertexArray; 1274 } 1275 1276 mState.vertexArray = array; 1277 1278 return !!vertexArray; 1279} 1280 1281bool Context::bindTransformFeedback(GLuint id) 1282{ 1283 if(!getTransformFeedback(id)) 1284 { 1285 mTransformFeedbackMap[id] = new TransformFeedback(id); 1286 } 1287 1288 mState.transformFeedback = id; 1289 1290 return true; 1291} 1292 1293bool Context::bindSampler(GLuint unit, GLuint sampler) 1294{ 1295 Sampler* samplerObject = getSampler(sampler); 1296 1297 if(sampler) 1298 { 1299 mState.sampler[unit] = samplerObject; 1300 } 1301 1302 return !!samplerObject; 1303} 1304 1305void Context::useProgram(GLuint program) 1306{ 1307 GLuint priorProgram = mState.currentProgram; 1308 mState.currentProgram = program; // Must switch before trying to delete, otherwise it only gets flagged. 1309 1310 if(priorProgram != program) 1311 { 1312 Program *newProgram = mResourceManager->getProgram(program); 1313 Program *oldProgram = mResourceManager->getProgram(priorProgram); 1314 1315 if(newProgram) 1316 { 1317 newProgram->addRef(); 1318 } 1319 1320 if(oldProgram) 1321 { 1322 oldProgram->release(); 1323 } 1324 } 1325} 1326 1327void Context::beginQuery(GLenum target, GLuint query) 1328{ 1329 // From EXT_occlusion_query_boolean: If BeginQueryEXT is called with an <id> 1330 // of zero, if the active query object name for <target> is non-zero (for the 1331 // targets ANY_SAMPLES_PASSED_EXT and ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, if 1332 // the active query for either target is non-zero), if <id> is the name of an 1333 // existing query object whose type does not match <target>, or if <id> is the 1334 // active query object name for any query type, the error INVALID_OPERATION is 1335 // generated. 1336 1337 // Ensure no other queries are active 1338 // NOTE: If other queries than occlusion are supported, we will need to check 1339 // separately that: 1340 // a) The query ID passed is not the current active query for any target/type 1341 // b) There are no active queries for the requested target (and in the case 1342 // of GL_ANY_SAMPLES_PASSED_EXT and GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT, 1343 // no query may be active for either if glBeginQuery targets either. 1344 for(int i = 0; i < QUERY_TYPE_COUNT; i++) 1345 { 1346 if(mState.activeQuery[i] != NULL) 1347 { 1348 return error(GL_INVALID_OPERATION); 1349 } 1350 } 1351 1352 QueryType qType; 1353 switch(target) 1354 { 1355 case GL_ANY_SAMPLES_PASSED_EXT: 1356 qType = QUERY_ANY_SAMPLES_PASSED; 1357 break; 1358 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT: 1359 qType = QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE; 1360 break; 1361 case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN: 1362 qType = QUERY_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN; 1363 break; 1364 default: 1365 ASSERT(false); 1366 } 1367 1368 Query *queryObject = createQuery(query, target); 1369 1370 // Check that name was obtained with glGenQueries 1371 if(!queryObject) 1372 { 1373 return error(GL_INVALID_OPERATION); 1374 } 1375 1376 // Check for type mismatch 1377 if(queryObject->getType() != target) 1378 { 1379 return error(GL_INVALID_OPERATION); 1380 } 1381 1382 // Set query as active for specified target 1383 mState.activeQuery[qType] = queryObject; 1384 1385 // Begin query 1386 queryObject->begin(); 1387} 1388 1389void Context::endQuery(GLenum target) 1390{ 1391 QueryType qType; 1392 1393 switch(target) 1394 { 1395 case GL_ANY_SAMPLES_PASSED_EXT: 1396 qType = QUERY_ANY_SAMPLES_PASSED; 1397 break; 1398 case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT: 1399 qType = QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE; 1400 break; 1401 case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN: 1402 qType = QUERY_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN; 1403 break; 1404 default: 1405 ASSERT(false); 1406 } 1407 1408 Query *queryObject = mState.activeQuery[qType]; 1409 1410 if(queryObject == NULL) 1411 { 1412 return error(GL_INVALID_OPERATION); 1413 } 1414 1415 queryObject->end(); 1416 1417 mState.activeQuery[qType] = NULL; 1418} 1419 1420void Context::setFramebufferZero(Framebuffer *buffer) 1421{ 1422 delete mFramebufferMap[0]; 1423 mFramebufferMap[0] = buffer; 1424} 1425 1426void Context::setRenderbufferStorage(RenderbufferStorage *renderbuffer) 1427{ 1428 Renderbuffer *renderbufferObject = mState.renderbuffer; 1429 renderbufferObject->setStorage(renderbuffer); 1430} 1431 1432Framebuffer *Context::getFramebuffer(unsigned int handle) const 1433{ 1434 FramebufferMap::const_iterator framebuffer = mFramebufferMap.find(handle); 1435 1436 if(framebuffer == mFramebufferMap.end()) 1437 { 1438 return NULL; 1439 } 1440 else 1441 { 1442 return framebuffer->second; 1443 } 1444} 1445 1446Fence *Context::getFence(unsigned int handle) const 1447{ 1448 FenceMap::const_iterator fence = mFenceMap.find(handle); 1449 1450 if(fence == mFenceMap.end()) 1451 { 1452 return NULL; 1453 } 1454 else 1455 { 1456 return fence->second; 1457 } 1458} 1459 1460FenceSync *Context::getFenceSync(GLsync handle) const 1461{ 1462 return mResourceManager->getFenceSync(static_cast<GLuint>(reinterpret_cast<uintptr_t>(handle))); 1463} 1464 1465Query *Context::getQuery(unsigned int handle) const 1466{ 1467 QueryMap::const_iterator query = mQueryMap.find(handle); 1468 1469 if(query == mQueryMap.end()) 1470 { 1471 return NULL; 1472 } 1473 else 1474 { 1475 return query->second; 1476 } 1477} 1478 1479Query *Context::createQuery(unsigned int handle, GLenum type) 1480{ 1481 QueryMap::iterator query = mQueryMap.find(handle); 1482 1483 if(query == mQueryMap.end()) 1484 { 1485 return NULL; 1486 } 1487 else 1488 { 1489 if(!query->second) 1490 { 1491 query->second = new Query(handle, type); 1492 query->second->addRef(); 1493 } 1494 1495 return query->second; 1496 } 1497} 1498 1499VertexArray *Context::getVertexArray(GLuint array) const 1500{ 1501 VertexArrayMap::const_iterator vertexArray = mVertexArrayMap.find(array); 1502 1503 return (vertexArray == mVertexArrayMap.end()) ? NULL : vertexArray->second; 1504} 1505 1506VertexArray *Context::getCurrentVertexArray() const 1507{ 1508 return getVertexArray(mState.vertexArray); 1509} 1510 1511bool Context::hasZeroDivisor() const 1512{ 1513 // Verify there is at least one active attribute with a divisor of zero 1514 es2::Program *programObject = getCurrentProgram(); 1515 for(int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++) 1516 { 1517 bool active = (programObject->getAttributeStream(attributeIndex) != -1); 1518 if(active && getCurrentVertexArray()->getVertexAttribute(attributeIndex).mDivisor == 0) 1519 { 1520 return true; 1521 } 1522 } 1523 1524 return false; 1525} 1526 1527TransformFeedback *Context::getTransformFeedback(GLuint transformFeedback) const 1528{ 1529 TransformFeedbackMap::const_iterator transformFeedbackObject = mTransformFeedbackMap.find(transformFeedback); 1530 1531 return (transformFeedbackObject == mTransformFeedbackMap.end()) ? NULL : transformFeedbackObject->second; 1532} 1533 1534Sampler *Context::getSampler(GLuint sampler) const 1535{ 1536 return mResourceManager->getSampler(sampler); 1537} 1538 1539Buffer *Context::getArrayBuffer() const 1540{ 1541 return mState.arrayBuffer; 1542} 1543 1544Buffer *Context::getElementArrayBuffer() const 1545{ 1546 return getCurrentVertexArray()->getElementArrayBuffer(); 1547} 1548 1549Buffer *Context::getCopyReadBuffer() const 1550{ 1551 return mState.copyReadBuffer; 1552} 1553 1554Buffer *Context::getCopyWriteBuffer() const 1555{ 1556 return mState.copyWriteBuffer; 1557} 1558 1559Buffer *Context::getPixelPackBuffer() const 1560{ 1561 return mState.pixelPackBuffer; 1562} 1563 1564Buffer *Context::getPixelUnpackBuffer() const 1565{ 1566 return mState.pixelUnpackBuffer; 1567} 1568 1569Buffer *Context::getUniformBuffer() const 1570{ 1571 return mState.uniformBuffer; 1572} 1573 1574bool Context::getBuffer(GLenum target, es2::Buffer **buffer) const 1575{ 1576 switch(target) 1577 { 1578 case GL_ARRAY_BUFFER: 1579 *buffer = getArrayBuffer(); 1580 break; 1581 case GL_ELEMENT_ARRAY_BUFFER: 1582 *buffer = getElementArrayBuffer(); 1583 break; 1584 case GL_COPY_READ_BUFFER: 1585 if(clientVersion >= 3) 1586 { 1587 *buffer = getCopyReadBuffer(); 1588 break; 1589 } 1590 else return false; 1591 case GL_COPY_WRITE_BUFFER: 1592 if(clientVersion >= 3) 1593 { 1594 *buffer = getCopyWriteBuffer(); 1595 break; 1596 } 1597 else return false; 1598 case GL_PIXEL_PACK_BUFFER: 1599 if(clientVersion >= 3) 1600 { 1601 *buffer = getPixelPackBuffer(); 1602 break; 1603 } 1604 else return false; 1605 case GL_PIXEL_UNPACK_BUFFER: 1606 if(clientVersion >= 3) 1607 { 1608 *buffer = getPixelUnpackBuffer(); 1609 break; 1610 } 1611 else return false; 1612 case GL_TRANSFORM_FEEDBACK_BUFFER: 1613 if(clientVersion >= 3) 1614 { 1615 TransformFeedback* transformFeedback = getTransformFeedback(); 1616 *buffer = transformFeedback ? static_cast<es2::Buffer*>(transformFeedback->getGenericBuffer()) : nullptr; 1617 break; 1618 } 1619 else return false; 1620 case GL_UNIFORM_BUFFER: 1621 if(clientVersion >= 3) 1622 { 1623 *buffer = getUniformBuffer(); 1624 break; 1625 } 1626 else return false; 1627 default: 1628 return false; 1629 } 1630 return true; 1631} 1632 1633TransformFeedback *Context::getTransformFeedback() const 1634{ 1635 return getTransformFeedback(mState.transformFeedback); 1636} 1637 1638Program *Context::getCurrentProgram() const 1639{ 1640 return mResourceManager->getProgram(mState.currentProgram); 1641} 1642 1643Texture2D *Context::getTexture2D() const 1644{ 1645 return static_cast<Texture2D*>(getSamplerTexture(mState.activeSampler, TEXTURE_2D)); 1646} 1647 1648Texture3D *Context::getTexture3D() const 1649{ 1650 return static_cast<Texture3D*>(getSamplerTexture(mState.activeSampler, TEXTURE_3D)); 1651} 1652 1653Texture2DArray *Context::getTexture2DArray() const 1654{ 1655 return static_cast<Texture2DArray*>(getSamplerTexture(mState.activeSampler, TEXTURE_2D_ARRAY)); 1656} 1657 1658TextureCubeMap *Context::getTextureCubeMap() const 1659{ 1660 return static_cast<TextureCubeMap*>(getSamplerTexture(mState.activeSampler, TEXTURE_CUBE)); 1661} 1662 1663TextureExternal *Context::getTextureExternal() const 1664{ 1665 return static_cast<TextureExternal*>(getSamplerTexture(mState.activeSampler, TEXTURE_EXTERNAL)); 1666} 1667 1668Texture *Context::getSamplerTexture(unsigned int sampler, TextureType type) const 1669{ 1670 GLuint texid = mState.samplerTexture[type][sampler].name(); 1671 1672 if(texid == 0) // Special case: 0 refers to different initial textures based on the target 1673 { 1674 switch (type) 1675 { 1676 case TEXTURE_2D: return mTexture2DZero; 1677 case TEXTURE_3D: return mTexture3DZero; 1678 case TEXTURE_2D_ARRAY: return mTexture2DArrayZero; 1679 case TEXTURE_CUBE: return mTextureCubeMapZero; 1680 case TEXTURE_EXTERNAL: return mTextureExternalZero; 1681 default: UNREACHABLE(); 1682 } 1683 } 1684 1685 return mState.samplerTexture[type][sampler]; 1686} 1687 1688bool Context::getBooleanv(GLenum pname, GLboolean *params) const 1689{ 1690 switch (pname) 1691 { 1692 case GL_SHADER_COMPILER: *params = GL_TRUE; break; 1693 case GL_SAMPLE_COVERAGE_INVERT: *params = mState.sampleCoverageInvert; break; 1694 case GL_DEPTH_WRITEMASK: *params = mState.depthMask; break; 1695 case GL_COLOR_WRITEMASK: 1696 params[0] = mState.colorMaskRed; 1697 params[1] = mState.colorMaskGreen; 1698 params[2] = mState.colorMaskBlue; 1699 params[3] = mState.colorMaskAlpha; 1700 break; 1701 case GL_CULL_FACE: *params = mState.cullFace; break; 1702 case GL_POLYGON_OFFSET_FILL: *params = mState.polygonOffsetFill; break; 1703 case GL_SAMPLE_ALPHA_TO_COVERAGE: *params = mState.sampleAlphaToCoverage; break; 1704 case GL_SAMPLE_COVERAGE: *params = mState.sampleCoverage; break; 1705 case GL_SCISSOR_TEST: *params = mState.scissorTest; break; 1706 case GL_STENCIL_TEST: *params = mState.stencilTest; break; 1707 case GL_DEPTH_TEST: *params = mState.depthTest; break; 1708 case GL_BLEND: *params = mState.blend; break; 1709 case GL_DITHER: *params = mState.dither; break; 1710 case GL_PRIMITIVE_RESTART_FIXED_INDEX: *params = mState.primitiveRestartFixedIndex; break; 1711 case GL_RASTERIZER_DISCARD: *params = mState.rasterizerDiscard; break; 1712 case GL_TRANSFORM_FEEDBACK_ACTIVE: 1713 { 1714 TransformFeedback* transformFeedback = getTransformFeedback(mState.transformFeedback); 1715 if(transformFeedback) 1716 { 1717 *params = transformFeedback->isActive(); 1718 break; 1719 } 1720 else return false; 1721 } 1722 case GL_TRANSFORM_FEEDBACK_PAUSED: 1723 { 1724 TransformFeedback* transformFeedback = getTransformFeedback(mState.transformFeedback); 1725 if(transformFeedback) 1726 { 1727 *params = transformFeedback->isPaused(); 1728 break; 1729 } 1730 else return false; 1731 } 1732 default: 1733 return false; 1734 } 1735 1736 return true; 1737} 1738 1739bool Context::getFloatv(GLenum pname, GLfloat *params) const 1740{ 1741 // Please note: DEPTH_CLEAR_VALUE is included in our internal getFloatv implementation 1742 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names 1743 // GetIntegerv as its native query function. As it would require conversion in any 1744 // case, this should make no difference to the calling application. 1745 switch (pname) 1746 { 1747 case GL_LINE_WIDTH: *params = mState.lineWidth; break; 1748 case GL_SAMPLE_COVERAGE_VALUE: *params = mState.sampleCoverageValue; break; 1749 case GL_DEPTH_CLEAR_VALUE: *params = mState.depthClearValue; break; 1750 case GL_POLYGON_OFFSET_FACTOR: *params = mState.polygonOffsetFactor; break; 1751 case GL_POLYGON_OFFSET_UNITS: *params = mState.polygonOffsetUnits; break; 1752 case GL_ALIASED_LINE_WIDTH_RANGE: 1753 params[0] = ALIASED_LINE_WIDTH_RANGE_MIN; 1754 params[1] = ALIASED_LINE_WIDTH_RANGE_MAX; 1755 break; 1756 case GL_ALIASED_POINT_SIZE_RANGE: 1757 params[0] = ALIASED_POINT_SIZE_RANGE_MIN; 1758 params[1] = ALIASED_POINT_SIZE_RANGE_MAX; 1759 break; 1760 case GL_DEPTH_RANGE: 1761 params[0] = mState.zNear; 1762 params[1] = mState.zFar; 1763 break; 1764 case GL_COLOR_CLEAR_VALUE: 1765 params[0] = mState.colorClearValue.red; 1766 params[1] = mState.colorClearValue.green; 1767 params[2] = mState.colorClearValue.blue; 1768 params[3] = mState.colorClearValue.alpha; 1769 break; 1770 case GL_BLEND_COLOR: 1771 params[0] = mState.blendColor.red; 1772 params[1] = mState.blendColor.green; 1773 params[2] = mState.blendColor.blue; 1774 params[3] = mState.blendColor.alpha; 1775 break; 1776 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT: 1777 *params = MAX_TEXTURE_MAX_ANISOTROPY; 1778 break; 1779 default: 1780 return false; 1781 } 1782 1783 return true; 1784} 1785 1786template bool Context::getIntegerv<GLint>(GLenum pname, GLint *params) const; 1787template bool Context::getIntegerv<GLint64>(GLenum pname, GLint64 *params) const; 1788 1789template<typename T> bool Context::getIntegerv(GLenum pname, T *params) const 1790{ 1791 // Please note: DEPTH_CLEAR_VALUE is not included in our internal getIntegerv implementation 1792 // because it is stored as a float, despite the fact that the GL ES 2.0 spec names 1793 // GetIntegerv as its native query function. As it would require conversion in any 1794 // case, this should make no difference to the calling application. You may find it in 1795 // Context::getFloatv. 1796 switch (pname) 1797 { 1798 case GL_MAX_VERTEX_ATTRIBS: *params = MAX_VERTEX_ATTRIBS; break; 1799 case GL_MAX_VERTEX_UNIFORM_VECTORS: *params = MAX_VERTEX_UNIFORM_VECTORS; break; 1800 case GL_MAX_VARYING_VECTORS: *params = MAX_VARYING_VECTORS; break; 1801 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = MAX_COMBINED_TEXTURE_IMAGE_UNITS; break; 1802 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: *params = MAX_VERTEX_TEXTURE_IMAGE_UNITS; break; 1803 case GL_MAX_TEXTURE_IMAGE_UNITS: *params = MAX_TEXTURE_IMAGE_UNITS; break; 1804 case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = MAX_FRAGMENT_UNIFORM_VECTORS; break; 1805 case GL_MAX_RENDERBUFFER_SIZE: *params = IMPLEMENTATION_MAX_RENDERBUFFER_SIZE; break; 1806 case GL_NUM_SHADER_BINARY_FORMATS: *params = 0; break; 1807 case GL_SHADER_BINARY_FORMATS: /* no shader binary formats are supported */ break; 1808 case GL_ARRAY_BUFFER_BINDING: *params = getArrayBufferName(); break; 1809 case GL_ELEMENT_ARRAY_BUFFER_BINDING: *params = getElementArrayBufferName(); break; 1810// case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE 1811 case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE: *params = mState.drawFramebuffer; break; 1812 case GL_READ_FRAMEBUFFER_BINDING_ANGLE: *params = mState.readFramebuffer; break; 1813 case GL_RENDERBUFFER_BINDING: *params = mState.renderbuffer.name(); break; 1814 case GL_CURRENT_PROGRAM: *params = mState.currentProgram; break; 1815 case GL_PACK_ALIGNMENT: *params = mState.packAlignment; break; 1816 case GL_UNPACK_ALIGNMENT: *params = mState.unpackInfo.alignment; break; 1817 case GL_GENERATE_MIPMAP_HINT: *params = mState.generateMipmapHint; break; 1818 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: *params = mState.fragmentShaderDerivativeHint; break; 1819 case GL_ACTIVE_TEXTURE: *params = (mState.activeSampler + GL_TEXTURE0); break; 1820 case GL_STENCIL_FUNC: *params = mState.stencilFunc; break; 1821 case GL_STENCIL_REF: *params = mState.stencilRef; break; 1822 case GL_STENCIL_VALUE_MASK: *params = mState.stencilMask; break; 1823 case GL_STENCIL_BACK_FUNC: *params = mState.stencilBackFunc; break; 1824 case GL_STENCIL_BACK_REF: *params = mState.stencilBackRef; break; 1825 case GL_STENCIL_BACK_VALUE_MASK: *params = mState.stencilBackMask; break; 1826 case GL_STENCIL_FAIL: *params = mState.stencilFail; break; 1827 case GL_STENCIL_PASS_DEPTH_FAIL: *params = mState.stencilPassDepthFail; break; 1828 case GL_STENCIL_PASS_DEPTH_PASS: *params = mState.stencilPassDepthPass; break; 1829 case GL_STENCIL_BACK_FAIL: *params = mState.stencilBackFail; break; 1830 case GL_STENCIL_BACK_PASS_DEPTH_FAIL: *params = mState.stencilBackPassDepthFail; break; 1831 case GL_STENCIL_BACK_PASS_DEPTH_PASS: *params = mState.stencilBackPassDepthPass; break; 1832 case GL_DEPTH_FUNC: *params = mState.depthFunc; break; 1833 case GL_BLEND_SRC_RGB: *params = mState.sourceBlendRGB; break; 1834 case GL_BLEND_SRC_ALPHA: *params = mState.sourceBlendAlpha; break; 1835 case GL_BLEND_DST_RGB: *params = mState.destBlendRGB; break; 1836 case GL_BLEND_DST_ALPHA: *params = mState.destBlendAlpha; break; 1837 case GL_BLEND_EQUATION_RGB: *params = mState.blendEquationRGB; break; 1838 case GL_BLEND_EQUATION_ALPHA: *params = mState.blendEquationAlpha; break; 1839 case GL_STENCIL_WRITEMASK: *params = mState.stencilWritemask; break; 1840 case GL_STENCIL_BACK_WRITEMASK: *params = mState.stencilBackWritemask; break; 1841 case GL_STENCIL_CLEAR_VALUE: *params = mState.stencilClearValue; break; 1842 case GL_SUBPIXEL_BITS: *params = 4; break; 1843 case GL_MAX_TEXTURE_SIZE: *params = IMPLEMENTATION_MAX_TEXTURE_SIZE; break; 1844 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: *params = IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE; break; 1845 case GL_NUM_COMPRESSED_TEXTURE_FORMATS: *params = NUM_COMPRESSED_TEXTURE_FORMATS; break; 1846 case GL_MAX_SAMPLES_ANGLE: *params = IMPLEMENTATION_MAX_SAMPLES; break; 1847 case GL_SAMPLE_BUFFERS: 1848 case GL_SAMPLES: 1849 { 1850 Framebuffer *framebuffer = getDrawFramebuffer(); 1851 int width, height, samples; 1852 1853 if(framebuffer->completeness(width, height, samples) == GL_FRAMEBUFFER_COMPLETE) 1854 { 1855 switch(pname) 1856 { 1857 case GL_SAMPLE_BUFFERS: 1858 if(samples > 1) 1859 { 1860 *params = 1; 1861 } 1862 else 1863 { 1864 *params = 0; 1865 } 1866 break; 1867 case GL_SAMPLES: 1868 *params = samples & ~1; 1869 break; 1870 } 1871 } 1872 else 1873 { 1874 *params = 0; 1875 } 1876 } 1877 break; 1878 case GL_IMPLEMENTATION_COLOR_READ_TYPE: 1879 { 1880 Framebuffer *framebuffer = getReadFramebuffer(); 1881 *params = framebuffer->getImplementationColorReadType(); 1882 } 1883 break; 1884 case GL_IMPLEMENTATION_COLOR_READ_FORMAT: 1885 { 1886 Framebuffer *framebuffer = getReadFramebuffer(); 1887 *params = framebuffer->getImplementationColorReadFormat(); 1888 } 1889 break; 1890 case GL_MAX_VIEWPORT_DIMS: 1891 { 1892 int maxDimension = IMPLEMENTATION_MAX_RENDERBUFFER_SIZE; 1893 params[0] = maxDimension; 1894 params[1] = maxDimension; 1895 } 1896 break; 1897 case GL_COMPRESSED_TEXTURE_FORMATS: 1898 { 1899 for(int i = 0; i < NUM_COMPRESSED_TEXTURE_FORMATS; i++) 1900 { 1901 params[i] = compressedTextureFormats[i]; 1902 } 1903 } 1904 break; 1905 case GL_VIEWPORT: 1906 params[0] = mState.viewportX; 1907 params[1] = mState.viewportY; 1908 params[2] = mState.viewportWidth; 1909 params[3] = mState.viewportHeight; 1910 break; 1911 case GL_SCISSOR_BOX: 1912 params[0] = mState.scissorX; 1913 params[1] = mState.scissorY; 1914 params[2] = mState.scissorWidth; 1915 params[3] = mState.scissorHeight; 1916 break; 1917 case GL_CULL_FACE_MODE: *params = mState.cullMode; break; 1918 case GL_FRONT_FACE: *params = mState.frontFace; break; 1919 case GL_RED_BITS: 1920 case GL_GREEN_BITS: 1921 case GL_BLUE_BITS: 1922 case GL_ALPHA_BITS: 1923 { 1924 Framebuffer *framebuffer = getDrawFramebuffer(); 1925 Renderbuffer *colorbuffer = framebuffer->getColorbuffer(0); 1926 1927 if(colorbuffer) 1928 { 1929 switch (pname) 1930 { 1931 case GL_RED_BITS: *params = colorbuffer->getRedSize(); break; 1932 case GL_GREEN_BITS: *params = colorbuffer->getGreenSize(); break; 1933 case GL_BLUE_BITS: *params = colorbuffer->getBlueSize(); break; 1934 case GL_ALPHA_BITS: *params = colorbuffer->getAlphaSize(); break; 1935 } 1936 } 1937 else 1938 { 1939 *params = 0; 1940 } 1941 } 1942 break; 1943 case GL_DEPTH_BITS: 1944 { 1945 Framebuffer *framebuffer = getDrawFramebuffer(); 1946 Renderbuffer *depthbuffer = framebuffer->getDepthbuffer(); 1947 1948 if(depthbuffer) 1949 { 1950 *params = depthbuffer->getDepthSize(); 1951 } 1952 else 1953 { 1954 *params = 0; 1955 } 1956 } 1957 break; 1958 case GL_STENCIL_BITS: 1959 { 1960 Framebuffer *framebuffer = getDrawFramebuffer(); 1961 Renderbuffer *stencilbuffer = framebuffer->getStencilbuffer(); 1962 1963 if(stencilbuffer) 1964 { 1965 *params = stencilbuffer->getStencilSize(); 1966 } 1967 else 1968 { 1969 *params = 0; 1970 } 1971 } 1972 break; 1973 case GL_TEXTURE_BINDING_2D: 1974 { 1975 if(mState.activeSampler < 0 || mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1) 1976 { 1977 error(GL_INVALID_OPERATION); 1978 return false; 1979 } 1980 1981 *params = mState.samplerTexture[TEXTURE_2D][mState.activeSampler].name(); 1982 } 1983 break; 1984 case GL_TEXTURE_BINDING_CUBE_MAP: 1985 { 1986 if(mState.activeSampler < 0 || mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1) 1987 { 1988 error(GL_INVALID_OPERATION); 1989 return false; 1990 } 1991 1992 *params = mState.samplerTexture[TEXTURE_CUBE][mState.activeSampler].name(); 1993 } 1994 break; 1995 case GL_TEXTURE_BINDING_EXTERNAL_OES: 1996 { 1997 if(mState.activeSampler < 0 || mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1) 1998 { 1999 error(GL_INVALID_OPERATION); 2000 return false; 2001 } 2002 2003 *params = mState.samplerTexture[TEXTURE_EXTERNAL][mState.activeSampler].name(); 2004 } 2005 break; 2006 case GL_TEXTURE_BINDING_3D_OES: 2007 case GL_TEXTURE_BINDING_2D_ARRAY: // GLES 3.0 2008 { 2009 if(mState.activeSampler < 0 || mState.activeSampler > MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1) 2010 { 2011 error(GL_INVALID_OPERATION); 2012 return false; 2013 } 2014 2015 *params = mState.samplerTexture[TEXTURE_3D][mState.activeSampler].name(); 2016 } 2017 break; 2018 case GL_COPY_READ_BUFFER_BINDING: // name, initially 0 2019 if(clientVersion >= 3) 2020 { 2021 *params = mState.copyReadBuffer.name(); 2022 } 2023 else 2024 { 2025 return false; 2026 } 2027 break; 2028 case GL_COPY_WRITE_BUFFER_BINDING: // name, initially 0 2029 if(clientVersion >= 3) 2030 { 2031 *params = mState.copyWriteBuffer.name(); 2032 } 2033 else 2034 { 2035 return false; 2036 } 2037 break; 2038 case GL_DRAW_BUFFER0: // symbolic constant, initial value is GL_BACK 2039 UNIMPLEMENTED(); 2040 *params = GL_BACK; 2041 break; 2042 case GL_DRAW_BUFFER1: // symbolic constant, initial value is GL_NONE 2043 case GL_DRAW_BUFFER2: 2044 case GL_DRAW_BUFFER3: 2045 case GL_DRAW_BUFFER4: 2046 case GL_DRAW_BUFFER5: 2047 case GL_DRAW_BUFFER6: 2048 case GL_DRAW_BUFFER7: 2049 case GL_DRAW_BUFFER8: 2050 case GL_DRAW_BUFFER9: 2051 case GL_DRAW_BUFFER10: 2052 case GL_DRAW_BUFFER11: 2053 case GL_DRAW_BUFFER12: 2054 case GL_DRAW_BUFFER13: 2055 case GL_DRAW_BUFFER14: 2056 case GL_DRAW_BUFFER15: 2057 UNIMPLEMENTED(); 2058 *params = GL_NONE; 2059 break; 2060 case GL_MAJOR_VERSION: // integer, at least 3 2061 UNIMPLEMENTED(); 2062 *params = 3; 2063 break; 2064 case GL_MAX_3D_TEXTURE_SIZE: // GLint, at least 2048 2065 *params = IMPLEMENTATION_MAX_TEXTURE_SIZE; 2066 break; 2067 case GL_MAX_ARRAY_TEXTURE_LAYERS: // GLint, at least 2048 2068 *params = IMPLEMENTATION_MAX_TEXTURE_SIZE; 2069 break; 2070 case GL_MAX_COLOR_ATTACHMENTS: // integer, at least 8 2071 UNIMPLEMENTED(); 2072 *params = IMPLEMENTATION_MAX_COLOR_ATTACHMENTS; 2073 break; 2074 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS: // integer, at least 50048 2075 UNIMPLEMENTED(); 2076 *params = MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS; 2077 break; 2078 case GL_MAX_COMBINED_UNIFORM_BLOCKS: // integer, at least 70 2079 UNIMPLEMENTED(); 2080 *params = 70; 2081 break; 2082 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS: // integer, at least 50176 2083 UNIMPLEMENTED(); 2084 *params = MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS; 2085 break; 2086 case GL_MAX_DRAW_BUFFERS: // integer, at least 8 2087 UNIMPLEMENTED(); 2088 *params = IMPLEMENTATION_MAX_DRAW_BUFFERS; 2089 break; 2090 case GL_MAX_ELEMENT_INDEX: 2091 *params = MAX_ELEMENT_INDEX; 2092 break; 2093 case GL_MAX_ELEMENTS_INDICES: 2094 *params = MAX_ELEMENTS_INDICES; 2095 break; 2096 case GL_MAX_ELEMENTS_VERTICES: 2097 *params = MAX_ELEMENTS_VERTICES; 2098 break; 2099 case GL_MAX_FRAGMENT_INPUT_COMPONENTS: // integer, at least 128 2100 UNIMPLEMENTED(); 2101 *params = 128; 2102 break; 2103 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: // integer, at least 12 2104 UNIMPLEMENTED(); 2105 *params = 12; 2106 break; 2107 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: // integer, at least 1024 2108 UNIMPLEMENTED(); 2109 *params = 1024; 2110 break; 2111 case GL_MAX_PROGRAM_TEXEL_OFFSET: // integer, minimum is 7 2112 UNIMPLEMENTED(); 2113 *params = 7; 2114 break; 2115 case GL_MAX_SERVER_WAIT_TIMEOUT: // integer 2116 UNIMPLEMENTED(); 2117 *params = 0; 2118 break; 2119 case GL_MAX_TEXTURE_LOD_BIAS: // integer, at least 2.0 2120 UNIMPLEMENTED(); 2121 *params = 2; 2122 break; 2123 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: // integer, at least 64 2124 UNIMPLEMENTED(); 2125 *params = 64; 2126 break; 2127 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: // integer, at least 4 2128 UNIMPLEMENTED(); 2129 *params = IMPLEMENTATION_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS; 2130 break; 2131 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: // integer, at least 4 2132 UNIMPLEMENTED(); 2133 *params = 4; 2134 break; 2135 case GL_MAX_UNIFORM_BLOCK_SIZE: // integer, at least 16384 2136 UNIMPLEMENTED(); 2137 *params = 16384; 2138 break; 2139 case GL_MAX_UNIFORM_BUFFER_BINDINGS: // integer, at least 36 2140 UNIMPLEMENTED(); 2141 *params = IMPLEMENTATION_MAX_UNIFORM_BUFFER_BINDINGS; 2142 break; 2143 case GL_MAX_VARYING_COMPONENTS: // integer, at least 60 2144 UNIMPLEMENTED(); 2145 *params = 60; 2146 break; 2147 case GL_MAX_VERTEX_OUTPUT_COMPONENTS: // integer, at least 64 2148 UNIMPLEMENTED(); 2149 *params = 64; 2150 break; 2151 case GL_MAX_VERTEX_UNIFORM_BLOCKS: // integer, at least 12 2152 UNIMPLEMENTED(); 2153 *params = 12; 2154 break; 2155 case GL_MAX_VERTEX_UNIFORM_COMPONENTS: // integer, at least 1024 2156 UNIMPLEMENTED(); 2157 *params = 1024; 2158 break; 2159 case GL_MIN_PROGRAM_TEXEL_OFFSET: // integer, maximum is -8 2160 UNIMPLEMENTED(); 2161 *params = -8; 2162 break; 2163 case GL_MINOR_VERSION: // integer 2164 UNIMPLEMENTED(); 2165 *params = 0; 2166 break; 2167 case GL_NUM_EXTENSIONS: // integer 2168 GLuint numExtensions; 2169 getExtensions(0, &numExtensions); 2170 *params = numExtensions; 2171 break; 2172 case GL_NUM_PROGRAM_BINARY_FORMATS: // integer, at least 0 2173 UNIMPLEMENTED(); 2174 *params = 0; 2175 break; 2176 case GL_PACK_ROW_LENGTH: // integer, initially 0 2177 *params = mState.packRowLength; 2178 break; 2179 case GL_PACK_SKIP_PIXELS: // integer, initially 0 2180 *params = mState.packSkipPixels; 2181 break; 2182 case GL_PACK_SKIP_ROWS: // integer, initially 0 2183 *params = mState.packSkipRows; 2184 break; 2185 case GL_PIXEL_PACK_BUFFER_BINDING: // integer, initially 0 2186 if(clientVersion >= 3) 2187 { 2188 *params = mState.pixelPackBuffer.name(); 2189 } 2190 else 2191 { 2192 return false; 2193 } 2194 break; 2195 case GL_PIXEL_UNPACK_BUFFER_BINDING: // integer, initially 0 2196 if(clientVersion >= 3) 2197 { 2198 *params = mState.pixelUnpackBuffer.name(); 2199 } 2200 else 2201 { 2202 return false; 2203 } 2204 break; 2205 case GL_PROGRAM_BINARY_FORMATS: // integer[GL_NUM_PROGRAM_BINARY_FORMATS] 2206 UNIMPLEMENTED(); 2207 *params = 0; 2208 break; 2209 case GL_READ_BUFFER: // symbolic constant, initial value is GL_BACK 2210 UNIMPLEMENTED(); 2211 *params = GL_BACK; 2212 break; 2213 case GL_SAMPLER_BINDING: // GLint, default 0 2214 UNIMPLEMENTED(); 2215 *params = 0; 2216 break; 2217 case GL_UNIFORM_BUFFER_BINDING: // name, initially 0 2218 if(clientVersion >= 3) 2219 { 2220 *params = mState.uniformBuffer.name(); 2221 } 2222 else 2223 { 2224 return false; 2225 } 2226 break; 2227 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: // integer, defaults to 1 2228 UNIMPLEMENTED(); 2229 *params = IMPLEMENTATION_UNIFORM_BUFFER_OFFSET_ALIGNMENT; 2230 break; 2231 case GL_UNIFORM_BUFFER_SIZE: // indexed[n] 64-bit integer, initially 0 2232 UNIMPLEMENTED(); 2233 *params = 0; 2234 break; 2235 case GL_UNIFORM_BUFFER_START: // indexed[n] 64-bit integer, initially 0 2236 UNIMPLEMENTED(); 2237 *params = 0; 2238 break; 2239 case GL_UNPACK_IMAGE_HEIGHT: // integer, initially 0 2240 *params = mState.unpackInfo.imageHeight; 2241 break; 2242 case GL_UNPACK_ROW_LENGTH: // integer, initially 0 2243 *params = mState.unpackInfo.rowLength; 2244 break; 2245 case GL_UNPACK_SKIP_IMAGES: // integer, initially 0 2246 *params = mState.unpackInfo.skipImages; 2247 break; 2248 case GL_UNPACK_SKIP_PIXELS: // integer, initially 0 2249 *params = mState.unpackInfo.skipPixels; 2250 break; 2251 case GL_UNPACK_SKIP_ROWS: // integer, initially 0 2252 *params = mState.unpackInfo.skipRows; 2253 break; 2254 case GL_VERTEX_ARRAY_BINDING: // GLint, initially 0 2255 *params = getCurrentVertexArray()->name; 2256 break; 2257 default: 2258 return false; 2259 } 2260 2261 return true; 2262} 2263 2264template bool Context::getTransformFeedbackiv<GLint>(GLuint xfb, GLenum pname, GLint *param) const; 2265template bool Context::getTransformFeedbackiv<GLint64>(GLuint xfb, GLenum pname, GLint64 *param) const; 2266 2267template<typename T> bool Context::getTransformFeedbackiv(GLuint xfb, GLenum pname, T *param) const 2268{ 2269 UNIMPLEMENTED(); 2270 2271 TransformFeedback* transformFeedback = getTransformFeedback(mState.transformFeedback); 2272 if(!transformFeedback) 2273 { 2274 return false; 2275 } 2276 2277 switch(pname) 2278 { 2279 case GL_TRANSFORM_FEEDBACK_BINDING: // GLint, initially 0 2280 *param = 0; 2281 break; 2282 case GL_TRANSFORM_FEEDBACK_ACTIVE: // boolean, initially GL_FALSE 2283 *param = transformFeedback->isActive(); 2284 break; 2285 case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: // name, initially 0 2286 *param = transformFeedback->name; 2287 break; 2288 case GL_TRANSFORM_FEEDBACK_PAUSED: // boolean, initially GL_FALSE 2289 *param = transformFeedback->isPaused(); 2290 break; 2291 case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE: // indexed[n] 64-bit integer, initially 0 2292 if(transformFeedback->getGenericBuffer()) 2293 { 2294 *param = transformFeedback->getGenericBuffer()->size(); 2295 break; 2296 } 2297 else return false; 2298 case GL_TRANSFORM_FEEDBACK_BUFFER_START: // indexed[n] 64-bit integer, initially 0 2299 *param = 0; 2300 break; 2301 default: 2302 return false; 2303 } 2304 2305 return true; 2306} 2307 2308bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams) const 2309{ 2310 // Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation 2311 // is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due 2312 // to the fact that it is stored internally as a float, and so would require conversion 2313 // if returned from Context::getIntegerv. Since this conversion is already implemented 2314 // in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we 2315 // place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling 2316 // application. 2317 switch (pname) 2318 { 2319 case GL_COMPRESSED_TEXTURE_FORMATS: 2320 { 2321 *type = GL_INT; 2322 *numParams = NUM_COMPRESSED_TEXTURE_FORMATS; 2323 } 2324 break; 2325 case GL_SHADER_BINARY_FORMATS: 2326 { 2327 *type = GL_INT; 2328 *numParams = 0; 2329 } 2330 break; 2331 case GL_MAX_VERTEX_ATTRIBS: 2332 case GL_MAX_VERTEX_UNIFORM_VECTORS: 2333 case GL_MAX_VARYING_VECTORS: 2334 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: 2335 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: 2336 case GL_MAX_TEXTURE_IMAGE_UNITS: 2337 case GL_MAX_FRAGMENT_UNIFORM_VECTORS: 2338 case GL_MAX_RENDERBUFFER_SIZE: 2339 case GL_NUM_SHADER_BINARY_FORMATS: 2340 case GL_NUM_COMPRESSED_TEXTURE_FORMATS: 2341 case GL_ARRAY_BUFFER_BINDING: 2342 case GL_FRAMEBUFFER_BINDING: 2343 case GL_RENDERBUFFER_BINDING: 2344 case GL_CURRENT_PROGRAM: 2345 case GL_PACK_ALIGNMENT: 2346 case GL_UNPACK_ALIGNMENT: 2347 case GL_GENERATE_MIPMAP_HINT: 2348 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: 2349 case GL_RED_BITS: 2350 case GL_GREEN_BITS: 2351 case GL_BLUE_BITS: 2352 case GL_ALPHA_BITS: 2353 case GL_DEPTH_BITS: 2354 case GL_STENCIL_BITS: 2355 case GL_ELEMENT_ARRAY_BUFFER_BINDING: 2356 case GL_CULL_FACE_MODE: 2357 case GL_FRONT_FACE: 2358 case GL_ACTIVE_TEXTURE: 2359 case GL_STENCIL_FUNC: 2360 case GL_STENCIL_VALUE_MASK: 2361 case GL_STENCIL_REF: 2362 case GL_STENCIL_FAIL: 2363 case GL_STENCIL_PASS_DEPTH_FAIL: 2364 case GL_STENCIL_PASS_DEPTH_PASS: 2365 case GL_STENCIL_BACK_FUNC: 2366 case GL_STENCIL_BACK_VALUE_MASK: 2367 case GL_STENCIL_BACK_REF: 2368 case GL_STENCIL_BACK_FAIL: 2369 case GL_STENCIL_BACK_PASS_DEPTH_FAIL: 2370 case GL_STENCIL_BACK_PASS_DEPTH_PASS: 2371 case GL_DEPTH_FUNC: 2372 case GL_BLEND_SRC_RGB: 2373 case GL_BLEND_SRC_ALPHA: 2374 case GL_BLEND_DST_RGB: 2375 case GL_BLEND_DST_ALPHA: 2376 case GL_BLEND_EQUATION_RGB: 2377 case GL_BLEND_EQUATION_ALPHA: 2378 case GL_STENCIL_WRITEMASK: 2379 case GL_STENCIL_BACK_WRITEMASK: 2380 case GL_STENCIL_CLEAR_VALUE: 2381 case GL_SUBPIXEL_BITS: 2382 case GL_MAX_TEXTURE_SIZE: 2383 case GL_MAX_CUBE_MAP_TEXTURE_SIZE: 2384 case GL_SAMPLE_BUFFERS: 2385 case GL_SAMPLES: 2386 case GL_IMPLEMENTATION_COLOR_READ_TYPE: 2387 case GL_IMPLEMENTATION_COLOR_READ_FORMAT: 2388 case GL_TEXTURE_BINDING_2D: 2389 case GL_TEXTURE_BINDING_CUBE_MAP: 2390 case GL_TEXTURE_BINDING_EXTERNAL_OES: 2391 case GL_TEXTURE_BINDING_3D_OES: 2392 case GL_COPY_READ_BUFFER_BINDING: 2393 case GL_COPY_WRITE_BUFFER_BINDING: 2394 case GL_DRAW_BUFFER0: 2395 case GL_DRAW_BUFFER1: 2396 case GL_DRAW_BUFFER2: 2397 case GL_DRAW_BUFFER3: 2398 case GL_DRAW_BUFFER4: 2399 case GL_DRAW_BUFFER5: 2400 case GL_DRAW_BUFFER6: 2401 case GL_DRAW_BUFFER7: 2402 case GL_DRAW_BUFFER8: 2403 case GL_DRAW_BUFFER9: 2404 case GL_DRAW_BUFFER10: 2405 case GL_DRAW_BUFFER11: 2406 case GL_DRAW_BUFFER12: 2407 case GL_DRAW_BUFFER13: 2408 case GL_DRAW_BUFFER14: 2409 case GL_DRAW_BUFFER15: 2410 case GL_MAJOR_VERSION: 2411 case GL_MAX_3D_TEXTURE_SIZE: 2412 case GL_MAX_ARRAY_TEXTURE_LAYERS: 2413 case GL_MAX_COLOR_ATTACHMENTS: 2414 case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS: 2415 case GL_MAX_COMBINED_UNIFORM_BLOCKS: 2416 case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS: 2417 case GL_MAX_DRAW_BUFFERS: 2418 case GL_MAX_ELEMENT_INDEX: 2419 case GL_MAX_ELEMENTS_INDICES: 2420 case GL_MAX_ELEMENTS_VERTICES: 2421 case GL_MAX_FRAGMENT_INPUT_COMPONENTS: 2422 case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: 2423 case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: 2424 case GL_MAX_PROGRAM_TEXEL_OFFSET: 2425 case GL_MAX_SERVER_WAIT_TIMEOUT: 2426 case GL_MAX_TEXTURE_LOD_BIAS: 2427 case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: 2428 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: 2429 case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: 2430 case GL_MAX_UNIFORM_BLOCK_SIZE: 2431 case GL_MAX_UNIFORM_BUFFER_BINDINGS: 2432 case GL_MAX_VARYING_COMPONENTS: 2433 case GL_MAX_VERTEX_OUTPUT_COMPONENTS: 2434 case GL_MAX_VERTEX_UNIFORM_BLOCKS: 2435 case GL_MAX_VERTEX_UNIFORM_COMPONENTS: 2436 case GL_MIN_PROGRAM_TEXEL_OFFSET: 2437 case GL_MINOR_VERSION: 2438 case GL_NUM_EXTENSIONS: 2439 case GL_NUM_PROGRAM_BINARY_FORMATS: 2440 case GL_PACK_ROW_LENGTH: 2441 case GL_PACK_SKIP_PIXELS: 2442 case GL_PACK_SKIP_ROWS: 2443 case GL_PIXEL_PACK_BUFFER_BINDING: 2444 case GL_PIXEL_UNPACK_BUFFER_BINDING: 2445 case GL_PROGRAM_BINARY_FORMATS: 2446 case GL_READ_BUFFER: 2447 case GL_SAMPLER_BINDING: 2448 case GL_TEXTURE_BINDING_2D_ARRAY: 2449 case GL_UNIFORM_BUFFER_BINDING: 2450 case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: 2451 case GL_UNIFORM_BUFFER_SIZE: 2452 case GL_UNIFORM_BUFFER_START: 2453 case GL_UNPACK_IMAGE_HEIGHT: 2454 case GL_UNPACK_ROW_LENGTH: 2455 case GL_UNPACK_SKIP_IMAGES: 2456 case GL_UNPACK_SKIP_PIXELS: 2457 case GL_UNPACK_SKIP_ROWS: 2458 case GL_VERTEX_ARRAY_BINDING: 2459 { 2460 *type = GL_INT; 2461 *numParams = 1; 2462 } 2463 break; 2464 case GL_MAX_SAMPLES_ANGLE: 2465 { 2466 *type = GL_INT; 2467 *numParams = 1; 2468 } 2469 break; 2470 case GL_MAX_VIEWPORT_DIMS: 2471 { 2472 *type = GL_INT; 2473 *numParams = 2; 2474 } 2475 break; 2476 case GL_VIEWPORT: 2477 case GL_SCISSOR_BOX: 2478 { 2479 *type = GL_INT; 2480 *numParams = 4; 2481 } 2482 break; 2483 case GL_SHADER_COMPILER: 2484 case GL_SAMPLE_COVERAGE_INVERT: 2485 case GL_DEPTH_WRITEMASK: 2486 case GL_CULL_FACE: // CULL_FACE through DITHER are natural to IsEnabled, 2487 case GL_POLYGON_OFFSET_FILL: // but can be retrieved through the Get{Type}v queries. 2488 case GL_SAMPLE_ALPHA_TO_COVERAGE: // For this purpose, they are treated here as bool-natural 2489 case GL_SAMPLE_COVERAGE: 2490 case GL_SCISSOR_TEST: 2491 case GL_STENCIL_TEST: 2492 case GL_DEPTH_TEST: 2493 case GL_BLEND: 2494 case GL_DITHER: 2495 case GL_PRIMITIVE_RESTART_FIXED_INDEX: 2496 case GL_RASTERIZER_DISCARD: 2497 { 2498 *type = GL_BOOL; 2499 *numParams = 1; 2500 } 2501 break; 2502 case GL_COLOR_WRITEMASK: 2503 { 2504 *type = GL_BOOL; 2505 *numParams = 4; 2506 } 2507 break; 2508 case GL_POLYGON_OFFSET_FACTOR: 2509 case GL_POLYGON_OFFSET_UNITS: 2510 case GL_SAMPLE_COVERAGE_VALUE: 2511 case GL_DEPTH_CLEAR_VALUE: 2512 case GL_LINE_WIDTH: 2513 { 2514 *type = GL_FLOAT; 2515 *numParams = 1; 2516 } 2517 break; 2518 case GL_ALIASED_LINE_WIDTH_RANGE: 2519 case GL_ALIASED_POINT_SIZE_RANGE: 2520 case GL_DEPTH_RANGE: 2521 { 2522 *type = GL_FLOAT; 2523 *numParams = 2; 2524 } 2525 break; 2526 case GL_COLOR_CLEAR_VALUE: 2527 case GL_BLEND_COLOR: 2528 { 2529 *type = GL_FLOAT; 2530 *numParams = 4; 2531 } 2532 break; 2533 case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT: 2534 *type = GL_FLOAT; 2535 *numParams = 1; 2536 break; 2537 default: 2538 return false; 2539 } 2540 2541 return true; 2542} 2543 2544void Context::applyScissor(int width, int height) 2545{ 2546 if(mState.scissorTest) 2547 { 2548 sw::Rect scissor = { mState.scissorX, mState.scissorY, mState.scissorX + mState.scissorWidth, mState.scissorY + mState.scissorHeight }; 2549 scissor.clip(0, 0, width, height); 2550 2551 device->setScissorRect(scissor); 2552 device->setScissorEnable(true); 2553 } 2554 else 2555 { 2556 device->setScissorEnable(false); 2557 } 2558} 2559 2560egl::Image *Context::getScissoredImage(GLint drawbuffer, int &x0, int &y0, int &width, int &height, bool depthStencil) 2561{ 2562 Framebuffer* framebuffer = getFramebuffer(drawbuffer); 2563 egl::Image* image = depthStencil ? framebuffer->getDepthStencil() : framebuffer->getRenderTarget(0); 2564 2565 applyScissor(image->getWidth(), image->getHeight()); 2566 2567 device->getScissoredRegion(image, x0, y0, width, height); 2568 2569 return image; 2570} 2571 2572// Applies the render target surface, depth stencil surface, viewport rectangle and scissor rectangle 2573bool Context::applyRenderTarget() 2574{ 2575 Framebuffer *framebuffer = getDrawFramebuffer(); 2576 int width, height, samples; 2577 2578 if(!framebuffer || framebuffer->completeness(width, height, samples) != GL_FRAMEBUFFER_COMPLETE) 2579 { 2580 return error(GL_INVALID_FRAMEBUFFER_OPERATION, false); 2581 } 2582 2583 egl::Image *renderTarget = framebuffer->getRenderTarget(0); 2584 device->setRenderTarget(renderTarget); 2585 if(renderTarget) renderTarget->release(); 2586 2587 egl::Image *depthStencil = framebuffer->getDepthStencil(); 2588 device->setDepthStencilSurface(depthStencil); 2589 if(depthStencil) depthStencil->release(); 2590 2591 Viewport viewport; 2592 float zNear = clamp01(mState.zNear); 2593 float zFar = clamp01(mState.zFar); 2594 2595 viewport.x0 = mState.viewportX; 2596 viewport.y0 = mState.viewportY; 2597 viewport.width = mState.viewportWidth; 2598 viewport.height = mState.viewportHeight; 2599 viewport.minZ = zNear; 2600 viewport.maxZ = zFar; 2601 2602 device->setViewport(viewport); 2603 2604 applyScissor(width, height); 2605 2606 Program *program = getCurrentProgram(); 2607 2608 if(program) 2609 { 2610 GLfloat nearFarDiff[3] = {zNear, zFar, zFar - zNear}; 2611 program->setUniform1fv(program->getUniformLocation("gl_DepthRange.near"), 1, &nearFarDiff[0]); 2612 program->setUniform1fv(program->getUniformLocation("gl_DepthRange.far"), 1, &nearFarDiff[1]); 2613 program->setUniform1fv(program->getUniformLocation("gl_DepthRange.diff"), 1, &nearFarDiff[2]); 2614 } 2615 2616 return true; 2617} 2618 2619// Applies the fixed-function state (culling, depth test, alpha blending, stenciling, etc) 2620void Context::applyState(GLenum drawMode) 2621{ 2622 Framebuffer *framebuffer = getDrawFramebuffer(); 2623 2624 if(mState.cullFace) 2625 { 2626 device->setCullMode(es2sw::ConvertCullMode(mState.cullMode, mState.frontFace)); 2627 } 2628 else 2629 { 2630 device->setCullMode(sw::CULL_NONE); 2631 } 2632 2633 if(mDepthStateDirty) 2634 { 2635 if(mState.depthTest) 2636 { 2637 device->setDepthBufferEnable(true); 2638 device->setDepthCompare(es2sw::ConvertDepthComparison(mState.depthFunc)); 2639 } 2640 else 2641 { 2642 device->setDepthBufferEnable(false); 2643 } 2644 2645 mDepthStateDirty = false; 2646 } 2647 2648 if(mBlendStateDirty) 2649 { 2650 if(mState.blend) 2651 { 2652 device->setAlphaBlendEnable(true); 2653 device->setSeparateAlphaBlendEnable(true); 2654 2655 device->setBlendConstant(es2sw::ConvertColor(mState.blendColor)); 2656 2657 device->setSourceBlendFactor(es2sw::ConvertBlendFunc(mState.sourceBlendRGB)); 2658 device->setDestBlendFactor(es2sw::ConvertBlendFunc(mState.destBlendRGB)); 2659 device->setBlendOperation(es2sw::ConvertBlendOp(mState.blendEquationRGB)); 2660 2661 device->setSourceBlendFactorAlpha(es2sw::ConvertBlendFunc(mState.sourceBlendAlpha)); 2662 device->setDestBlendFactorAlpha(es2sw::ConvertBlendFunc(mState.destBlendAlpha)); 2663 device->setBlendOperationAlpha(es2sw::ConvertBlendOp(mState.blendEquationAlpha)); 2664 } 2665 else 2666 { 2667 device->setAlphaBlendEnable(false); 2668 } 2669 2670 mBlendStateDirty = false; 2671 } 2672 2673 if(mStencilStateDirty || mFrontFaceDirty) 2674 { 2675 if(mState.stencilTest && framebuffer->hasStencil()) 2676 { 2677 device->setStencilEnable(true); 2678 device->setTwoSidedStencil(true); 2679 2680 // get the maximum size of the stencil ref 2681 Renderbuffer *stencilbuffer = framebuffer->getStencilbuffer(); 2682 GLuint maxStencil = (1 << stencilbuffer->getStencilSize()) - 1; 2683 2684 if(mState.frontFace == GL_CCW) 2685 { 2686 device->setStencilWriteMask(mState.stencilWritemask); 2687 device->setStencilCompare(es2sw::ConvertStencilComparison(mState.stencilFunc)); 2688 2689 device->setStencilReference((mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil); 2690 device->setStencilMask(mState.stencilMask); 2691 2692 device->setStencilFailOperation(es2sw::ConvertStencilOp(mState.stencilFail)); 2693 device->setStencilZFailOperation(es2sw::ConvertStencilOp(mState.stencilPassDepthFail)); 2694 device->setStencilPassOperation(es2sw::ConvertStencilOp(mState.stencilPassDepthPass)); 2695 2696 device->setStencilWriteMaskCCW(mState.stencilBackWritemask); 2697 device->setStencilCompareCCW(es2sw::ConvertStencilComparison(mState.stencilBackFunc)); 2698 2699 device->setStencilReferenceCCW((mState.stencilBackRef < (GLint)maxStencil) ? mState.stencilBackRef : maxStencil); 2700 device->setStencilMaskCCW(mState.stencilBackMask); 2701 2702 device->setStencilFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilBackFail)); 2703 device->setStencilZFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilBackPassDepthFail)); 2704 device->setStencilPassOperationCCW(es2sw::ConvertStencilOp(mState.stencilBackPassDepthPass)); 2705 } 2706 else 2707 { 2708 device->setStencilWriteMaskCCW(mState.stencilWritemask); 2709 device->setStencilCompareCCW(es2sw::ConvertStencilComparison(mState.stencilFunc)); 2710 2711 device->setStencilReferenceCCW((mState.stencilRef < (GLint)maxStencil) ? mState.stencilRef : maxStencil); 2712 device->setStencilMaskCCW(mState.stencilMask); 2713 2714 device->setStencilFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilFail)); 2715 device->setStencilZFailOperationCCW(es2sw::ConvertStencilOp(mState.stencilPassDepthFail)); 2716 device->setStencilPassOperationCCW(es2sw::ConvertStencilOp(mState.stencilPassDepthPass)); 2717 2718 device->setStencilWriteMask(mState.stencilBackWritemask); 2719 device->setStencilCompare(es2sw::ConvertStencilComparison(mState.stencilBackFunc)); 2720 2721 device->setStencilReference((mState.stencilBackRef < (GLint)maxStencil) ? mState.stencilBackRef : maxStencil); 2722 device->setStencilMask(mState.stencilBackMask); 2723 2724 device->setStencilFailOperation(es2sw::ConvertStencilOp(mState.stencilBackFail)); 2725 device->setStencilZFailOperation(es2sw::ConvertStencilOp(mState.stencilBackPassDepthFail)); 2726 device->setStencilPassOperation(es2sw::ConvertStencilOp(mState.stencilBackPassDepthPass)); 2727 } 2728 } 2729 else 2730 { 2731 device->setStencilEnable(false); 2732 } 2733 2734 mStencilStateDirty = false; 2735 mFrontFaceDirty = false; 2736 } 2737 2738 if(mMaskStateDirty) 2739 { 2740 device->setColorWriteMask(0, es2sw::ConvertColorMask(mState.colorMaskRed, mState.colorMaskGreen, mState.colorMaskBlue, mState.colorMaskAlpha)); 2741 device->setDepthWriteEnable(mState.depthMask); 2742 2743 mMaskStateDirty = false; 2744 } 2745 2746 if(mPolygonOffsetStateDirty) 2747 { 2748 if(mState.polygonOffsetFill) 2749 { 2750 Renderbuffer *depthbuffer = framebuffer->getDepthbuffer(); 2751 if(depthbuffer) 2752 { 2753 device->setSlopeDepthBias(mState.polygonOffsetFactor); 2754 float depthBias = ldexp(mState.polygonOffsetUnits, -(int)(depthbuffer->getDepthSize())); 2755 device->setDepthBias(depthBias); 2756 } 2757 } 2758 else 2759 { 2760 device->setSlopeDepthBias(0); 2761 device->setDepthBias(0); 2762 } 2763 2764 mPolygonOffsetStateDirty = false; 2765 } 2766 2767 if(mSampleStateDirty) 2768 { 2769 if(mState.sampleAlphaToCoverage) 2770 { 2771 device->setTransparencyAntialiasing(sw::TRANSPARENCY_ALPHA_TO_COVERAGE); 2772 } 2773 else 2774 { 2775 device->setTransparencyAntialiasing(sw::TRANSPARENCY_NONE); 2776 } 2777 2778 if(mState.sampleCoverage) 2779 { 2780 unsigned int mask = 0; 2781 if(mState.sampleCoverageValue != 0) 2782 { 2783 int width, height, samples; 2784 framebuffer->completeness(width, height, samples); 2785 2786 float threshold = 0.5f; 2787 2788 for(int i = 0; i < samples; i++) 2789 { 2790 mask <<= 1; 2791 2792 if((i + 1) * mState.sampleCoverageValue >= threshold) 2793 { 2794 threshold += 1.0f; 2795 mask |= 1; 2796 } 2797 } 2798 } 2799 2800 if(mState.sampleCoverageInvert) 2801 { 2802 mask = ~mask; 2803 } 2804 2805 device->setMultiSampleMask(mask); 2806 } 2807 else 2808 { 2809 device->setMultiSampleMask(0xFFFFFFFF); 2810 } 2811 2812 mSampleStateDirty = false; 2813 } 2814 2815 if(mDitherStateDirty) 2816 { 2817 // UNIMPLEMENTED(); // FIXME 2818 2819 mDitherStateDirty = false; 2820 } 2821} 2822 2823GLenum Context::applyVertexBuffer(GLint base, GLint first, GLsizei count, GLsizei instanceId) 2824{ 2825 TranslatedAttribute attributes[MAX_VERTEX_ATTRIBS]; 2826 2827 GLenum err = mVertexDataManager->prepareVertexData(first, count, attributes, instanceId); 2828 if(err != GL_NO_ERROR) 2829 { 2830 return err; 2831 } 2832 2833 Program *program = getCurrentProgram(); 2834 2835 device->resetInputStreams(false); 2836 2837 for(int i = 0; i < MAX_VERTEX_ATTRIBS; i++) 2838 { 2839 if(program->getAttributeStream(i) == -1) 2840 { 2841 continue; 2842 } 2843 2844 sw::Resource *resource = attributes[i].vertexBuffer; 2845 const void *buffer = (char*)resource->data() + attributes[i].offset; 2846 2847 int stride = attributes[i].stride; 2848 2849 buffer = (char*)buffer + stride * base; 2850 2851 sw::Stream attribute(resource, buffer, stride); 2852 2853 attribute.type = attributes[i].type; 2854 attribute.count = attributes[i].count; 2855 attribute.normalized = attributes[i].normalized; 2856 2857 int stream = program->getAttributeStream(i); 2858 device->setInputStream(stream, attribute); 2859 } 2860 2861 return GL_NO_ERROR; 2862} 2863 2864// Applies the indices and element array bindings 2865GLenum Context::applyIndexBuffer(const void *indices, GLuint start, GLuint end, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo) 2866{ 2867 GLenum err = mIndexDataManager->prepareIndexData(type, start, end, count, getCurrentVertexArray()->getElementArrayBuffer(), indices, indexInfo); 2868 2869 if(err == GL_NO_ERROR) 2870 { 2871 device->setIndexBuffer(indexInfo->indexBuffer); 2872 } 2873 2874 return err; 2875} 2876 2877// Applies the shaders and shader constants 2878void Context::applyShaders() 2879{ 2880 Program *programObject = getCurrentProgram(); 2881 sw::VertexShader *vertexShader = programObject->getVertexShader(); 2882 sw::PixelShader *pixelShader = programObject->getPixelShader(); 2883 2884 device->setVertexShader(vertexShader); 2885 device->setPixelShader(pixelShader); 2886 2887 if(programObject->getSerial() != mAppliedProgramSerial) 2888 { 2889 programObject->dirtyAllUniforms(); 2890 mAppliedProgramSerial = programObject->getSerial(); 2891 } 2892 2893 programObject->applyUniforms(); 2894} 2895 2896void Context::applyTextures() 2897{ 2898 applyTextures(sw::SAMPLER_PIXEL); 2899 applyTextures(sw::SAMPLER_VERTEX); 2900} 2901 2902void Context::applyTextures(sw::SamplerType samplerType) 2903{ 2904 Program *programObject = getCurrentProgram(); 2905 2906 int samplerCount = (samplerType == sw::SAMPLER_PIXEL) ? MAX_TEXTURE_IMAGE_UNITS : MAX_VERTEX_TEXTURE_IMAGE_UNITS; // Range of samplers of given sampler type 2907 2908 for(int samplerIndex = 0; samplerIndex < samplerCount; samplerIndex++) 2909 { 2910 int textureUnit = programObject->getSamplerMapping(samplerType, samplerIndex); // OpenGL texture image unit index 2911 2912 if(textureUnit != -1) 2913 { 2914 TextureType textureType = programObject->getSamplerTextureType(samplerType, samplerIndex); 2915 2916 Texture *texture = getSamplerTexture(textureUnit, textureType); 2917 2918 if(texture->isSamplerComplete()) 2919 { 2920 GLenum wrapS = texture->getWrapS(); 2921 GLenum wrapT = texture->getWrapT(); 2922 GLenum wrapR = texture->getWrapR(); 2923 GLenum texFilter = texture->getMinFilter(); 2924 GLenum magFilter = texture->getMagFilter(); 2925 GLfloat maxAnisotropy = texture->getMaxAnisotropy(); 2926 2927 device->setAddressingModeU(samplerType, samplerIndex, es2sw::ConvertTextureWrap(wrapS)); 2928 device->setAddressingModeV(samplerType, samplerIndex, es2sw::ConvertTextureWrap(wrapT)); 2929 device->setAddressingModeW(samplerType, samplerIndex, es2sw::ConvertTextureWrap(wrapR)); 2930 2931 sw::FilterType minFilter; 2932 sw::MipmapType mipFilter; 2933 es2sw::ConvertMinFilter(texFilter, &minFilter, &mipFilter, maxAnisotropy); 2934 // ASSERT(minFilter == es2sw::ConvertMagFilter(magFilter)); 2935 2936 device->setTextureFilter(samplerType, samplerIndex, minFilter); 2937 // device->setTextureFilter(samplerType, samplerIndex, es2sw::ConvertMagFilter(magFilter)); 2938 device->setMipmapFilter(samplerType, samplerIndex, mipFilter); 2939 device->setMaxAnisotropy(samplerType, samplerIndex, maxAnisotropy); 2940 2941 applyTexture(samplerType, samplerIndex, texture); 2942 } 2943 else 2944 { 2945 applyTexture(samplerType, samplerIndex, 0); 2946 } 2947 } 2948 else 2949 { 2950 applyTexture(samplerType, samplerIndex, NULL); 2951 } 2952 } 2953} 2954 2955void Context::applyTexture(sw::SamplerType type, int index, Texture *baseTexture) 2956{ 2957 Program *program = getCurrentProgram(); 2958 int sampler = (type == sw::SAMPLER_PIXEL) ? index : 16 + index; 2959 bool textureUsed = false; 2960 2961 if(type == sw::SAMPLER_PIXEL) 2962 { 2963 textureUsed = program->getPixelShader()->usesSampler(index); 2964 } 2965 else if(type == sw::SAMPLER_VERTEX) 2966 { 2967 textureUsed = program->getVertexShader()->usesSampler(index); 2968 } 2969 else UNREACHABLE(); 2970 2971 sw::Resource *resource = 0; 2972 2973 if(baseTexture && textureUsed) 2974 { 2975 resource = baseTexture->getResource(); 2976 } 2977 2978 device->setTextureResource(sampler, resource); 2979 2980 if(baseTexture && textureUsed) 2981 { 2982 int levelCount = baseTexture->getLevelCount(); 2983 2984 if(baseTexture->getTarget() == GL_TEXTURE_2D || baseTexture->getTarget() == GL_TEXTURE_EXTERNAL_OES) 2985 { 2986 Texture2D *texture = static_cast<Texture2D*>(baseTexture); 2987 2988 for(int mipmapLevel = 0; mipmapLevel < MIPMAP_LEVELS; mipmapLevel++) 2989 { 2990 int surfaceLevel = mipmapLevel; 2991 2992 if(surfaceLevel < 0) 2993 { 2994 surfaceLevel = 0; 2995 } 2996 else if(surfaceLevel >= levelCount) 2997 { 2998 surfaceLevel = levelCount - 1; 2999 } 3000 3001 egl::Image *surface = texture->getImage(surfaceLevel); 3002 device->setTextureLevel(sampler, 0, mipmapLevel, surface, sw::TEXTURE_2D); 3003 } 3004 } 3005 else if(baseTexture->getTarget() == GL_TEXTURE_3D_OES) 3006 { 3007 Texture3D *texture = static_cast<Texture3D*>(baseTexture); 3008 3009 for(int mipmapLevel = 0; mipmapLevel < MIPMAP_LEVELS; mipmapLevel++) 3010 { 3011 int surfaceLevel = mipmapLevel; 3012 3013 if(surfaceLevel < 0) 3014 { 3015 surfaceLevel = 0; 3016 } 3017 else if(surfaceLevel >= levelCount) 3018 { 3019 surfaceLevel = levelCount - 1; 3020 } 3021 3022 egl::Image *surface = texture->getImage(surfaceLevel); 3023 device->setTextureLevel(sampler, 0, mipmapLevel, surface, sw::TEXTURE_3D); 3024 } 3025 } 3026 else if(baseTexture->getTarget() == GL_TEXTURE_2D_ARRAY) 3027 { 3028 Texture2DArray *texture = static_cast<Texture2DArray*>(baseTexture); 3029 3030 for(int mipmapLevel = 0; mipmapLevel < MIPMAP_LEVELS; mipmapLevel++) 3031 { 3032 int surfaceLevel = mipmapLevel; 3033 3034 if(surfaceLevel < 0) 3035 { 3036 surfaceLevel = 0; 3037 } 3038 else if(surfaceLevel >= levelCount) 3039 { 3040 surfaceLevel = levelCount - 1; 3041 } 3042 3043 egl::Image *surface = texture->getImage(surfaceLevel); 3044 device->setTextureLevel(sampler, 0, mipmapLevel, surface, sw::TEXTURE_2D_ARRAY); 3045 } 3046 } 3047 else if(baseTexture->getTarget() == GL_TEXTURE_CUBE_MAP) 3048 { 3049 for(int face = 0; face < 6; face++) 3050 { 3051 TextureCubeMap *cubeTexture = static_cast<TextureCubeMap*>(baseTexture); 3052 3053 for(int mipmapLevel = 0; mipmapLevel < MIPMAP_LEVELS; mipmapLevel++) 3054 { 3055 int surfaceLevel = mipmapLevel; 3056 3057 if(surfaceLevel < 0) 3058 { 3059 surfaceLevel = 0; 3060 } 3061 else if(surfaceLevel >= levelCount) 3062 { 3063 surfaceLevel = levelCount - 1; 3064 } 3065 3066 egl::Image *surface = cubeTexture->getImage(face, surfaceLevel); 3067 device->setTextureLevel(sampler, face, mipmapLevel, surface, sw::TEXTURE_CUBE); 3068 } 3069 } 3070 } 3071 else UNIMPLEMENTED(); 3072 } 3073 else 3074 { 3075 device->setTextureLevel(sampler, 0, 0, 0, sw::TEXTURE_NULL); 3076 } 3077} 3078 3079void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, 3080 GLenum format, GLenum type, GLsizei *bufSize, void* pixels) 3081{ 3082 Framebuffer *framebuffer = getReadFramebuffer(); 3083 int framebufferWidth, framebufferHeight, framebufferSamples; 3084 3085 if(framebuffer->completeness(framebufferWidth, framebufferHeight, framebufferSamples) != GL_FRAMEBUFFER_COMPLETE) 3086 { 3087 return error(GL_INVALID_FRAMEBUFFER_OPERATION); 3088 } 3089 3090 if(getReadFramebufferName() != 0 && framebufferSamples != 0) 3091 { 3092 return error(GL_INVALID_OPERATION); 3093 } 3094 3095 if(format != GL_RGBA || type != GL_UNSIGNED_BYTE) 3096 { 3097 if(format != framebuffer->getImplementationColorReadFormat() || type != framebuffer->getImplementationColorReadType()) 3098 { 3099 return error(GL_INVALID_OPERATION); 3100 } 3101 } 3102 3103 GLsizei outputPitch = (mState.packRowLength > 0) ? mState.packRowLength : egl::ComputePitch(width, format, type, mState.packAlignment); 3104 3105 // Sized query sanity check 3106 if(bufSize) 3107 { 3108 int requiredSize = outputPitch * height; 3109 if(requiredSize > *bufSize) 3110 { 3111 return error(GL_INVALID_OPERATION); 3112 } 3113 } 3114 3115 egl::Image *renderTarget = framebuffer->getRenderTarget(0); 3116 3117 if(!renderTarget) 3118 { 3119 return error(GL_OUT_OF_MEMORY); 3120 } 3121 3122 x += mState.packSkipPixels; 3123 y += mState.packSkipRows; 3124 sw::Rect rect = {x, y, x + width, y + height}; 3125 rect.clip(0, 0, renderTarget->getWidth(), renderTarget->getHeight()); 3126 3127 unsigned char *source = (unsigned char*)renderTarget->lock(rect.x0, rect.y0, sw::LOCK_READONLY); 3128 unsigned char *dest = (unsigned char*)pixels; 3129 int inputPitch = (int)renderTarget->getPitch(); 3130 3131 for(int j = 0; j < rect.y1 - rect.y0; j++) 3132 { 3133 unsigned short *dest16 = (unsigned short*)dest; 3134 unsigned int *dest32 = (unsigned int*)dest; 3135 3136 if(renderTarget->getInternalFormat() == sw::FORMAT_A8B8G8R8 && 3137 format == GL_RGBA && type == GL_UNSIGNED_BYTE) 3138 { 3139 memcpy(dest, source, (rect.x1 - rect.x0) * 4); 3140 } 3141 else if(renderTarget->getInternalFormat() == sw::FORMAT_A8R8G8B8 && 3142 format == GL_RGBA && type == GL_UNSIGNED_BYTE) 3143 { 3144 for(int i = 0; i < rect.x1 - rect.x0; i++) 3145 { 3146 unsigned int argb = *(unsigned int*)(source + 4 * i); 3147 3148 dest32[i] = (argb & 0xFF00FF00) | ((argb & 0x000000FF) << 16) | ((argb & 0x00FF0000) >> 16); 3149 } 3150 } 3151 else if(renderTarget->getInternalFormat() == sw::FORMAT_X8R8G8B8 && 3152 format == GL_RGBA && type == GL_UNSIGNED_BYTE) 3153 { 3154 for(int i = 0; i < rect.x1 - rect.x0; i++) 3155 { 3156 unsigned int xrgb = *(unsigned int*)(source + 4 * i); 3157 3158 dest32[i] = (xrgb & 0xFF00FF00) | ((xrgb & 0x000000FF) << 16) | ((xrgb & 0x00FF0000) >> 16) | 0xFF000000; 3159 } 3160 } 3161 else if(renderTarget->getInternalFormat() == sw::FORMAT_X8R8G8B8 && 3162 format == GL_BGRA_EXT && type == GL_UNSIGNED_BYTE) 3163 { 3164 for(int i = 0; i < rect.x1 - rect.x0; i++) 3165 { 3166 unsigned int xrgb = *(unsigned int*)(source + 4 * i); 3167 3168 dest32[i] = xrgb | 0xFF000000; 3169 } 3170 } 3171 else if(renderTarget->getInternalFormat() == sw::FORMAT_A8R8G8B8 && 3172 format == GL_BGRA_EXT && type == GL_UNSIGNED_BYTE) 3173 { 3174 memcpy(dest, source, (rect.x1 - rect.x0) * 4); 3175 } 3176 else if(renderTarget->getInternalFormat() == sw::FORMAT_A16B16G16R16F && 3177 format == GL_RGBA && (type == GL_HALF_FLOAT || type == GL_HALF_FLOAT_OES)) 3178 { 3179 memcpy(dest, source, (rect.x1 - rect.x0) * 8); 3180 } 3181 else if(renderTarget->getInternalFormat() == sw::FORMAT_A32B32G32R32F && 3182 format == GL_RGBA && type == GL_FLOAT) 3183 { 3184 memcpy(dest, source, (rect.x1 - rect.x0) * 16); 3185 } 3186 else if(renderTarget->getInternalFormat() == sw::FORMAT_A1R5G5B5 && 3187 format == GL_BGRA_EXT && type == GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT) 3188 { 3189 memcpy(dest, source, (rect.x1 - rect.x0) * 2); 3190 } 3191 else if(renderTarget->getInternalFormat() == sw::FORMAT_R5G6B5 && 3192 format == 0x80E0 && type == GL_UNSIGNED_SHORT_5_6_5) // GL_BGR_EXT 3193 { 3194 memcpy(dest, source, (rect.x1 - rect.x0) * 2); 3195 } 3196 else 3197 { 3198 for(int i = 0; i < rect.x1 - rect.x0; i++) 3199 { 3200 float r; 3201 float g; 3202 float b; 3203 float a; 3204 3205 switch(renderTarget->getInternalFormat()) 3206 { 3207 case sw::FORMAT_R5G6B5: 3208 { 3209 unsigned short rgb = *(unsigned short*)(source + 2 * i); 3210 3211 a = 1.0f; 3212 b = (rgb & 0x001F) * (1.0f / 0x001F); 3213 g = (rgb & 0x07E0) * (1.0f / 0x07E0); 3214 r = (rgb & 0xF800) * (1.0f / 0xF800); 3215 } 3216 break; 3217 case sw::FORMAT_A1R5G5B5: 3218 { 3219 unsigned short argb = *(unsigned short*)(source + 2 * i); 3220 3221 a = (argb & 0x8000) ? 1.0f : 0.0f; 3222 b = (argb & 0x001F) * (1.0f / 0x001F); 3223 g = (argb & 0x03E0) * (1.0f / 0x03E0); 3224 r = (argb & 0x7C00) * (1.0f / 0x7C00); 3225 } 3226 break; 3227 case sw::FORMAT_A8R8G8B8: 3228 { 3229 unsigned int argb = *(unsigned int*)(source + 4 * i); 3230 3231 a = (argb & 0xFF000000) * (1.0f / 0xFF000000); 3232 b = (argb & 0x000000FF) * (1.0f / 0x000000FF); 3233 g = (argb & 0x0000FF00) * (1.0f / 0x0000FF00); 3234 r = (argb & 0x00FF0000) * (1.0f / 0x00FF0000); 3235 } 3236 break; 3237 case sw::FORMAT_A8B8G8R8: 3238 { 3239 unsigned int abgr = *(unsigned int*)(source + 4 * i); 3240 3241 a = (abgr & 0xFF000000) * (1.0f / 0xFF000000); 3242 b = (abgr & 0x00FF0000) * (1.0f / 0x00FF0000); 3243 g = (abgr & 0x0000FF00) * (1.0f / 0x0000FF00); 3244 r = (abgr & 0x000000FF) * (1.0f / 0x000000FF); 3245 } 3246 break; 3247 case sw::FORMAT_X8R8G8B8: 3248 { 3249 unsigned int xrgb = *(unsigned int*)(source + 4 * i); 3250 3251 a = 1.0f; 3252 b = (xrgb & 0x000000FF) * (1.0f / 0x000000FF); 3253 g = (xrgb & 0x0000FF00) * (1.0f / 0x0000FF00); 3254 r = (xrgb & 0x00FF0000) * (1.0f / 0x00FF0000); 3255 } 3256 break; 3257 case sw::FORMAT_X8B8G8R8: 3258 { 3259 unsigned int xbgr = *(unsigned int*)(source + 4 * i); 3260 3261 a = 1.0f; 3262 b = (xbgr & 0x00FF0000) * (1.0f / 0x00FF0000); 3263 g = (xbgr & 0x0000FF00) * (1.0f / 0x0000FF00); 3264 r = (xbgr & 0x000000FF) * (1.0f / 0x000000FF); 3265 } 3266 break; 3267 case sw::FORMAT_A2R10G10B10: 3268 { 3269 unsigned int argb = *(unsigned int*)(source + 4 * i); 3270 3271 a = (argb & 0xC0000000) * (1.0f / 0xC0000000); 3272 b = (argb & 0x000003FF) * (1.0f / 0x000003FF); 3273 g = (argb & 0x000FFC00) * (1.0f / 0x000FFC00); 3274 r = (argb & 0x3FF00000) * (1.0f / 0x3FF00000); 3275 } 3276 break; 3277 case sw::FORMAT_A32B32G32R32F: 3278 { 3279 r = *((float*)(source + 16 * i) + 0); 3280 g = *((float*)(source + 16 * i) + 1); 3281 b = *((float*)(source + 16 * i) + 2); 3282 a = *((float*)(source + 16 * i) + 3); 3283 } 3284 break; 3285 case sw::FORMAT_A16B16G16R16F: 3286 { 3287 r = (float)*((sw::half*)(source + 8 * i) + 0); 3288 g = (float)*((sw::half*)(source + 8 * i) + 1); 3289 b = (float)*((sw::half*)(source + 8 * i) + 2); 3290 a = (float)*((sw::half*)(source + 8 * i) + 3); 3291 } 3292 break; 3293 default: 3294 UNIMPLEMENTED(); // FIXME 3295 UNREACHABLE(); 3296 } 3297 3298 switch(format) 3299 { 3300 case GL_RGBA: 3301 switch(type) 3302 { 3303 case GL_UNSIGNED_BYTE: 3304 dest[4 * i + 0] = (unsigned char)(255 * r + 0.5f); 3305 dest[4 * i + 1] = (unsigned char)(255 * g + 0.5f); 3306 dest[4 * i + 2] = (unsigned char)(255 * b + 0.5f); 3307 dest[4 * i + 3] = (unsigned char)(255 * a + 0.5f); 3308 break; 3309 default: UNREACHABLE(); 3310 } 3311 break; 3312 case GL_BGRA_EXT: 3313 switch(type) 3314 { 3315 case GL_UNSIGNED_BYTE: 3316 dest[4 * i + 0] = (unsigned char)(255 * b + 0.5f); 3317 dest[4 * i + 1] = (unsigned char)(255 * g + 0.5f); 3318 dest[4 * i + 2] = (unsigned char)(255 * r + 0.5f); 3319 dest[4 * i + 3] = (unsigned char)(255 * a + 0.5f); 3320 break; 3321 case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT: 3322 // According to the desktop GL spec in the "Transfer of Pixel Rectangles" section 3323 // this type is packed as follows: 3324 // 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 3325 // -------------------------------------------------------------------------------- 3326 // | 4th | 3rd | 2nd | 1st component | 3327 // -------------------------------------------------------------------------------- 3328 // in the case of BGRA_EXT, B is the first component, G the second, and so forth. 3329 dest16[i] = 3330 ((unsigned short)(15 * a + 0.5f) << 12)| 3331 ((unsigned short)(15 * r + 0.5f) << 8) | 3332 ((unsigned short)(15 * g + 0.5f) << 4) | 3333 ((unsigned short)(15 * b + 0.5f) << 0); 3334 break; 3335 case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT: 3336 // According to the desktop GL spec in the "Transfer of Pixel Rectangles" section 3337 // this type is packed as follows: 3338 // 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 3339 // -------------------------------------------------------------------------------- 3340 // | 4th | 3rd | 2nd | 1st component | 3341 // -------------------------------------------------------------------------------- 3342 // in the case of BGRA_EXT, B is the first component, G the second, and so forth. 3343 dest16[i] = 3344 ((unsigned short)( a + 0.5f) << 15) | 3345 ((unsigned short)(31 * r + 0.5f) << 10) | 3346 ((unsigned short)(31 * g + 0.5f) << 5) | 3347 ((unsigned short)(31 * b + 0.5f) << 0); 3348 break; 3349 default: UNREACHABLE(); 3350 } 3351 break; 3352 case GL_RGB: 3353 switch(type) 3354 { 3355 case GL_UNSIGNED_SHORT_5_6_5: 3356 dest16[i] = 3357 ((unsigned short)(31 * b + 0.5f) << 0) | 3358 ((unsigned short)(63 * g + 0.5f) << 5) | 3359 ((unsigned short)(31 * r + 0.5f) << 11); 3360 break; 3361 default: UNREACHABLE(); 3362 } 3363 break; 3364 default: UNREACHABLE(); 3365 } 3366 } 3367 } 3368 3369 source += inputPitch; 3370 dest += outputPitch; 3371 } 3372 3373 renderTarget->unlock(); 3374 renderTarget->release(); 3375} 3376 3377void Context::clear(GLbitfield mask) 3378{ 3379 Framebuffer *framebuffer = getDrawFramebuffer(); 3380 3381 if(!framebuffer || framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE) 3382 { 3383 return error(GL_INVALID_FRAMEBUFFER_OPERATION); 3384 } 3385 3386 if(!applyRenderTarget()) 3387 { 3388 return; 3389 } 3390 3391 if(mask & GL_COLOR_BUFFER_BIT) 3392 { 3393 unsigned int rgbaMask = getColorMask(); 3394 3395 if(rgbaMask != 0) 3396 { 3397 unsigned int color = (unorm<8>(mState.colorClearValue.alpha) << 24) | 3398 (unorm<8>(mState.colorClearValue.red) << 16) | 3399 (unorm<8>(mState.colorClearValue.green) << 8) | 3400 (unorm<8>(mState.colorClearValue.blue) << 0); 3401 device->clearColor(color, rgbaMask); 3402 } 3403 } 3404 3405 if(mask & GL_DEPTH_BUFFER_BIT) 3406 { 3407 if(mState.depthMask != 0) 3408 { 3409 float depth = clamp01(mState.depthClearValue); 3410 device->clearDepth(depth); 3411 } 3412 } 3413 3414 if(mask & GL_STENCIL_BUFFER_BIT) 3415 { 3416 if(mState.stencilWritemask != 0) 3417 { 3418 int stencil = mState.stencilClearValue & 0x000000FF; 3419 device->clearStencil(stencil, mState.stencilWritemask); 3420 } 3421 } 3422} 3423 3424void Context::clearColorBuffer(GLint drawbuffer, const GLint *value) 3425{ 3426 unsigned int rgbaMask = getColorMask(); 3427 if(device && rgbaMask) 3428 { 3429 int x0(0), y0(0), width(0), height(0); 3430 egl::Image* image = getScissoredImage(drawbuffer, x0, y0, width, height, false); 3431 3432 unsigned int color = (value[0] < 0 ? 0 : (value[0] & 0x7F800000) << 1) | 3433 (value[1] < 0 ? 0 : (value[1] & 0x7F800000) >> 7) | 3434 (value[2] < 0 ? 0 : (value[2] & 0x7F800000) >> 15) | 3435 (value[3] < 0 ? 0 : (value[3] & 0x7F800000) >> 23); 3436 image->clearColorBuffer(color, rgbaMask, x0, y0, width, height); 3437 } 3438} 3439 3440void Context::clearColorBuffer(GLint drawbuffer, const GLuint *value) 3441{ 3442 unsigned int rgbaMask = getColorMask(); 3443 if(device && rgbaMask) 3444 { 3445 int x0(0), y0(0), width(0), height(0); 3446 egl::Image* image = getScissoredImage(drawbuffer, x0, y0, width, height, false); 3447 3448 unsigned int color = (value[0] & 0xFF000000) >> 0 | 3449 (value[1] & 0xFF000000) >> 8 | 3450 (value[2] & 0xFF000000) >> 16 | 3451 (value[3] & 0xFF000000) >> 24; 3452 image->clearColorBuffer(color, rgbaMask, x0, y0, width, height); 3453 } 3454} 3455 3456void Context::clearColorBuffer(GLint drawbuffer, const GLfloat *value) 3457{ 3458 unsigned int rgbaMask = getColorMask(); 3459 if(device && rgbaMask) 3460 { 3461 int x0(0), y0(0), width(0), height(0); 3462 egl::Image* image = getScissoredImage(drawbuffer, x0, y0, width, height, false); 3463 3464 unsigned int color = (unorm<8>(value[0]) << 24) | 3465 (unorm<8>(value[1]) << 16) | 3466 (unorm<8>(value[2]) << 8) | 3467 (unorm<8>(value[3]) << 0); 3468 image->clearColorBuffer(color, rgbaMask, x0, y0, width, height); 3469 } 3470} 3471 3472void Context::clearDepthBuffer(GLint drawbuffer, const GLfloat *value) 3473{ 3474 if(device && mState.depthMask) 3475 { 3476 int x0(0), y0(0), width(0), height(0); 3477 egl::Image* image = getScissoredImage(drawbuffer, x0, y0, width, height, true); 3478 3479 float depth = clamp01(value[0]); 3480 image->clearDepthBuffer(depth, x0, y0, width, height); 3481 } 3482} 3483 3484void Context::clearStencilBuffer(GLint drawbuffer, const GLint *value) 3485{ 3486 if(device && mState.stencilWritemask) 3487 { 3488 int x0(0), y0(0), width(0), height(0); 3489 egl::Image* image = getScissoredImage(drawbuffer, x0, y0, width, height, true); 3490 3491 unsigned char stencil = value[0] < 0 ? 0 : static_cast<unsigned char>(value[0] & 0x000000FF); 3492 image->clearStencilBuffer(stencil, static_cast<unsigned char>(mState.stencilWritemask), x0, y0, width, height); 3493 } 3494} 3495 3496void Context::clearDepthStencilBuffer(GLint drawbuffer, GLfloat depth, GLint stencil) 3497{ 3498 if(device && (mState.depthMask || mState.stencilWritemask)) 3499 { 3500 int x0(0), y0(0), width(0), height(0); 3501 egl::Image* image = getScissoredImage(drawbuffer, x0, y0, width, height, true); 3502 3503 if(mState.stencilWritemask) 3504 { 3505 image->clearStencilBuffer(static_cast<unsigned char>(stencil & 0x000000FF), static_cast<unsigned char>(mState.stencilWritemask), x0, y0, width, height); 3506 } 3507 3508 if(mState.depthMask) 3509 { 3510 image->clearDepthBuffer(clamp01(depth), x0, y0, width, height); 3511 } 3512 } 3513} 3514 3515void Context::drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount) 3516{ 3517 if(!mState.currentProgram) 3518 { 3519 return error(GL_INVALID_OPERATION); 3520 } 3521 3522 PrimitiveType primitiveType; 3523 int primitiveCount; 3524 3525 if(!es2sw::ConvertPrimitiveType(mode, count, primitiveType, primitiveCount)) 3526 return error(GL_INVALID_ENUM); 3527 3528 if(primitiveCount <= 0) 3529 { 3530 return; 3531 } 3532 3533 if(!applyRenderTarget()) 3534 { 3535 return; 3536 } 3537 3538 applyState(mode); 3539 3540 for(int i = 0; i < instanceCount; ++i) 3541 { 3542 device->setInstanceID(i); 3543 3544 GLenum err = applyVertexBuffer(0, first, count, i); 3545 if(err != GL_NO_ERROR) 3546 { 3547 return error(err); 3548 } 3549 3550 applyShaders(); 3551 applyTextures(); 3552 3553 if(!getCurrentProgram()->validateSamplers(false)) 3554 { 3555 return error(GL_INVALID_OPERATION); 3556 } 3557 3558 if(!cullSkipsDraw(mode)) 3559 { 3560 device->drawPrimitive(primitiveType, primitiveCount); 3561 } 3562 } 3563} 3564 3565void Context::drawElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLsizei instanceCount) 3566{ 3567 if(!mState.currentProgram) 3568 { 3569 return error(GL_INVALID_OPERATION); 3570 } 3571 3572 if(!indices && !getCurrentVertexArray()->getElementArrayBuffer()) 3573 { 3574 return error(GL_INVALID_OPERATION); 3575 } 3576 3577 PrimitiveType primitiveType; 3578 int primitiveCount; 3579 3580 if(!es2sw::ConvertPrimitiveType(mode, count, primitiveType, primitiveCount)) 3581 return error(GL_INVALID_ENUM); 3582 3583 if(primitiveCount <= 0) 3584 { 3585 return; 3586 } 3587 3588 if(!applyRenderTarget()) 3589 { 3590 return; 3591 } 3592 3593 applyState(mode); 3594 3595 for(int i = 0; i < instanceCount; ++i) 3596 { 3597 device->setInstanceID(i); 3598 3599 TranslatedIndexData indexInfo; 3600 GLenum err = applyIndexBuffer(indices, start, end, count, mode, type, &indexInfo); 3601 if(err != GL_NO_ERROR) 3602 { 3603 return error(err); 3604 } 3605 3606 GLsizei vertexCount = indexInfo.maxIndex - indexInfo.minIndex + 1; 3607 err = applyVertexBuffer(-(int)indexInfo.minIndex, indexInfo.minIndex, vertexCount, i); 3608 if(err != GL_NO_ERROR) 3609 { 3610 return error(err); 3611 } 3612 3613 applyShaders(); 3614 applyTextures(); 3615 3616 if(!getCurrentProgram()->validateSamplers(false)) 3617 { 3618 return error(GL_INVALID_OPERATION); 3619 } 3620 3621 if(!cullSkipsDraw(mode)) 3622 { 3623 device->drawIndexedPrimitive(primitiveType, indexInfo.indexOffset, primitiveCount, IndexDataManager::typeSize(type)); 3624 } 3625 } 3626} 3627 3628void Context::finish() 3629{ 3630 device->finish(); 3631} 3632 3633void Context::flush() 3634{ 3635 // We don't queue anything without processing it as fast as possible 3636} 3637 3638void Context::recordInvalidEnum() 3639{ 3640 mInvalidEnum = true; 3641} 3642 3643void Context::recordInvalidValue() 3644{ 3645 mInvalidValue = true; 3646} 3647 3648void Context::recordInvalidOperation() 3649{ 3650 mInvalidOperation = true; 3651} 3652 3653void Context::recordOutOfMemory() 3654{ 3655 mOutOfMemory = true; 3656} 3657 3658void Context::recordInvalidFramebufferOperation() 3659{ 3660 mInvalidFramebufferOperation = true; 3661} 3662 3663// Get one of the recorded errors and clear its flag, if any. 3664// [OpenGL ES 2.0.24] section 2.5 page 13. 3665GLenum Context::getError() 3666{ 3667 if(mInvalidEnum) 3668 { 3669 mInvalidEnum = false; 3670 3671 return GL_INVALID_ENUM; 3672 } 3673 3674 if(mInvalidValue) 3675 { 3676 mInvalidValue = false; 3677 3678 return GL_INVALID_VALUE; 3679 } 3680 3681 if(mInvalidOperation) 3682 { 3683 mInvalidOperation = false; 3684 3685 return GL_INVALID_OPERATION; 3686 } 3687 3688 if(mOutOfMemory) 3689 { 3690 mOutOfMemory = false; 3691 3692 return GL_OUT_OF_MEMORY; 3693 } 3694 3695 if(mInvalidFramebufferOperation) 3696 { 3697 mInvalidFramebufferOperation = false; 3698 3699 return GL_INVALID_FRAMEBUFFER_OPERATION; 3700 } 3701 3702 return GL_NO_ERROR; 3703} 3704 3705int Context::getSupportedMultiSampleDepth(sw::Format format, int requested) 3706{ 3707 if(requested <= 1) 3708 { 3709 return 1; 3710 } 3711 3712 if(requested == 2) 3713 { 3714 return 2; 3715 } 3716 3717 return 4; 3718} 3719 3720void Context::detachBuffer(GLuint buffer) 3721{ 3722 // [OpenGL ES 2.0.24] section 2.9 page 22: 3723 // If a buffer object is deleted while it is bound, all bindings to that object in the current context 3724 // (i.e. in the thread that called Delete-Buffers) are reset to zero. 3725 3726 if(getArrayBufferName() == buffer) 3727 { 3728 mState.arrayBuffer = NULL; 3729 } 3730 3731 for(auto vaoIt = mVertexArrayMap.begin(); vaoIt != mVertexArrayMap.end(); vaoIt++) 3732 { 3733 vaoIt->second->detachBuffer(buffer); 3734 } 3735 3736 for(int attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++) 3737 { 3738 if(mState.vertexAttribute[attribute].mBoundBuffer.name() == buffer) 3739 { 3740 mState.vertexAttribute[attribute].mBoundBuffer = NULL; 3741 } 3742 } 3743} 3744 3745void Context::detachTexture(GLuint texture) 3746{ 3747 // [OpenGL ES 2.0.24] section 3.8 page 84: 3748 // If a texture object is deleted, it is as if all texture units which are bound to that texture object are 3749 // rebound to texture object zero 3750 3751 for(int type = 0; type < TEXTURE_TYPE_COUNT; type++) 3752 { 3753 for(int sampler = 0; sampler < MAX_COMBINED_TEXTURE_IMAGE_UNITS; sampler++) 3754 { 3755 if(mState.samplerTexture[type][sampler].name() == texture) 3756 { 3757 mState.samplerTexture[type][sampler] = NULL; 3758 } 3759 } 3760 } 3761 3762 // [OpenGL ES 2.0.24] section 4.4 page 112: 3763 // If a texture object is deleted while its image is attached to the currently bound framebuffer, then it is 3764 // as if FramebufferTexture2D had been called, with a texture of 0, for each attachment point to which this 3765 // image was attached in the currently bound framebuffer. 3766 3767 Framebuffer *readFramebuffer = getReadFramebuffer(); 3768 Framebuffer *drawFramebuffer = getDrawFramebuffer(); 3769 3770 if(readFramebuffer) 3771 { 3772 readFramebuffer->detachTexture(texture); 3773 } 3774 3775 if(drawFramebuffer && drawFramebuffer != readFramebuffer) 3776 { 3777 drawFramebuffer->detachTexture(texture); 3778 } 3779} 3780 3781void Context::detachFramebuffer(GLuint framebuffer) 3782{ 3783 // [OpenGL ES 2.0.24] section 4.4 page 107: 3784 // If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though 3785 // BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero. 3786 3787 if(mState.readFramebuffer == framebuffer) 3788 { 3789 bindReadFramebuffer(0); 3790 } 3791 3792 if(mState.drawFramebuffer == framebuffer) 3793 { 3794 bindDrawFramebuffer(0); 3795 } 3796} 3797 3798void Context::detachRenderbuffer(GLuint renderbuffer) 3799{ 3800 // [OpenGL ES 2.0.24] section 4.4 page 109: 3801 // If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer 3802 // had been executed with the target RENDERBUFFER and name of zero. 3803 3804 if(mState.renderbuffer.name() == renderbuffer) 3805 { 3806 bindRenderbuffer(0); 3807 } 3808 3809 // [OpenGL ES 2.0.24] section 4.4 page 111: 3810 // If a renderbuffer object is deleted while its image is attached to the currently bound framebuffer, 3811 // then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment 3812 // point to which this image was attached in the currently bound framebuffer. 3813 3814 Framebuffer *readFramebuffer = getReadFramebuffer(); 3815 Framebuffer *drawFramebuffer = getDrawFramebuffer(); 3816 3817 if(readFramebuffer) 3818 { 3819 readFramebuffer->detachRenderbuffer(renderbuffer); 3820 } 3821 3822 if(drawFramebuffer && drawFramebuffer != readFramebuffer) 3823 { 3824 drawFramebuffer->detachRenderbuffer(renderbuffer); 3825 } 3826} 3827 3828void Context::detachSampler(GLuint sampler) 3829{ 3830 // [OpenGL ES 3.0.2] section 3.8.2 pages 123-124: 3831 // If a sampler object that is currently bound to one or more texture units is 3832 // deleted, it is as though BindSampler is called once for each texture unit to 3833 // which the sampler is bound, with unit set to the texture unit and sampler set to zero. 3834 for(size_t textureUnit = 0; textureUnit < MAX_COMBINED_TEXTURE_IMAGE_UNITS; ++textureUnit) 3835 { 3836 gl::BindingPointer<Sampler> &samplerBinding = mState.sampler[textureUnit]; 3837 if(samplerBinding.name() == sampler) 3838 { 3839 samplerBinding = NULL; 3840 } 3841 } 3842} 3843 3844bool Context::cullSkipsDraw(GLenum drawMode) 3845{ 3846 return mState.cullFace && mState.cullMode == GL_FRONT_AND_BACK && isTriangleMode(drawMode); 3847} 3848 3849bool Context::isTriangleMode(GLenum drawMode) 3850{ 3851 switch (drawMode) 3852 { 3853 case GL_TRIANGLES: 3854 case GL_TRIANGLE_FAN: 3855 case GL_TRIANGLE_STRIP: 3856 return true; 3857 case GL_POINTS: 3858 case GL_LINES: 3859 case GL_LINE_LOOP: 3860 case GL_LINE_STRIP: 3861 return false; 3862 default: UNREACHABLE(); 3863 } 3864 3865 return false; 3866} 3867 3868void Context::setVertexAttrib(GLuint index, const GLfloat *values) 3869{ 3870 ASSERT(index < MAX_VERTEX_ATTRIBS); 3871 3872 mState.vertexAttribute[index].setCurrentValue(values); 3873 3874 mVertexDataManager->dirtyCurrentValue(index); 3875} 3876 3877void Context::setVertexAttrib(GLuint index, const GLint *values) 3878{ 3879 ASSERT(index < MAX_VERTEX_ATTRIBS); 3880 3881 mState.vertexAttribute[index].setCurrentValue(values); 3882 3883 mVertexDataManager->dirtyCurrentValue(index); 3884} 3885 3886void Context::setVertexAttrib(GLuint index, const GLuint *values) 3887{ 3888 ASSERT(index < MAX_VERTEX_ATTRIBS); 3889 3890 mState.vertexAttribute[index].setCurrentValue(values); 3891 3892 mVertexDataManager->dirtyCurrentValue(index); 3893} 3894 3895void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, 3896 GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, 3897 GLbitfield mask) 3898{ 3899 Framebuffer *readFramebuffer = getReadFramebuffer(); 3900 Framebuffer *drawFramebuffer = getDrawFramebuffer(); 3901 3902 int readBufferWidth, readBufferHeight, readBufferSamples; 3903 int drawBufferWidth, drawBufferHeight, drawBufferSamples; 3904 3905 if(!readFramebuffer || readFramebuffer->completeness(readBufferWidth, readBufferHeight, readBufferSamples) != GL_FRAMEBUFFER_COMPLETE || 3906 !drawFramebuffer || drawFramebuffer->completeness(drawBufferWidth, drawBufferHeight, drawBufferSamples) != GL_FRAMEBUFFER_COMPLETE) 3907 { 3908 return error(GL_INVALID_FRAMEBUFFER_OPERATION); 3909 } 3910 3911 if(drawBufferSamples > 1) 3912 { 3913 return error(GL_INVALID_OPERATION); 3914 } 3915 3916 sw::SliceRect sourceRect; 3917 sw::SliceRect destRect; 3918 bool flipX = (srcX0 < srcX1) ^ (dstX0 < dstX1); 3919 bool flipy = (srcY0 < srcY1) ^ (dstY0 < dstY1); 3920 3921 if(srcX0 < srcX1) 3922 { 3923 sourceRect.x0 = srcX0; 3924 sourceRect.x1 = srcX1; 3925 } 3926 else 3927 { 3928 sourceRect.x0 = srcX1; 3929 sourceRect.x1 = srcX0; 3930 } 3931 3932 if(dstX0 < dstX1) 3933 { 3934 destRect.x0 = dstX0; 3935 destRect.x1 = dstX1; 3936 } 3937 else 3938 { 3939 destRect.x0 = dstX1; 3940 destRect.x1 = dstX0; 3941 } 3942 3943 if(srcY0 < srcY1) 3944 { 3945 sourceRect.y0 = srcY0; 3946 sourceRect.y1 = srcY1; 3947 } 3948 else 3949 { 3950 sourceRect.y0 = srcY1; 3951 sourceRect.y1 = srcY0; 3952 } 3953 3954 if(dstY0 < dstY1) 3955 { 3956 destRect.y0 = dstY0; 3957 destRect.y1 = dstY1; 3958 } 3959 else 3960 { 3961 destRect.y0 = dstY1; 3962 destRect.y1 = dstY0; 3963 } 3964 3965 sw::Rect sourceScissoredRect = sourceRect; 3966 sw::Rect destScissoredRect = destRect; 3967 3968 if(mState.scissorTest) // Only write to parts of the destination framebuffer which pass the scissor test 3969 { 3970 if(destRect.x0 < mState.scissorX) 3971 { 3972 int xDiff = mState.scissorX - destRect.x0; 3973 destScissoredRect.x0 = mState.scissorX; 3974 sourceScissoredRect.x0 += xDiff; 3975 } 3976 3977 if(destRect.x1 > mState.scissorX + mState.scissorWidth) 3978 { 3979 int xDiff = destRect.x1 - (mState.scissorX + mState.scissorWidth); 3980 destScissoredRect.x1 = mState.scissorX + mState.scissorWidth; 3981 sourceScissoredRect.x1 -= xDiff; 3982 } 3983 3984 if(destRect.y0 < mState.scissorY) 3985 { 3986 int yDiff = mState.scissorY - destRect.y0; 3987 destScissoredRect.y0 = mState.scissorY; 3988 sourceScissoredRect.y0 += yDiff; 3989 } 3990 3991 if(destRect.y1 > mState.scissorY + mState.scissorHeight) 3992 { 3993 int yDiff = destRect.y1 - (mState.scissorY + mState.scissorHeight); 3994 destScissoredRect.y1 = mState.scissorY + mState.scissorHeight; 3995 sourceScissoredRect.y1 -= yDiff; 3996 } 3997 } 3998 3999 sw::Rect sourceTrimmedRect = sourceScissoredRect; 4000 sw::Rect destTrimmedRect = destScissoredRect; 4001 4002 // The source & destination rectangles also may need to be trimmed if they fall out of the bounds of 4003 // the actual draw and read surfaces. 4004 if(sourceTrimmedRect.x0 < 0) 4005 { 4006 int xDiff = 0 - sourceTrimmedRect.x0; 4007 sourceTrimmedRect.x0 = 0; 4008 destTrimmedRect.x0 += xDiff; 4009 } 4010 4011 if(sourceTrimmedRect.x1 > readBufferWidth) 4012 { 4013 int xDiff = sourceTrimmedRect.x1 - readBufferWidth; 4014 sourceTrimmedRect.x1 = readBufferWidth; 4015 destTrimmedRect.x1 -= xDiff; 4016 } 4017 4018 if(sourceTrimmedRect.y0 < 0) 4019 { 4020 int yDiff = 0 - sourceTrimmedRect.y0; 4021 sourceTrimmedRect.y0 = 0; 4022 destTrimmedRect.y0 += yDiff; 4023 } 4024 4025 if(sourceTrimmedRect.y1 > readBufferHeight) 4026 { 4027 int yDiff = sourceTrimmedRect.y1 - readBufferHeight; 4028 sourceTrimmedRect.y1 = readBufferHeight; 4029 destTrimmedRect.y1 -= yDiff; 4030 } 4031 4032 if(destTrimmedRect.x0 < 0) 4033 { 4034 int xDiff = 0 - destTrimmedRect.x0; 4035 destTrimmedRect.x0 = 0; 4036 sourceTrimmedRect.x0 += xDiff; 4037 } 4038 4039 if(destTrimmedRect.x1 > drawBufferWidth) 4040 { 4041 int xDiff = destTrimmedRect.x1 - drawBufferWidth; 4042 destTrimmedRect.x1 = drawBufferWidth; 4043 sourceTrimmedRect.x1 -= xDiff; 4044 } 4045 4046 if(destTrimmedRect.y0 < 0) 4047 { 4048 int yDiff = 0 - destTrimmedRect.y0; 4049 destTrimmedRect.y0 = 0; 4050 sourceTrimmedRect.y0 += yDiff; 4051 } 4052 4053 if(destTrimmedRect.y1 > drawBufferHeight) 4054 { 4055 int yDiff = destTrimmedRect.y1 - drawBufferHeight; 4056 destTrimmedRect.y1 = drawBufferHeight; 4057 sourceTrimmedRect.y1 -= yDiff; 4058 } 4059 4060 bool partialBufferCopy = false; 4061 4062 if(sourceTrimmedRect.y1 - sourceTrimmedRect.y0 < readBufferHeight || 4063 sourceTrimmedRect.x1 - sourceTrimmedRect.x0 < readBufferWidth || 4064 destTrimmedRect.y1 - destTrimmedRect.y0 < drawBufferHeight || 4065 destTrimmedRect.x1 - destTrimmedRect.x0 < drawBufferWidth || 4066 sourceTrimmedRect.y0 != 0 || destTrimmedRect.y0 != 0 || sourceTrimmedRect.x0 != 0 || destTrimmedRect.x0 != 0) 4067 { 4068 partialBufferCopy = true; 4069 } 4070 4071 bool blitRenderTarget = false; 4072 bool blitDepthStencil = false; 4073 4074 if(mask & GL_COLOR_BUFFER_BIT) 4075 { 4076 const bool validReadType = readFramebuffer->getColorbufferType(getReadFramebufferColorIndex()) == GL_TEXTURE_2D || 4077 readFramebuffer->getColorbufferType(getReadFramebufferColorIndex()) == GL_RENDERBUFFER; 4078 const bool validDrawType = drawFramebuffer->getColorbufferType(0) == GL_TEXTURE_2D || 4079 drawFramebuffer->getColorbufferType(0) == GL_RENDERBUFFER; 4080 if(!validReadType || !validDrawType) 4081 { 4082 return error(GL_INVALID_OPERATION); 4083 } 4084 4085 if(partialBufferCopy && readBufferSamples > 1) 4086 { 4087 return error(GL_INVALID_OPERATION); 4088 } 4089 4090 blitRenderTarget = true; 4091 } 4092 4093 if(mask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) 4094 { 4095 Renderbuffer *readDSBuffer = NULL; 4096 Renderbuffer *drawDSBuffer = NULL; 4097 4098 // We support OES_packed_depth_stencil, and do not support a separately attached depth and stencil buffer, so if we have 4099 // both a depth and stencil buffer, it will be the same buffer. 4100 4101 if(mask & GL_DEPTH_BUFFER_BIT) 4102 { 4103 if(readFramebuffer->getDepthbuffer() && drawFramebuffer->getDepthbuffer()) 4104 { 4105 if(readFramebuffer->getDepthbufferType() != drawFramebuffer->getDepthbufferType()) 4106 { 4107 return error(GL_INVALID_OPERATION); 4108 } 4109 4110 blitDepthStencil = true; 4111 readDSBuffer = readFramebuffer->getDepthbuffer(); 4112 drawDSBuffer = drawFramebuffer->getDepthbuffer(); 4113 } 4114 } 4115 4116 if(mask & GL_STENCIL_BUFFER_BIT) 4117 { 4118 if(readFramebuffer->getStencilbuffer() && drawFramebuffer->getStencilbuffer()) 4119 { 4120 if(readFramebuffer->getStencilbufferType() != drawFramebuffer->getStencilbufferType()) 4121 { 4122 return error(GL_INVALID_OPERATION); 4123 } 4124 4125 blitDepthStencil = true; 4126 readDSBuffer = readFramebuffer->getStencilbuffer(); 4127 drawDSBuffer = drawFramebuffer->getStencilbuffer(); 4128 } 4129 } 4130 4131 if(partialBufferCopy) 4132 { 4133 ERR("Only whole-buffer depth and stencil blits are supported by this implementation."); 4134 return error(GL_INVALID_OPERATION); // Only whole-buffer copies are permitted 4135 } 4136 4137 if((drawDSBuffer && drawDSBuffer->getSamples() > 1) || 4138 (readDSBuffer && readDSBuffer->getSamples() > 1)) 4139 { 4140 return error(GL_INVALID_OPERATION); 4141 } 4142 } 4143 4144 if(blitRenderTarget || blitDepthStencil) 4145 { 4146 if(blitRenderTarget) 4147 { 4148 egl::Image *readRenderTarget = readFramebuffer->getReadRenderTarget(); 4149 egl::Image *drawRenderTarget = drawFramebuffer->getRenderTarget(0); 4150 4151 if(flipX) 4152 { 4153 swap(destRect.x0, destRect.x1); 4154 } 4155 if(flipy) 4156 { 4157 swap(destRect.y0, destRect.y1); 4158 } 4159 4160 bool success = device->stretchRect(readRenderTarget, &sourceRect, drawRenderTarget, &destRect, false); 4161 4162 readRenderTarget->release(); 4163 drawRenderTarget->release(); 4164 4165 if(!success) 4166 { 4167 ERR("BlitFramebuffer failed."); 4168 return; 4169 } 4170 } 4171 4172 if(blitDepthStencil) 4173 { 4174 bool success = device->stretchRect(readFramebuffer->getDepthStencil(), NULL, drawFramebuffer->getDepthStencil(), NULL, false); 4175 4176 if(!success) 4177 { 4178 ERR("BlitFramebuffer failed."); 4179 return; 4180 } 4181 } 4182 } 4183} 4184 4185void Context::bindTexImage(egl::Surface *surface) 4186{ 4187 es2::Texture2D *textureObject = getTexture2D(); 4188 4189 if(textureObject) 4190 { 4191 textureObject->bindTexImage(surface); 4192 } 4193} 4194 4195EGLenum Context::validateSharedImage(EGLenum target, GLuint name, GLuint textureLevel) 4196{ 4197 GLenum textureTarget = GL_NONE; 4198 4199 switch(target) 4200 { 4201 case EGL_GL_TEXTURE_2D_KHR: 4202 textureTarget = GL_TEXTURE_2D; 4203 break; 4204 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR: 4205 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR: 4206 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR: 4207 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR: 4208 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR: 4209 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR: 4210 textureTarget = GL_TEXTURE_CUBE_MAP; 4211 break; 4212 case EGL_GL_RENDERBUFFER_KHR: 4213 break; 4214 default: 4215 return EGL_BAD_PARAMETER; 4216 } 4217 4218 if(textureLevel >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS) 4219 { 4220 return EGL_BAD_MATCH; 4221 } 4222 4223 if(textureTarget != GL_NONE) 4224 { 4225 es2::Texture *texture = getTexture(name); 4226 4227 if(!texture || texture->getTarget() != textureTarget) 4228 { 4229 return EGL_BAD_PARAMETER; 4230 } 4231 4232 if(texture->isShared(textureTarget, textureLevel)) // Bound to an EGLSurface or already an EGLImage sibling 4233 { 4234 return EGL_BAD_ACCESS; 4235 } 4236 4237 if(textureLevel != 0 && !texture->isSamplerComplete()) 4238 { 4239 return EGL_BAD_PARAMETER; 4240 } 4241 4242 if(textureLevel == 0 && !(texture->isSamplerComplete() && texture->getLevelCount() == 1)) 4243 { 4244 return EGL_BAD_PARAMETER; 4245 } 4246 } 4247 else if(target == EGL_GL_RENDERBUFFER_KHR) 4248 { 4249 es2::Renderbuffer *renderbuffer = getRenderbuffer(name); 4250 4251 if(!renderbuffer) 4252 { 4253 return EGL_BAD_PARAMETER; 4254 } 4255 4256 if(renderbuffer->isShared()) // Already an EGLImage sibling 4257 { 4258 return EGL_BAD_ACCESS; 4259 } 4260 } 4261 else UNREACHABLE(); 4262 4263 return EGL_SUCCESS; 4264} 4265 4266egl::Image *Context::createSharedImage(EGLenum target, GLuint name, GLuint textureLevel) 4267{ 4268 GLenum textureTarget = GL_NONE; 4269 4270 switch(target) 4271 { 4272 case EGL_GL_TEXTURE_2D_KHR: textureTarget = GL_TEXTURE_2D; break; 4273 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X; break; 4274 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_NEGATIVE_X; break; 4275 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_Y; break; 4276 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_NEGATIVE_Y; break; 4277 case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_Z; break; 4278 case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR: textureTarget = GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; break; 4279 } 4280 4281 if(textureTarget != GL_NONE) 4282 { 4283 es2::Texture *texture = getTexture(name); 4284 4285 return texture->createSharedImage(textureTarget, textureLevel); 4286 } 4287 else if(target == EGL_GL_RENDERBUFFER_KHR) 4288 { 4289 es2::Renderbuffer *renderbuffer = getRenderbuffer(name); 4290 4291 return renderbuffer->createSharedImage(); 4292 } 4293 else UNREACHABLE(); 4294 4295 return 0; 4296} 4297 4298Device *Context::getDevice() 4299{ 4300 return device; 4301} 4302 4303const GLubyte* Context::getExtensions(GLuint index, GLuint* numExt) const 4304{ 4305 // Keep list sorted in following order: 4306 // OES extensions 4307 // EXT extensions 4308 // Vendor extensions 4309 static const GLubyte* extensions[] = { 4310 (const GLubyte*)"GL_OES_compressed_ETC1_RGB8_texture", 4311 (const GLubyte*)"GL_OES_depth_texture", 4312 (const GLubyte*)"GL_OES_depth_texture_cube_map", 4313 (const GLubyte*)"GL_OES_EGL_image", 4314 (const GLubyte*)"GL_OES_EGL_image_external", 4315 (const GLubyte*)"GL_OES_element_index_uint", 4316 (const GLubyte*)"GL_OES_packed_depth_stencil", 4317 (const GLubyte*)"GL_OES_rgb8_rgba8", 4318 (const GLubyte*)"GL_OES_standard_derivatives", 4319 (const GLubyte*)"GL_OES_texture_float", 4320 (const GLubyte*)"GL_OES_texture_float_linear", 4321 (const GLubyte*)"GL_OES_texture_half_float", 4322 (const GLubyte*)"GL_OES_texture_half_float_linear", 4323 (const GLubyte*)"GL_OES_texture_npot", 4324 (const GLubyte*)"GL_OES_texture_3D", 4325 (const GLubyte*)"GL_EXT_blend_minmax", 4326 (const GLubyte*)"GL_EXT_occlusion_query_boolean", 4327 (const GLubyte*)"GL_EXT_read_format_bgra", 4328#if (S3TC_SUPPORT) 4329 (const GLubyte*)"GL_EXT_texture_compression_dxt1", 4330#endif 4331 (const GLubyte*)"GL_EXT_texture_filter_anisotropic", 4332 (const GLubyte*)"GL_EXT_texture_format_BGRA8888", 4333 (const GLubyte*)"GL_ANGLE_framebuffer_blit", 4334 (const GLubyte*)"GL_NV_framebuffer_blit", 4335 (const GLubyte*)"GL_ANGLE_framebuffer_multisample", 4336#if (S3TC_SUPPORT) 4337 (const GLubyte*)"GL_ANGLE_texture_compression_dxt3", 4338 (const GLubyte*)"GL_ANGLE_texture_compression_dxt5", 4339#endif 4340 (const GLubyte*)"GL_NV_fence", 4341 (const GLubyte*)"GL_EXT_instanced_arrays", 4342 (const GLubyte*)"GL_ANGLE_instanced_arrays", 4343 }; 4344 static const GLuint numExtensions = sizeof(extensions) / sizeof(*extensions); 4345 4346 if(numExt) 4347 { 4348 *numExt = numExtensions; 4349 return nullptr; 4350 } 4351 4352 if(index == GL_INVALID_INDEX) 4353 { 4354 static GLubyte* extensionsCat = nullptr; 4355 if((extensionsCat == nullptr) && (numExtensions > 0)) 4356 { 4357 int totalLength = numExtensions; // 1 space between each extension name + terminating null 4358 for(int i = 0; i < numExtensions; ++i) 4359 { 4360 totalLength += strlen(reinterpret_cast<const char*>(extensions[i])); 4361 } 4362 extensionsCat = new GLubyte[totalLength]; 4363 extensionsCat[0] = '\0'; 4364 for(int i = 0; i < numExtensions; ++i) 4365 { 4366 if(i != 0) 4367 { 4368 strcat(reinterpret_cast<char*>(extensionsCat), " "); 4369 } 4370 strcat(reinterpret_cast<char*>(extensionsCat), reinterpret_cast<const char*>(extensions[i])); 4371 } 4372 } 4373 return extensionsCat; 4374 } 4375 4376 if(index >= numExtensions) 4377 { 4378 return nullptr; 4379 } 4380 4381 return extensions[index]; 4382} 4383 4384} 4385 4386egl::Context *es2CreateContext(const egl::Config *config, const egl::Context *shareContext, int clientVersion) 4387{ 4388 ASSERT(!shareContext || shareContext->getClientVersion() == clientVersion); // Should be checked by eglCreateContext 4389 return new es2::Context(config, static_cast<const es2::Context*>(shareContext), clientVersion); 4390} 4391