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