summaryrefslogtreecommitdiffstats
path: root/ANGLE
diff options
context:
space:
mode:
authorIain Merrick <husky@google.com>2010-09-13 16:35:48 +0100
committerIain Merrick <husky@google.com>2010-09-16 12:10:42 +0100
commit5abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306 (patch)
treeddce1aa5e3b6967a69691892e500897558ff8ab6 /ANGLE
parent12bec63ec71e46baba27f0bd9bd9d8067683690a (diff)
downloadexternal_webkit-5abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306.zip
external_webkit-5abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306.tar.gz
external_webkit-5abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306.tar.bz2
Merge WebKit at r67178 : Initial merge by git.
Change-Id: I57e01163b6866cb029cdadf405a0394a3918bc18
Diffstat (limited to 'ANGLE')
-rw-r--r--ANGLE/ANGLE.xcodeproj/project.pbxproj5
-rw-r--r--ANGLE/ChangeLog458
-rw-r--r--ANGLE/include/GLES2/gl2ext.h58
-rw-r--r--ANGLE/include/GLSLANG/ResourceLimits.h21
-rw-r--r--ANGLE/include/GLSLANG/ShaderLang.h30
-rw-r--r--ANGLE/src/compiler/BaseTypes.h21
-rw-r--r--ANGLE/src/compiler/Initialize.cpp38
-rw-r--r--ANGLE/src/compiler/Initialize.h2
-rw-r--r--ANGLE/src/compiler/InitializeDll.cpp95
-rw-r--r--ANGLE/src/compiler/InitializeDll.h7
-rw-r--r--ANGLE/src/compiler/InitializeParseContext.h5
-rw-r--r--ANGLE/src/compiler/Intermediate.cpp123
-rw-r--r--ANGLE/src/compiler/OutputGLSL.cpp6
-rw-r--r--ANGLE/src/compiler/OutputHLSL.cpp30
-rw-r--r--ANGLE/src/compiler/ParseHelper.cpp78
-rw-r--r--ANGLE/src/compiler/PoolAlloc.h28
-rw-r--r--ANGLE/src/compiler/ShaderLang.cpp44
-rw-r--r--ANGLE/src/compiler/SymbolTable.cpp2
-rw-r--r--ANGLE/src/compiler/SymbolTable.h2
-rw-r--r--ANGLE/src/compiler/Types.h165
-rw-r--r--ANGLE/src/compiler/glslang.l4
-rw-r--r--ANGLE/src/compiler/glslang.y35
-rw-r--r--ANGLE/src/compiler/intermediate.h119
-rw-r--r--ANGLE/src/compiler/parseConst.cpp36
-rw-r--r--ANGLE/src/compiler/preprocessor/atom.c7
-rw-r--r--ANGLE/src/compiler/preprocessor/atom.h5
-rw-r--r--ANGLE/src/compiler/preprocessor/compile.h5
-rw-r--r--ANGLE/src/compiler/preprocessor/cpp.c5
-rw-r--r--ANGLE/src/compiler/preprocessor/cpp.h5
-rw-r--r--ANGLE/src/compiler/preprocessor/cppstruct.c5
-rw-r--r--ANGLE/src/compiler/preprocessor/memory.c5
-rw-r--r--ANGLE/src/compiler/preprocessor/memory.h5
-rw-r--r--ANGLE/src/compiler/preprocessor/parser.h5
-rw-r--r--ANGLE/src/compiler/preprocessor/preprocess.h5
-rw-r--r--ANGLE/src/compiler/preprocessor/scanner.c5
-rw-r--r--ANGLE/src/compiler/preprocessor/scanner.h5
-rw-r--r--ANGLE/src/compiler/preprocessor/slglobals.h5
-rw-r--r--ANGLE/src/compiler/preprocessor/symbols.c7
-rw-r--r--ANGLE/src/compiler/preprocessor/symbols.h5
-rw-r--r--ANGLE/src/compiler/preprocessor/tokens.c7
-rw-r--r--ANGLE/src/compiler/preprocessor/tokens.h5
-rw-r--r--ANGLE/src/libEGL/Display.cpp341
-rw-r--r--ANGLE/src/libEGL/Display.h12
-rw-r--r--ANGLE/src/libEGL/Surface.cpp242
-rw-r--r--ANGLE/src/libEGL/Surface.h13
-rw-r--r--ANGLE/src/libEGL/libEGL.cpp5
-rw-r--r--ANGLE/src/libEGL/libEGL.vcproj4
-rw-r--r--ANGLE/src/libGLESv2/Blit.cpp6
-rw-r--r--ANGLE/src/libGLESv2/Buffer.cpp2
-rw-r--r--ANGLE/src/libGLESv2/Buffer.h5
-rw-r--r--ANGLE/src/libGLESv2/Context.cpp1287
-rw-r--r--ANGLE/src/libGLESv2/Context.h111
-rw-r--r--ANGLE/src/libGLESv2/Framebuffer.cpp286
-rw-r--r--ANGLE/src/libGLESv2/Framebuffer.h41
-rw-r--r--ANGLE/src/libGLESv2/Program.cpp94
-rw-r--r--ANGLE/src/libGLESv2/Program.h15
-rw-r--r--ANGLE/src/libGLESv2/RefCountObject.cpp51
-rw-r--r--ANGLE/src/libGLESv2/RefCountObject.h70
-rw-r--r--ANGLE/src/libGLESv2/Renderbuffer.cpp295
-rw-r--r--ANGLE/src/libGLESv2/Renderbuffer.h123
-rw-r--r--ANGLE/src/libGLESv2/ResourceManager.cpp340
-rw-r--r--ANGLE/src/libGLESv2/ResourceManager.h92
-rw-r--r--ANGLE/src/libGLESv2/Shader.cpp43
-rw-r--r--ANGLE/src/libGLESv2/Shader.h22
-rw-r--r--ANGLE/src/libGLESv2/Texture.cpp558
-rw-r--r--ANGLE/src/libGLESv2/Texture.h103
-rw-r--r--ANGLE/src/libGLESv2/libGLESv2.cpp508
-rw-r--r--ANGLE/src/libGLESv2/libGLESv2.def12
-rw-r--r--ANGLE/src/libGLESv2/libGLESv2.vcproj16
-rw-r--r--ANGLE/src/libGLESv2/main.h1
-rw-r--r--ANGLE/src/libGLESv2/utilities.cpp68
-rw-r--r--ANGLE/src/libGLESv2/utilities.h6
72 files changed, 4528 insertions, 1747 deletions
diff --git a/ANGLE/ANGLE.xcodeproj/project.pbxproj b/ANGLE/ANGLE.xcodeproj/project.pbxproj
index 67b6c3f..95f41c3 100644
--- a/ANGLE/ANGLE.xcodeproj/project.pbxproj
+++ b/ANGLE/ANGLE.xcodeproj/project.pbxproj
@@ -35,7 +35,6 @@
FB39D2B11200F35A00088E69 /* UnfoldSelect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FB39D26D1200F35A00088E69 /* UnfoldSelect.cpp */; };
FB39D7231201032000088E69 /* glslang.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FB39D7201201032000088E69 /* glslang.cpp */; };
FB39D7241201032000088E69 /* glslang_tab.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FB39D7221201032000088E69 /* glslang_tab.cpp */; };
- FB39D76D120110FC00088E69 /* ResourceLimits.h in Headers */ = {isa = PBXBuildFile; fileRef = FB39D2BE1200F3E600088E69 /* ResourceLimits.h */; settings = {ATTRIBUTES = (Public, ); }; };
FB39D76E120110FC00088E69 /* ShaderLang.h in Headers */ = {isa = PBXBuildFile; fileRef = FB39D2BF1200F3E600088E69 /* ShaderLang.h */; settings = {ATTRIBUTES = (Public, ); }; };
/* End PBXBuildFile section */
@@ -177,7 +176,6 @@
FB39D26D1200F35A00088E69 /* UnfoldSelect.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = UnfoldSelect.cpp; sourceTree = "<group>"; };
FB39D26E1200F35A00088E69 /* UnfoldSelect.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; path = UnfoldSelect.h; sourceTree = "<group>"; };
FB39D26F1200F35A00088E69 /* unistd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = unistd.h; sourceTree = "<group>"; };
- FB39D2BE1200F3E600088E69 /* ResourceLimits.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; path = ResourceLimits.h; sourceTree = "<group>"; };
FB39D2BF1200F3E600088E69 /* ShaderLang.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.h; fileEncoding = 4; path = ShaderLang.h; sourceTree = "<group>"; };
FB39D7201201032000088E69 /* glslang.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = glslang.cpp; path = DerivedSources/ANGLE/glslang.cpp; sourceTree = BUILT_PRODUCTS_DIR; };
FB39D7211201032000088E69 /* glslang_tab.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = glslang_tab.h; path = DerivedSources/ANGLE/glslang_tab.h; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -413,7 +411,6 @@
FB39D2BD1200F3E600088E69 /* GLSLANG */ = {
isa = PBXGroup;
children = (
- FB39D2BE1200F3E600088E69 /* ResourceLimits.h */,
FB39D2BF1200F3E600088E69 /* ShaderLang.h */,
);
name = GLSLANG;
@@ -427,7 +424,6 @@
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
- FB39D76D120110FC00088E69 /* ResourceLimits.h in Headers */,
FB39D76E120110FC00088E69 /* ShaderLang.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -461,7 +457,6 @@
isa = PBXProject;
buildConfigurationList = FB39D0731200ED9200088E69 /* Build configuration list for PBXProject "ANGLE" */;
compatibilityVersion = "Xcode 2.4";
- developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
English,
diff --git a/ANGLE/ChangeLog b/ANGLE/ChangeLog
index 44234a8..e886a42 100644
--- a/ANGLE/ChangeLog
+++ b/ANGLE/ChangeLog
@@ -1,3 +1,461 @@
+2010-09-01 Zhenyao Mo <zmo@google.com>
+
+ Reviewed by Kenneth Russell.
+
+ Roll ANGLE under webkit to r402
+ https://bugs.webkit.org/show_bug.cgi?id=45004
+
+ * ANGLE.xcodeproj/project.pbxproj:
+ * include/GLES2/gl2ext.h:
+ * include/GLSLANG/ResourceLimits.h: Removed.
+ * include/GLSLANG/ShaderLang.h:
+ * src/compiler/BaseTypes.h:
+ (getPrecisionString):
+ (getBasicString):
+ (IsSampler):
+ (getQualifierString):
+ * src/compiler/Initialize.cpp:
+ (BuiltInConstants):
+ (IdentifyBuiltIns):
+ * src/compiler/Initialize.h:
+ * src/compiler/InitializeDll.cpp:
+ (InitProcess):
+ (DetachProcess):
+ (InitThread):
+ (DetachThread):
+ * src/compiler/InitializeDll.h:
+ * src/compiler/InitializeParseContext.h:
+ * src/compiler/Intermediate.cpp:
+ (GetHigherPrecision):
+ (TIntermediate::addBinaryMath):
+ (TIntermediate::setAggregateOperator):
+ (TIntermediate::addComma):
+ (TIntermediate::postProcess):
+ (TIntermBinary::promote):
+ (CompareStruct):
+ * src/compiler/OutputGLSL.cpp:
+ (TOutputGLSL::writeFunctionParameters):
+ (TOutputGLSL::visitUnary):
+ (TOutputGLSL::visitBranch):
+ * src/compiler/OutputHLSL.cpp:
+ (sh::OutputHLSL::header):
+ (sh::OutputHLSL::visitBinary):
+ (sh::OutputHLSL::visitAggregate):
+ (sh::OutputHLSL::handleExcessiveLoop):
+ (sh::OutputHLSL::addConstructor):
+ * src/compiler/ParseHelper.cpp:
+ (TParseContext::constructorErrorCheck):
+ (TParseContext::samplerErrorCheck):
+ (TParseContext::paramErrorCheck):
+ (TParseContext::findFunction):
+ (TParseContext::executeInitializer):
+ (TParseContext::addConstructor):
+ (TParseContext::addConstStruct):
+ (FreeParseContextIndex):
+ (GetGlobalParseContext):
+ * src/compiler/PoolAlloc.h:
+ (TPoolAllocator::tHeader::tHeader):
+ (pool_allocator::allocate):
+ (pool_allocator::deallocate):
+ * src/compiler/ShaderLang.cpp:
+ (ShInitialize):
+ (ShFinalize):
+ (ShInitBuiltInResource):
+ * src/compiler/SymbolTable.cpp:
+ (TType::getStructSize):
+ * src/compiler/SymbolTable.h:
+ (TVariable::setQualifier):
+ * src/compiler/Types.h:
+ (TType::TType):
+ (TType::getBasicType):
+ (TType::setBasicType):
+ (TType::getPrecision):
+ (TType::setPrecision):
+ (TType::getQualifier):
+ (TType::setQualifier):
+ (TType::getNominalSize):
+ (TType::setNominalSize):
+ (TType::isMatrix):
+ (TType::setMatrix):
+ (TType::isArray):
+ (TType::getArraySize):
+ (TType::setArraySize):
+ (TType::getMaxArraySize):
+ (TType::setMaxArraySize):
+ (TType::clearArrayness):
+ (TType::setArrayInformationType):
+ (TType::getArrayInformationType):
+ (TType::isVector):
+ (TType::isScalar):
+ (TType::setStruct):
+ (TType::getTypeName):
+ (TType::setTypeName):
+ (TType::isField):
+ (TType::getFieldName):
+ (TType::setFieldName):
+ (TType::getBasicString):
+ (TType::getPrecisionString):
+ (TType::getQualifierString):
+ * src/compiler/glslang.l:
+ * src/compiler/glslang.y:
+ * src/compiler/intermediate.h:
+ (TIntermNode::getLine):
+ (TIntermNode::setLine):
+ (TIntermTyped::getAsTyped):
+ (TIntermTyped::setType):
+ (TIntermTyped::getType):
+ (TIntermTyped::getTypePointer):
+ (TIntermTyped::getBasicType):
+ (TIntermTyped::getQualifier):
+ (TIntermTyped::getPrecision):
+ (TIntermTyped::getNominalSize):
+ (TIntermTyped::isMatrix):
+ (TIntermTyped::isArray):
+ (TIntermTyped::isVector):
+ (TIntermTyped::isScalar):
+ (TIntermTyped::getBasicString):
+ (TIntermTyped::getQualifierString):
+ (TIntermSymbol::getId):
+ (TIntermSymbol::getSymbol):
+ (TIntermOperator::setOp):
+ (TIntermBinary::setLeft):
+ (TIntermBinary::setRight):
+ (TIntermBinary::getLeft):
+ (TIntermBinary::getRight):
+ (TIntermUnary::setOperand):
+ (TIntermUnary::getOperand):
+ (TIntermAggregate::getAsAggregate):
+ (TIntermAggregate::getSequence):
+ (TIntermAggregate::setName):
+ (TIntermAggregate::getName):
+ (TIntermAggregate::setUserDefined):
+ (TIntermAggregate::isUserDefined):
+ (TIntermAggregate::getQualifier):
+ (TIntermAggregate::setOptimize):
+ (TIntermAggregate::setDebug):
+ (TIntermSelection::getCondition):
+ (TIntermSelection::getTrueBlock):
+ (TIntermSelection::getFalseBlock):
+ (TIntermSelection::getAsSelectionNode):
+ * src/compiler/parseConst.cpp:
+ (TConstTraverser::TConstTraverser):
+ * src/compiler/preprocessor/atom.c:
+ (InitAtomTable):
+ * src/compiler/preprocessor/atom.h:
+ * src/compiler/preprocessor/compile.h:
+ * src/compiler/preprocessor/cpp.c:
+ * src/compiler/preprocessor/cpp.h:
+ * src/compiler/preprocessor/cppstruct.c:
+ * src/compiler/preprocessor/memory.c:
+ * src/compiler/preprocessor/memory.h:
+ * src/compiler/preprocessor/parser.h:
+ * src/compiler/preprocessor/preprocess.h:
+ * src/compiler/preprocessor/scanner.c:
+ * src/compiler/preprocessor/scanner.h:
+ * src/compiler/preprocessor/slglobals.h:
+ * src/compiler/preprocessor/symbols.c:
+ (NewSymbol):
+ * src/compiler/preprocessor/symbols.h:
+ * src/compiler/preprocessor/tokens.c:
+ (RecordToken):
+ * src/compiler/preprocessor/tokens.h:
+ * src/libEGL/Display.cpp:
+ (egl::Display::Display):
+ (egl::Display::initialize):
+ (egl::Display::terminate):
+ (egl::Display::createDevice):
+ (egl::Display::createWindowSurface):
+ (egl::Display::createContext):
+ (egl::Display::getMultiSampleSupport):
+ (egl::Display::getCompressedTextureSupport):
+ * src/libEGL/Display.h:
+ * src/libEGL/Surface.cpp:
+ (egl::Surface::Surface):
+ (egl::Surface::resetSwapChain):
+ (egl::Surface::getWindowHandle):
+ (egl::Surface::writeRecordableFlipState):
+ (egl::Surface::applyFlipState):
+ (egl::Surface::releaseRecordedState):
+ (egl::Surface::checkForWindowResize):
+ (egl::Surface::swap):
+ * src/libEGL/Surface.h:
+ * src/libEGL/libEGL.cpp:
+ * src/libEGL/libEGL.vcproj:
+ * src/libGLESv2/Blit.cpp:
+ (gl::Blit::setVertexShader):
+ (gl::Blit::setPixelShader):
+ (gl::Blit::setFormatConvertShaders):
+ * src/libGLESv2/Buffer.cpp:
+ (gl::Buffer::Buffer):
+ * src/libGLESv2/Buffer.h:
+ * src/libGLESv2/Context.cpp:
+ (gl::Context::Context):
+ (gl::Context::~Context):
+ (gl::Context::makeCurrent):
+ (gl::Context::markAllStateDirty):
+ (gl::Context::getReadFramebufferHandle):
+ (gl::Context::getDrawFramebufferHandle):
+ (gl::Context::getRenderbufferHandle):
+ (gl::Context::getArrayBufferHandle):
+ (gl::Context::setVertexAttribState):
+ (gl::Context::createBuffer):
+ (gl::Context::createProgram):
+ (gl::Context::createShader):
+ (gl::Context::createTexture):
+ (gl::Context::createRenderbuffer):
+ (gl::Context::deleteBuffer):
+ (gl::Context::deleteShader):
+ (gl::Context::deleteProgram):
+ (gl::Context::deleteTexture):
+ (gl::Context::deleteRenderbuffer):
+ (gl::Context::getBuffer):
+ (gl::Context::getShader):
+ (gl::Context::getProgram):
+ (gl::Context::getTexture):
+ (gl::Context::getRenderbuffer):
+ (gl::Context::getReadFramebuffer):
+ (gl::Context::getDrawFramebuffer):
+ (gl::Context::bindArrayBuffer):
+ (gl::Context::bindElementArrayBuffer):
+ (gl::Context::bindTexture2D):
+ (gl::Context::bindTextureCubeMap):
+ (gl::Context::bindReadFramebuffer):
+ (gl::Context::bindDrawFramebuffer):
+ (gl::Context::bindRenderbuffer):
+ (gl::Context::useProgram):
+ (gl::Context::setFramebufferZero):
+ (gl::Context::setRenderbufferStorage):
+ (gl::Context::getFramebuffer):
+ (gl::Context::getArrayBuffer):
+ (gl::Context::getElementArrayBuffer):
+ (gl::Context::getCurrentProgram):
+ (gl::Context::getTexture2D):
+ (gl::Context::getTextureCubeMap):
+ (gl::Context::getSamplerTexture):
+ (gl::Context::getFloatv):
+ (gl::Context::getIntegerv):
+ (gl::Context::getQueryParameterInfo):
+ (gl::Context::applyRenderTarget):
+ (gl::Context::applyState):
+ (gl::Context::applyIndexBuffer):
+ (gl::Context::readPixels):
+ (gl::Context::clear):
+ (gl::Context::finish):
+ (gl::Context::flush):
+ (gl::Context::supportsShaderModel3):
+ (gl::Context::getMaxSupportedSamples):
+ (gl::Context::getNearestSupportedSamples):
+ (gl::Context::supportsCompressedTextures):
+ (gl::Context::detachBuffer):
+ (gl::Context::detachTexture):
+ (gl::Context::detachFramebuffer):
+ (gl::Context::detachRenderbuffer):
+ (gl::Context::getIncompleteTexture):
+ (gl::Context::initExtensionString):
+ (gl::Context::blitFramebuffer):
+ * src/libGLESv2/Context.h:
+ (gl::AttributeState::AttributeState):
+ * src/libGLESv2/Framebuffer.cpp:
+ (gl::Framebuffer::Framebuffer):
+ (gl::Framebuffer::~Framebuffer):
+ (gl::Framebuffer::lookupRenderbuffer):
+ (gl::Framebuffer::setColorbuffer):
+ (gl::Framebuffer::setDepthbuffer):
+ (gl::Framebuffer::setStencilbuffer):
+ (gl::Framebuffer::detachTexture):
+ (gl::Framebuffer::detachRenderbuffer):
+ (gl::Framebuffer::getRenderTargetSerial):
+ (gl::Framebuffer::getRenderTarget):
+ (gl::Framebuffer::getDepthStencil):
+ (gl::Framebuffer::getDepthbufferSerial):
+ (gl::Framebuffer::getStencilbufferSerial):
+ (gl::Framebuffer::getColorbuffer):
+ (gl::Framebuffer::getDepthbuffer):
+ (gl::Framebuffer::getStencilbuffer):
+ (gl::Framebuffer::getColorbufferHandle):
+ (gl::Framebuffer::getDepthbufferHandle):
+ (gl::Framebuffer::getStencilbufferHandle):
+ (gl::Framebuffer::hasStencil):
+ (gl::Framebuffer::isMultisample):
+ (gl::Framebuffer::completeness):
+ (gl::DefaultFramebuffer::DefaultFramebuffer):
+ (gl::Framebuffer::getSamples):
+ (gl::DefaultFramebuffer::completeness):
+ * src/libGLESv2/Framebuffer.h:
+ * src/libGLESv2/Program.cpp:
+ (gl::Program::Program):
+ (gl::Program::~Program):
+ (gl::Program::attachShader):
+ (gl::Program::detachShader):
+ (gl::Program::linkVaryings):
+ (gl::Program::link):
+ (gl::Program::unlink):
+ (gl::Program::release):
+ (gl::Program::addRef):
+ (gl::Program::getRefCount):
+ (gl::Program::getDxViewportLocation):
+ * src/libGLESv2/Program.h:
+ * src/libGLESv2/RefCountObject.cpp: Added.
+ (gl::RefCountObject::RefCountObject):
+ (gl::RefCountObject::~RefCountObject):
+ (gl::RefCountObject::addRef):
+ (gl::RefCountObject::release):
+ (gl::RefCountObjectBindingPointer::set):
+ * src/libGLESv2/RefCountObject.h: Added.
+ (gl::RefCountObject::id):
+ (gl::RefCountObjectBindingPointer::RefCountObjectBindingPointer):
+ (gl::RefCountObjectBindingPointer::~RefCountObjectBindingPointer):
+ (gl::RefCountObjectBindingPointer::get):
+ (gl::RefCountObjectBindingPointer::id):
+ (gl::RefCountObjectBindingPointer::operator ! ):
+ (gl::BindingPointer::set):
+ (gl::BindingPointer::get):
+ (gl::BindingPointer::operator -> ):
+ * src/libGLESv2/Renderbuffer.cpp:
+ (gl::Renderbuffer::Renderbuffer):
+ (gl::Renderbuffer::~Renderbuffer):
+ (gl::Renderbuffer::isColorbuffer):
+ (gl::Renderbuffer::isDepthbuffer):
+ (gl::Renderbuffer::isStencilbuffer):
+ (gl::Renderbuffer::getRenderTarget):
+ (gl::Renderbuffer::getDepthStencil):
+ (gl::Renderbuffer::getWidth):
+ (gl::Renderbuffer::getHeight):
+ (gl::Renderbuffer::getFormat):
+ (gl::Renderbuffer::getD3DFormat):
+ (gl::Renderbuffer::getSerial):
+ (gl::Renderbuffer::setStorage):
+ (gl::RenderbufferStorage::RenderbufferStorage):
+ (gl::RenderbufferStorage::~RenderbufferStorage):
+ (gl::RenderbufferStorage::isColorbuffer):
+ (gl::RenderbufferStorage::isDepthbuffer):
+ (gl::RenderbufferStorage::isStencilbuffer):
+ (gl::RenderbufferStorage::getRenderTarget):
+ (gl::RenderbufferStorage::getDepthStencil):
+ (gl::RenderbufferStorage::getWidth):
+ (gl::RenderbufferStorage::getHeight):
+ (gl::RenderbufferStorage::setSize):
+ (gl::RenderbufferStorage::getFormat):
+ (gl::RenderbufferStorage::getD3DFormat):
+ (gl::RenderbufferStorage::getSamples):
+ (gl::RenderbufferStorage::getSerial):
+ (gl::RenderbufferStorage::issueSerial):
+ (gl::Colorbuffer::Colorbuffer):
+ (gl::Colorbuffer::isColorbuffer):
+ (gl::Colorbuffer::getRedSize):
+ (gl::Colorbuffer::getGreenSize):
+ (gl::Colorbuffer::getBlueSize):
+ (gl::Colorbuffer::getAlphaSize):
+ (gl::DepthStencilbuffer::DepthStencilbuffer):
+ (gl::DepthStencilbuffer::~DepthStencilbuffer):
+ (gl::DepthStencilbuffer::isDepthbuffer):
+ (gl::DepthStencilbuffer::isStencilbuffer):
+ (gl::DepthStencilbuffer::getDepthSize):
+ (gl::DepthStencilbuffer::getStencilSize):
+ (gl::DepthStencilbuffer::getDepthStencil):
+ (gl::Depthbuffer::Depthbuffer):
+ (gl::Depthbuffer::~Depthbuffer):
+ (gl::Depthbuffer::isDepthbuffer):
+ (gl::Depthbuffer::isStencilbuffer):
+ (gl::Stencilbuffer::Stencilbuffer):
+ (gl::Stencilbuffer::~Stencilbuffer):
+ (gl::Stencilbuffer::isDepthbuffer):
+ (gl::Stencilbuffer::isStencilbuffer):
+ * src/libGLESv2/Renderbuffer.h:
+ (gl::Renderbuffer::getStorage):
+ * src/libGLESv2/ResourceManager.cpp: Added.
+ (gl::ResourceManager::ResourceManager):
+ (gl::ResourceManager::~ResourceManager):
+ (gl::ResourceManager::addRef):
+ (gl::ResourceManager::release):
+ (gl::ResourceManager::createBuffer):
+ (gl::ResourceManager::createShader):
+ (gl::ResourceManager::createProgram):
+ (gl::ResourceManager::createTexture):
+ (gl::ResourceManager::createRenderbuffer):
+ (gl::ResourceManager::deleteBuffer):
+ (gl::ResourceManager::deleteShader):
+ (gl::ResourceManager::deleteProgram):
+ (gl::ResourceManager::deleteTexture):
+ (gl::ResourceManager::deleteRenderbuffer):
+ (gl::ResourceManager::getBuffer):
+ (gl::ResourceManager::getShader):
+ (gl::ResourceManager::getTexture):
+ (gl::ResourceManager::getProgram):
+ (gl::ResourceManager::getRenderbuffer):
+ (gl::ResourceManager::setRenderbuffer):
+ (gl::ResourceManager::checkBufferAllocation):
+ (gl::ResourceManager::checkTextureAllocation):
+ (gl::ResourceManager::checkRenderbufferAllocation):
+ * src/libGLESv2/ResourceManager.h: Added.
+ * src/libGLESv2/Shader.cpp:
+ (gl::Shader::Shader):
+ (gl::Shader::addRef):
+ (gl::Shader::release):
+ (gl::Shader::getRefCount):
+ (gl::Shader::parseVaryings):
+ (gl::VertexShader::VertexShader):
+ (gl::FragmentShader::FragmentShader):
+ * src/libGLESv2/Shader.h:
+ * src/libGLESv2/Texture.cpp:
+ (gl::Texture::Image::Image):
+ (gl::Texture::Texture):
+ (gl::Texture::getBlitter):
+ (gl::Texture::selectFormat):
+ (gl::Texture::loadImageData):
+ (gl::Texture::loadAlphaImageData):
+ (gl::Texture::loadLuminanceImageData):
+ (gl::Texture::loadLuminanceAlphaImageData):
+ (gl::Texture::loadRGBUByteImageData):
+ (gl::Texture::loadRGB565ImageData):
+ (gl::Texture::loadRGBAUByteImageData):
+ (gl::Texture::loadRGBA4444ImageData):
+ (gl::Texture::loadRGBA5551ImageData):
+ (gl::Texture::loadBGRAImageData):
+ (gl::Texture::createSurface):
+ (gl::Texture::setImage):
+ (gl::Texture::setCompressedImage):
+ (gl::Texture::subImage):
+ (gl::Texture::subImageCompressed):
+ (gl::Texture2D::Texture2D):
+ (gl::Texture2D::getFormat):
+ (gl::Texture2D::setCompressedImage):
+ (gl::Texture2D::subImage):
+ (gl::Texture2D::subImageCompressed):
+ (gl::Texture2D::copyImage):
+ (gl::Texture2D::copySubImage):
+ (gl::Texture2D::isCompressed):
+ (gl::Texture2D::getColorbuffer):
+ (gl::TextureCubeMap::TextureCubeMap):
+ (gl::TextureCubeMap::getFormat):
+ (gl::TextureCubeMap::setCompressedImage):
+ (gl::TextureCubeMap::subImage):
+ (gl::TextureCubeMap::subImageCompressed):
+ (gl::TextureCubeMap::isCompressed):
+ (gl::TextureCubeMap::copyImage):
+ (gl::TextureCubeMap::copySubImage):
+ (gl::TextureCubeMap::getColorbuffer):
+ (gl::Texture::TextureColorbufferProxy::addRef):
+ (gl::Texture::TextureColorbufferProxy::release):
+ (gl::Texture::TextureColorbufferProxy::getWidth):
+ (gl::Texture::TextureColorbufferProxy::getHeight):
+ (gl::Texture::TextureColorbufferProxy::getFormat):
+ * src/libGLESv2/Texture.h:
+ * src/libGLESv2/libGLESv2.cpp:
+ * src/libGLESv2/libGLESv2.def:
+ * src/libGLESv2/libGLESv2.vcproj:
+ * src/libGLESv2/main.h:
+ * src/libGLESv2/utilities.cpp:
+ (gl::ComputeCompressedPitch):
+ (gl::ComputeCompressedSize):
+ (gl::IsCompressed):
+ (gl::ComputePixelSize):
+ (gl::CheckTextureFormatType):
+ (es2dx::ConvertRenderbufferFormat):
+ (es2dx::GetSamplesFromMultisampleType):
+ (es2dx::GetMultisampleTypeFromSamples):
+ * src/libGLESv2/utilities.h:
+
2010-08-17 Chris Marrin <cmarrin@apple.com>
Unreviewed.
diff --git a/ANGLE/include/GLES2/gl2ext.h b/ANGLE/include/GLES2/gl2ext.h
index 80a6820..01844de 100644
--- a/ANGLE/include/GLES2/gl2ext.h
+++ b/ANGLE/include/GLES2/gl2ext.h
@@ -222,6 +222,12 @@ typedef void* GLeglImageOES;
#define GL_UNSIGNED_INT_2_10_10_10_REV_EXT 0x8368
#endif
+/* GL_EXT_texture_compression_dxt1 */
+#ifndef GL_EXT_texture_compression_dxt1
+#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0
+#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1
+#endif
+
/*------------------------------------------------------------------------*
* IMG extension tokens
*------------------------------------------------------------------------*/
@@ -351,6 +357,25 @@ typedef void* GLeglImageOES;
#endif
/*------------------------------------------------------------------------*
+ * ANGLE extension tokens
+ *------------------------------------------------------------------------*/
+
+/* GL_ANGLE_framebuffer_blit */
+#ifndef GL_ANGLE_framebuffer_blit
+#define GL_READ_FRAMEBUFFER_ANGLE 0x8CA8
+#define GL_DRAW_FRAMEBUFFER_ANGLE 0x8CA9
+#define GL_DRAW_FRAMEBUFFER_BINDING_ANGLE 0x8CA6 // alias GL_FRAMEBUFFER_BINDING
+#define GL_READ_FRAMEBUFFER_BINDING_ANGLE 0x8CAA
+#endif
+
+/* GL_ANGLE_framebuffer_multisample */
+#ifndef GL_ANGLE_framebuffer_multisample
+#define GL_RENDERBUFFER_SAMPLES_ANGLE 0x8CAB
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE 0x8D56
+#define GL_MAX_SAMPLES_ANGLE 0x8D57
+#endif
+
+/*------------------------------------------------------------------------*
* End of extension tokens, start of corresponding extension functions
*------------------------------------------------------------------------*/
@@ -623,6 +648,11 @@ typedef void (GL_APIENTRYP PFNGLMULTIDRAWELEMENTSEXTPROC) (GLenum mode, const GL
#define GL_EXT_texture_type_2_10_10_10_REV 1
#endif
+/* GL_EXT_texture_compression_dxt1 */
+#ifndef GL_EXT_texture_compression_dxt1
+#define GL_EXT_texture_compression_dxt1 1
+#endif
+
/*------------------------------------------------------------------------*
* IMG extension functions
*------------------------------------------------------------------------*/
@@ -766,6 +796,34 @@ typedef void (GL_APIENTRYP PFNGLSTARTTILINGQCOMPROC) (GLuint x, GLuint y, GLuint
typedef void (GL_APIENTRYP PFNGLENDTILINGQCOMPROC) (GLbitfield preserveMask);
#endif
+/*------------------------------------------------------------------------*
+ * ANGLE extension functions
+ *------------------------------------------------------------------------*/
+
+/* GL_ANGLE_framebuffer_blit */
+#ifndef GL_ANGLE_framebuffer_blit
+#define GL_ANGLE_framebuffer_blit 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glBlitFramebufferANGLE (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
+ GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
+ GLbitfield mask, GLenum filter);
+#endif
+typedef void (GL_APIENTRYP PFNGLBLITFRAMEBUFFERANGLEPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
+ GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
+ GLbitfield mask, GLenum filter);
+#endif
+
+/* GL_ANGLE_framebuffer_multisample */
+#ifndef GL_ANGLE_framebuffer_multisample
+#define GL_ANGLE_framebuffer_multisample 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleANGLE (GLenum target, GLsizei samples, GLenum internalformat,
+ GLsizei width, GLsizei height);
+#endif
+typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEANGLEPROC) (GLenum target, GLsizei samples, GLenum internalformat,
+ GLsizei width, GLsizei height);
+#endif
+
#ifdef __cplusplus
}
#endif
diff --git a/ANGLE/include/GLSLANG/ResourceLimits.h b/ANGLE/include/GLSLANG/ResourceLimits.h
deleted file mode 100644
index 7b7a4b7..0000000
--- a/ANGLE/include/GLSLANG/ResourceLimits.h
+++ /dev/null
@@ -1,21 +0,0 @@
-//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-
-#ifndef _RESOURCE_LIMITS_INCLUDED_
-#define _RESOURCE_LIMITS_INCLUDED_
-
-struct TBuiltInResource
-{
- int maxVertexAttribs;
- int maxVertexUniformVectors;
- int maxVaryingVectors;
- int maxVertexTextureImageUnits;
- int maxCombinedTextureImageUnits;
- int maxTextureImageUnits;
- int maxFragmentUniformVectors;
- int maxDrawBuffers;
-};
-#endif // _RESOURCE_LIMITS_INCLUDED_
diff --git a/ANGLE/include/GLSLANG/ShaderLang.h b/ANGLE/include/GLSLANG/ShaderLang.h
index 19e6df0..e0a5cc8 100644
--- a/ANGLE/include/GLSLANG/ShaderLang.h
+++ b/ANGLE/include/GLSLANG/ShaderLang.h
@@ -6,8 +6,6 @@
#ifndef _COMPILER_INTERFACE_INCLUDED_
#define _COMPILER_INTERFACE_INCLUDED_
-#include "ResourceLimits.h"
-
//
// This is the platform independent interface between an OGL driver
// and the shading language compiler.
@@ -19,10 +17,12 @@ extern "C" {
//
// Driver must call this first, once, before doing any other
// compiler operations.
+// If the function succeeds, the return value is nonzero, else zero.
//
int ShInitialize();
//
// Driver should call this at shutdown.
+// If the function succeeds, the return value is nonzero, else zero.
//
int ShFinalize();
//
@@ -44,6 +44,32 @@ typedef enum {
} EShSpec;
//
+// Implementation dependent built-in resources (constants and extensions).
+// The names for these resources has been obtained by stripping gl_/GL_.
+//
+typedef struct
+{
+ // Constants.
+ int MaxVertexAttribs;
+ int MaxVertexUniformVectors;
+ int MaxVaryingVectors;
+ int MaxVertexTextureImageUnits;
+ int MaxCombinedTextureImageUnits;
+ int MaxTextureImageUnits;
+ int MaxFragmentUniformVectors;
+ int MaxDrawBuffers;
+
+ // Extensions.
+ // Set to 1 to enable the extension, else 0.
+ int OES_standard_derivatives;
+} TBuiltInResource;
+
+//
+// Initialize built-in resources with minimum expected values.
+//
+void ShInitBuiltInResource(TBuiltInResource* resources);
+
+//
// Optimization level for the compiler.
//
typedef enum {
diff --git a/ANGLE/src/compiler/BaseTypes.h b/ANGLE/src/compiler/BaseTypes.h
index cb646fc..9f4a860 100644
--- a/ANGLE/src/compiler/BaseTypes.h
+++ b/ANGLE/src/compiler/BaseTypes.h
@@ -19,7 +19,7 @@ enum TPrecision
EbpHigh,
};
-__inline const char* getPrecisionString(TPrecision p)
+inline const char* getPrecisionString(TPrecision p)
{
switch(p)
{
@@ -47,7 +47,22 @@ enum TBasicType
EbtAddress, // should be deprecated??
};
-__inline bool IsSampler(TBasicType type)
+inline const char* getBasicString(TBasicType t)
+{
+ switch (t)
+ {
+ case EbtVoid: return "void"; break;
+ case EbtFloat: return "float"; break;
+ case EbtInt: return "int"; break;
+ case EbtBool: return "bool"; break;
+ case EbtSampler2D: return "sampler2D"; break;
+ case EbtSamplerCube: return "samplerCube"; break;
+ case EbtStruct: return "structure"; break;
+ default: return "unknown type";
+ }
+}
+
+inline bool IsSampler(TBasicType type)
{
return type > EbtGuardSamplerBegin && type < EbtGuardSamplerEnd;
}
@@ -100,7 +115,7 @@ enum TQualifier
//
// This is just for debug print out, carried along with the definitions above.
//
-__inline const char* getQualifierString(TQualifier q)
+inline const char* getQualifierString(TQualifier q)
{
switch(q)
{
diff --git a/ANGLE/src/compiler/Initialize.cpp b/ANGLE/src/compiler/Initialize.cpp
index 58c6162..6bfcf4f 100644
--- a/ANGLE/src/compiler/Initialize.cpp
+++ b/ANGLE/src/compiler/Initialize.cpp
@@ -472,15 +472,15 @@ static TString BuiltInConstants(const TBuiltInResource &resources)
{
TStringStream s;
- s << "const int gl_MaxVertexAttribs = " << resources.maxVertexAttribs << ";";
- s << "const int gl_MaxVertexUniformVectors = " << resources.maxVertexUniformVectors << ";";
+ s << "const int gl_MaxVertexAttribs = " << resources.MaxVertexAttribs << ";";
+ s << "const int gl_MaxVertexUniformVectors = " << resources.MaxVertexUniformVectors << ";";
- s << "const int gl_MaxVaryingVectors = " << resources.maxVaryingVectors << ";";
- s << "const int gl_MaxVertexTextureImageUnits = " << resources.maxVertexTextureImageUnits << ";";
- s << "const int gl_MaxCombinedTextureImageUnits = " << resources.maxCombinedTextureImageUnits << ";";
- s << "const int gl_MaxTextureImageUnits = " << resources.maxTextureImageUnits << ";";
- s << "const int gl_MaxFragmentUniformVectors = " << resources.maxFragmentUniformVectors << ";";
- s << "const int gl_MaxDrawBuffers = " << resources.maxDrawBuffers << ";";
+ s << "const int gl_MaxVaryingVectors = " << resources.MaxVaryingVectors << ";";
+ s << "const int gl_MaxVertexTextureImageUnits = " << resources.MaxVertexTextureImageUnits << ";";
+ s << "const int gl_MaxCombinedTextureImageUnits = " << resources.MaxCombinedTextureImageUnits << ";";
+ s << "const int gl_MaxTextureImageUnits = " << resources.MaxTextureImageUnits << ";";
+ s << "const int gl_MaxFragmentUniformVectors = " << resources.MaxFragmentUniformVectors << ";";
+ s << "const int gl_MaxDrawBuffers = " << resources.MaxDrawBuffers << ";";
return s.str();
}
@@ -591,23 +591,23 @@ void IdentifyBuiltIns(EShLanguage language, EShSpec spec, const TBuiltInResource
symbolTable.relateToOperator("all", EOpAll);
// Map language-specific operators.
- switch(language) {
- case EShLangVertex:
- break;
- case EShLangFragment:
- //symbolTable.relateToOperator("dFdx", EOpDPdx); // OES_standard_derivatives extension
- //symbolTable.relateToOperator("dFdy", EOpDPdy); // OES_standard_derivatives extension
- //symbolTable.relateToOperator("fwidth", EOpFwidth); // OES_standard_derivatives extension
- break;
- default: break;
- }
+ switch(language) {
+ case EShLangVertex:
+ break;
+ case EShLangFragment:
+ //symbolTable.relateToOperator("dFdx", EOpDPdx); // OES_standard_derivatives extension
+ //symbolTable.relateToOperator("dFdy", EOpDPdy); // OES_standard_derivatives extension
+ //symbolTable.relateToOperator("fwidth", EOpFwidth); // OES_standard_derivatives extension
+ break;
+ default: break;
+ }
// Finally add resource-specific variables.
switch(language) {
case EShLangFragment: {
// Set up gl_FragData. The array size.
TType fragData(EbtFloat, EbpMedium, EvqFragColor, 4, false, true);
- fragData.setArraySize(resources.maxDrawBuffers);
+ fragData.setArraySize(resources.MaxDrawBuffers);
symbolTable.insert(*new TVariable(NewPoolTString("gl_FragData"), fragData));
}
break;
diff --git a/ANGLE/src/compiler/Initialize.h b/ANGLE/src/compiler/Initialize.h
index 03c9937..c078659 100644
--- a/ANGLE/src/compiler/Initialize.h
+++ b/ANGLE/src/compiler/Initialize.h
@@ -7,8 +7,6 @@
#ifndef _INITIALIZE_INCLUDED_
#define _INITIALIZE_INCLUDED_
-#include "GLSLANG/ResourceLimits.h"
-
#include "compiler/Common.h"
#include "compiler/ShHandle.h"
#include "compiler/SymbolTable.h"
diff --git a/ANGLE/src/compiler/InitializeDll.cpp b/ANGLE/src/compiler/InitializeDll.cpp
index 06f8384..8763cfe 100644
--- a/ANGLE/src/compiler/InitializeDll.cpp
+++ b/ANGLE/src/compiler/InitializeDll.cpp
@@ -6,72 +6,88 @@
#include "compiler/InitializeDll.h"
-#include "GLSLANG/ShaderLang.h"
-
#include "compiler/InitializeGlobals.h"
#include "compiler/InitializeParseContext.h"
+#include "compiler/osinclude.h"
OS_TLSIndex ThreadInitializeIndex = OS_INVALID_TLS_INDEX;
bool InitProcess()
{
if (ThreadInitializeIndex != OS_INVALID_TLS_INDEX) {
- //
- // Function is re-entrant.
- //
+ //
+ // Function is re-entrant.
+ //
return true;
- }
+ }
ThreadInitializeIndex = OS_AllocTLSIndex();
if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX) {
assert(0 && "InitProcess(): Failed to allocate TLS area for init flag");
return false;
- }
+ }
if (!InitializePoolIndex()) {
assert(0 && "InitProcess(): Failed to initalize global pool");
return false;
- }
+ }
if (!InitializeParseContextIndex()) {
assert(0 && "InitProcess(): Failed to initalize parse context");
return false;
- }
+ }
- InitThread();
- return true;
+ return InitThread();
}
+bool DetachProcess()
+{
+ bool success = true;
+
+ if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX)
+ return true;
+
+ success = DetachThread();
+
+ if (!FreeParseContextIndex())
+ success = false;
+
+ FreePoolIndex();
+
+ OS_FreeTLSIndex(ThreadInitializeIndex);
+ ThreadInitializeIndex = OS_INVALID_TLS_INDEX;
+
+ return success;
+}
bool InitThread()
{
- //
+ //
// This function is re-entrant
- //
+ //
if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX) {
- assert(0 && "InitThread(): Process hasn't been initalised.");
+ assert(0 && "InitThread(): Process hasn't been initalised.");
return false;
- }
+ }
if (OS_GetTLSValue(ThreadInitializeIndex) != 0)
return true;
- InitializeGlobalPools();
+ InitializeGlobalPools();
- if (!InitializeGlobalParseContext())
+ if (!InitializeGlobalParseContext())
return false;
if (!OS_SetTLSValue(ThreadInitializeIndex, (void *)1)) {
- assert(0 && "InitThread(): Unable to set init flag.");
+ assert(0 && "InitThread(): Unable to set init flag.");
return false;
- }
+ }
return true;
}
-
bool DetachThread()
{
bool success = true;
@@ -79,42 +95,21 @@ bool DetachThread()
if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX)
return true;
- //
- // Function is re-entrant and this thread may not have been initalised.
- //
+ //
+ // Function is re-entrant and this thread may not have been initalised.
+ //
if (OS_GetTLSValue(ThreadInitializeIndex) != 0) {
if (!OS_SetTLSValue(ThreadInitializeIndex, (void *)0)) {
- assert(0 && "DetachThread(): Unable to clear init flag.");
+ assert(0 && "DetachThread(): Unable to clear init flag.");
success = false;
- }
+ }
- FreeGlobalPools();
-
- if (!FreeParseContext())
+ if (!FreeParseContext())
success = false;
- }
-
- return success;
-}
-
-bool DetachProcess()
-{
- bool success = true;
-
- if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX)
- return true;
-
- ShFinalize();
-
- success = DetachThread();
-
- FreePoolIndex();
- if (!FreeParseContextIndex())
- success = false;
-
- OS_FreeTLSIndex(ThreadInitializeIndex);
- ThreadInitializeIndex = OS_INVALID_TLS_INDEX;
+ FreeGlobalPools();
+ }
return success;
}
+
diff --git a/ANGLE/src/compiler/InitializeDll.h b/ANGLE/src/compiler/InitializeDll.h
index bb17540..857238e 100644
--- a/ANGLE/src/compiler/InitializeDll.h
+++ b/ANGLE/src/compiler/InitializeDll.h
@@ -6,14 +6,11 @@
#ifndef __INITIALIZEDLL_H
#define __INITIALIZEDLL_H
-
-#include "compiler/osinclude.h"
-
-
bool InitProcess();
+bool DetachProcess();
+
bool InitThread();
bool DetachThread();
-bool DetachProcess();
#endif // __INITIALIZEDLL_H
diff --git a/ANGLE/src/compiler/InitializeParseContext.h b/ANGLE/src/compiler/InitializeParseContext.h
index 68295d0..760fd09 100644
--- a/ANGLE/src/compiler/InitializeParseContext.h
+++ b/ANGLE/src/compiler/InitializeParseContext.h
@@ -6,12 +6,11 @@
#ifndef __INITIALIZE_PARSE_CONTEXT_INCLUDED_
#define __INITIALIZE_PARSE_CONTEXT_INCLUDED_
-#include "compiler/osinclude.h"
bool InitializeParseContextIndex();
-bool InitializeGlobalParseContext();
-bool FreeParseContext();
bool FreeParseContextIndex();
+bool InitializeGlobalParseContext();
+bool FreeParseContext();
#endif // __INITIALIZE_PARSE_CONTEXT_INCLUDED_
diff --git a/ANGLE/src/compiler/Intermediate.cpp b/ANGLE/src/compiler/Intermediate.cpp
index f65bc80..5ebd919 100644
--- a/ANGLE/src/compiler/Intermediate.cpp
+++ b/ANGLE/src/compiler/Intermediate.cpp
@@ -10,6 +10,7 @@
#include <float.h>
#include <limits.h>
+#include <algorithm>
#include "compiler/localintermediate.h"
#include "compiler/QualifierAlive.h"
@@ -17,9 +18,10 @@
bool CompareStructure(const TType& leftNodeType, ConstantUnion* rightUnionArray, ConstantUnion* leftUnionArray);
-TPrecision GetHighestPrecision( TPrecision left, TPrecision right ){
+static TPrecision GetHigherPrecision( TPrecision left, TPrecision right ){
return left > right ? left : right;
}
+
////////////////////////////////////////////////////////////////////////////
//
// First set of functions are to help build the intermediate representation.
@@ -111,12 +113,6 @@ TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIn
TIntermConstantUnion *leftTempConstant = left->getAsConstantUnion();
TIntermConstantUnion *rightTempConstant = right->getAsConstantUnion();
- if (leftTempConstant)
- leftTempConstant = left->getAsConstantUnion();
-
- if (rightTempConstant)
- rightTempConstant = right->getAsConstantUnion();
-
//
// See if we can fold constants.
//
@@ -307,7 +303,7 @@ TIntermAggregate* TIntermediate::setAggregateOperator(TIntermNode* node, TOperat
//
// Set the operator.
//
- aggNode->setOperator(op);
+ aggNode->setOp(op);
if (line != 0)
aggNode->setLine(line);
@@ -519,9 +515,9 @@ TIntermTyped* TIntermediate::addComma(TIntermTyped* left, TIntermTyped* right, T
return right;
} else {
TIntermTyped *commaAggregate = growAggregate(left, right, line);
- commaAggregate->getAsAggregate()->setOperator(EOpComma);
+ commaAggregate->getAsAggregate()->setOp(EOpComma);
commaAggregate->setType(right->getType());
- commaAggregate->getTypePointer()->changeQualifier(EvqTemporary);
+ commaAggregate->getTypePointer()->setQualifier(EvqTemporary);
return commaAggregate;
}
}
@@ -644,7 +640,7 @@ bool TIntermediate::postProcess(TIntermNode* root, EShLanguage language)
//
TIntermAggregate* aggRoot = root->getAsAggregate();
if (aggRoot && aggRoot->getOp() == EOpNull)
- aggRoot->setOperator(EOpSequence);
+ aggRoot->setOp(EOpSequence);
return true;
}
@@ -764,16 +760,9 @@ bool TIntermUnary::promote(TInfoSink&)
//
bool TIntermBinary::promote(TInfoSink& infoSink)
{
- int size = left->getNominalSize();
- if (right->getNominalSize() > size)
- size = right->getNominalSize();
-
- TBasicType type = left->getBasicType();
-
- //
- // Arrays have to be exact matches.
- //
- if ((left->isArray() || right->isArray()) && (left->getType() != right->getType()))
+ // GLSL ES 2.0 does not support implicit type casting.
+ // So the basic type should always match.
+ if (left->getBasicType() != right->getBasicType())
return false;
//
@@ -782,16 +771,27 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
//
setType(left->getType());
- TPrecision highestPrecision = GetHighestPrecision(left->getPrecision(), right->getPrecision());
- getTypePointer()->changePrecision(highestPrecision);
+ // The result gets promoted to the highest precision.
+ TPrecision higherPrecision = GetHigherPrecision(left->getPrecision(), right->getPrecision());
+ getTypePointer()->setPrecision(higherPrecision);
+
+ // Binary operations results in temporary variables unless both
+ // operands are const.
+ if (left->getQualifier() != EvqConst || right->getQualifier() != EvqConst) {
+ getTypePointer()->setQualifier(EvqTemporary);
+ }
//
// Array operations.
//
- if (left->isArray()) {
+ if (left->isArray() || right->isArray()) {
+ //
+ // Arrays types have to be exact matches.
+ //
+ if (left->getType() != right->getType())
+ return false;
switch (op) {
-
//
// Promote to conditional
//
@@ -812,17 +812,16 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
default:
return false;
}
-
return true;
}
+ int size = std::max(left->getNominalSize(), right->getNominalSize());
+
//
- // All scalars. Code after this test assumes this case is removed!
+ // All scalars. Code after this test assumes this case is removed!
//
if (size == 1) {
-
switch (op) {
-
//
// Promote to conditional
//
@@ -840,33 +839,36 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
//
case EOpLogicalAnd:
case EOpLogicalOr:
+ // Both operands must be of type bool.
if (left->getBasicType() != EbtBool || right->getBasicType() != EbtBool)
return false;
setType(TType(EbtBool, EbpUndefined));
break;
- //
- // Everything else should have matching types
- //
default:
- if (left->getBasicType() != right->getBasicType() ||
- left->isMatrix() != right->isMatrix())
- return false;
+ break;
}
-
return true;
}
- //
+ // If we reach here, at least one of the operands is vector or matrix.
+ // The other operand could be a scalar, vector, or matrix.
// Are the sizes compatible?
//
- if ( left->getNominalSize() != size && left->getNominalSize() != 1 ||
- right->getNominalSize() != size && right->getNominalSize() != 1)
- return false;
+ if (left->getNominalSize() != right->getNominalSize()) {
+ // If the nominal size of operands do not match:
+ // One of them must be scalar.
+ if (left->getNominalSize() != 1 && right->getNominalSize() != 1)
+ return false;
+ // Operator cannot be of type pure assignment.
+ if (op == EOpAssign || op == EOpInitialize)
+ return false;
+ }
//
// Can these two operands be combined?
//
+ TBasicType basicType = left->getBasicType();
switch (op) {
case EOpMul:
if (!left->isMatrix() && right->isMatrix()) {
@@ -874,12 +876,12 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
op = EOpVectorTimesMatrix;
else {
op = EOpMatrixTimesScalar;
- setType(TType(type, highestPrecision, EvqTemporary, size, true));
+ setType(TType(basicType, higherPrecision, EvqTemporary, size, true));
}
} else if (left->isMatrix() && !right->isMatrix()) {
if (right->isVector()) {
op = EOpMatrixTimesVector;
- setType(TType(type, highestPrecision, EvqTemporary, size, false));
+ setType(TType(basicType, higherPrecision, EvqTemporary, size, false));
} else {
op = EOpMatrixTimesScalar;
}
@@ -890,7 +892,7 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
// leave as component product
} else if (left->isVector() || right->isVector()) {
op = EOpVectorTimesScalar;
- setType(TType(type, highestPrecision, EvqTemporary, size, false));
+ setType(TType(basicType, higherPrecision, EvqTemporary, size, false));
}
} else {
infoSink.info.message(EPrefixInternalError, "Missing elses", getLine());
@@ -919,18 +921,16 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
if (! left->isVector())
return false;
op = EOpVectorTimesScalarAssign;
- setType(TType(type, highestPrecision, EvqTemporary, size, false));
+ setType(TType(basicType, higherPrecision, EvqTemporary, size, false));
}
} else {
infoSink.info.message(EPrefixInternalError, "Missing elses", getLine());
return false;
}
break;
+
case EOpAssign:
case EOpInitialize:
- if (left->getNominalSize() != right->getNominalSize())
- return false;
- // fall through
case EOpAdd:
case EOpSub:
case EOpDiv:
@@ -938,10 +938,9 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
case EOpSubAssign:
case EOpDivAssign:
if (left->isMatrix() && right->isVector() ||
- left->isVector() && right->isMatrix() ||
- left->getBasicType() != right->getBasicType())
+ left->isVector() && right->isMatrix())
return false;
- setType(TType(type, highestPrecision, EvqTemporary, size, left->isMatrix() || right->isMatrix()));
+ setType(TType(basicType, higherPrecision, EvqTemporary, size, left->isMatrix() || right->isMatrix()));
break;
case EOpEqual:
@@ -951,8 +950,7 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
case EOpLessThanEqual:
case EOpGreaterThanEqual:
if (left->isMatrix() && right->isVector() ||
- left->isVector() && right->isMatrix() ||
- left->getBasicType() != right->getBasicType())
+ left->isVector() && right->isMatrix())
return false;
setType(TType(EbtBool, EbpUndefined));
break;
@@ -960,30 +958,13 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
default:
return false;
}
-
- //
- // One more check for assignment. The Resulting type has to match the left operand.
- //
- switch (op) {
- case EOpAssign:
- case EOpInitialize:
- case EOpAddAssign:
- case EOpSubAssign:
- case EOpMulAssign:
- case EOpDivAssign:
- if (getType() != left->getType())
- return false;
- break;
- default:
- break;
- }
-
+
return true;
}
bool CompareStruct(const TType& leftNodeType, ConstantUnion* rightUnionArray, ConstantUnion* leftUnionArray)
{
- TTypeList* fields = leftNodeType.getStruct();
+ const TTypeList* fields = leftNodeType.getStruct();
size_t structSize = fields->size();
int index = 0;
diff --git a/ANGLE/src/compiler/OutputGLSL.cpp b/ANGLE/src/compiler/OutputGLSL.cpp
index 486a27a..fd263b6 100644
--- a/ANGLE/src/compiler/OutputGLSL.cpp
+++ b/ANGLE/src/compiler/OutputGLSL.cpp
@@ -147,7 +147,7 @@ void TOutputGLSL::writeFunctionParameters(const TIntermSequence& args)
out << arrayBrackets(type);
// Put a comma if this is not the last argument.
- if (iter != --args.end())
+ if (iter != args.end() - 1)
out << ", ";
}
}
@@ -304,8 +304,6 @@ bool TOutputGLSL::visitBinary(Visit visit, TIntermBinary* node)
bool TOutputGLSL::visitUnary(Visit visit, TIntermUnary* node)
{
- TInfoSinkBase& out = objSink();
-
switch (node->getOp())
{
case EOpNegative: writeTriplet(visit, "(-", NULL, ")"); break;
@@ -650,8 +648,6 @@ bool TOutputGLSL::visitLoop(Visit visit, TIntermLoop* node)
bool TOutputGLSL::visitBranch(Visit visit, TIntermBranch* node)
{
- TInfoSinkBase &out = objSink();
-
switch (node->getFlowOp())
{
case EOpKill: writeTriplet(visit, "discard", NULL, NULL); break;
diff --git a/ANGLE/src/compiler/OutputHLSL.cpp b/ANGLE/src/compiler/OutputHLSL.cpp
index 36f527c..8b8a4e6 100644
--- a/ANGLE/src/compiler/OutputHLSL.cpp
+++ b/ANGLE/src/compiler/OutputHLSL.cpp
@@ -181,7 +181,7 @@ void OutputHLSL::header()
if (mUsesFragCoord)
{
- out << "uniform float4 dx_Window;\n"
+ out << "uniform float4 dx_Viewport;\n"
"uniform float2 dx_Depth;\n";
}
@@ -791,11 +791,11 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node)
{
if (node->getLeft()->isMatrix())
{
- switch (node->getLeft()->getSize())
+ switch (node->getLeft()->getNominalSize())
{
- case 2 * 2: mUsesEqualMat2 = true; break;
- case 3 * 3: mUsesEqualMat3 = true; break;
- case 4 * 4: mUsesEqualMat4 = true; break;
+ case 2: mUsesEqualMat2 = true; break;
+ case 3: mUsesEqualMat3 = true; break;
+ case 4: mUsesEqualMat4 = true; break;
default: UNREACHABLE();
}
}
@@ -804,7 +804,7 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node)
switch (node->getLeft()->getBasicType())
{
case EbtFloat:
- switch (node->getLeft()->getSize())
+ switch (node->getLeft()->getNominalSize())
{
case 2: mUsesEqualVec2 = true; break;
case 3: mUsesEqualVec3 = true; break;
@@ -813,7 +813,7 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node)
}
break;
case EbtInt:
- switch (node->getLeft()->getSize())
+ switch (node->getLeft()->getNominalSize())
{
case 2: mUsesEqualIVec2 = true; break;
case 3: mUsesEqualIVec3 = true; break;
@@ -822,7 +822,7 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node)
}
break;
case EbtBool:
- switch (node->getLeft()->getSize())
+ switch (node->getLeft()->getNominalSize())
{
case 2: mUsesEqualBVec2 = true; break;
case 3: mUsesEqualBVec3 = true; break;
@@ -1288,7 +1288,7 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
case EOpVectorNotEqual: outputTriplet(visit, "(", " != ", ")"); break;
case EOpMod:
{
- switch (node->getSequence()[0]->getAsTyped()->getSize()) // Number of components in the first argument
+ switch (node->getSequence()[0]->getAsTyped()->getNominalSize()) // Number of components in the first argument
{
case 1: mUsesMod1 = true; break;
case 2: mUsesMod2 = true; break;
@@ -1317,7 +1317,7 @@ bool OutputHLSL::visitAggregate(Visit visit, TIntermAggregate *node)
case EOpCross: outputTriplet(visit, "cross(", ", ", ")"); break;
case EOpFaceForward:
{
- switch (node->getSequence()[0]->getAsTyped()->getSize()) // Number of components in the first argument
+ switch (node->getSequence()[0]->getAsTyped()->getNominalSize()) // Number of components in the first argument
{
case 1: mUsesFaceforward1 = true; break;
case 2: mUsesFaceforward2 = true; break;
@@ -1553,7 +1553,7 @@ bool OutputHLSL::handleExcessiveLoop(TIntermLoop *node)
if (symbol && constant)
{
- if (constant->getBasicType() == EbtInt && constant->getSize() == 1)
+ if (constant->getBasicType() == EbtInt && constant->getNominalSize() == 1)
{
index = symbol;
initial = constant->getUnionArrayPointer()[0].getIConst();
@@ -1575,7 +1575,7 @@ bool OutputHLSL::handleExcessiveLoop(TIntermLoop *node)
if (constant)
{
- if (constant->getBasicType() == EbtInt && constant->getSize() == 1)
+ if (constant->getBasicType() == EbtInt && constant->getNominalSize() == 1)
{
comparator = test->getOp();
limit = constant->getUnionArrayPointer()[0].getIConst();
@@ -1597,7 +1597,7 @@ bool OutputHLSL::handleExcessiveLoop(TIntermLoop *node)
if (constant)
{
- if (constant->getBasicType() == EbtInt && constant->getSize() == 1)
+ if (constant->getBasicType() == EbtInt && constant->getNominalSize() == 1)
{
int value = constant->getUnionArrayPointer()[0].getIConst();
@@ -1848,8 +1848,8 @@ void OutputHLSL::addConstructor(const TType &type, const TString &name, const TI
TType ctorType = type;
ctorType.clearArrayness();
- ctorType.changePrecision(EbpHigh);
- ctorType.changeQualifier(EvqTemporary);
+ ctorType.setPrecision(EbpHigh);
+ ctorType.setQualifier(EvqTemporary);
TString ctorName = type.getStruct() ? decorate(name) : name;
diff --git a/ANGLE/src/compiler/ParseHelper.cpp b/ANGLE/src/compiler/ParseHelper.cpp
index f1ab572..407226b 100644
--- a/ANGLE/src/compiler/ParseHelper.cpp
+++ b/ANGLE/src/compiler/ParseHelper.cpp
@@ -486,7 +486,7 @@ bool TParseContext::constructorErrorCheck(int line, TIntermNode* node, TFunction
}
if (constType)
- type->changeQualifier(EvqConst);
+ type->setQualifier(EvqConst);
if (type->isArray() && type->getArraySize() != function.getParamCount()) {
error(line, "array constructor needs one argument per array element", "constructor", "");
@@ -586,14 +586,14 @@ bool TParseContext::samplerErrorCheck(int line, const TPublicType& pType, const
{
if (pType.type == EbtStruct) {
if (containsSampler(*pType.userDef)) {
- error(line, reason, TType::getBasicString(pType.type), "(structure contains a sampler)");
+ error(line, reason, getBasicString(pType.type), "(structure contains a sampler)");
return true;
}
return false;
} else if (IsSampler(pType.type)) {
- error(line, reason, TType::getBasicString(pType.type), "");
+ error(line, reason, getBasicString(pType.type), "");
return true;
}
@@ -879,9 +879,9 @@ bool TParseContext::paramErrorCheck(int line, TQualifier qualifier, TQualifier p
}
if (qualifier == EvqConst)
- type->changeQualifier(EvqConstReadOnly);
+ type->setQualifier(EvqConstReadOnly);
else
- type->changeQualifier(paramQualifier);
+ type->setQualifier(paramQualifier);
return false;
}
@@ -913,21 +913,24 @@ bool TParseContext::extensionErrorCheck(int line, const char* extension)
//
const TFunction* TParseContext::findFunction(int line, TFunction* call, bool *builtIn)
{
- const TSymbol* symbol = symbolTable.find(call->getMangledName(), builtIn);
+ // First find by unmangled name to check whether the function name has been
+ // hidden by a variable name or struct typename.
+ const TSymbol* symbol = symbolTable.find(call->getName(), builtIn);
+ if (symbol == 0) {
+ symbol = symbolTable.find(call->getMangledName(), builtIn);
+ }
- if (symbol == 0) {
+ if (symbol == 0) {
error(line, "no matching overloaded function found", call->getName().c_str(), "");
return 0;
}
- if (! symbol->isFunction()) {
+ if (!symbol->isFunction()) {
error(line, "function name expected", call->getName().c_str(), "");
return 0;
}
-
- const TFunction* function = static_cast<const TFunction*>(symbol);
-
- return function;
+
+ return static_cast<const TFunction*>(symbol);
}
//
@@ -973,13 +976,13 @@ bool TParseContext::executeInitializer(TSourceLoc line, TString& identifier, TPu
if (qualifier == EvqConst) {
if (qualifier != initializer->getType().getQualifier()) {
error(line, " assigning non-constant to", "=", "'%s'", variable->getType().getCompleteString().c_str());
- variable->getType().changeQualifier(EvqTemporary);
+ variable->getType().setQualifier(EvqTemporary);
return true;
}
if (type != initializer->getType()) {
error(line, " non-matching types for const initializer ",
variable->getType().getQualifierString(), "");
- variable->getType().changeQualifier(EvqTemporary);
+ variable->getType().setQualifier(EvqTemporary);
return true;
}
if (initializer->getAsConstantUnion()) {
@@ -998,7 +1001,7 @@ bool TParseContext::executeInitializer(TSourceLoc line, TString& identifier, TPu
variable->shareConstPointer(constArray);
} else {
error(line, " cannot assign to", "=", "'%s'", variable->getType().getCompleteString().c_str());
- variable->getType().changeQualifier(EvqTemporary);
+ variable->getType().setQualifier(EvqTemporary);
return true;
}
}
@@ -1049,7 +1052,7 @@ TIntermTyped* TParseContext::addConstructor(TIntermNode* node, const TType* type
TIntermAggregate* aggrNode = node->getAsAggregate();
- TTypeList::iterator memberTypes;
+ TTypeList::const_iterator memberTypes;
if (op == EOpConstructStruct)
memberTypes = type->getStruct()->begin();
@@ -1347,7 +1350,7 @@ TIntermTyped* TParseContext::addConstArrayNode(int index, TIntermTyped* node, TS
//
TIntermTyped* TParseContext::addConstStruct(TString& identifier, TIntermTyped* node, TSourceLoc line)
{
- TTypeList* fields = node->getType().getStruct();
+ const TTypeList* fields = node->getType().getStruct();
TIntermTyped *typedNode;
int instanceSize = 0;
unsigned int index = 0;
@@ -1410,6 +1413,20 @@ bool InitializeParseContextIndex()
return true;
}
+bool FreeParseContextIndex()
+{
+ OS_TLSIndex tlsiIndex = GlobalParseContextIndex;
+
+ if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) {
+ assert(0 && "FreeParseContextIndex(): Parse Context index not initalised");
+ return false;
+ }
+
+ GlobalParseContextIndex = OS_INVALID_TLS_INDEX;
+
+ return OS_FreeTLSIndex(tlsiIndex);
+}
+
bool InitializeGlobalParseContext()
{
if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) {
@@ -1435,17 +1452,6 @@ bool InitializeGlobalParseContext()
return true;
}
-TParseContextPointer& GetGlobalParseContext()
-{
- //
- // Minimal error checking for speed
- //
-
- TThreadParseContext *lpParseContext = static_cast<TThreadParseContext *>(OS_GetTLSValue(GlobalParseContextIndex));
-
- return lpParseContext->lpGlobalParseContext;
-}
-
bool FreeParseContext()
{
if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) {
@@ -1460,16 +1466,14 @@ bool FreeParseContext()
return true;
}
-bool FreeParseContextIndex()
+TParseContextPointer& GetGlobalParseContext()
{
- OS_TLSIndex tlsiIndex = GlobalParseContextIndex;
-
- if (GlobalParseContextIndex == OS_INVALID_TLS_INDEX) {
- assert(0 && "FreeParseContextIndex(): Parse Context index not initalised");
- return false;
- }
+ //
+ // Minimal error checking for speed
+ //
- GlobalParseContextIndex = OS_INVALID_TLS_INDEX;
+ TThreadParseContext *lpParseContext = static_cast<TThreadParseContext *>(OS_GetTLSValue(GlobalParseContextIndex));
- return OS_FreeTLSIndex(tlsiIndex);
+ return lpParseContext->lpGlobalParseContext;
}
+
diff --git a/ANGLE/src/compiler/PoolAlloc.h b/ANGLE/src/compiler/PoolAlloc.h
index 0fa3194..645db78 100644
--- a/ANGLE/src/compiler/PoolAlloc.h
+++ b/ANGLE/src/compiler/PoolAlloc.h
@@ -157,11 +157,12 @@ protected:
struct tHeader {
tHeader(tHeader* nextPage, size_t pageCount) :
+ nextPage(nextPage),
+ pageCount(pageCount)
#ifdef GUARD_BLOCKS
- lastAllocation(0),
+ , lastAllocation(0)
#endif
- nextPage(nextPage),
- pageCount(pageCount) { }
+ { }
~tHeader() {
#ifdef GUARD_BLOCKS
@@ -263,19 +264,26 @@ public:
template<class Other>
pool_allocator(const pool_allocator<Other>& p) : allocator(p.getAllocator()) { }
+#if defined(__SUNPRO_CC) && !defined(_RWSTD_ALLOCATOR)
+ // libCStd on some platforms have a different allocate/deallocate interface.
+ // Caller pre-bakes sizeof(T) into 'n' which is the number of bytes to be
+ // allocated, not the number of elements.
+ void* allocate(size_type n) {
+ return getAllocator().allocate(n);
+ }
+ void* allocate(size_type n, const void*) {
+ return getAllocator().allocate(n);
+ }
+ void deallocate(void*, size_type) {}
+#else
pointer allocate(size_type n) {
return reinterpret_cast<pointer>(getAllocator().allocate(n * sizeof(T)));
}
pointer allocate(size_type n, const void*) {
return reinterpret_cast<pointer>(getAllocator().allocate(n * sizeof(T)));
}
-
- void deallocate(void*, size_type) { }
- void deallocate(pointer, size_type) { }
-
- pointer _Charalloc(size_t n) {
- return reinterpret_cast<pointer>(getAllocator().allocate(n));
- }
+ void deallocate(pointer, size_type) {}
+#endif // _RWSTD_ALLOCATOR
void construct(pointer p, const T& val) { new ((void *)p) T(val); }
void destroy(pointer p) { p->T::~T(); }
diff --git a/ANGLE/src/compiler/ShaderLang.cpp b/ANGLE/src/compiler/ShaderLang.cpp
index 3c36ef8..e0c646a 100644
--- a/ANGLE/src/compiler/ShaderLang.cpp
+++ b/ANGLE/src/compiler/ShaderLang.cpp
@@ -90,15 +90,45 @@ static bool GenerateBuiltInSymbolTable(
//
int ShInitialize()
{
- bool ret = InitProcess();
+ if (!InitProcess())
+ return 0;
- return ret ? 1 : 0;
+ return 1;
}
//
-// Driver calls these to create and destroy compiler objects.
+// Cleanup symbol tables
+//
+int ShFinalize()
+{
+ if (!DetachProcess())
+ return 0;
+
+ return 1;
+}
+
+//
+// Initialize built-in resources with minimum expected values.
//
+void ShInitBuiltInResource(TBuiltInResource* resources)
+{
+ // Constants.
+ resources->MaxVertexAttribs = 8;
+ resources->MaxVertexUniformVectors = 128;
+ resources->MaxVaryingVectors = 8;
+ resources->MaxVertexTextureImageUnits = 0;
+ resources->MaxCombinedTextureImageUnits = 8;
+ resources->MaxTextureImageUnits = 8;
+ resources->MaxFragmentUniformVectors = 16;
+ resources->MaxDrawBuffers = 1;
+
+ // Extensions.
+ resources->OES_standard_derivatives = 0;
+}
+//
+// Driver calls these to create and destroy compiler objects.
+//
ShHandle ShConstructCompiler(EShLanguage language, EShSpec spec, const TBuiltInResource* resources)
{
if (!InitThread())
@@ -130,14 +160,6 @@ void ShDestruct(ShHandle handle)
}
//
-// Cleanup symbol tables
-//
-int ShFinalize()
-{
- return 1;
-}
-
-//
// Do an actual compile on the given strings. The result is left
// in the given compile object.
//
diff --git a/ANGLE/src/compiler/SymbolTable.cpp b/ANGLE/src/compiler/SymbolTable.cpp
index d97f0ec..1b08667 100644
--- a/ANGLE/src/compiler/SymbolTable.cpp
+++ b/ANGLE/src/compiler/SymbolTable.cpp
@@ -65,7 +65,7 @@ int TType::getStructSize() const
}
if (structureSize == 0)
- for (TTypeList::iterator tl = getStruct()->begin(); tl != getStruct()->end(); tl++)
+ for (TTypeList::const_iterator tl = getStruct()->begin(); tl != getStruct()->end(); tl++)
structureSize += ((*tl).type)->getObjectSize();
return structureSize;
diff --git a/ANGLE/src/compiler/SymbolTable.h b/ANGLE/src/compiler/SymbolTable.h
index 07c81d1..b1a80b5 100644
--- a/ANGLE/src/compiler/SymbolTable.h
+++ b/ANGLE/src/compiler/SymbolTable.h
@@ -76,7 +76,7 @@ public:
TType& getType() { return type; }
const TType& getType() const { return type; }
bool isUserType() const { return userType; }
- void changeQualifier(TQualifier qualifier) { type.changeQualifier(qualifier); }
+ void setQualifier(TQualifier qualifier) { type.setQualifier(qualifier); }
void updateArrayInformationType(TType *t) { arrayInformationType = t; }
TType* getArrayInformationType() { return arrayInformationType; }
diff --git a/ANGLE/src/compiler/Types.h b/ANGLE/src/compiler/Types.h
index 44511b4..897b28f 100644
--- a/ANGLE/src/compiler/Types.h
+++ b/ANGLE/src/compiler/Types.h
@@ -82,28 +82,27 @@ typedef TMap<TTypeList*, TTypeList*>::iterator TStructureMapIterator;
class TType {
public:
POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
- explicit TType(TBasicType t, TPrecision p, TQualifier q = EvqTemporary, int s = 1, bool m = false, bool a = false) :
- type(t), precision(p), qualifier(q), size(s), matrix(m), array(a), arraySize(0),
- structure(0), structureSize(0), maxArraySize(0), arrayInformationType(0), fieldName(0), mangled(0), typeName(0)
- { }
+ TType() {}
+ TType(TBasicType t, TPrecision p, TQualifier q = EvqTemporary, int s = 1, bool m = false, bool a = false) :
+ type(t), precision(p), qualifier(q), size(s), matrix(m), array(a), arraySize(0),
+ structure(0), structureSize(0), maxArraySize(0), arrayInformationType(0), fieldName(0), mangled(0), typeName(0)
+ {
+ }
explicit TType(const TPublicType &p) :
- type(p.type), precision(p.precision), qualifier(p.qualifier), size(p.size), matrix(p.matrix), array(p.array), arraySize(p.arraySize),
- structure(0), structureSize(0), maxArraySize(0), arrayInformationType(0), fieldName(0), mangled(0), typeName(0)
- {
- if (p.userDef) {
- structure = p.userDef->getStruct();
- typeName = NewPoolTString(p.userDef->getTypeName().c_str());
- }
- }
- explicit TType(TTypeList* userDef, const TString& n, TPrecision p = EbpUndefined) :
- type(EbtStruct), precision(p), qualifier(EvqTemporary), size(1), matrix(false), array(false), arraySize(0),
- structure(userDef), structureSize(0), maxArraySize(0), arrayInformationType(0), fieldName(0), mangled(0) {
- typeName = NewPoolTString(n.c_str());
- }
- explicit TType() {}
- virtual ~TType() {}
-
- TType(const TType& type) { *this = type; }
+ type(p.type), precision(p.precision), qualifier(p.qualifier), size(p.size), matrix(p.matrix), array(p.array), arraySize(p.arraySize),
+ structure(0), structureSize(0), maxArraySize(0), arrayInformationType(0), fieldName(0), mangled(0), typeName(0)
+ {
+ if (p.userDef) {
+ structure = p.userDef->getStruct();
+ typeName = NewPoolTString(p.userDef->getTypeName().c_str());
+ }
+ }
+ TType(TTypeList* userDef, const TString& n, TPrecision p = EbpUndefined) :
+ type(EbtStruct), precision(p), qualifier(EvqTemporary), size(1), matrix(false), array(false), arraySize(0),
+ structure(userDef), structureSize(0), maxArraySize(0), arrayInformationType(0), fieldName(0), mangled(0)
+ {
+ typeName = NewPoolTString(n.c_str());
+ }
void copyType(const TType& copyOf, TStructureMap& remapper)
{
@@ -157,77 +156,19 @@ public:
return newType;
}
- virtual void setType(TBasicType t, int s, bool m, bool a, int aS = 0)
- { type = t; size = s; matrix = m; array = a; arraySize = aS; }
- virtual void setType(TBasicType t, int s, bool m, TType* userDef = 0)
- { type = t;
- size = s;
- matrix = m;
- if (userDef)
- structure = userDef->getStruct();
- // leave array information intact.
- }
- virtual void setTypeName(const TString& n) { typeName = NewPoolTString(n.c_str()); }
- virtual void setFieldName(const TString& n) { fieldName = NewPoolTString(n.c_str()); }
- virtual const TString& getTypeName() const
- {
- assert(typeName);
- return *typeName;
- }
+ TBasicType getBasicType() const { return type; }
+ void setBasicType(TBasicType t) { type = t; }
- virtual const TString& getFieldName() const
- {
- assert(fieldName);
- return *fieldName;
- }
+ TPrecision getPrecision() const { return precision; }
+ void setPrecision(TPrecision p) { precision = p; }
- virtual TBasicType getBasicType() const { return type; }
- virtual TPrecision getPrecision() const { return precision; }
- virtual TQualifier getQualifier() const { return qualifier; }
- virtual void changePrecision(TPrecision p) { precision = p; }
- virtual void changeQualifier(TQualifier q) { qualifier = q; }
+ TQualifier getQualifier() const { return qualifier; }
+ void setQualifier(TQualifier q) { qualifier = q; }
// One-dimensional size of single instance type
- virtual int getNominalSize() const { return size; }
-
- // Full-dimensional size of single instance of type
- virtual int getInstanceSize() const
- {
- if (matrix)
- return size * size;
- else
- return size;
- }
-
- virtual bool isMatrix() const { return matrix ? true : false; }
- virtual bool isArray() const { return array ? true : false; }
- bool isField() const { return fieldName != 0; }
- int getArraySize() const { return arraySize; }
- void setArraySize(int s) { array = true; arraySize = s; }
- void setMaxArraySize (int s) { maxArraySize = s; }
- int getMaxArraySize () const { return maxArraySize; }
- void clearArrayness() { array = false; arraySize = 0; maxArraySize = 0; }
- void setArrayInformationType(TType* t) { arrayInformationType = t; }
- TType* getArrayInformationType() const { return arrayInformationType; }
- virtual bool isVector() const { return size > 1 && !matrix; }
- virtual bool isScalar() const { return size == 1 && !matrix && !structure; }
- static const char* getBasicString(TBasicType t) {
- switch (t) {
- case EbtVoid: return "void"; break;
- case EbtFloat: return "float"; break;
- case EbtInt: return "int"; break;
- case EbtBool: return "bool"; break;
- case EbtSampler2D: return "sampler2D"; break;
- case EbtSamplerCube: return "samplerCube"; break;
- case EbtStruct: return "structure"; break;
- default: return "unknown type";
- }
- }
- const char* getBasicString() const { return TType::getBasicString(type); }
- const char* getPrecisionString() const { return ::getPrecisionString(precision); }
- const char* getQualifierString() const { return ::getQualifierString(qualifier); }
- TTypeList* getStruct() { return structure; }
-
+ int getNominalSize() const { return size; }
+ void setNominalSize(int s) { size = s; }
+ // Full size of single instance of type
int getObjectSize() const
{
int totalSize;
@@ -245,7 +186,45 @@ public:
return totalSize;
}
+ bool isMatrix() const { return matrix ? true : false; }
+ void setMatrix(bool m) { matrix = m; }
+
+ bool isArray() const { return array ? true : false; }
+ int getArraySize() const { return arraySize; }
+ void setArraySize(int s) { array = true; arraySize = s; }
+ int getMaxArraySize () const { return maxArraySize; }
+ void setMaxArraySize (int s) { maxArraySize = s; }
+ void clearArrayness() { array = false; arraySize = 0; maxArraySize = 0; }
+ void setArrayInformationType(TType* t) { arrayInformationType = t; }
+ TType* getArrayInformationType() const { return arrayInformationType; }
+
+ bool isVector() const { return size > 1 && !matrix; }
+ bool isScalar() const { return size == 1 && !matrix && !structure; }
+
TTypeList* getStruct() const { return structure; }
+ void setStruct(TTypeList* s) { structure = s; }
+
+ const TString& getTypeName() const
+ {
+ assert(typeName);
+ return *typeName;
+ }
+ void setTypeName(const TString& n)
+ {
+ typeName = NewPoolTString(n.c_str());
+ }
+
+ bool isField() const { return fieldName != 0; }
+ const TString& getFieldName() const
+ {
+ assert(fieldName);
+ return *fieldName;
+ }
+ void setFieldName(const TString& n)
+ {
+ fieldName = NewPoolTString(n.c_str());
+ }
+
TString& getMangledName() {
if (!mangled) {
mangled = NewPoolTString("");
@@ -255,6 +234,7 @@ public:
return *mangled;
}
+
bool sameElementType(const TType& right) const {
return type == right.type &&
size == right.size &&
@@ -282,6 +262,10 @@ public:
return false;
}
+
+ const char* getBasicString() const { return ::getBasicString(type); }
+ const char* getPrecisionString() const { return ::getPrecisionString(precision); }
+ const char* getQualifierString() const { return ::getQualifierString(qualifier); }
TString getCompleteString() const;
protected:
@@ -295,11 +279,12 @@ protected:
unsigned int matrix : 1;
unsigned int array : 1;
int arraySize;
+ int maxArraySize;
+ TType* arrayInformationType;
TTypeList* structure; // 0 unless this is a struct
mutable int structureSize;
- int maxArraySize;
- TType* arrayInformationType;
+
TString *fieldName; // for structure field names
TString *mangled;
TString *typeName; // for structure field type name
diff --git a/ANGLE/src/compiler/glslang.l b/ANGLE/src/compiler/glslang.l
index 395c0bf..02c226f 100644
--- a/ANGLE/src/compiler/glslang.l
+++ b/ANGLE/src/compiler/glslang.l
@@ -309,7 +309,7 @@ int PaParseStrings(char* argv[], int strLen[], int argc, TParseContext& parseCon
if (*cpp->PaStrLen >= 0) {
int ret = yyparse((void*)(&parseContextLocal));
- if (cpp->CompileError == 1 || parseContextLocal.recoveredFromError || parseContextLocal.numErrors > 0)
+ if (ret || cpp->CompileError == 1 || parseContextLocal.recoveredFromError || parseContextLocal.numErrors > 0)
return 1;
else
return 0;
@@ -318,7 +318,7 @@ int PaParseStrings(char* argv[], int strLen[], int argc, TParseContext& parseCon
return 0;
}
-void yyerror(char *s)
+void yyerror(const char *s)
{
if (((TParseContext *)cpp->pC)->AfterEOF) {
if (cpp->tokensBeforeEOF == 1) {
diff --git a/ANGLE/src/compiler/glslang.y b/ANGLE/src/compiler/glslang.y
index a297ad2..d0d29df 100644
--- a/ANGLE/src/compiler/glslang.y
+++ b/ANGLE/src/compiler/glslang.y
@@ -38,7 +38,7 @@ compiler/tools. Remove it when we can exclusively use the newer version.
#define parseContext ((TParseContext*)(parseContextLocal))
#define YYLEX_PARAM parseContextLocal
#define YY_DECL int yylex(YYSTYPE* pyylval, void* parseContextLocal)
-extern void yyerror(char*);
+extern void yyerror(const char*);
#define FRAG_VERT_ONLY(S, L) { \
if (parseContext->language != EShLangFragment && \
@@ -311,7 +311,7 @@ postfix_expression
$$->setType(TType($1->getBasicType(), $1->getPrecision(), EvqTemporary, $1->getNominalSize(), $1->isMatrix()));
if ($1->getType().getQualifier() == EvqConst)
- $$->getTypePointer()->changeQualifier(EvqConst);
+ $$->getTypePointer()->setQualifier(EvqConst);
} else if ($1->isMatrix() && $1->getType().getQualifier() == EvqConst)
$$->setType(TType($1->getBasicType(), $1->getPrecision(), EvqConst, $1->getNominalSize()));
else if ($1->isMatrix())
@@ -389,7 +389,7 @@ postfix_expression
}
} else if ($1->getBasicType() == EbtStruct) {
bool fieldFound = false;
- TTypeList* fields = $1->getType().getStruct();
+ const TTypeList* fields = $1->getType().getStruct();
if (fields == 0) {
parseContext->error($2.line, "structure has no fields", "Internal Error", "");
parseContext->recover();
@@ -413,7 +413,7 @@ postfix_expression
$$->setType(*(*fields)[i].type);
// change the qualifier of the return type, not of the structure field
// as the structure definition is shared between various structures.
- $$->getTypePointer()->changeQualifier(EvqConst);
+ $$->getTypePointer()->setQualifier(EvqConst);
}
} else {
ConstantUnion *unionArray = new ConstantUnion[1];
@@ -673,7 +673,7 @@ function_identifier
break;
}
if (op == EOpNull) {
- parseContext->error($1.line, "cannot construct this type", TType::getBasicString($1.type), "");
+ parseContext->error($1.line, "cannot construct this type", getBasicString($1.type), "");
parseContext->recover();
$1.type = EbtFloat;
op = EOpConstructFloat;
@@ -1007,12 +1007,12 @@ declaration
}
}
- prototype->setOperator(EOpPrototype);
+ prototype->setOp(EOpPrototype);
$$ = prototype;
}
| init_declarator_list SEMICOLON {
if ($1.intermAggregate)
- $1.intermAggregate->setOperator(EOpDeclaration);
+ $1.intermAggregate->setOp(EOpDeclaration);
$$ = $1.intermAggregate;
}
| PRECISION precision_qualifier type_specifier_no_prec SEMICOLON {
@@ -1795,19 +1795,24 @@ struct_declaration
}
for (unsigned int i = 0; i < $$->size(); ++i) {
//
- // Careful not to replace already know aspects of type, like array-ness
+ // Careful not to replace already known aspects of type, like array-ness
//
- (*$$)[i].type->setType($1.type, $1.size, $1.matrix, $1.userDef);
+ TType* type = (*$$)[i].type;
+ type->setBasicType($1.type);
+ type->setNominalSize($1.size);
+ type->setMatrix($1.matrix);
// don't allow arrays of arrays
- if ((*$$)[i].type->isArray()) {
+ if (type->isArray()) {
if (parseContext->arrayTypeErrorCheck($1.line, $1))
parseContext->recover();
}
if ($1.array)
- (*$$)[i].type->setArraySize($1.arraySize);
- if ($1.userDef)
- (*$$)[i].type->setTypeName($1.userDef->getTypeName());
+ type->setArraySize($1.arraySize);
+ if ($1.userDef) {
+ type->setStruct($1.userDef->getStruct());
+ type->setTypeName($1.userDef->getTypeName());
+ }
}
}
;
@@ -1873,7 +1878,7 @@ compound_statement
: LEFT_BRACE RIGHT_BRACE { $$ = 0; }
| LEFT_BRACE { parseContext->symbolTable.push(); } statement_list { parseContext->symbolTable.pop(); } RIGHT_BRACE {
if ($3 != 0)
- $3->setOperator(EOpSequence);
+ $3->setOp(EOpSequence);
$$ = $3;
}
;
@@ -1890,7 +1895,7 @@ compound_statement_no_new_scope
}
| LEFT_BRACE statement_list RIGHT_BRACE {
if ($2)
- $2->setOperator(EOpSequence);
+ $2->setOp(EOpSequence);
$$ = $2;
}
;
diff --git a/ANGLE/src/compiler/intermediate.h b/ANGLE/src/compiler/intermediate.h
index c83fc48..d262905 100644
--- a/ANGLE/src/compiler/intermediate.h
+++ b/ANGLE/src/compiler/intermediate.h
@@ -203,8 +203,10 @@ public:
POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
TIntermNode() : line(0) {}
- virtual TSourceLoc getLine() const { return line; }
- virtual void setLine(TSourceLoc l) { line = l; }
+
+ TSourceLoc getLine() const { return line; }
+ void setLine(TSourceLoc l) { line = l; }
+
virtual void traverse(TIntermTraverser*) = 0;
virtual TIntermTyped* getAsTyped() { return 0; }
virtual TIntermConstantUnion* getAsConstantUnion() { return 0; }
@@ -215,6 +217,7 @@ public:
virtual TIntermSymbol* getAsSymbolNode() { return 0; }
virtual TIntermLoop* getAsLoopNode() { return 0; }
virtual ~TIntermNode() { }
+
protected:
TSourceLoc line;
};
@@ -233,22 +236,23 @@ struct TIntermNodePair {
class TIntermTyped : public TIntermNode {
public:
TIntermTyped(const TType& t) : type(t) { }
- virtual TIntermTyped* getAsTyped() { return this; }
- virtual void setType(const TType& t) { type = t; }
- virtual const TType& getType() const { return type; }
- virtual TType* getTypePointer() { return &type; }
-
- virtual TBasicType getBasicType() const { return type.getBasicType(); }
- virtual TQualifier getQualifier() const { return type.getQualifier(); }
- virtual TPrecision getPrecision() const { return type.getPrecision(); }
- virtual int getNominalSize() const { return type.getNominalSize(); }
- virtual int getSize() const { return type.getInstanceSize(); }
- virtual bool isMatrix() const { return type.isMatrix(); }
- virtual bool isArray() const { return type.isArray(); }
- virtual bool isVector() const { return type.isVector(); }
- virtual bool isScalar() const { return type.isScalar(); }
- const char* getBasicString() const { return type.getBasicString(); }
- const char* getQualifierString() const { return type.getQualifierString(); }
+ virtual TIntermTyped* getAsTyped() { return this; }
+
+ void setType(const TType& t) { type = t; }
+ const TType& getType() const { return type; }
+ TType* getTypePointer() { return &type; }
+
+ TBasicType getBasicType() const { return type.getBasicType(); }
+ TQualifier getQualifier() const { return type.getQualifier(); }
+ TPrecision getPrecision() const { return type.getPrecision(); }
+ int getNominalSize() const { return type.getNominalSize(); }
+
+ bool isMatrix() const { return type.isMatrix(); }
+ bool isArray() const { return type.isArray(); }
+ bool isVector() const { return type.isVector(); }
+ bool isScalar() const { return type.isScalar(); }
+ const char* getBasicString() const { return type.getBasicString(); }
+ const char* getQualifierString() const { return type.getQualifierString(); }
TString getCompleteString() const { return type.getCompleteString(); }
protected:
@@ -266,13 +270,16 @@ public:
test(aTest),
terminal(aTerminal),
first(testFirst) { }
+
virtual TIntermLoop* getAsLoopNode() { return this; }
virtual void traverse(TIntermTraverser*);
+
TIntermNode *getInit() { return init; }
TIntermNode *getBody() { return body; }
TIntermTyped *getTest() { return test; }
TIntermTyped *getTerminal() { return terminal; }
bool testFirst() { return first; }
+
protected:
TIntermNode *init;
TIntermNode *body; // code to loop over
@@ -289,9 +296,12 @@ public:
TIntermBranch(TOperator op, TIntermTyped* e) :
flowOp(op),
expression(e) { }
+
virtual void traverse(TIntermTraverser*);
+
TOperator getFlowOp() { return flowOp; }
TIntermTyped* getExpression() { return expression; }
+
protected:
TOperator flowOp;
TIntermTyped* expression; // non-zero except for "return exp;" statements
@@ -307,10 +317,13 @@ public:
// it is essential to use "symbol = sym" to assign to symbol
TIntermSymbol(int i, const TString& sym, const TType& t) :
TIntermTyped(t), id(i) { symbol = sym;}
- virtual int getId() const { return id; }
- virtual const TString& getSymbol() const { return symbol; }
+
+ int getId() const { return id; }
+ const TString& getSymbol() const { return symbol; }
+
virtual void traverse(TIntermTraverser*);
virtual TIntermSymbol* getAsSymbolNode() { return this; }
+
protected:
int id;
TString symbol;
@@ -319,11 +332,15 @@ protected:
class TIntermConstantUnion : public TIntermTyped {
public:
TIntermConstantUnion(ConstantUnion *unionPointer, const TType& t) : TIntermTyped(t), unionArrayPointer(unionPointer) { }
+
ConstantUnion* getUnionArrayPointer() const { return unionArrayPointer; }
void setUnionArrayPointer(ConstantUnion *c) { unionArrayPointer = c; }
+
virtual TIntermConstantUnion* getAsConstantUnion() { return this; }
- virtual void traverse(TIntermTraverser* );
- virtual TIntermTyped* fold(TOperator, TIntermTyped*, TInfoSink&);
+ virtual void traverse(TIntermTraverser*);
+
+ TIntermTyped* fold(TOperator, TIntermTyped*, TInfoSink&);
+
protected:
ConstantUnion *unionArrayPointer;
};
@@ -334,9 +351,11 @@ protected:
class TIntermOperator : public TIntermTyped {
public:
TOperator getOp() const { return op; }
+ void setOp(TOperator o) { op = o; }
+
bool modifiesState() const;
bool isConstructor() const;
- virtual bool promote(TInfoSink&) { return true; }
+
protected:
TIntermOperator(TOperator o) : TIntermTyped(TType(EbtFloat, EbpUndefined)), op(o) {}
TIntermOperator(TOperator o, TType& t) : TIntermTyped(t), op(o) {}
@@ -349,13 +368,16 @@ protected:
class TIntermBinary : public TIntermOperator {
public:
TIntermBinary(TOperator o) : TIntermOperator(o) {}
- virtual void traverse(TIntermTraverser*);
- virtual void setLeft(TIntermTyped* n) { left = n; }
- virtual void setRight(TIntermTyped* n) { right = n; }
- virtual TIntermTyped* getLeft() const { return left; }
- virtual TIntermTyped* getRight() const { return right; }
+
virtual TIntermBinary* getAsBinaryNode() { return this; }
- virtual bool promote(TInfoSink&);
+ virtual void traverse(TIntermTraverser*);
+
+ void setLeft(TIntermTyped* n) { left = n; }
+ void setRight(TIntermTyped* n) { right = n; }
+ TIntermTyped* getLeft() const { return left; }
+ TIntermTyped* getRight() const { return right; }
+ bool promote(TInfoSink&);
+
protected:
TIntermTyped* left;
TIntermTyped* right;
@@ -368,11 +390,14 @@ class TIntermUnary : public TIntermOperator {
public:
TIntermUnary(TOperator o, TType& t) : TIntermOperator(o, t), operand(0) {}
TIntermUnary(TOperator o) : TIntermOperator(o), operand(0) {}
+
virtual void traverse(TIntermTraverser*);
- virtual void setOperand(TIntermTyped* o) { operand = o; }
- virtual TIntermTyped* getOperand() { return operand; }
virtual TIntermUnary* getAsUnaryNode() { return this; }
- virtual bool promote(TInfoSink&);
+
+ void setOperand(TIntermTyped* o) { operand = o; }
+ TIntermTyped* getOperand() { return operand; }
+ bool promote(TInfoSink&);
+
protected:
TIntermTyped* operand;
};
@@ -387,21 +412,24 @@ public:
TIntermAggregate() : TIntermOperator(EOpNull), userDefined(false), pragmaTable(0) { }
TIntermAggregate(TOperator o) : TIntermOperator(o), pragmaTable(0) { }
~TIntermAggregate() { delete pragmaTable; }
+
virtual TIntermAggregate* getAsAggregate() { return this; }
- virtual void setOperator(TOperator o) { op = o; }
- virtual TIntermSequence& getSequence() { return sequence; }
- virtual void setName(const TString& n) { name = n; }
- virtual const TString& getName() const { return name; }
virtual void traverse(TIntermTraverser*);
- virtual void setUserDefined() { userDefined = true; }
- virtual bool isUserDefined() { return userDefined; }
- virtual TQualifierList& getQualifier() { return qualifier; }
+
+ TIntermSequence& getSequence() { return sequence; }
+ void setName(const TString& n) { name = n; }
+ const TString& getName() const { return name; }
+
+ void setUserDefined() { userDefined = true; }
+ bool isUserDefined() { return userDefined; }
+ TQualifierList& getQualifier() { return qualifier; }
void setOptimize(bool o) { optimize = o; }
- void setDebug(bool d) { debug = d; }
bool getOptimize() { return optimize; }
+ void setDebug(bool d) { debug = d; }
bool getDebug() { return debug; }
void addToPragmaTable(const TPragmaTable& pTable);
const TPragmaTable& getPragmaTable() const { return *pragmaTable; }
+
protected:
TIntermAggregate(const TIntermAggregate&); // disallow copy constructor
TIntermAggregate& operator=(const TIntermAggregate&); // disallow assignment operator
@@ -423,12 +451,15 @@ public:
TIntermTyped(TType(EbtVoid, EbpUndefined)), condition(cond), trueBlock(trueB), falseBlock(falseB) {}
TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB, const TType& type) :
TIntermTyped(type), condition(cond), trueBlock(trueB), falseBlock(falseB) {}
+
virtual void traverse(TIntermTraverser*);
+
bool usesTernaryOperator() const { return getBasicType() != EbtVoid; }
- virtual TIntermNode* getCondition() const { return condition; }
- virtual TIntermNode* getTrueBlock() const { return trueBlock; }
- virtual TIntermNode* getFalseBlock() const { return falseBlock; }
- virtual TIntermSelection* getAsSelectionNode() { return this; }
+ TIntermNode* getCondition() const { return condition; }
+ TIntermNode* getTrueBlock() const { return trueBlock; }
+ TIntermNode* getFalseBlock() const { return falseBlock; }
+ TIntermSelection* getAsSelectionNode() { return this; }
+
protected:
TIntermTyped* condition;
TIntermNode* trueBlock;
diff --git a/ANGLE/src/compiler/parseConst.cpp b/ANGLE/src/compiler/parseConst.cpp
index 833d429..9a8a50c 100644
--- a/ANGLE/src/compiler/parseConst.cpp
+++ b/ANGLE/src/compiler/parseConst.cpp
@@ -12,23 +12,31 @@
//
class TConstTraverser : public TIntermTraverser {
public:
- TConstTraverser(ConstantUnion* cUnion, bool singleConstParam, TOperator constructType, TInfoSink& sink, TSymbolTable& symTable, TType& t) : unionArray(cUnion), type(t),
- constructorType(constructType), singleConstantParam(singleConstParam), infoSink(sink), symbolTable(symTable), error(false), isMatrix(false), matrixSize(0)
- {
- index = 0;
- }
+ TConstTraverser(ConstantUnion* cUnion, bool singleConstParam, TOperator constructType, TInfoSink& sink, TSymbolTable& symTable, TType& t)
+ : error(false),
+ index(0),
+ unionArray(cUnion),
+ type(t),
+ constructorType(constructType),
+ singleConstantParam(singleConstParam),
+ infoSink(sink),
+ symbolTable(symTable),
+ size(0),
+ isMatrix(false),
+ matrixSize(0) {
+ }
- bool error;
+ bool error;
protected:
- void visitSymbol(TIntermSymbol*);
- void visitConstantUnion(TIntermConstantUnion*);
- bool visitBinary(Visit visit, TIntermBinary*);
- bool visitUnary(Visit visit, TIntermUnary*);
- bool visitSelection(Visit visit, TIntermSelection*);
- bool visitAggregate(Visit visit, TIntermAggregate*);
- bool visitLoop(Visit visit, TIntermLoop*);
- bool visitBranch(Visit visit, TIntermBranch*);
+ void visitSymbol(TIntermSymbol*);
+ void visitConstantUnion(TIntermConstantUnion*);
+ bool visitBinary(Visit visit, TIntermBinary*);
+ bool visitUnary(Visit visit, TIntermUnary*);
+ bool visitSelection(Visit visit, TIntermSelection*);
+ bool visitAggregate(Visit visit, TIntermAggregate*);
+ bool visitLoop(Visit visit, TIntermLoop*);
+ bool visitBranch(Visit visit, TIntermBranch*);
int index;
ConstantUnion *unionArray;
diff --git a/ANGLE/src/compiler/preprocessor/atom.c b/ANGLE/src/compiler/preprocessor/atom.c
index 32b9c74..c5636b7 100644
--- a/ANGLE/src/compiler/preprocessor/atom.c
+++ b/ANGLE/src/compiler/preprocessor/atom.c
@@ -1,8 +1,3 @@
-//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
/****************************************************************************\
Copyright (c) 2002, NVIDIA Corporation.
@@ -624,7 +619,7 @@ static int AddAtomFixed(AtomTable *atable, const char *s, int atom)
int InitAtomTable(AtomTable *atable, int htsize)
{
- int ii;
+ unsigned int ii;
htsize = htsize <= 0 ? INIT_HASH_TABLE_SIZE : htsize;
if (!InitStringTable(&atable->stable))
diff --git a/ANGLE/src/compiler/preprocessor/atom.h b/ANGLE/src/compiler/preprocessor/atom.h
index 9d42037..1d84c32 100644
--- a/ANGLE/src/compiler/preprocessor/atom.h
+++ b/ANGLE/src/compiler/preprocessor/atom.h
@@ -1,8 +1,3 @@
-//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
/****************************************************************************\
Copyright (c) 2002, NVIDIA Corporation.
diff --git a/ANGLE/src/compiler/preprocessor/compile.h b/ANGLE/src/compiler/preprocessor/compile.h
index a40b99e..5bfa902 100644
--- a/ANGLE/src/compiler/preprocessor/compile.h
+++ b/ANGLE/src/compiler/preprocessor/compile.h
@@ -1,8 +1,3 @@
-//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
/****************************************************************************\
Copyright (c) 2002, NVIDIA Corporation.
diff --git a/ANGLE/src/compiler/preprocessor/cpp.c b/ANGLE/src/compiler/preprocessor/cpp.c
index 6bf8e65..f15c56d 100644
--- a/ANGLE/src/compiler/preprocessor/cpp.c
+++ b/ANGLE/src/compiler/preprocessor/cpp.c
@@ -1,8 +1,3 @@
-//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
/****************************************************************************\
Copyright (c) 2002, NVIDIA Corporation.
diff --git a/ANGLE/src/compiler/preprocessor/cpp.h b/ANGLE/src/compiler/preprocessor/cpp.h
index 658475e..db4c184 100644
--- a/ANGLE/src/compiler/preprocessor/cpp.h
+++ b/ANGLE/src/compiler/preprocessor/cpp.h
@@ -1,8 +1,3 @@
-//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
/****************************************************************************\
Copyright (c) 2002, NVIDIA Corporation.
diff --git a/ANGLE/src/compiler/preprocessor/cppstruct.c b/ANGLE/src/compiler/preprocessor/cppstruct.c
index afbc477..8e142bc 100644
--- a/ANGLE/src/compiler/preprocessor/cppstruct.c
+++ b/ANGLE/src/compiler/preprocessor/cppstruct.c
@@ -1,8 +1,3 @@
-//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
/****************************************************************************\
Copyright (c) 2002, NVIDIA Corporation.
diff --git a/ANGLE/src/compiler/preprocessor/memory.c b/ANGLE/src/compiler/preprocessor/memory.c
index 393a0d0..e6fea7a 100644
--- a/ANGLE/src/compiler/preprocessor/memory.c
+++ b/ANGLE/src/compiler/preprocessor/memory.c
@@ -1,8 +1,3 @@
-//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
/****************************************************************************\
Copyright (c) 2002, NVIDIA Corporation.
diff --git a/ANGLE/src/compiler/preprocessor/memory.h b/ANGLE/src/compiler/preprocessor/memory.h
index e7f5b75..b3ae2f9 100644
--- a/ANGLE/src/compiler/preprocessor/memory.h
+++ b/ANGLE/src/compiler/preprocessor/memory.h
@@ -1,8 +1,3 @@
-//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
/****************************************************************************\
Copyright (c) 2002, NVIDIA Corporation.
diff --git a/ANGLE/src/compiler/preprocessor/parser.h b/ANGLE/src/compiler/preprocessor/parser.h
index 91a6200..f67342b 100644
--- a/ANGLE/src/compiler/preprocessor/parser.h
+++ b/ANGLE/src/compiler/preprocessor/parser.h
@@ -1,8 +1,3 @@
-//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
/****************************************************************************\
Copyright (c) 2002, NVIDIA Corporation.
diff --git a/ANGLE/src/compiler/preprocessor/preprocess.h b/ANGLE/src/compiler/preprocessor/preprocess.h
index 3dd605b..0602c91 100644
--- a/ANGLE/src/compiler/preprocessor/preprocess.h
+++ b/ANGLE/src/compiler/preprocessor/preprocess.h
@@ -1,8 +1,3 @@
-//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
/****************************************************************************\
Copyright (c) 2002, NVIDIA Corporation.
diff --git a/ANGLE/src/compiler/preprocessor/scanner.c b/ANGLE/src/compiler/preprocessor/scanner.c
index 0944da5..c77d271 100644
--- a/ANGLE/src/compiler/preprocessor/scanner.c
+++ b/ANGLE/src/compiler/preprocessor/scanner.c
@@ -1,8 +1,3 @@
-//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
/****************************************************************************\
Copyright (c) 2002, NVIDIA Corporation.
diff --git a/ANGLE/src/compiler/preprocessor/scanner.h b/ANGLE/src/compiler/preprocessor/scanner.h
index c422b3a..571fe57 100644
--- a/ANGLE/src/compiler/preprocessor/scanner.h
+++ b/ANGLE/src/compiler/preprocessor/scanner.h
@@ -1,8 +1,3 @@
-//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
/****************************************************************************\
Copyright (c) 2002, NVIDIA Corporation.
diff --git a/ANGLE/src/compiler/preprocessor/slglobals.h b/ANGLE/src/compiler/preprocessor/slglobals.h
index a535180..4634626 100644
--- a/ANGLE/src/compiler/preprocessor/slglobals.h
+++ b/ANGLE/src/compiler/preprocessor/slglobals.h
@@ -1,8 +1,3 @@
-//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
/****************************************************************************\
Copyright (c) 2002, NVIDIA Corporation.
diff --git a/ANGLE/src/compiler/preprocessor/symbols.c b/ANGLE/src/compiler/preprocessor/symbols.c
index 1193abb..5baedf5 100644
--- a/ANGLE/src/compiler/preprocessor/symbols.c
+++ b/ANGLE/src/compiler/preprocessor/symbols.c
@@ -1,8 +1,3 @@
-//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
/****************************************************************************\
Copyright (c) 2002, NVIDIA Corporation.
@@ -157,7 +152,7 @@ Symbol *NewSymbol(SourceLoc *loc, Scope *fScope, int name, symbolkind kind)
{
Symbol *lSymb;
char *pch;
- int ii;
+ unsigned int ii;
lSymb = (Symbol *) mem_Alloc(fScope->pool, sizeof(Symbol));
lSymb->left = NULL;
diff --git a/ANGLE/src/compiler/preprocessor/symbols.h b/ANGLE/src/compiler/preprocessor/symbols.h
index 41e0778..c19f79c 100644
--- a/ANGLE/src/compiler/preprocessor/symbols.h
+++ b/ANGLE/src/compiler/preprocessor/symbols.h
@@ -1,8 +1,3 @@
-//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
/****************************************************************************\
Copyright (c) 2002, NVIDIA Corporation.
diff --git a/ANGLE/src/compiler/preprocessor/tokens.c b/ANGLE/src/compiler/preprocessor/tokens.c
index 7cfc73d..057cce8 100644
--- a/ANGLE/src/compiler/preprocessor/tokens.c
+++ b/ANGLE/src/compiler/preprocessor/tokens.c
@@ -1,8 +1,3 @@
-//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
/****************************************************************************\
Copyright (c) 2002, NVIDIA Corporation.
@@ -210,7 +205,7 @@ void DeleteTokenStream(TokenStream *pTok)
void RecordToken(TokenStream *pTok, int token, yystypepp * yylvalpp)
{
const char *s;
- unsigned char *str=NULL;
+ char *str=NULL;
if (token > 256)
lAddByte(pTok, (unsigned char)((token & 0x7f) + 0x80));
diff --git a/ANGLE/src/compiler/preprocessor/tokens.h b/ANGLE/src/compiler/preprocessor/tokens.h
index 8d7e712..8766df9 100644
--- a/ANGLE/src/compiler/preprocessor/tokens.h
+++ b/ANGLE/src/compiler/preprocessor/tokens.h
@@ -1,8 +1,3 @@
-//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
/****************************************************************************\
Copyright (c) 2002, NVIDIA Corporation.
diff --git a/ANGLE/src/libEGL/Display.cpp b/ANGLE/src/libEGL/Display.cpp
index 287d8da..e2802da 100644
--- a/ANGLE/src/libEGL/Display.cpp
+++ b/ANGLE/src/libEGL/Display.cpp
@@ -23,8 +23,12 @@ namespace egl
{
Display::Display(HDC deviceContext) : mDc(deviceContext)
{
+ mD3d9Module = NULL;
+
mD3d9 = NULL;
+ mD3d9ex = NULL;
mDevice = NULL;
+ mDeviceWindow = NULL;
mAdapter = D3DADAPTER_DEFAULT;
@@ -51,7 +55,38 @@ bool Display::initialize()
return true;
}
- mD3d9 = Direct3DCreate9(D3D_SDK_VERSION);
+ mD3d9Module = LoadLibrary(TEXT("d3d9.dll"));
+ if (mD3d9Module == NULL)
+ {
+ terminate();
+ return false;
+ }
+
+ typedef IDirect3D9* (WINAPI *Direct3DCreate9Func)(UINT);
+ Direct3DCreate9Func Direct3DCreate9Ptr = reinterpret_cast<Direct3DCreate9Func>(GetProcAddress(mD3d9Module, "Direct3DCreate9"));
+
+ if (Direct3DCreate9Ptr == NULL)
+ {
+ terminate();
+ return false;
+ }
+
+ typedef HRESULT (WINAPI *Direct3DCreate9ExFunc)(UINT, IDirect3D9Ex**);
+ Direct3DCreate9ExFunc Direct3DCreate9ExPtr = reinterpret_cast<Direct3DCreate9ExFunc>(GetProcAddress(mD3d9Module, "Direct3DCreate9Ex"));
+
+ // Use Direct3D9Ex if available. Among other things, this version is less
+ // inclined to report a lost context, for example when the user switches
+ // desktop. Direct3D9Ex is available in Windows Vista and later if suitable drivers are available.
+ if (Direct3DCreate9ExPtr && SUCCEEDED(Direct3DCreate9ExPtr(D3D_SDK_VERSION, &mD3d9ex)))
+ {
+ ASSERT(mD3d9ex);
+ mD3d9ex->QueryInterface(IID_IDirect3D9, reinterpret_cast<void**>(&mD3d9));
+ ASSERT(mD3d9);
+ }
+ else
+ {
+ mD3d9 = Direct3DCreate9Ptr(D3D_SDK_VERSION);
+ }
if (mD3d9)
{
@@ -69,86 +104,91 @@ bool Display::initialize()
if (mDeviceCaps.PixelShaderVersion < D3DPS_VERSION(2, 0))
{
- mD3d9->Release();
- mD3d9 = NULL;
+ terminate();
+ return error(EGL_NOT_INITIALIZED, false);
}
- else
- {
- mMinSwapInterval = 4;
- mMaxSwapInterval = 0;
- if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_IMMEDIATE) {mMinSwapInterval = std::min(mMinSwapInterval, 0); mMaxSwapInterval = std::max(mMaxSwapInterval, 0);}
- if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_ONE) {mMinSwapInterval = std::min(mMinSwapInterval, 1); mMaxSwapInterval = std::max(mMaxSwapInterval, 1);}
- if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_TWO) {mMinSwapInterval = std::min(mMinSwapInterval, 2); mMaxSwapInterval = std::max(mMaxSwapInterval, 2);}
- if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_THREE) {mMinSwapInterval = std::min(mMinSwapInterval, 3); mMaxSwapInterval = std::max(mMaxSwapInterval, 3);}
- if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_FOUR) {mMinSwapInterval = std::min(mMinSwapInterval, 4); mMaxSwapInterval = std::max(mMaxSwapInterval, 4);}
+ mMinSwapInterval = 4;
+ mMaxSwapInterval = 0;
- const D3DFORMAT renderTargetFormats[] =
- {
- D3DFMT_A1R5G5B5,
- // D3DFMT_A2R10G10B10, // The color_ramp conformance test uses ReadPixels with UNSIGNED_BYTE causing it to think that rendering skipped a colour value.
- D3DFMT_A8R8G8B8,
- D3DFMT_R5G6B5,
- D3DFMT_X1R5G5B5,
- D3DFMT_X8R8G8B8
- };
-
- const D3DFORMAT depthStencilFormats[] =
- {
- // D3DFMT_D16_LOCKABLE,
- D3DFMT_D32,
- // D3DFMT_D15S1,
- D3DFMT_D24S8,
- D3DFMT_D24X8,
- // D3DFMT_D24X4S4,
- D3DFMT_D16,
- // D3DFMT_D32F_LOCKABLE,
- // D3DFMT_D24FS8
- };
-
- D3DDISPLAYMODE currentDisplayMode;
- mD3d9->GetAdapterDisplayMode(mAdapter, &currentDisplayMode);
-
- ConfigSet configSet;
-
- for (int formatIndex = 0; formatIndex < sizeof(renderTargetFormats) / sizeof(D3DFORMAT); formatIndex++)
- {
- D3DFORMAT renderTargetFormat = renderTargetFormats[formatIndex];
+ if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_IMMEDIATE) {mMinSwapInterval = std::min(mMinSwapInterval, 0); mMaxSwapInterval = std::max(mMaxSwapInterval, 0);}
+ if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_ONE) {mMinSwapInterval = std::min(mMinSwapInterval, 1); mMaxSwapInterval = std::max(mMaxSwapInterval, 1);}
+ if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_TWO) {mMinSwapInterval = std::min(mMinSwapInterval, 2); mMaxSwapInterval = std::max(mMaxSwapInterval, 2);}
+ if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_THREE) {mMinSwapInterval = std::min(mMinSwapInterval, 3); mMaxSwapInterval = std::max(mMaxSwapInterval, 3);}
+ if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_FOUR) {mMinSwapInterval = std::min(mMinSwapInterval, 4); mMaxSwapInterval = std::max(mMaxSwapInterval, 4);}
+
+ const D3DFORMAT renderTargetFormats[] =
+ {
+ D3DFMT_A1R5G5B5,
+ // D3DFMT_A2R10G10B10, // The color_ramp conformance test uses ReadPixels with UNSIGNED_BYTE causing it to think that rendering skipped a colour value.
+ D3DFMT_A8R8G8B8,
+ D3DFMT_R5G6B5,
+ D3DFMT_X1R5G5B5,
+ D3DFMT_X8R8G8B8
+ };
+
+ const D3DFORMAT depthStencilFormats[] =
+ {
+ // D3DFMT_D16_LOCKABLE,
+ D3DFMT_D32,
+ // D3DFMT_D15S1,
+ D3DFMT_D24S8,
+ D3DFMT_D24X8,
+ // D3DFMT_D24X4S4,
+ D3DFMT_D16,
+ // D3DFMT_D32F_LOCKABLE,
+ // D3DFMT_D24FS8
+ };
+
+ D3DDISPLAYMODE currentDisplayMode;
+ mD3d9->GetAdapterDisplayMode(mAdapter, &currentDisplayMode);
+
+ ConfigSet configSet;
+
+ for (int formatIndex = 0; formatIndex < sizeof(renderTargetFormats) / sizeof(D3DFORMAT); formatIndex++)
+ {
+ D3DFORMAT renderTargetFormat = renderTargetFormats[formatIndex];
- HRESULT result = mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, renderTargetFormat);
+ HRESULT result = mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, renderTargetFormat);
- if (SUCCEEDED(result))
+ if (SUCCEEDED(result))
+ {
+ for (int depthStencilIndex = 0; depthStencilIndex < sizeof(depthStencilFormats) / sizeof(D3DFORMAT); depthStencilIndex++)
{
- for (int depthStencilIndex = 0; depthStencilIndex < sizeof(depthStencilFormats) / sizeof(D3DFORMAT); depthStencilIndex++)
+ D3DFORMAT depthStencilFormat = depthStencilFormats[depthStencilIndex];
+ HRESULT result = mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, depthStencilFormat);
+
+ if (SUCCEEDED(result))
{
- D3DFORMAT depthStencilFormat = depthStencilFormats[depthStencilIndex];
- HRESULT result = mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, depthStencilFormat);
+ HRESULT result = mD3d9->CheckDepthStencilMatch(mAdapter, mDeviceType, currentDisplayMode.Format, renderTargetFormat, depthStencilFormat);
if (SUCCEEDED(result))
{
- HRESULT result = mD3d9->CheckDepthStencilMatch(mAdapter, mDeviceType, currentDisplayMode.Format, renderTargetFormat, depthStencilFormat);
+ // FIXME: enumerate multi-sampling
- if (SUCCEEDED(result))
- {
- // FIXME: Enumerate multi-sampling
-
- configSet.add(currentDisplayMode, mMinSwapInterval, mMaxSwapInterval, renderTargetFormat, depthStencilFormat, 0);
- }
+ configSet.add(currentDisplayMode, mMinSwapInterval, mMaxSwapInterval, renderTargetFormat, depthStencilFormat, 0);
}
}
}
}
+ }
- // Give the sorted configs a unique ID and store them internally
- EGLint index = 1;
- for (ConfigSet::Iterator config = configSet.mSet.begin(); config != configSet.mSet.end(); config++)
- {
- Config configuration = *config;
- configuration.mConfigID = index;
- index++;
+ // Give the sorted configs a unique ID and store them internally
+ EGLint index = 1;
+ for (ConfigSet::Iterator config = configSet.mSet.begin(); config != configSet.mSet.end(); config++)
+ {
+ Config configuration = *config;
+ configuration.mConfigID = index;
+ index++;
- mConfigSet.mSet.insert(configuration);
- }
+ mConfigSet.mSet.insert(configuration);
+ }
+
+ if (!createDevice())
+ {
+ terminate();
+
+ return false;
}
}
@@ -185,6 +225,24 @@ void Display::terminate()
mD3d9->Release();
mD3d9 = NULL;
}
+
+ if (mDeviceWindow)
+ {
+ DestroyWindow(mDeviceWindow);
+ mDeviceWindow = NULL;
+ }
+
+ if (mD3d9ex)
+ {
+ mD3d9ex->Release();
+ mD3d9ex = NULL;
+ }
+
+ if (mD3d9Module)
+ {
+ FreeLibrary(mD3d9Module);
+ mD3d9Module = NULL;
+ }
}
void Display::startScene()
@@ -254,132 +312,74 @@ bool Display::getConfigAttrib(EGLConfig config, EGLint attribute, EGLint *value)
return true;
}
-Surface *Display::createWindowSurface(HWND window, EGLConfig config)
+bool Display::createDevice()
{
- const Config *configuration = mConfigSet.get(config);
+ static const TCHAR windowName[] = TEXT("AngleHiddenWindow");
+ static const TCHAR className[] = TEXT("STATIC");
+
+ mDeviceWindow = CreateWindowEx(WS_EX_NOACTIVATE, className, windowName, WS_DISABLED | WS_POPUP, 0, 0, 1, 1, HWND_MESSAGE, NULL, GetModuleHandle(NULL), NULL);
D3DPRESENT_PARAMETERS presentParameters = {0};
- presentParameters.AutoDepthStencilFormat = configuration->mDepthStencilFormat;
+ // The default swap chain is never actually used. Surface will create a new swap chain with the proper parameters.
+ presentParameters.AutoDepthStencilFormat = D3DFMT_UNKNOWN;
presentParameters.BackBufferCount = 1;
- presentParameters.BackBufferFormat = configuration->mRenderTargetFormat;
- presentParameters.BackBufferWidth = 0;
- presentParameters.BackBufferHeight = 0;
- presentParameters.EnableAutoDepthStencil = configuration->mDepthSize ? TRUE : FALSE;
+ presentParameters.BackBufferFormat = D3DFMT_UNKNOWN;
+ presentParameters.BackBufferWidth = 1;
+ presentParameters.BackBufferHeight = 1;
+ presentParameters.EnableAutoDepthStencil = FALSE;
presentParameters.Flags = 0;
- presentParameters.hDeviceWindow = window;
- presentParameters.MultiSampleQuality = 0; // FIXME: Unimplemented
- presentParameters.MultiSampleType = D3DMULTISAMPLE_NONE; // FIXME: Unimplemented
+ presentParameters.hDeviceWindow = mDeviceWindow;
+ presentParameters.MultiSampleQuality = 0;
+ presentParameters.MultiSampleType = D3DMULTISAMPLE_NONE;
presentParameters.PresentationInterval = convertInterval(mMinSwapInterval);
- presentParameters.SwapEffect = D3DSWAPEFFECT_COPY;
- presentParameters.Windowed = TRUE; // FIXME
+ presentParameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
+ presentParameters.Windowed = TRUE;
- IDirect3DSwapChain9 *swapChain = NULL;
- IDirect3DSurface9 *depthStencilSurface = NULL;
+ DWORD behaviorFlags = D3DCREATE_FPU_PRESERVE | D3DCREATE_NOWINDOWCHANGES;
- if (!mDevice)
+ HRESULT result = mD3d9->CreateDevice(mAdapter, mDeviceType, mDeviceWindow, behaviorFlags | D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE, &presentParameters, &mDevice);
+
+ if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
{
- DWORD behaviorFlags = D3DCREATE_FPU_PRESERVE | D3DCREATE_NOWINDOWCHANGES;
+ return error(EGL_BAD_ALLOC, false);
+ }
- HRESULT result = mD3d9->CreateDevice(mAdapter, mDeviceType, window, behaviorFlags | D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE, &presentParameters, &mDevice);
+ if (FAILED(result))
+ {
+ result = mD3d9->CreateDevice(mAdapter, mDeviceType, mDeviceWindow, behaviorFlags | D3DCREATE_SOFTWARE_VERTEXPROCESSING, &presentParameters, &mDevice);
if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
{
- return error(EGL_BAD_ALLOC, (egl::Surface*)NULL);
- }
-
- if (FAILED(result))
- {
- result = mD3d9->CreateDevice(mAdapter, mDeviceType, window, behaviorFlags | D3DCREATE_SOFTWARE_VERTEXPROCESSING, &presentParameters, &mDevice);
-
- if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
- {
- return error(EGL_BAD_ALLOC, (egl::Surface*)NULL);
- }
- }
-
- ASSERT(SUCCEEDED(result));
-
- if (mDevice)
- {
- mSceneStarted = false;
- mDevice->GetSwapChain(0, &swapChain);
- mDevice->GetDepthStencilSurface(&depthStencilSurface);
+ return error(EGL_BAD_ALLOC, false);
}
}
- else
- {
- if (!mSurfaceSet.empty())
- {
- // if the device already exists, and there are other surfaces/windows currently in use, we need to create
- // a separate swap chain for the new draw surface.
- HRESULT result = mDevice->CreateAdditionalSwapChain(&presentParameters, &swapChain);
-
- if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
- {
- ERR("Could not create additional swap chains. Out of memory.");
- return error(EGL_BAD_ALLOC, (egl::Surface*)NULL);
- }
-
- ASSERT(SUCCEEDED(result));
- // CreateAdditionalSwapChain does not automatically generate a depthstencil surface, unlike
- // CreateDevice, so we must do so explicitly.
- result = mDevice->CreateDepthStencilSurface(presentParameters.BackBufferWidth, presentParameters.BackBufferHeight,
- presentParameters.AutoDepthStencilFormat, presentParameters.MultiSampleType,
- presentParameters.MultiSampleQuality, FALSE, &depthStencilSurface, NULL);
+ ASSERT(SUCCEEDED(result));
- if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
- {
- swapChain->Release();
- ERR("Could not create depthstencil surface for new swap chain. Out of memory.");
- return error(EGL_BAD_ALLOC, (egl::Surface*)NULL);
- }
+ // Permanent non-default states
+ mDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, TRUE);
- ASSERT(SUCCEEDED(result));
- }
- else
- {
- // if the device already exists, but there are no surfaces in use, then all the surfaces/windows
- // have been destroyed, and we should repurpose the originally created depthstencil surface for
- // use with the new surface we are creating.
- HRESULT result = mDevice->Reset(&presentParameters);
+ mSceneStarted = false;
- if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
- {
- ERR("Could not reset presentation parameters for device. Out of memory.");
- return error(EGL_BAD_ALLOC, (egl::Surface*)NULL);
- }
-
- ASSERT(SUCCEEDED(result));
-
- if (mDevice)
- {
- mSceneStarted = false;
- mDevice->GetSwapChain(0, &swapChain);
- mDevice->GetDepthStencilSurface(&depthStencilSurface);
- }
- }
- }
-
- Surface *surface = NULL;
+ return true;
+}
- if (swapChain)
- {
- surface = new Surface(this, swapChain, depthStencilSurface, configuration);
- mSurfaceSet.insert(surface);
+Surface *Display::createWindowSurface(HWND window, EGLConfig config)
+{
+ const Config *configuration = mConfigSet.get(config);
- swapChain->Release();
- }
+ Surface *surface = new Surface(this, configuration, window);
+ mSurfaceSet.insert(surface);
return surface;
}
-EGLContext Display::createContext(EGLConfig configHandle)
+EGLContext Display::createContext(EGLConfig configHandle, const gl::Context *shareContext)
{
const egl::Config *config = mConfigSet.get(configHandle);
- gl::Context *context = glCreateContext(config);
+ gl::Context *context = glCreateContext(config, shareContext);
mContextSet.insert(context);
return context;
@@ -468,4 +468,23 @@ D3DCAPS9 Display::getDeviceCaps()
{
return mDeviceCaps;
}
+
+void Display::getMultiSampleSupport(D3DFORMAT format, bool *multiSampleArray)
+{
+ for (int multiSampleIndex = 0; multiSampleIndex <= D3DMULTISAMPLE_16_SAMPLES; multiSampleIndex++)
+ {
+ HRESULT result = mD3d9->CheckDeviceMultiSampleType(mAdapter, mDeviceType, format,
+ TRUE, (D3DMULTISAMPLE_TYPE)multiSampleIndex, NULL);
+
+ multiSampleArray[multiSampleIndex] = SUCCEEDED(result);
+ }
+}
+
+bool Display::getCompressedTextureSupport()
+{
+ D3DDISPLAYMODE currentDisplayMode;
+ mD3d9->GetAdapterDisplayMode(mAdapter, &currentDisplayMode);
+
+ return SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT1));
+}
}
diff --git a/ANGLE/src/libEGL/Display.h b/ANGLE/src/libEGL/Display.h
index 02c9fde..bd33012 100644
--- a/ANGLE/src/libEGL/Display.h
+++ b/ANGLE/src/libEGL/Display.h
@@ -43,7 +43,7 @@ class Display
bool getConfigAttrib(EGLConfig config, EGLint attribute, EGLint *value);
egl::Surface *createWindowSurface(HWND window, EGLConfig config);
- EGLContext createContext(EGLConfig configHandle);
+ EGLContext createContext(EGLConfig configHandle, const gl::Context *shareContext);
void destroySurface(egl::Surface *surface);
void destroyContext(gl::Context *context);
@@ -60,16 +60,22 @@ class Display
virtual IDirect3DDevice9 *getDevice();
virtual D3DCAPS9 getDeviceCaps();
+ virtual void getMultiSampleSupport(D3DFORMAT format, bool *multiSampleArray);
+ virtual bool getCompressedTextureSupport();
private:
DISALLOW_COPY_AND_ASSIGN(Display);
const HDC mDc;
+ HMODULE mD3d9Module;
+
UINT mAdapter;
D3DDEVTYPE mDeviceType;
- IDirect3D9 *mD3d9;
+ IDirect3D9 *mD3d9; // Always valid after successful initialization.
+ IDirect3D9Ex *mD3d9ex; // Might be null if D3D9Ex is not supported.
IDirect3DDevice9 *mDevice;
D3DCAPS9 mDeviceCaps;
+ HWND mDeviceWindow;
bool mSceneStarted;
GLint mSwapInterval;
@@ -84,6 +90,8 @@ class Display
typedef std::set<gl::Context*> ContextSet;
ContextSet mContextSet;
+
+ bool createDevice();
};
}
diff --git a/ANGLE/src/libEGL/Surface.cpp b/ANGLE/src/libEGL/Surface.cpp
index ef5c6c7..a5638d4 100644
--- a/ANGLE/src/libEGL/Surface.cpp
+++ b/ANGLE/src/libEGL/Surface.cpp
@@ -17,9 +17,11 @@
namespace egl
{
-Surface::Surface(Display *display, IDirect3DSwapChain9 *swapChain, IDirect3DSurface9 *depthStencil, const Config *config)
- : mDisplay(display), mSwapChain(swapChain), mDepthStencil(depthStencil), mConfig(config)
+Surface::Surface(Display *display, const Config *config, HWND window)
+ : mDisplay(display), mConfig(config), mWindow(window)
{
+ mSwapChain = NULL;
+ mDepthStencil = NULL;
mBackBuffer = NULL;
mRenderTarget = NULL;
mFlipTexture = NULL;
@@ -30,42 +32,7 @@ Surface::Surface(Display *display, IDirect3DSwapChain9 *swapChain, IDirect3DSurf
mRenderBuffer = EGL_BACK_BUFFER;
mSwapBehavior = EGL_BUFFER_PRESERVED;
- if (mSwapChain)
- {
- mSwapChain->AddRef();
- mSwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &mBackBuffer);
-
- D3DSURFACE_DESC description;
- mBackBuffer->GetDesc(&description);
-
- mWidth = description.Width;
- mHeight = description.Height;
-
- IDirect3DDevice9 *device = display->getDevice();
- HRESULT result = device->CreateRenderTarget(mWidth, mHeight, description.Format, description.MultiSampleType, description.MultiSampleQuality, FALSE, &mRenderTarget, NULL);
-
- if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
- {
- error(EGL_BAD_ALLOC);
-
- return;
- }
-
- ASSERT(SUCCEEDED(result));
-
- result = device->CreateTexture(mWidth, mHeight, 1, D3DUSAGE_RENDERTARGET, description.Format, D3DPOOL_DEFAULT, &mFlipTexture, NULL);
-
- if (FAILED(result))
- {
- ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
-
- error(EGL_BAD_ALLOC);
-
- mRenderTarget->Release();
-
- return;
- }
- }
+ resetSwapChain();
}
Surface::~Surface()
@@ -106,20 +73,121 @@ Surface::~Surface()
}
}
-HWND Surface::getWindowHandle()
+void Surface::resetSwapChain()
{
- if (mSwapChain)
+ IDirect3DDevice9 *device = mDisplay->getDevice();
+
+ D3DPRESENT_PARAMETERS presentParameters = {0};
+
+ presentParameters.AutoDepthStencilFormat = mConfig->mDepthStencilFormat;
+ presentParameters.BackBufferCount = 1;
+ presentParameters.BackBufferFormat = mConfig->mRenderTargetFormat;
+ presentParameters.EnableAutoDepthStencil = FALSE;
+ presentParameters.Flags = 0;
+ presentParameters.hDeviceWindow = getWindowHandle();
+ presentParameters.MultiSampleQuality = 0; // FIXME: Unimplemented
+ presentParameters.MultiSampleType = D3DMULTISAMPLE_NONE; // FIXME: Unimplemented
+ presentParameters.PresentationInterval = Display::convertInterval(mConfig->mMinSwapInterval);
+ presentParameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
+ presentParameters.Windowed = TRUE;
+
+ RECT windowRect;
+ if (!GetClientRect(getWindowHandle(), &windowRect))
+ {
+ ASSERT(false);
+ return;
+ }
+
+ presentParameters.BackBufferWidth = windowRect.right - windowRect.left;
+ presentParameters.BackBufferHeight = windowRect.bottom - windowRect.top;
+
+ IDirect3DSwapChain9 *swapChain = NULL;
+ HRESULT result = device->CreateAdditionalSwapChain(&presentParameters, &swapChain);
+
+ if (FAILED(result))
+ {
+ ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
+
+ ERR("Could not create additional swap chains: %08lX", result);
+ return error(EGL_BAD_ALLOC);
+ }
+
+ IDirect3DSurface9 *depthStencilSurface = NULL;
+ result = device->CreateDepthStencilSurface(presentParameters.BackBufferWidth, presentParameters.BackBufferHeight,
+ presentParameters.AutoDepthStencilFormat, presentParameters.MultiSampleType,
+ presentParameters.MultiSampleQuality, FALSE, &depthStencilSurface, NULL);
+
+ if (FAILED(result))
+ {
+ ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
+
+ swapChain->Release();
+
+ ERR("Could not create depthstencil surface for new swap chain: %08lX", result);
+ return error(EGL_BAD_ALLOC);
+ }
+
+ IDirect3DSurface9 *renderTarget = NULL;
+ result = device->CreateRenderTarget(presentParameters.BackBufferWidth, presentParameters.BackBufferHeight, presentParameters.BackBufferFormat,
+ presentParameters.MultiSampleType, presentParameters.MultiSampleQuality, FALSE, &renderTarget, NULL);
+
+ if (FAILED(result))
+ {
+ ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
+
+ swapChain->Release();
+ depthStencilSurface->Release();
+
+ ERR("Could not create render target surface for new swap chain: %08lX", result);
+ return error(EGL_BAD_ALLOC);
+ }
+
+ ASSERT(SUCCEEDED(result));
+
+ IDirect3DTexture9 *flipTexture = NULL;
+ result = device->CreateTexture(presentParameters.BackBufferWidth, presentParameters.BackBufferHeight, 1, D3DUSAGE_RENDERTARGET,
+ presentParameters.BackBufferFormat, D3DPOOL_DEFAULT, &flipTexture, NULL);
+
+ if (FAILED(result))
{
- D3DPRESENT_PARAMETERS presentParameters;
- mSwapChain->GetPresentParameters(&presentParameters);
+ ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
+
+ swapChain->Release();
+ depthStencilSurface->Release();
+ renderTarget->Release();
- return presentParameters.hDeviceWindow;
+ ERR("Could not create flip texture for new swap chain: %08lX", result);
+ return error(EGL_BAD_ALLOC);
}
- return NULL;
+ IDirect3DSurface9 *backBuffer = NULL;
+ swapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &backBuffer);
+
+ if (mSwapChain) mSwapChain->Release();
+ if (mDepthStencil) mDepthStencil->Release();
+ if (mBackBuffer) mBackBuffer->Release();
+ if (mRenderTarget) mRenderTarget->Release();
+ if (mFlipTexture) mFlipTexture->Release();
+
+ mWidth = presentParameters.BackBufferWidth;
+ mHeight = presentParameters.BackBufferHeight;
+
+ mSwapChain = swapChain;
+ mDepthStencil = depthStencilSurface;
+ mBackBuffer = backBuffer;
+ mRenderTarget = renderTarget;
+ mFlipTexture = flipTexture;
+
+ // The flip state block recorded mFlipTexture so it is now invalid.
+ releaseRecordedState(device);
+}
+
+HWND Surface::getWindowHandle()
+{
+ return mWindow;
}
-void Surface::writeRecordableFlipState(IDirect3DDevice9 *device, IDirect3DTexture9 *source)
+void Surface::writeRecordableFlipState(IDirect3DDevice9 *device)
{
// Disable all pipeline operations
device->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
@@ -138,16 +206,18 @@ void Surface::writeRecordableFlipState(IDirect3DDevice9 *device, IDirect3DTextur
device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
device->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
- device->SetTexture(0, source);
+ device->SetTexture(0, NULL); // The actual texture will change after resizing. But the pre-flip state block must save/restore the texture.
device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
device->SetSamplerState(0, D3DSAMP_SRGBTEXTURE, FALSE);
+ device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
+ device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
device->SetFVF(D3DFVF_XYZRHW | D3DFVF_TEX1);
device->SetStreamSourceFreq(0, 1); // DrawPrimitiveUP only cares about stream 0, not the rest.
}
-void Surface::applyFlipState(IDirect3DDevice9 *device, IDirect3DTexture9 *source)
+void Surface::applyFlipState(IDirect3DDevice9 *device)
{
HRESULT hr;
@@ -158,7 +228,7 @@ void Surface::applyFlipState(IDirect3DDevice9 *device, IDirect3DTexture9 *source
// mPreFlipState will record the original state each entry.
hr = device->BeginStateBlock();
ASSERT(SUCCEEDED(hr));
- writeRecordableFlipState(device, source);
+ writeRecordableFlipState(device);
hr = device->EndStateBlock(&mPreFlipState);
ASSERT(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY);
@@ -171,7 +241,7 @@ void Surface::applyFlipState(IDirect3DDevice9 *device, IDirect3DTexture9 *source
hr = device->BeginStateBlock();
ASSERT(SUCCEEDED(hr));
- writeRecordableFlipState(device, source);
+ writeRecordableFlipState(device);
hr = device->EndStateBlock(&mFlipState);
ASSERT(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY);
@@ -223,29 +293,88 @@ void Surface::restoreState(IDirect3DDevice9 *device)
}
}
+// On the next flip, this will cause the state to be recorded from scratch.
+// In particular we need to do this if the flip texture changes.
+void Surface::releaseRecordedState(IDirect3DDevice9 *device)
+{
+ if (mFlipState)
+ {
+ mFlipState->Release();
+ mFlipState = NULL;
+ }
+
+ if (mPreFlipState)
+ {
+ mPreFlipState->Release();
+ mPreFlipState = NULL;
+ }
+}
+
+bool Surface::checkForWindowResize()
+{
+ RECT client;
+ if (!GetClientRect(getWindowHandle(), &client))
+ {
+ ASSERT(false);
+ return false;
+ }
+
+ if (getWidth() != client.right - client.left || getHeight() != client.bottom - client.top)
+ {
+ resetSwapChain();
+
+ if (static_cast<egl::Surface*>(getCurrentDrawSurface()) == this)
+ {
+ glMakeCurrent(glGetCurrentContext(), static_cast<egl::Display*>(getCurrentDisplay()), this);
+ }
+
+ return true;
+ }
+
+ return false;
+}
+
bool Surface::swap()
{
if (mSwapChain)
{
+ IDirect3DTexture9 *flipTexture = mFlipTexture;
+ flipTexture->AddRef();
+
+ IDirect3DSurface9 *renderTarget = mRenderTarget;
+ renderTarget->AddRef();
+
+ EGLint oldWidth = mWidth;
+ EGLint oldHeight = mHeight;
+
+ checkForWindowResize();
+
IDirect3DDevice9 *device = mDisplay->getDevice();
IDirect3DSurface9 *textureSurface;
- mFlipTexture->GetSurfaceLevel(0, &textureSurface);
+ flipTexture->GetSurfaceLevel(0, &textureSurface);
mDisplay->endScene();
- device->StretchRect(mRenderTarget, NULL, textureSurface, NULL, D3DTEXF_NONE);
+ device->StretchRect(renderTarget, NULL, textureSurface, NULL, D3DTEXF_NONE);
+ renderTarget->Release();
- applyFlipState(device, mFlipTexture);
+ applyFlipState(device);
+ device->SetTexture(0, flipTexture);
+
+ float xscale = (float)mWidth / oldWidth;
+ float yscale = (float)mHeight / oldHeight;
// Render the texture upside down into the back buffer
- float quad[4][6] = {{ 0 - 0.5f, 0 - 0.5f, 0.0f, 1.0f, 0.0f, 1.0f},
- {mWidth - 0.5f, 0 - 0.5f, 0.0f, 1.0f, 1.0f, 1.0f},
- {mWidth - 0.5f, mHeight - 0.5f, 0.0f, 1.0f, 1.0f, 0.0f},
- { 0 - 0.5f, mHeight - 0.5f, 0.0f, 1.0f, 0.0f, 0.0f}}; // x, y, z, rhw, u, v
+ // Texcoords are chosen to pin a potentially resized image into the upper-left corner without scaling.
+ float quad[4][6] = {{ 0 - 0.5f, 0 - 0.5f, 0.0f, 1.0f, 0.0f, 1.0f },
+ {mWidth - 0.5f, 0 - 0.5f, 0.0f, 1.0f, xscale, 1.0f },
+ {mWidth - 0.5f, mHeight - 0.5f, 0.0f, 1.0f, xscale, 1.0f-yscale},
+ { 0 - 0.5f, mHeight - 0.5f, 0.0f, 1.0f, 0.0f, 1.0f-yscale}}; // x, y, z, rhw, u, v
mDisplay->startScene();
device->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, quad, 6 * sizeof(float));
+ flipTexture->Release();
textureSurface->Release();
restoreState(device);
@@ -264,6 +393,7 @@ bool Surface::swap()
}
ASSERT(SUCCEEDED(result));
+
}
return true;
diff --git a/ANGLE/src/libEGL/Surface.h b/ANGLE/src/libEGL/Surface.h
index 8c684a0..5bc912c 100644
--- a/ANGLE/src/libEGL/Surface.h
+++ b/ANGLE/src/libEGL/Surface.h
@@ -25,7 +25,7 @@ class Config;
class Surface
{
public:
- Surface(Display *display, IDirect3DSwapChain9 *swapChain, IDirect3DSurface9* depthStencil, const egl::Config *config);
+ Surface(Display *display, const egl::Config *config, HWND window);
~Surface();
@@ -42,20 +42,25 @@ class Surface
DISALLOW_COPY_AND_ASSIGN(Surface);
Display *const mDisplay;
- IDirect3DSwapChain9 *const mSwapChain;
+ IDirect3DSwapChain9 *mSwapChain;
IDirect3DSurface9 *mBackBuffer;
IDirect3DSurface9 *mRenderTarget;
IDirect3DSurface9 *mDepthStencil;
IDirect3DTexture9 *mFlipTexture;
- void applyFlipState(IDirect3DDevice9 *device, IDirect3DTexture9 *source);
+ void resetSwapChain();
+ bool checkForWindowResize();
+
+ void applyFlipState(IDirect3DDevice9 *device);
void restoreState(IDirect3DDevice9 *device);
- void writeRecordableFlipState(IDirect3DDevice9 *device, IDirect3DTexture9 *source);
+ void writeRecordableFlipState(IDirect3DDevice9 *device);
+ void releaseRecordedState(IDirect3DDevice9 *device);
IDirect3DStateBlock9 *mFlipState;
IDirect3DStateBlock9 *mPreFlipState;
IDirect3DSurface9 *mPreFlipBackBuffer;
IDirect3DSurface9 *mPreFlipDepthStencil;
+ const HWND mWindow; // Window that the surface is created for.
const egl::Config *mConfig; // EGL config surface was created with
EGLint mHeight; // Height of surface
EGLint mWidth; // Width of surface
diff --git a/ANGLE/src/libEGL/libEGL.cpp b/ANGLE/src/libEGL/libEGL.cpp
index 5c2cc1d..5ceb6ef 100644
--- a/ANGLE/src/libEGL/libEGL.cpp
+++ b/ANGLE/src/libEGL/libEGL.cpp
@@ -772,7 +772,7 @@ EGLContext __stdcall eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLConte
return EGL_NO_CONTEXT;
}
- EGLContext context = display->createContext(config);
+ EGLContext context = display->createContext(config, static_cast<gl::Context*>(share_context));
return success(context);
}
@@ -824,9 +824,8 @@ EGLBoolean __stdcall eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface
egl::Display *display = static_cast<egl::Display*>(dpy);
gl::Context *context = static_cast<gl::Context*>(ctx);
IDirect3DDevice9 *device = display->getDevice();
- DWORD passes;
- if (!device || device->ValidateDevice(&passes) == D3DERR_DEVICELOST)
+ if (!device || device->TestCooperativeLevel() != D3D_OK)
{
return error(EGL_CONTEXT_LOST, EGL_FALSE);
}
diff --git a/ANGLE/src/libEGL/libEGL.vcproj b/ANGLE/src/libEGL/libEGL.vcproj
index 30e6183..505f4d9 100644
--- a/ANGLE/src/libEGL/libEGL.vcproj
+++ b/ANGLE/src/libEGL/libEGL.vcproj
@@ -62,7 +62,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="d3d9.lib"
+ AdditionalDependencies="dxguid.lib"
LinkIncremental="2"
ModuleDefinitionFile="libEGL.def"
GenerateDebugInformation="true"
@@ -140,7 +140,7 @@
/>
<Tool
Name="VCLinkerTool"
- AdditionalDependencies="d3d9.lib"
+ AdditionalDependencies="dxguid.lib"
LinkIncremental="1"
ModuleDefinitionFile="libEGL.def"
GenerateDebugInformation="true"
diff --git a/ANGLE/src/libGLESv2/Blit.cpp b/ANGLE/src/libGLESv2/Blit.cpp
index 92bde05..00c878f 100644
--- a/ANGLE/src/libGLESv2/Blit.cpp
+++ b/ANGLE/src/libGLESv2/Blit.cpp
@@ -232,12 +232,12 @@ bool Blit::setShader(ShaderId source, const char *profile,
bool Blit::setVertexShader(ShaderId shader)
{
- return setShader<IDirect3DVertexShader9>(shader, mContext->getVertexShaderProfile(), &IDirect3DDevice9::CreateVertexShader, &IDirect3DDevice9::SetVertexShader);
+ return setShader<IDirect3DVertexShader9>(shader, mContext->supportsShaderModel3() ? "vs_3_0" : "vs_2_0", &IDirect3DDevice9::CreateVertexShader, &IDirect3DDevice9::SetVertexShader);
}
bool Blit::setPixelShader(ShaderId shader)
{
- return setShader<IDirect3DPixelShader9>(shader, mContext->getPixelShaderProfile(), &IDirect3DDevice9::CreatePixelShader, &IDirect3DDevice9::SetPixelShader);
+ return setShader<IDirect3DPixelShader9>(shader, mContext->supportsShaderModel3() ? "ps_3_0" : "ps_2_0", &IDirect3DDevice9::CreatePixelShader, &IDirect3DDevice9::SetPixelShader);
}
RECT Blit::getSurfaceRect(IDirect3DSurface9 *surface) const
@@ -325,6 +325,7 @@ bool Blit::setFormatConvertShaders(GLenum destFormat)
{
default: UNREACHABLE();
case GL_RGBA:
+ case GL_BGRA_EXT:
case GL_RGB:
case GL_ALPHA:
okay = okay && setPixelShader(SHADER_PS_COMPONENTMASK);
@@ -351,6 +352,7 @@ bool Blit::setFormatConvertShaders(GLenum destFormat)
{
default: UNREACHABLE();
case GL_RGBA:
+ case GL_BGRA_EXT:
psConst0[X] = 1;
psConst0[Z] = 1;
break;
diff --git a/ANGLE/src/libGLESv2/Buffer.cpp b/ANGLE/src/libGLESv2/Buffer.cpp
index 87d4185..43993e7 100644
--- a/ANGLE/src/libGLESv2/Buffer.cpp
+++ b/ANGLE/src/libGLESv2/Buffer.cpp
@@ -13,7 +13,7 @@
namespace gl
{
-Buffer::Buffer()
+Buffer::Buffer(GLuint id) : RefCountObject(id)
{
mContents = NULL;
mSize = 0;
diff --git a/ANGLE/src/libGLESv2/Buffer.h b/ANGLE/src/libGLESv2/Buffer.h
index 5fe0d75..5611cc9 100644
--- a/ANGLE/src/libGLESv2/Buffer.h
+++ b/ANGLE/src/libGLESv2/Buffer.h
@@ -18,14 +18,15 @@
#include <GLES2/gl2.h>
#include "common/angleutils.h"
+#include "libGLESv2/RefCountObject.h"
namespace gl
{
-class Buffer
+class Buffer : public RefCountObject
{
public:
- Buffer();
+ explicit Buffer(GLuint id);
virtual ~Buffer();
diff --git a/ANGLE/src/libGLESv2/Context.cpp b/ANGLE/src/libGLESv2/Context.cpp
index 55a83ff..48ef8fc 100644
--- a/ANGLE/src/libGLESv2/Context.cpp
+++ b/ANGLE/src/libGLESv2/Context.cpp
@@ -17,6 +17,7 @@
#include "libGLESv2/mathutil.h"
#include "libGLESv2/utilities.h"
#include "libGLESv2/Blit.h"
+#include "libGLESv2/ResourceManager.h"
#include "libGLESv2/Buffer.h"
#include "libGLESv2/FrameBuffer.h"
#include "libGLESv2/Program.h"
@@ -33,7 +34,7 @@
namespace gl
{
-Context::Context(const egl::Config *config)
+Context::Context(const egl::Config *config, const gl::Context *shareContext)
: mConfig(config)
{
setClearColor(0.0f, 0.0f, 0.0f, 0.0f);
@@ -103,37 +104,39 @@ Context::Context(const egl::Config *config)
mState.colorMaskAlpha = true;
mState.depthMask = true;
+ if (shareContext != NULL)
+ {
+ mResourceManager = shareContext->mResourceManager;
+ mResourceManager->addRef();
+ }
+ else
+ {
+ mResourceManager = new ResourceManager();
+ }
+
// [OpenGL ES 2.0.24] section 3.7 page 83:
// In the initial state, TEXTURE_2D and TEXTURE_CUBE_MAP have twodimensional
// and cube map texture state vectors respectively associated with them.
// In order that access to these initial textures not be lost, they are treated as texture
// objects all of whose names are 0.
- mTexture2DZero = new Texture2D(this);
- mTextureCubeMapZero = new TextureCubeMap(this);
+ mTexture2DZero = new Texture2D(0);
+ mTextureCubeMapZero = new TextureCubeMap(0);
mColorbufferZero = NULL;
- mDepthbufferZero = NULL;
- mStencilbufferZero = NULL;
+ mDepthStencilbufferZero = NULL;
mState.activeSampler = 0;
- mState.arrayBuffer = 0;
- mState.elementArrayBuffer = 0;
+ bindArrayBuffer(0);
+ bindElementArrayBuffer(0);
bindTextureCubeMap(0);
bindTexture2D(0);
- bindFramebuffer(0);
+ bindReadFramebuffer(0);
+ bindDrawFramebuffer(0);
bindRenderbuffer(0);
for (int type = 0; type < SAMPLER_TYPE_COUNT; type++)
{
- for (int sampler = 0; sampler < MAX_TEXTURE_IMAGE_UNITS; sampler++)
- {
- mState.samplerTexture[type][sampler] = 0;
- }
- }
-
- for (int type = 0; type < SAMPLER_TYPE_COUNT; type++)
- {
mIncompleteTextures[type] = NULL;
}
@@ -155,65 +158,72 @@ Context::Context(const egl::Config *config)
mHasBeenCurrent = false;
+ mMaxSupportedSamples = 0;
mMaskedClearSavedState = NULL;
markAllStateDirty();
}
Context::~Context()
{
- mState.currentProgram = 0;
-
- for (int type = 0; type < SAMPLER_TYPE_COUNT; type++)
+ if (mState.currentProgram != 0)
{
- delete mIncompleteTextures[type];
+ Program *programObject = mResourceManager->getProgram(mState.currentProgram);
+ if (programObject)
+ {
+ programObject->release();
+ }
+ mState.currentProgram = 0;
}
- delete mTexture2DZero;
- delete mTextureCubeMapZero;
-
- delete mColorbufferZero;
- delete mDepthbufferZero;
- delete mStencilbufferZero;
-
- delete mBufferBackEnd;
- delete mVertexDataManager;
- delete mIndexDataManager;
- delete mBlit;
-
- while (!mBufferMap.empty())
+ while (!mFramebufferMap.empty())
{
- deleteBuffer(mBufferMap.begin()->first);
+ deleteFramebuffer(mFramebufferMap.begin()->first);
}
- while (!mProgramMap.empty())
+ while (!mMultiSampleSupport.empty())
{
- deleteProgram(mProgramMap.begin()->first);
+ delete [] mMultiSampleSupport.begin()->second;
+ mMultiSampleSupport.erase(mMultiSampleSupport.begin());
}
- while (!mShaderMap.empty())
+ for (int type = 0; type < SAMPLER_TYPE_COUNT; type++)
{
- deleteShader(mShaderMap.begin()->first);
+ for (int sampler = 0; sampler < MAX_TEXTURE_IMAGE_UNITS; sampler++)
+ {
+ mState.samplerTexture[type][sampler].set(NULL);
+ }
}
- while (!mFramebufferMap.empty())
+ for (int type = 0; type < SAMPLER_TYPE_COUNT; type++)
{
- deleteFramebuffer(mFramebufferMap.begin()->first);
+ delete mIncompleteTextures[type];
}
- while (!mRenderbufferMap.empty())
+ for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
{
- deleteRenderbuffer(mRenderbufferMap.begin()->first);
+ mState.vertexAttribute[i].mBoundBuffer.set(NULL);
}
- while (!mTextureMap.empty())
- {
- deleteTexture(mTextureMap.begin()->first);
- }
+ mState.arrayBuffer.set(NULL);
+ mState.elementArrayBuffer.set(NULL);
+ mState.texture2D.set(NULL);
+ mState.textureCubeMap.set(NULL);
+ mState.renderbuffer.set(NULL);
+
+ delete mTexture2DZero;
+ delete mTextureCubeMapZero;
+
+ delete mBufferBackEnd;
+ delete mVertexDataManager;
+ delete mIndexDataManager;
+ delete mBlit;
if (mMaskedClearSavedState)
{
mMaskedClearSavedState->Release();
}
+
+ mResourceManager->release();
}
void Context::makeCurrent(egl::Display *display, egl::Surface *surface)
@@ -229,6 +239,34 @@ void Context::makeCurrent(egl::Display *display, egl::Surface *surface)
mIndexDataManager = new IndexDataManager(this, mBufferBackEnd);
mBlit = new Blit(this);
+ const D3DFORMAT renderBufferFormats[] =
+ {
+ D3DFMT_A8R8G8B8,
+ D3DFMT_X8R8G8B8,
+ D3DFMT_R5G6B5,
+ D3DFMT_D24S8
+ };
+
+ int max = 0;
+ for (int i = 0; i < sizeof(renderBufferFormats) / sizeof(D3DFORMAT); ++i)
+ {
+ bool *multisampleArray = new bool[D3DMULTISAMPLE_16_SAMPLES + 1];
+ display->getMultiSampleSupport(renderBufferFormats[i], multisampleArray);
+ mMultiSampleSupport[renderBufferFormats[i]] = multisampleArray;
+
+ for (int j = D3DMULTISAMPLE_16_SAMPLES; j >= 0; --j)
+ {
+ if (multisampleArray[j] && j != D3DMULTISAMPLE_NONMASKABLE && j > max)
+ {
+ max = j;
+ }
+ }
+ }
+
+ mMaxSupportedSamples = max;
+
+ mSupportsCompressedTextures = display->getCompressedTextureSupport();
+
initExtensionString();
mState.viewportX = 0;
@@ -248,19 +286,11 @@ void Context::makeCurrent(egl::Display *display, egl::Surface *surface)
IDirect3DSurface9 *defaultRenderTarget = surface->getRenderTarget();
IDirect3DSurface9 *depthStencil = surface->getDepthStencil();
- Framebuffer *framebufferZero = new Framebuffer();
Colorbuffer *colorbufferZero = new Colorbuffer(defaultRenderTarget);
- Depthbuffer *depthbufferZero = new Depthbuffer(depthStencil);
- Stencilbuffer *stencilbufferZero = new Stencilbuffer(depthStencil);
+ DepthStencilbuffer *depthStencilbufferZero = new DepthStencilbuffer(depthStencil);
+ Framebuffer *framebufferZero = new DefaultFramebuffer(colorbufferZero, depthStencilbufferZero);
setFramebufferZero(framebufferZero);
- setColorbufferZero(colorbufferZero);
- setDepthbufferZero(depthbufferZero);
- setStencilbufferZero(stencilbufferZero);
-
- framebufferZero->setColorbuffer(GL_RENDERBUFFER, 0);
- framebufferZero->setDepthbuffer(GL_RENDERBUFFER, 0);
- framebufferZero->setStencilbuffer(GL_RENDERBUFFER, 0);
defaultRenderTarget->Release();
@@ -269,16 +299,7 @@ void Context::makeCurrent(egl::Display *display, egl::Surface *surface)
depthStencil->Release();
}
- if (mDeviceCaps.PixelShaderVersion == D3DPS_VERSION(3, 0))
- {
- mPsProfile = "ps_3_0";
- mVsProfile = "vs_3_0";
- }
- else // egl::Display guarantees support for at least 2.0
- {
- mPsProfile = "ps_2_0";
- mVsProfile = "vs_2_0";
- }
+ mSupportsShaderModel3 = mDeviceCaps.PixelShaderVersion == D3DPS_VERSION(3, 0);
markAllStateDirty();
}
@@ -300,6 +321,12 @@ void Context::markAllStateDirty()
mScissorStateDirty = true;
mSampleStateDirty = true;
mDitherStateDirty = true;
+ mFrontFaceDirty = true;
+
+ if (mBufferBackEnd != NULL)
+ {
+ mBufferBackEnd->invalidate();
+ }
}
void Context::setClearColor(float red, float green, float blue, float alpha)
@@ -671,19 +698,24 @@ void Context::setActiveSampler(int active)
mState.activeSampler = active;
}
-GLuint Context::getFramebufferHandle() const
+GLuint Context::getReadFramebufferHandle() const
{
- return mState.framebuffer;
+ return mState.readFramebuffer;
+}
+
+GLuint Context::getDrawFramebufferHandle() const
+{
+ return mState.drawFramebuffer;
}
GLuint Context::getRenderbufferHandle() const
{
- return mState.renderbuffer;
+ return mState.renderbuffer.id();
}
GLuint Context::getArrayBufferHandle() const
{
- return mState.arrayBuffer;
+ return mState.arrayBuffer.id();
}
void Context::setVertexAttribEnabled(unsigned int attribNum, bool enabled)
@@ -696,10 +728,10 @@ const AttributeState &Context::getVertexAttribState(unsigned int attribNum)
return mState.vertexAttribute[attribNum];
}
-void Context::setVertexAttribState(unsigned int attribNum, GLuint boundBuffer, GLint size, GLenum type, bool normalized,
+void Context::setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type, bool normalized,
GLsizei stride, const void *pointer)
{
- mState.vertexAttribute[attribNum].mBoundBuffer = boundBuffer;
+ mState.vertexAttribute[attribNum].mBoundBuffer.set(boundBuffer);
mState.vertexAttribute[attribNum].mSize = size;
mState.vertexAttribute[attribNum].mType = type;
mState.vertexAttribute[attribNum].mNormalized = normalized;
@@ -738,72 +770,29 @@ GLint Context::getUnpackAlignment() const
return mState.unpackAlignment;
}
-// Returns an unused buffer name
GLuint Context::createBuffer()
{
- unsigned int handle = 1;
-
- while (mBufferMap.find(handle) != mBufferMap.end())
- {
- handle++;
- }
-
- mBufferMap[handle] = NULL;
-
- return handle;
+ return mResourceManager->createBuffer();
}
-// Returns an unused shader/program name
-GLuint Context::createShader(GLenum type)
+GLuint Context::createProgram()
{
- unsigned int handle = 1;
-
- while (mShaderMap.find(handle) != mShaderMap.end() || mProgramMap.find(handle) != mProgramMap.end()) // Shared name space
- {
- handle++;
- }
-
- if (type == GL_VERTEX_SHADER)
- {
- mShaderMap[handle] = new VertexShader(this, handle);
- }
- else if (type == GL_FRAGMENT_SHADER)
- {
- mShaderMap[handle] = new FragmentShader(this, handle);
- }
- else UNREACHABLE();
-
- return handle;
+ return mResourceManager->createProgram();
}
-// Returns an unused program/shader name
-GLuint Context::createProgram()
+GLuint Context::createShader(GLenum type)
{
- unsigned int handle = 1;
-
- while (mProgramMap.find(handle) != mProgramMap.end() || mShaderMap.find(handle) != mShaderMap.end()) // Shared name space
- {
- handle++;
- }
-
- mProgramMap[handle] = new Program();
-
- return handle;
+ return mResourceManager->createShader(type);
}
-// Returns an unused texture name
GLuint Context::createTexture()
{
- unsigned int handle = 1;
-
- while (mTextureMap.find(handle) != mTextureMap.end())
- {
- handle++;
- }
-
- mTextureMap[handle] = NULL;
+ return mResourceManager->createTexture();
+}
- return handle;
+GLuint Context::createRenderbuffer()
+{
+ return mResourceManager->createRenderbuffer();
}
// Returns an unused framebuffer name
@@ -821,85 +810,44 @@ GLuint Context::createFramebuffer()
return handle;
}
-// Returns an unused renderbuffer name
-GLuint Context::createRenderbuffer()
-{
- unsigned int handle = 1;
-
- while (mRenderbufferMap.find(handle) != mRenderbufferMap.end())
- {
- handle++;
- }
-
- mRenderbufferMap[handle] = NULL;
-
- return handle;
-}
-
void Context::deleteBuffer(GLuint buffer)
{
- BufferMap::iterator bufferObject = mBufferMap.find(buffer);
-
- if (bufferObject != mBufferMap.end())
+ if (mResourceManager->getBuffer(buffer))
{
detachBuffer(buffer);
-
- delete bufferObject->second;
- mBufferMap.erase(bufferObject);
}
+
+ mResourceManager->deleteBuffer(buffer);
}
void Context::deleteShader(GLuint shader)
{
- ShaderMap::iterator shaderObject = mShaderMap.find(shader);
-
- if (shaderObject != mShaderMap.end())
- {
- if (!shaderObject->second->isAttached())
- {
- delete shaderObject->second;
- mShaderMap.erase(shaderObject);
- }
- else
- {
- shaderObject->second->flagForDeletion();
- }
- }
+ mResourceManager->deleteShader(shader);
}
void Context::deleteProgram(GLuint program)
{
- ProgramMap::iterator programObject = mProgramMap.find(program);
-
- if (programObject != mProgramMap.end())
- {
- if (program != mState.currentProgram)
- {
- delete programObject->second;
- mProgramMap.erase(programObject);
- }
- else
- {
- programObject->second->flagForDeletion();
- }
- }
+ mResourceManager->deleteProgram(program);
}
void Context::deleteTexture(GLuint texture)
{
- TextureMap::iterator textureObject = mTextureMap.find(texture);
-
- if (textureObject != mTextureMap.end())
+ if (mResourceManager->getTexture(texture))
{
detachTexture(texture);
+ }
- if (texture != 0)
- {
- delete textureObject->second;
- }
+ mResourceManager->deleteTexture(texture);
+}
- mTextureMap.erase(textureObject);
+void Context::deleteRenderbuffer(GLuint renderbuffer)
+{
+ if (mResourceManager->getRenderbuffer(renderbuffer))
+ {
+ detachRenderbuffer(renderbuffer);
}
+
+ mResourceManager->deleteRenderbuffer(renderbuffer);
}
void Context::deleteFramebuffer(GLuint framebuffer)
@@ -915,307 +863,186 @@ void Context::deleteFramebuffer(GLuint framebuffer)
}
}
-void Context::deleteRenderbuffer(GLuint renderbuffer)
+Buffer *Context::getBuffer(GLuint handle)
{
- RenderbufferMap::iterator renderbufferObject = mRenderbufferMap.find(renderbuffer);
-
- if (renderbufferObject != mRenderbufferMap.end())
- {
- detachRenderbuffer(renderbuffer);
-
- delete renderbufferObject->second;
- mRenderbufferMap.erase(renderbufferObject);
- }
+ return mResourceManager->getBuffer(handle);
}
-void Context::bindArrayBuffer(unsigned int buffer)
+Shader *Context::getShader(GLuint handle)
{
- if (buffer != 0 && !getBuffer(buffer))
- {
- mBufferMap[buffer] = new Buffer();
- }
-
- mState.arrayBuffer = buffer;
+ return mResourceManager->getShader(handle);
}
-void Context::bindElementArrayBuffer(unsigned int buffer)
+Program *Context::getProgram(GLuint handle)
{
- if (buffer != 0 && !getBuffer(buffer))
- {
- mBufferMap[buffer] = new Buffer();
- }
-
- mState.elementArrayBuffer = buffer;
+ return mResourceManager->getProgram(handle);
}
-void Context::bindTexture2D(GLuint texture)
+Texture *Context::getTexture(GLuint handle)
{
- if (!getTexture(texture) && texture != 0)
- {
- mTextureMap[texture] = new Texture2D(this);
- }
-
- mState.texture2D = texture;
-
- mState.samplerTexture[SAMPLER_2D][mState.activeSampler] = texture;
+ return mResourceManager->getTexture(handle);
}
-void Context::bindTextureCubeMap(GLuint texture)
+Renderbuffer *Context::getRenderbuffer(GLuint handle)
{
- if (!getTexture(texture) && texture != 0)
- {
- mTextureMap[texture] = new TextureCubeMap(this);
- }
-
- mState.textureCubeMap = texture;
-
- mState.samplerTexture[SAMPLER_CUBE][mState.activeSampler] = texture;
+ return mResourceManager->getRenderbuffer(handle);
}
-void Context::bindFramebuffer(GLuint framebuffer)
+Framebuffer *Context::getReadFramebuffer()
{
- if (!getFramebuffer(framebuffer))
- {
- mFramebufferMap[framebuffer] = new Framebuffer();
- }
-
- mState.framebuffer = framebuffer;
+ return getFramebuffer(mState.readFramebuffer);
}
-void Context::bindRenderbuffer(GLuint renderbuffer)
+Framebuffer *Context::getDrawFramebuffer()
{
- if (renderbuffer != 0 && !getRenderbuffer(renderbuffer))
- {
- mRenderbufferMap[renderbuffer] = new Renderbuffer();
- }
-
- mState.renderbuffer = renderbuffer;
+ return getFramebuffer(mState.drawFramebuffer);
}
-void Context::useProgram(GLuint program)
+void Context::bindArrayBuffer(unsigned int buffer)
{
- Program *programObject = getCurrentProgram();
-
- GLuint priorProgram = mState.currentProgram;
- mState.currentProgram = program; // Must switch before trying to delete, otherwise it only gets flagged.
+ mResourceManager->checkBufferAllocation(buffer);
- if (programObject && programObject->isFlaggedForDeletion())
- {
- deleteProgram(priorProgram);
- }
+ mState.arrayBuffer.set(getBuffer(buffer));
}
-void Context::setFramebufferZero(Framebuffer *buffer)
+void Context::bindElementArrayBuffer(unsigned int buffer)
{
- delete mFramebufferMap[0];
- mFramebufferMap[0] = buffer;
-}
+ mResourceManager->checkBufferAllocation(buffer);
-void Context::setColorbufferZero(Colorbuffer *buffer)
-{
- delete mColorbufferZero;
- mColorbufferZero = buffer;
+ mState.elementArrayBuffer.set(getBuffer(buffer));
}
-void Context::setDepthbufferZero(Depthbuffer *buffer)
+void Context::bindTexture2D(GLuint texture)
{
- delete mDepthbufferZero;
- mDepthbufferZero = buffer;
-}
+ mResourceManager->checkTextureAllocation(texture, SAMPLER_2D);
-void Context::setStencilbufferZero(Stencilbuffer *buffer)
-{
- delete mStencilbufferZero;
- mStencilbufferZero = buffer;
-}
+ mState.texture2D.set(getTexture(texture));
-void Context::setRenderbuffer(Renderbuffer *buffer)
-{
- delete mRenderbufferMap[mState.renderbuffer];
- mRenderbufferMap[mState.renderbuffer] = buffer;
+ mState.samplerTexture[SAMPLER_2D][mState.activeSampler].set(mState.texture2D.get());
}
-Buffer *Context::getBuffer(unsigned int handle)
+void Context::bindTextureCubeMap(GLuint texture)
{
- BufferMap::iterator buffer = mBufferMap.find(handle);
+ mResourceManager->checkTextureAllocation(texture, SAMPLER_CUBE);
- if (buffer == mBufferMap.end())
- {
- return NULL;
- }
- else
- {
- return buffer->second;
- }
-}
+ mState.textureCubeMap.set(getTexture(texture));
-Shader *Context::getShader(unsigned int handle)
-{
- ShaderMap::iterator shader = mShaderMap.find(handle);
-
- if (shader == mShaderMap.end())
- {
- return NULL;
- }
- else
- {
- return shader->second;
- }
+ mState.samplerTexture[SAMPLER_CUBE][mState.activeSampler].set(mState.textureCubeMap.get());
}
-Program *Context::getProgram(unsigned int handle)
+void Context::bindReadFramebuffer(GLuint framebuffer)
{
- ProgramMap::iterator program = mProgramMap.find(handle);
-
- if (program == mProgramMap.end())
- {
- return NULL;
- }
- else
+ if (!getFramebuffer(framebuffer))
{
- return program->second;
+ mFramebufferMap[framebuffer] = new Framebuffer();
}
-}
-
-Texture *Context::getTexture(unsigned int handle)
-{
- if (handle == 0) return NULL;
-
- TextureMap::iterator texture = mTextureMap.find(handle);
- if (texture == mTextureMap.end())
- {
- return NULL;
- }
- else
- {
- return texture->second;
- }
+ mState.readFramebuffer = framebuffer;
}
-Framebuffer *Context::getFramebuffer(unsigned int handle)
+void Context::bindDrawFramebuffer(GLuint framebuffer)
{
- FramebufferMap::iterator framebuffer = mFramebufferMap.find(handle);
-
- if (framebuffer == mFramebufferMap.end())
- {
- return NULL;
- }
- else
+ if (!getFramebuffer(framebuffer))
{
- return framebuffer->second;
+ mFramebufferMap[framebuffer] = new Framebuffer();
}
+
+ mState.drawFramebuffer = framebuffer;
}
-Renderbuffer *Context::getRenderbuffer(unsigned int handle)
+void Context::bindRenderbuffer(GLuint renderbuffer)
{
- RenderbufferMap::iterator renderbuffer = mRenderbufferMap.find(handle);
+ mResourceManager->checkRenderbufferAllocation(renderbuffer);
- if (renderbuffer == mRenderbufferMap.end())
- {
- return NULL;
- }
- else
- {
- return renderbuffer->second;
- }
+ mState.renderbuffer.set(getRenderbuffer(renderbuffer));
}
-Colorbuffer *Context::getColorbuffer(GLuint handle)
+void Context::useProgram(GLuint program)
{
- if (handle != 0)
+ GLuint priorProgram = mState.currentProgram;
+ mState.currentProgram = program; // Must switch before trying to delete, otherwise it only gets flagged.
+
+ if (priorProgram != program)
{
- Renderbuffer *renderbuffer = getRenderbuffer(handle);
+ Program *newProgram = mResourceManager->getProgram(program);
+ Program *oldProgram = mResourceManager->getProgram(priorProgram);
- if (renderbuffer && renderbuffer->isColorbuffer())
+ if (newProgram)
{
- return static_cast<Colorbuffer*>(renderbuffer);
+ newProgram->addRef();
+ }
+
+ if (oldProgram)
+ {
+ oldProgram->release();
}
}
- else // Special case: 0 refers to different initial render targets based on the attachment type
- {
- return mColorbufferZero;
- }
-
- return NULL;
}
-Depthbuffer *Context::getDepthbuffer(GLuint handle)
+void Context::setFramebufferZero(Framebuffer *buffer)
{
- if (handle != 0)
- {
- Renderbuffer *renderbuffer = getRenderbuffer(handle);
-
- if (renderbuffer && renderbuffer->isDepthbuffer())
- {
- return static_cast<Depthbuffer*>(renderbuffer);
- }
- }
- else // Special case: 0 refers to different initial render targets based on the attachment type
- {
- return mDepthbufferZero;
- }
+ delete mFramebufferMap[0];
+ mFramebufferMap[0] = buffer;
+}
- return NULL;
+void Context::setRenderbufferStorage(RenderbufferStorage *renderbuffer)
+{
+ Renderbuffer *renderbufferObject = mState.renderbuffer.get();
+ renderbufferObject->setStorage(renderbuffer);
}
-Stencilbuffer *Context::getStencilbuffer(GLuint handle)
+Framebuffer *Context::getFramebuffer(unsigned int handle)
{
- if (handle != 0)
- {
- Renderbuffer *renderbuffer = getRenderbuffer(handle);
+ FramebufferMap::iterator framebuffer = mFramebufferMap.find(handle);
- if (renderbuffer && renderbuffer->isStencilbuffer())
- {
- return static_cast<Stencilbuffer*>(renderbuffer);
- }
+ if (framebuffer == mFramebufferMap.end())
+ {
+ return NULL;
}
else
{
- return mStencilbufferZero;
+ return framebuffer->second;
}
-
- return NULL;
}
Buffer *Context::getArrayBuffer()
{
- return getBuffer(mState.arrayBuffer);
+ return mState.arrayBuffer.get();
}
Buffer *Context::getElementArrayBuffer()
{
- return getBuffer(mState.elementArrayBuffer);
+ return mState.elementArrayBuffer.get();
}
Program *Context::getCurrentProgram()
{
- return getProgram(mState.currentProgram);
+ return mResourceManager->getProgram(mState.currentProgram);
}
Texture2D *Context::getTexture2D()
{
- if (mState.texture2D == 0) // Special case: 0 refers to different initial textures based on the target
+ if (mState.texture2D.id() == 0) // Special case: 0 refers to different initial textures based on the target
{
return mTexture2DZero;
}
- return (Texture2D*)getTexture(mState.texture2D);
+ return static_cast<Texture2D*>(mState.texture2D.get());
}
TextureCubeMap *Context::getTextureCubeMap()
{
- if (mState.textureCubeMap == 0) // Special case: 0 refers to different initial textures based on the target
+ if (mState.textureCubeMap.id() == 0) // Special case: 0 refers to different initial textures based on the target
{
return mTextureCubeMapZero;
}
- return (TextureCubeMap*)getTexture(mState.textureCubeMap);
+ return static_cast<TextureCubeMap*>(mState.textureCubeMap.get());
}
Texture *Context::getSamplerTexture(unsigned int sampler, SamplerType type)
{
- GLuint texid = mState.samplerTexture[type][sampler];
+ GLuint texid = mState.samplerTexture[type][sampler].id();
if (texid == 0)
{
@@ -1227,12 +1054,7 @@ Texture *Context::getSamplerTexture(unsigned int sampler, SamplerType type)
}
}
- return getTexture(texid);
-}
-
-Framebuffer *Context::getFramebuffer()
-{
- return getFramebuffer(mState.framebuffer);
+ return mState.samplerTexture[type][sampler].get();
}
bool Context::getBooleanv(GLenum pname, GLboolean *params)
@@ -1283,7 +1105,7 @@ bool Context::getFloatv(GLenum pname, GLfloat *params)
break;
case GL_ALIASED_POINT_SIZE_RANGE:
params[0] = gl::ALIASED_POINT_SIZE_RANGE_MIN;
- params[1] = gl::ALIASED_POINT_SIZE_RANGE_MAX;
+ params[1] = supportsShaderModel3() ? gl::ALIASED_POINT_SIZE_RANGE_MAX_SM3 : gl::ALIASED_POINT_SIZE_RANGE_MAX_SM2;
break;
case GL_DEPTH_RANGE:
params[0] = mState.zNear;
@@ -1326,13 +1148,13 @@ bool Context::getIntegerv(GLenum pname, GLint *params)
case GL_MAX_FRAGMENT_UNIFORM_VECTORS: *params = gl::MAX_FRAGMENT_UNIFORM_VECTORS; break;
case GL_MAX_RENDERBUFFER_SIZE: *params = gl::MAX_RENDERBUFFER_SIZE; break;
case GL_NUM_SHADER_BINARY_FORMATS: *params = 0; break;
- case GL_NUM_COMPRESSED_TEXTURE_FORMATS: *params = 0; break;
- case GL_COMPRESSED_TEXTURE_FORMATS: /* no compressed texture formats are supported */ break;
case GL_SHADER_BINARY_FORMATS: /* no shader binary formats are supported */ break;
- case GL_ARRAY_BUFFER_BINDING: *params = mState.arrayBuffer; break;
- case GL_ELEMENT_ARRAY_BUFFER_BINDING: *params = mState.elementArrayBuffer; break;
- case GL_FRAMEBUFFER_BINDING: *params = mState.framebuffer; break;
- case GL_RENDERBUFFER_BINDING: *params = mState.renderbuffer; break;
+ case GL_ARRAY_BUFFER_BINDING: *params = mState.arrayBuffer.id(); break;
+ case GL_ELEMENT_ARRAY_BUFFER_BINDING: *params = mState.elementArrayBuffer.id(); break;
+ //case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
+ case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE: *params = mState.drawFramebuffer; break;
+ case GL_READ_FRAMEBUFFER_BINDING_ANGLE: *params = mState.readFramebuffer; break;
+ case GL_RENDERBUFFER_BINDING: *params = mState.renderbuffer.id(); break;
case GL_CURRENT_PROGRAM: *params = mState.currentProgram; break;
case GL_PACK_ALIGNMENT: *params = mState.packAlignment; break;
case GL_UNPACK_ALIGNMENT: *params = mState.unpackAlignment; break;
@@ -1363,8 +1185,63 @@ bool Context::getIntegerv(GLenum pname, GLint *params)
case GL_SUBPIXEL_BITS: *params = 4; break;
case GL_MAX_TEXTURE_SIZE: *params = gl::MAX_TEXTURE_SIZE; break;
case GL_MAX_CUBE_MAP_TEXTURE_SIZE: *params = gl::MAX_CUBE_MAP_TEXTURE_SIZE; break;
- case GL_SAMPLE_BUFFERS: *params = 0; break;
- case GL_SAMPLES: *params = 0; break;
+ case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
+ {
+ if (supportsCompressedTextures())
+ {
+ // at current, only GL_COMPRESSED_RGB_S3TC_DXT1_EXT and
+ // GL_COMPRESSED_RGBA_S3TC_DXT1_EXT are supported
+ *params = 2;
+ }
+ else
+ {
+ *params = 0;
+ }
+ }
+ break;
+ case GL_MAX_SAMPLES_ANGLE:
+ {
+ GLsizei maxSamples = getMaxSupportedSamples();
+ if (maxSamples != 0)
+ {
+ *params = maxSamples;
+ }
+ else
+ {
+ return false;
+ }
+
+ break;
+ }
+ case GL_SAMPLE_BUFFERS:
+ case GL_SAMPLES:
+ {
+ gl::Framebuffer *framebuffer = getDrawFramebuffer();
+ if (framebuffer->completeness() == GL_FRAMEBUFFER_COMPLETE)
+ {
+ switch (pname)
+ {
+ case GL_SAMPLE_BUFFERS:
+ if (framebuffer->getSamples() != 0)
+ {
+ *params = 1;
+ }
+ else
+ {
+ *params = 0;
+ }
+ break;
+ case GL_SAMPLES:
+ *params = framebuffer->getSamples();
+ break;
+ }
+ }
+ else
+ {
+ *params = 0;
+ }
+ }
+ break;
case GL_IMPLEMENTATION_COLOR_READ_TYPE: *params = gl::IMPLEMENTATION_COLOR_READ_TYPE; break;
case GL_IMPLEMENTATION_COLOR_READ_FORMAT: *params = gl::IMPLEMENTATION_COLOR_READ_FORMAT; break;
case GL_MAX_VIEWPORT_DIMS:
@@ -1374,6 +1251,15 @@ bool Context::getIntegerv(GLenum pname, GLint *params)
params[1] = maxDimension;
}
break;
+ case GL_COMPRESSED_TEXTURE_FORMATS:
+ {
+ if (supportsCompressedTextures())
+ {
+ params[0] = GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
+ params[1] = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
+ }
+ }
+ break;
case GL_VIEWPORT:
params[0] = mState.viewportX;
params[1] = mState.viewportY;
@@ -1393,7 +1279,7 @@ bool Context::getIntegerv(GLenum pname, GLint *params)
case GL_BLUE_BITS:
case GL_ALPHA_BITS:
{
- gl::Framebuffer *framebuffer = getFramebuffer();
+ gl::Framebuffer *framebuffer = getDrawFramebuffer();
gl::Colorbuffer *colorbuffer = framebuffer->getColorbuffer();
if (colorbuffer)
@@ -1414,8 +1300,8 @@ bool Context::getIntegerv(GLenum pname, GLint *params)
break;
case GL_DEPTH_BITS:
{
- gl::Framebuffer *framebuffer = getFramebuffer();
- gl::Depthbuffer *depthbuffer = framebuffer->getDepthbuffer();
+ gl::Framebuffer *framebuffer = getDrawFramebuffer();
+ gl::DepthStencilbuffer *depthbuffer = framebuffer->getDepthbuffer();
if (depthbuffer)
{
@@ -1429,8 +1315,8 @@ bool Context::getIntegerv(GLenum pname, GLint *params)
break;
case GL_STENCIL_BITS:
{
- gl::Framebuffer *framebuffer = getFramebuffer();
- gl::Stencilbuffer *stencilbuffer = framebuffer->getStencilbuffer();
+ gl::Framebuffer *framebuffer = getDrawFramebuffer();
+ gl::DepthStencilbuffer *stencilbuffer = framebuffer->getStencilbuffer();
if (stencilbuffer)
{
@@ -1450,7 +1336,7 @@ bool Context::getIntegerv(GLenum pname, GLint *params)
return false;
}
- *params = mState.samplerTexture[SAMPLER_2D][mState.activeSampler];
+ *params = mState.samplerTexture[SAMPLER_2D][mState.activeSampler].id();
}
break;
case GL_TEXTURE_BINDING_CUBE_MAP:
@@ -1461,7 +1347,7 @@ bool Context::getIntegerv(GLenum pname, GLint *params)
return false;
}
- *params = mState.samplerTexture[SAMPLER_CUBE][mState.activeSampler];
+ *params = mState.samplerTexture[SAMPLER_CUBE][mState.activeSampler].id();
}
break;
default:
@@ -1552,6 +1438,19 @@ bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *nu
*numParams = 1;
}
break;
+ case GL_MAX_SAMPLES_ANGLE:
+ {
+ if (getMaxSupportedSamples() != 0)
+ {
+ *type = GL_INT;
+ *numParams = 1;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ break;
case GL_MAX_VIEWPORT_DIMS:
{
*type = GL_INT;
@@ -1626,7 +1525,7 @@ bool Context::applyRenderTarget(bool ignoreViewport)
{
IDirect3DDevice9 *device = getDevice();
- Framebuffer *framebufferObject = getFramebuffer();
+ Framebuffer *framebufferObject = getDrawFramebuffer();
if (!framebufferObject || framebufferObject->completeness() != GL_FRAMEBUFFER_COMPLETE)
{
@@ -1636,20 +1535,35 @@ bool Context::applyRenderTarget(bool ignoreViewport)
}
IDirect3DSurface9 *renderTarget = framebufferObject->getRenderTarget();
- IDirect3DSurface9 *depthStencil = framebufferObject->getDepthStencil();
+ IDirect3DSurface9 *depthStencil = NULL;
unsigned int renderTargetSerial = framebufferObject->getRenderTargetSerial();
if (renderTargetSerial != mAppliedRenderTargetSerial)
{
device->SetRenderTarget(0, renderTarget);
mAppliedRenderTargetSerial = renderTargetSerial;
+ mScissorStateDirty = true; // Scissor area must be clamped to render target's size-- this is different for different render targets.
}
- unsigned int depthbufferSerial = framebufferObject->getDepthbufferSerial();
- if (depthbufferSerial != mAppliedDepthbufferSerial)
+ unsigned int depthbufferSerial = 0;
+ unsigned int stencilbufferSerial = 0;
+ if (framebufferObject->getDepthbufferType() != GL_NONE)
+ {
+ depthStencil = framebufferObject->getDepthbuffer()->getDepthStencil();
+ depthbufferSerial = framebufferObject->getDepthbuffer()->getSerial();
+ }
+ else if (framebufferObject->getStencilbufferType() != GL_NONE)
+ {
+ depthStencil = framebufferObject->getStencilbuffer()->getDepthStencil();
+ stencilbufferSerial = framebufferObject->getStencilbuffer()->getSerial();
+ }
+
+ if (depthbufferSerial != mAppliedDepthbufferSerial ||
+ stencilbufferSerial != mAppliedStencilbufferSerial)
{
device->SetDepthStencilSurface(depthStencil);
mAppliedDepthbufferSerial = depthbufferSerial;
+ mAppliedStencilbufferSerial = stencilbufferSerial;
}
D3DVIEWPORT9 viewport;
@@ -1690,7 +1604,8 @@ bool Context::applyRenderTarget(bool ignoreViewport)
mState.scissorY,
mState.scissorX + mState.scissorWidth,
mState.scissorY + mState.scissorHeight};
-
+ rect.right = std::min(static_cast<UINT>(rect.right), desc.Width);
+ rect.bottom = std::min(static_cast<UINT>(rect.bottom), desc.Height);
device->SetScissorRect(&rect);
device->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE);
}
@@ -1698,7 +1613,7 @@ bool Context::applyRenderTarget(bool ignoreViewport)
{
device->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE);
}
-
+
mScissorStateDirty = false;
}
@@ -1710,7 +1625,7 @@ bool Context::applyRenderTarget(bool ignoreViewport)
GLfloat xy[2] = {1.0f / viewport.Width, 1.0f / viewport.Height};
programObject->setUniform2fv(halfPixelSize, 1, (GLfloat*)&xy);
- GLint window = programObject->getDxWindowLocation();
+ GLint window = programObject->getDxViewportLocation();
GLfloat whxy[4] = {mState.viewportWidth / 2.0f, mState.viewportHeight / 2.0f,
(float)mState.viewportX + mState.viewportWidth / 2.0f,
(float)mState.viewportY + mState.viewportHeight / 2.0f};
@@ -1748,6 +1663,8 @@ void Context::applyState(GLenum drawMode)
GLint alwaysFront = !isTriangleMode(drawMode);
programObject->setUniform1iv(pointsOrLines, 1, &alwaysFront);
+ Framebuffer *framebufferObject = getDrawFramebuffer();
+
if (mCullStateDirty || mFrontFaceDirty)
{
if (mState.cullFace)
@@ -1764,7 +1681,7 @@ void Context::applyState(GLenum drawMode)
if (mDepthStateDirty)
{
- if (mState.depthTest)
+ if (mState.depthTest && framebufferObject->getDepthbufferType() != GL_NONE)
{
device->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
device->SetRenderState(D3DRS_ZFUNC, es2dx::ConvertComparison(mState.depthFunc));
@@ -1826,7 +1743,7 @@ void Context::applyState(GLenum drawMode)
if (mStencilStateDirty || mFrontFaceDirty)
{
- if (mState.stencilTest && hasStencil())
+ if (mState.stencilTest && framebufferObject->hasStencil())
{
device->SetRenderState(D3DRS_STENCILENABLE, TRUE);
device->SetRenderState(D3DRS_TWOSIDEDSTENCILMODE, TRUE);
@@ -1844,8 +1761,7 @@ void Context::applyState(GLenum drawMode)
}
// get the maximum size of the stencil ref
- gl::Framebuffer *framebuffer = getFramebuffer();
- gl::Stencilbuffer *stencilbuffer = framebuffer->getStencilbuffer();
+ gl::DepthStencilbuffer *stencilbuffer = framebufferObject->getStencilbuffer();
GLuint maxStencil = (1 << stencilbuffer->getStencilSize()) - 1;
device->SetRenderState(mState.frontFace == GL_CCW ? D3DRS_STENCILWRITEMASK : D3DRS_CCW_STENCILWRITEMASK, mState.stencilWritemask);
@@ -1897,7 +1813,7 @@ void Context::applyState(GLenum drawMode)
{
if (mState.polygonOffsetFill)
{
- gl::Depthbuffer *depthbuffer = getFramebuffer()->getDepthbuffer();
+ gl::DepthStencilbuffer *depthbuffer = framebufferObject->getDepthbuffer();
if (depthbuffer)
{
device->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, *((DWORD*)&mState.polygonOffsetFactor));
@@ -1914,7 +1830,7 @@ void Context::applyState(GLenum drawMode)
mPolygonOffsetStateDirty = false;
}
- if (mConfig->mMultiSample != 0 && mSampleStateDirty)
+ if (framebufferObject->isMultisample() && mSampleStateDirty)
{
if (mState.sampleAlphaToCoverage)
{
@@ -1923,7 +1839,34 @@ void Context::applyState(GLenum drawMode)
if (mState.sampleCoverage)
{
- FIXME("Sample coverage is unimplemented.");
+ device->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, TRUE);
+ unsigned int mask = 0;
+ if (mState.sampleCoverageValue != 0)
+ {
+ float threshold = 0.5f;
+
+ for (int i = 0; i < framebufferObject->getSamples(); ++i)
+ {
+ mask <<= 1;
+
+ if ((i + 1) * mState.sampleCoverageValue >= threshold)
+ {
+ threshold += 1.0f;
+ mask |= 1;
+ }
+ }
+ }
+
+ if (mState.sampleCoverageInvert)
+ {
+ mask = ~mask;
+ }
+
+ device->SetRenderState(D3DRS_MULTISAMPLEMASK, mask);
+ }
+ else
+ {
+ device->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, FALSE);
}
mSampleStateDirty = false;
@@ -2005,7 +1948,7 @@ GLenum Context::applyVertexBuffer(const TranslatedIndexData &indexInfo)
// Applies the indices and element array bindings to the Direct3D 9 device
GLenum Context::applyIndexBuffer(const void *indices, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo)
{
- GLenum err = mIndexDataManager->preRenderValidate(mode, type, count, getBuffer(mState.elementArrayBuffer), indices, indexInfo);
+ GLenum err = mIndexDataManager->preRenderValidate(mode, type, count, mState.elementArrayBuffer.get(), indices, indexInfo);
if (err == GL_NO_ERROR)
{
@@ -2092,7 +2035,18 @@ void Context::applyTextures()
void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels)
{
- Framebuffer *framebuffer = getFramebuffer();
+ Framebuffer *framebuffer = getReadFramebuffer();
+
+ if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
+ {
+ return error(GL_INVALID_FRAMEBUFFER_OPERATION);
+ }
+
+ if (getReadFramebufferHandle() != 0 && framebuffer->getSamples() != 0)
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
IDirect3DSurface9 *renderTarget = framebuffer->getRenderTarget();
IDirect3DDevice9 *device = getDevice();
@@ -2155,6 +2109,19 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum
for (int j = 0; j < rect.bottom - rect.top; j++)
{
+ if (desc.Format == D3DFMT_A8R8G8B8 &&
+ format == GL_BGRA_EXT &&
+ type == GL_UNSIGNED_BYTE)
+ {
+ // Fast path for EXT_read_format_bgra, given
+ // an RGBA source buffer. Note that buffers with no
+ // alpha go through the slow path below.
+ memcpy(dest + j * outputPitch,
+ source + j * lock.Pitch,
+ (rect.right - rect.left) * 4);
+ continue;
+ }
+
for (int i = 0; i < rect.right - rect.left; i++)
{
float r;
@@ -2243,6 +2210,46 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum
default: UNREACHABLE();
}
break;
+ case GL_BGRA_EXT:
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ dest[4 * i + j * outputPitch + 0] = (unsigned char)(255 * b + 0.5f);
+ dest[4 * i + j * outputPitch + 1] = (unsigned char)(255 * g + 0.5f);
+ dest[4 * i + j * outputPitch + 2] = (unsigned char)(255 * r + 0.5f);
+ dest[4 * i + j * outputPitch + 3] = (unsigned char)(255 * a + 0.5f);
+ break;
+ case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
+ // According to the desktop GL spec in the "Transfer of Pixel Rectangles" section
+ // this type is packed as follows:
+ // 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
+ // --------------------------------------------------------------------------------
+ // | 4th | 3rd | 2nd | 1st component |
+ // --------------------------------------------------------------------------------
+ // in the case of BGRA_EXT, B is the first component, G the second, and so forth.
+ dest16[i + j * outputPitch / sizeof(unsigned short)] =
+ ((unsigned short)(15 * a + 0.5f) << 12)|
+ ((unsigned short)(15 * r + 0.5f) << 8) |
+ ((unsigned short)(15 * g + 0.5f) << 4) |
+ ((unsigned short)(15 * b + 0.5f) << 0);
+ break;
+ case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
+ // According to the desktop GL spec in the "Transfer of Pixel Rectangles" section
+ // this type is packed as follows:
+ // 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
+ // --------------------------------------------------------------------------------
+ // | 4th | 3rd | 2nd | 1st component |
+ // --------------------------------------------------------------------------------
+ // in the case of BGRA_EXT, B is the first component, G the second, and so forth.
+ dest16[i + j * outputPitch / sizeof(unsigned short)] =
+ ((unsigned short)( a + 0.5f) << 15) |
+ ((unsigned short)(31 * r + 0.5f) << 10) |
+ ((unsigned short)(31 * g + 0.5f) << 5) |
+ ((unsigned short)(31 * b + 0.5f) << 0);
+ break;
+ default: UNREACHABLE();
+ }
+ break;
case GL_RGB: // IMPLEMENTATION_COLOR_READ_FORMAT
switch (type)
{
@@ -2267,7 +2274,7 @@ void Context::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum
void Context::clear(GLbitfield mask)
{
- Framebuffer *framebufferObject = getFramebuffer();
+ Framebuffer *framebufferObject = getDrawFramebuffer();
if (!framebufferObject || framebufferObject->completeness() != GL_FRAMEBUFFER_COMPLETE)
{
@@ -2299,22 +2306,24 @@ void Context::clear(GLbitfield mask)
}
}
- IDirect3DSurface9 *depthStencil = framebufferObject->getDepthStencil();
-
GLuint stencilUnmasked = 0x0;
- if ((mask & GL_STENCIL_BUFFER_BIT) && depthStencil)
+ if (mask & GL_STENCIL_BUFFER_BIT)
{
- D3DSURFACE_DESC desc;
- depthStencil->GetDesc(&desc);
-
mask &= ~GL_STENCIL_BUFFER_BIT;
- unsigned int stencilSize = es2dx::GetStencilSize(desc.Format);
- stencilUnmasked = (0x1 << stencilSize) - 1;
-
- if (stencilUnmasked != 0x0)
+ if (framebufferObject->getStencilbufferType() != GL_NONE)
{
- flags |= D3DCLEAR_STENCIL;
+ IDirect3DSurface9 *depthStencil = framebufferObject->getStencilbuffer()->getDepthStencil();
+ D3DSURFACE_DESC desc;
+ depthStencil->GetDesc(&desc);
+
+ unsigned int stencilSize = es2dx::GetStencilSize(desc.Format);
+ stencilUnmasked = (0x1 << stencilSize) - 1;
+
+ if (stencilUnmasked != 0x0)
+ {
+ flags |= D3DCLEAR_STENCIL;
+ }
}
}
@@ -2618,7 +2627,8 @@ void Context::finish()
IDirect3DStateBlock9 *savedState = NULL;
device->CreateStateBlock(D3DSBT_ALL, &savedState);
- occlusionQuery->Issue(D3DISSUE_BEGIN);
+ HRESULT result = occlusionQuery->Issue(D3DISSUE_BEGIN);
+ ASSERT(SUCCEEDED(result));
// Render something outside the render target
device->SetStreamSourceFreq(0, 1);
@@ -2629,7 +2639,8 @@ void Context::finish()
display->startScene();
device->DrawPrimitiveUP(D3DPT_POINTLIST, 1, data, sizeof(data));
- occlusionQuery->Issue(D3DISSUE_END);
+ result = occlusionQuery->Issue(D3DISSUE_END);
+ ASSERT(SUCCEEDED(result));
while (occlusionQuery->GetData(NULL, 0, D3DGETDATA_FLUSH) == S_FALSE)
{
@@ -2663,15 +2674,16 @@ void Context::flush()
if (eventQuery)
{
- eventQuery->Issue(D3DISSUE_END);
+ HRESULT result = eventQuery->Issue(D3DISSUE_END);
+ ASSERT(SUCCEEDED(result));
- while (eventQuery->GetData(NULL, 0, D3DGETDATA_FLUSH) == S_FALSE)
+ result = eventQuery->GetData(NULL, 0, D3DGETDATA_FLUSH);
+ eventQuery->Release();
+
+ if (result == D3DERR_DEVICELOST)
{
- // Keep polling, but allow other threads to do something useful first
- Sleep(0);
+ error(GL_OUT_OF_MEMORY);
}
-
- eventQuery->Release();
}
}
@@ -2742,14 +2754,43 @@ GLenum Context::getError()
return GL_NO_ERROR;
}
-const char *Context::getPixelShaderProfile()
+bool Context::supportsShaderModel3() const
{
- return mPsProfile;
+ return mSupportsShaderModel3;
}
-const char *Context::getVertexShaderProfile()
+int Context::getMaxSupportedSamples() const
{
- return mVsProfile;
+ return mMaxSupportedSamples;
+}
+
+int Context::getNearestSupportedSamples(D3DFORMAT format, int requested) const
+{
+ if (requested == 0)
+ {
+ return requested;
+ }
+
+ std::map<D3DFORMAT, bool *>::const_iterator itr = mMultiSampleSupport.find(format);
+ if (itr == mMultiSampleSupport.end())
+ {
+ return -1;
+ }
+
+ for (int i = requested; i <= D3DMULTISAMPLE_16_SAMPLES; ++i)
+ {
+ if (itr->second[i] && i != D3DMULTISAMPLE_NONMASKABLE)
+ {
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+bool Context::supportsCompressedTextures() const
+{
+ return mSupportsCompressedTextures;
}
void Context::detachBuffer(GLuint buffer)
@@ -2758,21 +2799,21 @@ void Context::detachBuffer(GLuint buffer)
// If a buffer object is deleted while it is bound, all bindings to that object in the current context
// (i.e. in the thread that called Delete-Buffers) are reset to zero.
- if (mState.arrayBuffer == buffer)
+ if (mState.arrayBuffer.id() == buffer)
{
- mState.arrayBuffer = 0;
+ mState.arrayBuffer.set(NULL);
}
- if (mState.elementArrayBuffer == buffer)
+ if (mState.elementArrayBuffer.id() == buffer)
{
- mState.elementArrayBuffer = 0;
+ mState.elementArrayBuffer.set(NULL);
}
for (int attribute = 0; attribute < MAX_VERTEX_ATTRIBS; attribute++)
{
- if (mState.vertexAttribute[attribute].mBoundBuffer == buffer)
+ if (mState.vertexAttribute[attribute].mBoundBuffer.id() == buffer)
{
- mState.vertexAttribute[attribute].mBoundBuffer = 0;
+ mState.vertexAttribute[attribute].mBoundBuffer.set(NULL);
}
}
}
@@ -2787,9 +2828,9 @@ void Context::detachTexture(GLuint texture)
{
for (int sampler = 0; sampler < MAX_TEXTURE_IMAGE_UNITS; sampler++)
{
- if (mState.samplerTexture[type][sampler] == texture)
+ if (mState.samplerTexture[type][sampler].id() == texture)
{
- mState.samplerTexture[type][sampler] = 0;
+ mState.samplerTexture[type][sampler].set(NULL);
}
}
}
@@ -2799,11 +2840,17 @@ void Context::detachTexture(GLuint texture)
// as if FramebufferTexture2D had been called, with a texture of 0, for each attachment point to which this
// image was attached in the currently bound framebuffer.
- Framebuffer *framebuffer = getFramebuffer();
+ Framebuffer *readFramebuffer = getReadFramebuffer();
+ Framebuffer *drawFramebuffer = getDrawFramebuffer();
- if (framebuffer)
+ if (readFramebuffer)
{
- framebuffer->detachTexture(texture);
+ readFramebuffer->detachTexture(texture);
+ }
+
+ if (drawFramebuffer && drawFramebuffer != readFramebuffer)
+ {
+ drawFramebuffer->detachTexture(texture);
}
}
@@ -2813,9 +2860,14 @@ void Context::detachFramebuffer(GLuint framebuffer)
// If a framebuffer that is currently bound to the target FRAMEBUFFER is deleted, it is as though
// BindFramebuffer had been executed with the target of FRAMEBUFFER and framebuffer of zero.
- if (mState.framebuffer == framebuffer)
+ if (mState.readFramebuffer == framebuffer)
+ {
+ bindReadFramebuffer(0);
+ }
+
+ if (mState.drawFramebuffer == framebuffer)
{
- bindFramebuffer(0);
+ bindDrawFramebuffer(0);
}
}
@@ -2825,7 +2877,7 @@ void Context::detachRenderbuffer(GLuint renderbuffer)
// If a renderbuffer that is currently bound to RENDERBUFFER is deleted, it is as though BindRenderbuffer
// had been executed with the target RENDERBUFFER and name of zero.
- if (mState.renderbuffer == renderbuffer)
+ if (mState.renderbuffer.id() == renderbuffer)
{
bindRenderbuffer(0);
}
@@ -2835,11 +2887,17 @@ void Context::detachRenderbuffer(GLuint renderbuffer)
// then it is as if FramebufferRenderbuffer had been called, with a renderbuffer of 0, for each attachment
// point to which this image was attached in the currently bound framebuffer.
- Framebuffer *framebuffer = getFramebuffer();
+ Framebuffer *readFramebuffer = getReadFramebuffer();
+ Framebuffer *drawFramebuffer = getDrawFramebuffer();
+
+ if (readFramebuffer)
+ {
+ readFramebuffer->detachRenderbuffer(renderbuffer);
+ }
- if (framebuffer)
+ if (drawFramebuffer && drawFramebuffer != readFramebuffer)
{
- framebuffer->detachRenderbuffer(renderbuffer);
+ drawFramebuffer->detachRenderbuffer(renderbuffer);
}
}
@@ -2859,7 +2917,7 @@ Texture *Context::getIncompleteTexture(SamplerType type)
case SAMPLER_2D:
{
- Texture2D *incomplete2d = new Texture2D(this);
+ Texture2D *incomplete2d = new Texture2D(Texture::INCOMPLETE_TEXTURE_ID);
incomplete2d->setImage(0, GL_RGBA, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color);
t = incomplete2d;
}
@@ -2867,7 +2925,7 @@ Texture *Context::getIncompleteTexture(SamplerType type)
case SAMPLER_CUBE:
{
- TextureCubeMap *incompleteCube = new TextureCubeMap(this);
+ TextureCubeMap *incompleteCube = new TextureCubeMap(Texture::INCOMPLETE_TEXTURE_ID);
incompleteCube->setImagePosX(0, GL_RGBA, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color);
incompleteCube->setImageNegX(0, GL_RGBA, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 1, color);
@@ -2911,23 +2969,6 @@ bool Context::isTriangleMode(GLenum drawMode)
return false;
}
-bool Context::hasStencil()
-{
- Framebuffer *framebufferObject = getFramebuffer();
-
- if (framebufferObject)
- {
- Stencilbuffer *stencilbufferObject = framebufferObject->getStencilbuffer();
-
- if (stencilbufferObject)
- {
- return stencilbufferObject->getStencilSize() > 0;
- }
- }
-
- return false;
-}
-
void Context::setVertexAttrib(GLuint index, const GLfloat *values)
{
ASSERT(index < gl::MAX_VERTEX_ATTRIBS);
@@ -2942,6 +2983,22 @@ void Context::setVertexAttrib(GLuint index, const GLfloat *values)
void Context::initExtensionString()
{
+ mExtensionString += "GL_OES_packed_depth_stencil ";
+ mExtensionString += "GL_EXT_texture_format_BGRA8888 ";
+ mExtensionString += "GL_EXT_read_format_bgra ";
+ mExtensionString += "GL_ANGLE_framebuffer_blit ";
+ mExtensionString += "GL_OES_rgb8_rgba8 ";
+
+ if (supportsCompressedTextures())
+ {
+ mExtensionString += "GL_EXT_texture_compression_dxt1 ";
+ }
+
+ if (getMaxSupportedSamples() != 0)
+ {
+ mExtensionString += "GL_ANGLE_framebuffer_multisample ";
+ }
+
if (mBufferBackEnd->supportIntIndices())
{
mExtensionString += "GL_OES_element_index_uint ";
@@ -2959,13 +3016,285 @@ const char *Context::getExtensionString() const
return mExtensionString.c_str();
}
+void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
+ GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
+ GLbitfield mask)
+{
+ IDirect3DDevice9 *device = getDevice();
+
+ Framebuffer *readFramebuffer = getReadFramebuffer();
+ Framebuffer *drawFramebuffer = getDrawFramebuffer();
+
+ if (!readFramebuffer || readFramebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE ||
+ !drawFramebuffer || drawFramebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
+ {
+ return error(GL_INVALID_FRAMEBUFFER_OPERATION);
+ }
+
+ if (drawFramebuffer->getSamples() != 0)
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
+ RECT sourceRect;
+ RECT destRect;
+
+ if (srcX0 < srcX1)
+ {
+ sourceRect.left = srcX0;
+ sourceRect.right = srcX1;
+ destRect.left = dstX0;
+ destRect.right = dstX1;
+ }
+ else
+ {
+ sourceRect.left = srcX1;
+ destRect.left = dstX1;
+ sourceRect.right = srcX0;
+ destRect.right = dstX0;
+ }
+
+ // Arguments to StretchRect must be in D3D-style (0-top) coordinates, so we must
+ // flip our Y-values here
+ if (srcY0 < srcY1)
+ {
+ sourceRect.bottom = srcY1;
+ destRect.bottom = dstY1;
+ sourceRect.top = srcY0;
+ destRect.top = dstY0;
+ }
+ else
+ {
+ sourceRect.bottom = srcY0;
+ destRect.bottom = dstY0;
+ sourceRect.top = srcY1;
+ destRect.top = dstY1;
+ }
+
+ RECT sourceScissoredRect = sourceRect;
+ RECT destScissoredRect = destRect;
+
+ if (mState.scissorTest)
+ {
+ // Only write to parts of the destination framebuffer which pass the scissor test
+ // Please note: the destRect is now in D3D-style coordinates, so the *top* of the
+ // rect will be checked against scissorY, rather than the bottom.
+ if (destRect.left < mState.scissorX)
+ {
+ int xDiff = mState.scissorX - destRect.left;
+ destScissoredRect.left = mState.scissorX;
+ sourceScissoredRect.left += xDiff;
+ }
+
+ if (destRect.right > mState.scissorX + mState.scissorWidth)
+ {
+ int xDiff = destRect.right - (mState.scissorX + mState.scissorWidth);
+ destScissoredRect.right = mState.scissorX + mState.scissorWidth;
+ sourceScissoredRect.right -= xDiff;
+ }
+
+ if (destRect.top < mState.scissorY)
+ {
+ int yDiff = mState.scissorY - destRect.top;
+ destScissoredRect.top = mState.scissorY;
+ sourceScissoredRect.top += yDiff;
+ }
+
+ if (destRect.bottom > mState.scissorY + mState.scissorHeight)
+ {
+ int yDiff = destRect.bottom - (mState.scissorY + mState.scissorHeight);
+ destScissoredRect.bottom = mState.scissorY + mState.scissorHeight;
+ sourceScissoredRect.bottom -= yDiff;
+ }
+ }
+
+ bool blitRenderTarget = false;
+ bool blitDepthStencil = false;
+
+ RECT sourceTrimmedRect = sourceScissoredRect;
+ RECT destTrimmedRect = destScissoredRect;
+
+ // The source & destination rectangles also may need to be trimmed if they fall out of the bounds of
+ // the actual draw and read surfaces.
+ if (sourceTrimmedRect.left < 0)
+ {
+ int xDiff = 0 - sourceTrimmedRect.left;
+ sourceTrimmedRect.left = 0;
+ destTrimmedRect.left += xDiff;
+ }
+
+ int readBufferWidth = readFramebuffer->getColorbuffer()->getWidth();
+ int readBufferHeight = readFramebuffer->getColorbuffer()->getHeight();
+ int drawBufferWidth = drawFramebuffer->getColorbuffer()->getWidth();
+ int drawBufferHeight = drawFramebuffer->getColorbuffer()->getHeight();
+
+ if (sourceTrimmedRect.right > readBufferWidth)
+ {
+ int xDiff = sourceTrimmedRect.right - readBufferWidth;
+ sourceTrimmedRect.right = readBufferWidth;
+ destTrimmedRect.right -= xDiff;
+ }
+
+ if (sourceTrimmedRect.top < 0)
+ {
+ int yDiff = 0 - sourceTrimmedRect.top;
+ sourceTrimmedRect.top = 0;
+ destTrimmedRect.top += yDiff;
+ }
+
+ if (sourceTrimmedRect.bottom > readBufferHeight)
+ {
+ int yDiff = sourceTrimmedRect.bottom - readBufferHeight;
+ sourceTrimmedRect.bottom = readBufferHeight;
+ destTrimmedRect.bottom -= yDiff;
+ }
+
+ if (destTrimmedRect.left < 0)
+ {
+ int xDiff = 0 - destTrimmedRect.left;
+ destTrimmedRect.left = 0;
+ sourceTrimmedRect.left += xDiff;
+ }
+
+ if (destTrimmedRect.right > drawBufferWidth)
+ {
+ int xDiff = destTrimmedRect.right - drawBufferWidth;
+ destTrimmedRect.right = drawBufferWidth;
+ sourceTrimmedRect.right -= xDiff;
+ }
+
+ if (destTrimmedRect.top < 0)
+ {
+ int yDiff = 0 - destTrimmedRect.top;
+ destTrimmedRect.top = 0;
+ sourceTrimmedRect.top += yDiff;
+ }
+
+ if (destTrimmedRect.bottom > drawBufferHeight)
+ {
+ int yDiff = destTrimmedRect.bottom - drawBufferHeight;
+ destTrimmedRect.bottom = drawBufferHeight;
+ sourceTrimmedRect.bottom -= yDiff;
+ }
+
+ bool partialBufferCopy = false;
+ if (sourceTrimmedRect.bottom - sourceTrimmedRect.top < readFramebuffer->getColorbuffer()->getHeight() ||
+ sourceTrimmedRect.right - sourceTrimmedRect.left < readFramebuffer->getColorbuffer()->getWidth() ||
+ destTrimmedRect.bottom - destTrimmedRect.top < drawFramebuffer->getColorbuffer()->getHeight() ||
+ destTrimmedRect.right - destTrimmedRect.left < drawFramebuffer->getColorbuffer()->getWidth() ||
+ sourceTrimmedRect.top != 0 || destTrimmedRect.top != 0 || sourceTrimmedRect.left != 0 || destTrimmedRect.left != 0)
+ {
+ partialBufferCopy = true;
+ }
+
+ if (mask & GL_COLOR_BUFFER_BIT)
+ {
+ if (readFramebuffer->getColorbufferType() != drawFramebuffer->getColorbufferType() ||
+ readFramebuffer->getColorbuffer()->getD3DFormat() != drawFramebuffer->getColorbuffer()->getD3DFormat())
+ {
+ ERR("Color buffer format conversion in BlitFramebufferANGLE not supported by this implementation");
+ return error(GL_INVALID_OPERATION);
+ }
+
+ if (partialBufferCopy && readFramebuffer->getSamples() != 0)
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
+ blitRenderTarget = true;
+
+ }
+
+ if (mask & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT))
+ {
+ DepthStencilbuffer *readDSBuffer = NULL;
+ DepthStencilbuffer *drawDSBuffer = NULL;
+
+ // We support OES_packed_depth_stencil, and do not support a separately attached depth and stencil buffer, so if we have
+ // both a depth and stencil buffer, it will be the same buffer.
+
+ if (mask & GL_DEPTH_BUFFER_BIT)
+ {
+ if (readFramebuffer->getDepthbuffer() && drawFramebuffer->getDepthbuffer())
+ {
+ if (readFramebuffer->getDepthbufferType() != drawFramebuffer->getDepthbufferType() ||
+ readFramebuffer->getDepthbuffer()->getD3DFormat() != drawFramebuffer->getDepthbuffer()->getD3DFormat())
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
+ blitDepthStencil = true;
+ readDSBuffer = readFramebuffer->getDepthbuffer();
+ drawDSBuffer = drawFramebuffer->getDepthbuffer();
+ }
+ }
+
+ if (mask & GL_STENCIL_BUFFER_BIT)
+ {
+ if (readFramebuffer->getStencilbuffer() && drawFramebuffer->getStencilbuffer())
+ {
+ if (readFramebuffer->getStencilbufferType() != drawFramebuffer->getStencilbufferType() ||
+ readFramebuffer->getStencilbuffer()->getD3DFormat() != drawFramebuffer->getStencilbuffer()->getD3DFormat())
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
+ blitDepthStencil = true;
+ readDSBuffer = readFramebuffer->getStencilbuffer();
+ drawDSBuffer = drawFramebuffer->getStencilbuffer();
+ }
+ }
+
+ if (partialBufferCopy)
+ {
+ ERR("Only whole-buffer depth and stencil blits are supported by this implementation.");
+ return error(GL_INVALID_OPERATION); // only whole-buffer copies are permitted
+ }
+
+ if ((drawDSBuffer && drawDSBuffer->getSamples() != 0) ||
+ (readDSBuffer && readDSBuffer->getSamples() != 0))
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+ }
+
+ if (blitRenderTarget || blitDepthStencil)
+ {
+ egl::Display *display = getDisplay();
+ display->endScene();
+
+ if (blitRenderTarget)
+ {
+ HRESULT result = device->StretchRect(readFramebuffer->getRenderTarget(), &sourceTrimmedRect,
+ drawFramebuffer->getRenderTarget(), &destTrimmedRect, D3DTEXF_NONE);
+
+ if (FAILED(result))
+ {
+ ERR("BlitFramebufferANGLE failed: StretchRect returned %x.", result);
+ return;
+ }
+ }
+
+ if (blitDepthStencil)
+ {
+ HRESULT result = device->StretchRect(readFramebuffer->getDepthStencil(), NULL, drawFramebuffer->getDepthStencil(), NULL, D3DTEXF_NONE);
+
+ if (FAILED(result))
+ {
+ ERR("BlitFramebufferANGLE failed: StretchRect returned %x.", result);
+ return;
+ }
+ }
+ }
+}
+
}
extern "C"
{
-gl::Context *glCreateContext(const egl::Config *config)
+gl::Context *glCreateContext(const egl::Config *config, const gl::Context *shareContext)
{
- return new gl::Context(config);
+ return new gl::Context(config, shareContext);
}
void glDestroyContext(gl::Context *context)
diff --git a/ANGLE/src/libGLESv2/Context.h b/ANGLE/src/libGLESv2/Context.h
index 913fae2..6bca756 100644
--- a/ANGLE/src/libGLESv2/Context.h
+++ b/ANGLE/src/libGLESv2/Context.h
@@ -7,8 +7,8 @@
// Context.h: Defines the gl::Context class, managing all GL state and performing
// rendering operations. It is the GLES2 specific implementation of EGLContext.
-#ifndef INCLUDE_CONTEXT_H_
-#define INCLUDE_CONTEXT_H_
+#ifndef LIBGLESV2_CONTEXT_H_
+#define LIBGLESV2_CONTEXT_H_
#define GL_APICALL
#include <GLES2/gl2.h>
@@ -19,6 +19,8 @@
#include <map>
#include "common/angleutils.h"
+#include "libGLESv2/ResourceManager.h"
+#include "libGLESv2/RefCountObject.h"
namespace egl
{
@@ -40,9 +42,11 @@ class Texture2D;
class TextureCubeMap;
class Framebuffer;
class Renderbuffer;
+class RenderbufferStorage;
class Colorbuffer;
class Depthbuffer;
class Stencilbuffer;
+class DepthStencilbuffer;
class VertexDataManager;
class IndexDataManager;
class BufferBackEnd;
@@ -67,15 +71,8 @@ enum
const float ALIASED_LINE_WIDTH_RANGE_MIN = 1.0f;
const float ALIASED_LINE_WIDTH_RANGE_MAX = 1.0f;
const float ALIASED_POINT_SIZE_RANGE_MIN = 1.0f;
-const float ALIASED_POINT_SIZE_RANGE_MAX = 1.0f;
-
-enum SamplerType
-{
- SAMPLER_2D,
- SAMPLER_CUBE,
-
- SAMPLER_TYPE_COUNT
-};
+const float ALIASED_POINT_SIZE_RANGE_MAX_SM2 = 1.0f;
+const float ALIASED_POINT_SIZE_RANGE_MAX_SM3 = 64.0f;
struct Color
{
@@ -90,7 +87,7 @@ class AttributeState
{
public:
AttributeState()
- : mType(GL_FLOAT), mSize(0), mNormalized(false), mStride(0), mPointer(NULL), mBoundBuffer(0), mEnabled(false)
+ : mType(GL_FLOAT), mSize(0), mNormalized(false), mStride(0), mPointer(NULL), mEnabled(false)
{
mCurrentValue[0] = 0;
mCurrentValue[1] = 0;
@@ -105,7 +102,7 @@ class AttributeState
GLsizei mStride; // 0 means natural stride
const void *mPointer;
- GLuint mBoundBuffer; // Captured when VertexArrayPointer is called.
+ BindingPointer<Buffer> mBoundBuffer; // Captured when VertexArrayPointer is called.
bool mEnabled; // From Enable/DisableVertexAttribArray
@@ -180,16 +177,17 @@ struct State
bool depthMask;
int activeSampler; // Active texture unit selector - GL_TEXTURE0
- GLuint arrayBuffer;
- GLuint elementArrayBuffer;
- GLuint texture2D;
- GLuint textureCubeMap;
- GLuint framebuffer;
- GLuint renderbuffer;
+ BindingPointer<Buffer> arrayBuffer;
+ BindingPointer<Buffer> elementArrayBuffer;
+ BindingPointer<Texture> texture2D;
+ BindingPointer<Texture> textureCubeMap;
+ GLuint readFramebuffer;
+ GLuint drawFramebuffer;
+ BindingPointer<Renderbuffer> renderbuffer;
GLuint currentProgram;
AttributeState vertexAttribute[MAX_VERTEX_ATTRIBS];
- GLuint samplerTexture[SAMPLER_TYPE_COUNT][MAX_TEXTURE_IMAGE_UNITS];
+ BindingPointer<Texture> samplerTexture[SAMPLER_TYPE_COUNT][MAX_TEXTURE_IMAGE_UNITS];
GLint unpackAlignment;
GLint packAlignment;
@@ -198,7 +196,7 @@ struct State
class Context
{
public:
- Context(const egl::Config *config);
+ Context(const egl::Config *config, const gl::Context *shareContext);
~Context();
@@ -276,14 +274,15 @@ class Context
void setActiveSampler(int active);
- GLuint getFramebufferHandle() const;
+ GLuint getReadFramebufferHandle() const;
+ GLuint getDrawFramebufferHandle() const;
GLuint getRenderbufferHandle() const;
GLuint getArrayBufferHandle() const;
void setVertexAttribEnabled(unsigned int attribNum, bool enabled);
const AttributeState &getVertexAttribState(unsigned int attribNum);
- void setVertexAttribState(unsigned int attribNum, GLuint boundBuffer, GLint size, GLenum type,
+ void setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type,
bool normalized, GLsizei stride, const void *pointer);
const void *getVertexAttribPointer(unsigned int attribNum) const;
@@ -295,33 +294,36 @@ class Context
void setPackAlignment(GLint alignment);
GLint getPackAlignment() const;
+ // These create and destroy methods are merely pass-throughs to
+ // ResourceManager, which owns these object types
GLuint createBuffer();
GLuint createShader(GLenum type);
GLuint createProgram();
GLuint createTexture();
- GLuint createFramebuffer();
GLuint createRenderbuffer();
void deleteBuffer(GLuint buffer);
void deleteShader(GLuint shader);
void deleteProgram(GLuint program);
void deleteTexture(GLuint texture);
- void deleteFramebuffer(GLuint framebuffer);
void deleteRenderbuffer(GLuint renderbuffer);
+ // Framebuffers are owned by the Context, so these methods do not pass through
+ GLuint createFramebuffer();
+ void deleteFramebuffer(GLuint framebuffer);
+
void bindArrayBuffer(GLuint buffer);
void bindElementArrayBuffer(GLuint buffer);
void bindTexture2D(GLuint texture);
void bindTextureCubeMap(GLuint texture);
- void bindFramebuffer(GLuint framebuffer);
+ void bindReadFramebuffer(GLuint framebuffer);
+ void bindDrawFramebuffer(GLuint framebuffer);
void bindRenderbuffer(GLuint renderbuffer);
void useProgram(GLuint program);
void setFramebufferZero(Framebuffer *framebuffer);
- void setColorbufferZero(Colorbuffer *renderbuffer);
- void setDepthbufferZero(Depthbuffer *depthBuffer);
- void setStencilbufferZero(Stencilbuffer *stencilBuffer);
- void setRenderbuffer(Renderbuffer *renderbuffer);
+
+ void setRenderbufferStorage(RenderbufferStorage *renderbuffer);
void setVertexAttrib(GLuint index, const GLfloat *values);
@@ -331,9 +333,6 @@ class Context
Texture *getTexture(GLuint handle);
Framebuffer *getFramebuffer(GLuint handle);
Renderbuffer *getRenderbuffer(GLuint handle);
- Colorbuffer *getColorbuffer(GLuint handle);
- Depthbuffer *getDepthbuffer(GLuint handle);
- Stencilbuffer *getStencilbuffer(GLuint handle);
Buffer *getArrayBuffer();
Buffer *getElementArrayBuffer();
@@ -341,7 +340,8 @@ class Context
Texture2D *getTexture2D();
TextureCubeMap *getTextureCubeMap();
Texture *getSamplerTexture(unsigned int sampler, SamplerType type);
- Framebuffer *getFramebuffer();
+ Framebuffer *getReadFramebuffer();
+ Framebuffer *getDrawFramebuffer();
bool getFloatv(GLenum pname, GLfloat *params);
bool getIntegerv(GLenum pname, GLint *params);
@@ -373,10 +373,15 @@ class Context
GLenum getError();
- const char *getPixelShaderProfile();
- const char *getVertexShaderProfile();
-
+ bool supportsShaderModel3() const;
+ GLsizei getMaxSupportedSamples() const;
+ int getNearestSupportedSamples(D3DFORMAT format, int requested) const;
const char *getExtensionString() const;
+ bool supportsCompressedTextures() const;
+
+ void blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
+ GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
+ GLbitfield mask);
Blit *getBlitter() { return mBlit; }
@@ -396,7 +401,6 @@ class Context
bool cullSkipsDraw(GLenum drawMode);
bool isTriangleMode(GLenum drawMode);
- bool hasStencil();
const egl::Config *const mConfig;
@@ -406,27 +410,11 @@ class Context
TextureCubeMap *mTextureCubeMapZero;
Colorbuffer *mColorbufferZero;
- Depthbuffer *mDepthbufferZero;
- Stencilbuffer *mStencilbufferZero;
-
- typedef std::map<GLuint, Buffer*> BufferMap;
- BufferMap mBufferMap;
-
- typedef std::map<GLuint, Shader*> ShaderMap;
- ShaderMap mShaderMap;
-
- typedef std::map<GLuint, Program*> ProgramMap;
- ProgramMap mProgramMap;
-
- typedef std::map<GLuint, Texture*> TextureMap;
- TextureMap mTextureMap;
+ DepthStencilbuffer *mDepthStencilbufferZero;
typedef std::map<GLuint, Framebuffer*> FramebufferMap;
FramebufferMap mFramebufferMap;
- typedef std::map<GLuint, Renderbuffer*> RenderbufferMap;
- RenderbufferMap mRenderbufferMap;
-
void initExtensionString();
std::string mExtensionString;
@@ -435,7 +423,7 @@ class Context
IndexDataManager *mIndexDataManager;
Blit *mBlit;
-
+
Texture *mIncompleteTextures[SAMPLER_TYPE_COUNT];
// Recorded errors
@@ -450,9 +438,12 @@ class Context
unsigned int mAppliedProgram;
unsigned int mAppliedRenderTargetSerial;
unsigned int mAppliedDepthbufferSerial;
+ unsigned int mAppliedStencilbufferSerial;
- const char *mPsProfile;
- const char *mVsProfile;
+ bool mSupportsShaderModel3;
+ std::map<D3DFORMAT, bool *> mMultiSampleSupport;
+ GLsizei mMaxSupportedSamples;
+ bool mSupportsCompressedTextures;
// state caching flags
bool mClearStateDirty;
@@ -471,13 +462,15 @@ class Context
IDirect3DStateBlock9 *mMaskedClearSavedState;
D3DCAPS9 mDeviceCaps;
+
+ ResourceManager *mResourceManager;
};
}
extern "C"
{
// Exported functions for use by EGL
-gl::Context *glCreateContext(const egl::Config *config);
+gl::Context *glCreateContext(const egl::Config *config, const gl::Context *shareContext);
void glDestroyContext(gl::Context *context);
void glMakeCurrent(gl::Context *context, egl::Display *display, egl::Surface *surface);
gl::Context *glGetCurrentContext();
diff --git a/ANGLE/src/libGLESv2/Framebuffer.cpp b/ANGLE/src/libGLESv2/Framebuffer.cpp
index 1a3b01e..5c4bc99 100644
--- a/ANGLE/src/libGLESv2/Framebuffer.cpp
+++ b/ANGLE/src/libGLESv2/Framebuffer.cpp
@@ -16,85 +16,109 @@
namespace gl
{
+
Framebuffer::Framebuffer()
{
mColorbufferType = GL_NONE;
- mColorbufferHandle = 0;
-
mDepthbufferType = GL_NONE;
- mDepthbufferHandle = 0;
-
mStencilbufferType = GL_NONE;
- mStencilbufferHandle = 0;
}
Framebuffer::~Framebuffer()
{
+ mColorbufferPointer.set(NULL);
+ mDepthbufferPointer.set(NULL);
+ mStencilbufferPointer.set(NULL);
+}
+
+Renderbuffer *Framebuffer::lookupRenderbuffer(GLenum type, GLuint handle) const
+{
+ gl::Context *context = gl::getContext();
+ Renderbuffer *buffer = NULL;
+
+ if (type == GL_NONE)
+ {
+ buffer = NULL;
+ }
+ else if (type == GL_RENDERBUFFER)
+ {
+ buffer = context->getRenderbuffer(handle);
+ }
+ else if (IsTextureTarget(type))
+ {
+ buffer = context->getTexture(handle)->getColorbuffer(type);
+ }
+ else
+ {
+ UNREACHABLE();
+ }
+
+ return buffer;
}
void Framebuffer::setColorbuffer(GLenum type, GLuint colorbuffer)
{
mColorbufferType = type;
- mColorbufferHandle = colorbuffer;
+ mColorbufferPointer.set(lookupRenderbuffer(type, colorbuffer));
}
void Framebuffer::setDepthbuffer(GLenum type, GLuint depthbuffer)
{
mDepthbufferType = type;
- mDepthbufferHandle = depthbuffer;
+ mDepthbufferPointer.set(lookupRenderbuffer(type, depthbuffer));
}
void Framebuffer::setStencilbuffer(GLenum type, GLuint stencilbuffer)
{
mStencilbufferType = type;
- mStencilbufferHandle = stencilbuffer;
+ mStencilbufferPointer.set(lookupRenderbuffer(type, stencilbuffer));
}
void Framebuffer::detachTexture(GLuint texture)
{
- if (mColorbufferHandle == texture && IsTextureTarget(mColorbufferType))
+ if (mColorbufferPointer.id() == texture && IsTextureTarget(mColorbufferType))
{
mColorbufferType = GL_NONE;
- mColorbufferHandle = 0;
+ mColorbufferPointer.set(NULL);
}
- if (mDepthbufferHandle == texture && IsTextureTarget(mDepthbufferType))
+ if (mDepthbufferPointer.id() == texture && IsTextureTarget(mDepthbufferType))
{
mDepthbufferType = GL_NONE;
- mDepthbufferHandle = 0;
+ mDepthbufferPointer.set(NULL);
}
- if (mStencilbufferHandle == texture && IsTextureTarget(mStencilbufferType))
+ if (mStencilbufferPointer.id() == texture && IsTextureTarget(mStencilbufferType))
{
mStencilbufferType = GL_NONE;
- mStencilbufferHandle = 0;
+ mStencilbufferPointer.set(NULL);
}
}
void Framebuffer::detachRenderbuffer(GLuint renderbuffer)
{
- if (mColorbufferHandle == renderbuffer && mColorbufferType == GL_RENDERBUFFER)
+ if (mColorbufferPointer.id() == renderbuffer && mColorbufferType == GL_RENDERBUFFER)
{
mColorbufferType = GL_NONE;
- mColorbufferHandle = 0;
+ mColorbufferPointer.set(NULL);
}
- if (mDepthbufferHandle == renderbuffer && mDepthbufferType == GL_RENDERBUFFER)
+ if (mDepthbufferPointer.id() == renderbuffer && mDepthbufferType == GL_RENDERBUFFER)
{
mDepthbufferType = GL_NONE;
- mDepthbufferHandle = 0;
+ mDepthbufferPointer.set(NULL);
}
- if (mStencilbufferHandle == renderbuffer && mStencilbufferType == GL_RENDERBUFFER)
+ if (mStencilbufferPointer.id() == renderbuffer && mStencilbufferType == GL_RENDERBUFFER)
{
mStencilbufferType = GL_NONE;
- mStencilbufferHandle = 0;
+ mStencilbufferPointer.set(NULL);
}
}
unsigned int Framebuffer::getRenderTargetSerial()
{
- Renderbuffer *colorbuffer = getColorbuffer();
+ Renderbuffer *colorbuffer = mColorbufferPointer.get();
if (colorbuffer)
{
@@ -106,7 +130,7 @@ unsigned int Framebuffer::getRenderTargetSerial()
IDirect3DSurface9 *Framebuffer::getRenderTarget()
{
- Renderbuffer *colorbuffer = getColorbuffer();
+ Renderbuffer *colorbuffer = mColorbufferPointer.get();
if (colorbuffer)
{
@@ -116,10 +140,26 @@ IDirect3DSurface9 *Framebuffer::getRenderTarget()
return NULL;
}
+IDirect3DSurface9 *Framebuffer::getDepthStencil()
+{
+ Renderbuffer *depthstencilbuffer = mDepthbufferPointer.get();
+
+ if (!depthstencilbuffer)
+ {
+ depthstencilbuffer = mStencilbufferPointer.get();
+ }
+
+ if (depthstencilbuffer)
+ {
+ return depthstencilbuffer->getDepthStencil();
+ }
+
+ return NULL;
+}
+
unsigned int Framebuffer::getDepthbufferSerial()
{
- gl::Context *context = gl::getContext();
- Depthbuffer *depthbuffer = context->getDepthbuffer(mDepthbufferHandle);
+ Renderbuffer *depthbuffer = mDepthbufferPointer.get();
if (depthbuffer)
{
@@ -129,70 +169,58 @@ unsigned int Framebuffer::getDepthbufferSerial()
return 0;
}
-IDirect3DSurface9 *Framebuffer::getDepthStencil()
+unsigned int Framebuffer::getStencilbufferSerial()
{
- gl::Context *context = gl::getContext();
- Depthbuffer *depthbuffer = context->getDepthbuffer(mDepthbufferHandle);
+ Renderbuffer *stencilbuffer = mStencilbufferPointer.get();
- if (depthbuffer)
+ if (stencilbuffer)
{
- return depthbuffer->getDepthStencil();
+ return stencilbuffer->getSerial();
}
- return NULL;
+ return 0;
}
Colorbuffer *Framebuffer::getColorbuffer()
{
- gl::Context *context = gl::getContext();
- Colorbuffer *colorbuffer = NULL;
+ Renderbuffer *rb = mColorbufferPointer.get();
- if (mColorbufferType == GL_NONE)
+ if (rb != NULL && rb->isColorbuffer())
{
- UNREACHABLE();
- colorbuffer = NULL;
- }
- else if (mColorbufferType == GL_RENDERBUFFER)
- {
- colorbuffer = context->getColorbuffer(mColorbufferHandle);
+ return static_cast<Colorbuffer*>(rb->getStorage());
}
else
{
- colorbuffer = context->getTexture(mColorbufferHandle)->getColorbuffer(mColorbufferType);
- }
-
- if (colorbuffer && colorbuffer->isColorbuffer())
- {
- return colorbuffer;
+ return NULL;
}
-
- return NULL;
}
-Depthbuffer *Framebuffer::getDepthbuffer()
+DepthStencilbuffer *Framebuffer::getDepthbuffer()
{
- gl::Context *context = gl::getContext();
- Depthbuffer *depthbuffer = context->getDepthbuffer(mDepthbufferHandle);
+ Renderbuffer *rb = mDepthbufferPointer.get();
- if (depthbuffer && depthbuffer->isDepthbuffer())
+ if (rb != NULL && rb->isDepthbuffer())
{
- return depthbuffer;
+ return static_cast<DepthStencilbuffer*>(rb->getStorage());
+ }
+ else
+ {
+ return NULL;
}
-
- return NULL;
}
-Stencilbuffer *Framebuffer::getStencilbuffer()
+DepthStencilbuffer *Framebuffer::getStencilbuffer()
{
- gl::Context *context = gl::getContext();
- Stencilbuffer *stencilbuffer = context->getStencilbuffer(mStencilbufferHandle);
+ Renderbuffer *rb = mStencilbufferPointer.get();
- if (stencilbuffer && stencilbuffer->isStencilbuffer())
+ if (rb != NULL && rb->isStencilbuffer())
{
- return stencilbuffer;
+ return static_cast<DepthStencilbuffer*>(rb->getStorage());
+ }
+ else
+ {
+ return NULL;
}
-
- return NULL;
}
GLenum Framebuffer::getColorbufferType()
@@ -212,25 +240,56 @@ GLenum Framebuffer::getStencilbufferType()
GLuint Framebuffer::getColorbufferHandle()
{
- return mColorbufferHandle;
+ return mColorbufferPointer.id();
}
GLuint Framebuffer::getDepthbufferHandle()
{
- return mDepthbufferHandle;
+ return mDepthbufferPointer.id();
}
GLuint Framebuffer::getStencilbufferHandle()
{
- return mStencilbufferHandle;
+ return mStencilbufferPointer.id();
}
-GLenum Framebuffer::completeness()
+bool Framebuffer::hasStencil()
{
- gl::Context *context = gl::getContext();
+ if (mStencilbufferType != GL_NONE)
+ {
+ DepthStencilbuffer *stencilbufferObject = getStencilbuffer();
+ if (stencilbufferObject)
+ {
+ return stencilbufferObject->getStencilSize() > 0;
+ }
+ }
+
+ return false;
+}
+
+bool Framebuffer::isMultisample()
+{
+ // If the framebuffer is not complete, attachment samples may be mismatched, and it
+ // cannot be used as a multisample framebuffer. If it is complete, it is required to
+ // have a color attachment, and all its attachments must have the same number of samples,
+ // so the number of samples for the colorbuffer will indicate whether the framebuffer is
+ // multisampled.
+ if (completeness() == GL_FRAMEBUFFER_COMPLETE && getColorbuffer()->getSamples() > 0)
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+GLenum Framebuffer::completeness()
+{
int width = 0;
int height = 0;
+ int samples = -1;
if (mColorbufferType != GL_NONE)
{
@@ -246,13 +305,29 @@ GLenum Framebuffer::completeness()
return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
}
+ if (IsTextureTarget(mColorbufferType))
+ {
+ if (IsCompressed(colorbuffer->getFormat()))
+ {
+ return GL_FRAMEBUFFER_UNSUPPORTED;
+ }
+ }
+
width = colorbuffer->getWidth();
height = colorbuffer->getHeight();
+ samples = colorbuffer->getSamples();
}
+ else
+ {
+ return GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT;
+ }
+
+ DepthStencilbuffer *depthbuffer = NULL;
+ DepthStencilbuffer *stencilbuffer = NULL;
if (mDepthbufferType != GL_NONE)
{
- Depthbuffer *depthbuffer = context->getDepthbuffer(mDepthbufferHandle);
+ depthbuffer = getDepthbuffer();
if (!depthbuffer)
{
@@ -273,11 +348,28 @@ GLenum Framebuffer::completeness()
{
return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
}
+
+ if (samples == -1)
+ {
+ samples = depthbuffer->getSamples();
+ }
+ else if (samples != depthbuffer->getSamples())
+ {
+ return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE;
+ }
+
+ if (IsTextureTarget(mDepthbufferType))
+ {
+ if (IsCompressed(depthbuffer->getFormat()))
+ {
+ return GL_FRAMEBUFFER_UNSUPPORTED;
+ }
+ }
}
if (mStencilbufferType != GL_NONE)
{
- Stencilbuffer *stencilbuffer = context->getStencilbuffer(mStencilbufferHandle);
+ stencilbuffer = getStencilbuffer();
if (!stencilbuffer)
{
@@ -298,8 +390,66 @@ GLenum Framebuffer::completeness()
{
return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
}
+
+ if (samples == -1)
+ {
+ samples = stencilbuffer->getSamples();
+ }
+ else if (samples != stencilbuffer->getSamples())
+ {
+ return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE;
+ }
+
+ if (IsTextureTarget(mStencilbufferType))
+ {
+ if (IsCompressed(stencilbuffer->getFormat()))
+ {
+ return GL_FRAMEBUFFER_UNSUPPORTED;
+ }
+ }
+ }
+
+ if (mDepthbufferType == GL_RENDERBUFFER && mStencilbufferType == GL_RENDERBUFFER)
+ {
+ if (depthbuffer->getFormat() != GL_DEPTH24_STENCIL8_OES ||
+ stencilbuffer->getFormat() != GL_DEPTH24_STENCIL8_OES ||
+ depthbuffer->getSerial() != stencilbuffer->getSerial())
+ {
+ return GL_FRAMEBUFFER_UNSUPPORTED;
+ }
+ }
+
+ return GL_FRAMEBUFFER_COMPLETE;
+}
+
+DefaultFramebuffer::DefaultFramebuffer(Colorbuffer *color, DepthStencilbuffer *depthStencil)
+{
+ mColorbufferType = GL_RENDERBUFFER;
+ mDepthbufferType = GL_RENDERBUFFER;
+ mStencilbufferType = GL_RENDERBUFFER;
+
+ mColorbufferPointer.set(new Renderbuffer(0, color));
+
+ Renderbuffer *depthStencilRenderbuffer = new Renderbuffer(0, depthStencil);
+ mDepthbufferPointer.set(depthStencilRenderbuffer);
+ mStencilbufferPointer.set(depthStencilRenderbuffer);
+}
+
+int Framebuffer::getSamples()
+{
+ if (completeness() == GL_FRAMEBUFFER_COMPLETE)
+ {
+ return getColorbuffer()->getSamples();
+ }
+ else
+ {
+ return 0;
}
+}
+GLenum DefaultFramebuffer::completeness()
+{
return GL_FRAMEBUFFER_COMPLETE;
}
+
}
diff --git a/ANGLE/src/libGLESv2/Framebuffer.h b/ANGLE/src/libGLESv2/Framebuffer.h
index c35f940..0995145 100644
--- a/ANGLE/src/libGLESv2/Framebuffer.h
+++ b/ANGLE/src/libGLESv2/Framebuffer.h
@@ -15,19 +15,22 @@
#include <d3d9.h>
#include "common/angleutils.h"
+#include "libGLESv2/RefCountObject.h"
namespace gl
{
+class Renderbuffer;
class Colorbuffer;
class Depthbuffer;
class Stencilbuffer;
+class DepthStencilbuffer;
class Framebuffer
{
public:
Framebuffer();
- ~Framebuffer();
+ virtual ~Framebuffer();
void setColorbuffer(GLenum type, GLuint colorbuffer);
void setDepthbuffer(GLenum type, GLuint depthbuffer);
@@ -41,10 +44,11 @@ class Framebuffer
unsigned int getRenderTargetSerial();
unsigned int getDepthbufferSerial();
+ unsigned int getStencilbufferSerial();
Colorbuffer *getColorbuffer();
- Depthbuffer *getDepthbuffer();
- Stencilbuffer *getStencilbuffer();
+ DepthStencilbuffer *getDepthbuffer();
+ DepthStencilbuffer *getStencilbuffer();
GLenum getColorbufferType();
GLenum getDepthbufferType();
@@ -54,20 +58,39 @@ class Framebuffer
GLuint getDepthbufferHandle();
GLuint getStencilbufferHandle();
- GLenum completeness();
+ bool hasStencil();
+ bool isMultisample();
+ int getSamples();
- private:
- DISALLOW_COPY_AND_ASSIGN(Framebuffer);
+ virtual GLenum completeness();
- GLuint mColorbufferHandle;
+ protected:
GLenum mColorbufferType;
+ BindingPointer<Renderbuffer> mColorbufferPointer;
- GLuint mDepthbufferHandle;
GLenum mDepthbufferType;
+ BindingPointer<Renderbuffer> mDepthbufferPointer;
- GLuint mStencilbufferHandle;
GLenum mStencilbufferType;
+ BindingPointer<Renderbuffer> mStencilbufferPointer;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(Framebuffer);
+
+ Renderbuffer *lookupRenderbuffer(GLenum type, GLuint handle) const;
+};
+
+class DefaultFramebuffer : public Framebuffer
+{
+ public:
+ DefaultFramebuffer(Colorbuffer *color, DepthStencilbuffer *depthStencil);
+
+ virtual GLenum completeness();
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(DefaultFramebuffer);
};
+
}
#endif // LIBGLESV2_FRAMEBUFFER_H_
diff --git a/ANGLE/src/libGLESv2/Program.cpp b/ANGLE/src/libGLESv2/Program.cpp
index 78253c7..a32bc9f 100644
--- a/ANGLE/src/libGLESv2/Program.cpp
+++ b/ANGLE/src/libGLESv2/Program.cpp
@@ -45,7 +45,7 @@ UniformLocation::UniformLocation(const std::string &name, unsigned int element,
{
}
-Program::Program()
+Program::Program(ResourceManager *manager, GLuint handle) : mResourceManager(manager), mHandle(handle)
{
mFragmentShader = NULL;
mVertexShader = NULL;
@@ -62,6 +62,8 @@ Program::Program()
mDeleteStatus = false;
+ mRefCount = 0;
+
mSerial = issueSerial();
}
@@ -71,12 +73,12 @@ Program::~Program()
if (mVertexShader != NULL)
{
- mVertexShader->detach();
+ mVertexShader->release();
}
if (mFragmentShader != NULL)
{
- mFragmentShader->detach();
+ mFragmentShader->release();
}
}
@@ -90,7 +92,7 @@ bool Program::attachShader(Shader *shader)
}
mVertexShader = (VertexShader*)shader;
- mVertexShader->attach();
+ mVertexShader->addRef();
}
else if (shader->getType() == GL_FRAGMENT_SHADER)
{
@@ -100,7 +102,7 @@ bool Program::attachShader(Shader *shader)
}
mFragmentShader = (FragmentShader*)shader;
- mFragmentShader->attach();
+ mFragmentShader->addRef();
}
else UNREACHABLE();
@@ -116,7 +118,7 @@ bool Program::detachShader(Shader *shader)
return false;
}
- mVertexShader->detach();
+ mVertexShader->release();
mVertexShader = NULL;
}
else if (shader->getType() == GL_FRAGMENT_SHADER)
@@ -126,7 +128,7 @@ bool Program::detachShader(Shader *shader)
return false;
}
- mFragmentShader->detach();
+ mFragmentShader->release();
mFragmentShader = NULL;
}
else UNREACHABLE();
@@ -1195,6 +1197,10 @@ bool Program::linkVaryings()
}
}
+ Context *context = getContext();
+ bool sm3 = context->supportsShaderModel3();
+ std::string varyingSemantic = (sm3 ? "COLOR" : "TEXCOORD");
+
mVertexHLSL += "struct VS_INPUT\n"
"{\n";
@@ -1228,12 +1234,17 @@ bool Program::linkVaryings()
{
int registerSize = packing[r][3] ? 4 : (packing[r][2] ? 3 : (packing[r][1] ? 2 : 1));
- mVertexHLSL += " float" + str(registerSize) + " v" + str(r) + " : TEXCOORD" + str(r) + ";\n";
+ mVertexHLSL += " float" + str(registerSize) + " v" + str(r) + " : " + varyingSemantic + str(r) + ";\n";
}
if (mFragmentShader->mUsesFragCoord)
{
- mVertexHLSL += " float4 gl_FragCoord : TEXCOORD" + str(registers) + ";\n";
+ mVertexHLSL += " float4 gl_FragCoord : " + varyingSemantic + str(registers) + ";\n";
+ }
+
+ if (mVertexShader->mUsesPointSize && sm3)
+ {
+ mVertexHLSL += " float gl_PointSize : PSIZE;\n";
}
mVertexHLSL += "};\n"
@@ -1262,6 +1273,11 @@ bool Program::linkVaryings()
" output.gl_Position.z = (gl_Position.z + gl_Position.w) * 0.5;\n"
" output.gl_Position.w = gl_Position.w;\n";
+ if (mVertexShader->mUsesPointSize && sm3)
+ {
+ mVertexHLSL += " output.gl_PointSize = clamp(gl_PointSize, 1.0, " + str((int)ALIASED_POINT_SIZE_RANGE_MAX_SM3) + ");\n";
+ }
+
if (mFragmentShader->mUsesFragCoord)
{
mVertexHLSL += " output.gl_FragCoord = gl_Position;\n";
@@ -1345,7 +1361,7 @@ bool Program::linkVaryings()
for (int j = 0; j < rows; j++)
{
std::string n = str(varying->reg + i * rows + j);
- mPixelHLSL += " float4 v" + n + " : TEXCOORD" + n + ";\n";
+ mPixelHLSL += " float4 v" + n + " : " + varyingSemantic + n + ";\n";
}
}
}
@@ -1354,9 +1370,14 @@ bool Program::linkVaryings()
if (mFragmentShader->mUsesFragCoord)
{
- mPixelHLSL += " float4 gl_FragCoord : TEXCOORD" + str(registers) + ";\n";
+ mPixelHLSL += " float4 gl_FragCoord : " + varyingSemantic + str(registers) + ";\n";
+ }
+
+ if (mFragmentShader->mUsesPointCoord && sm3)
+ {
+ mPixelHLSL += " float2 gl_PointCoord : TEXCOORD0;\n";
}
-
+
if (mFragmentShader->mUsesFrontFacing)
{
mPixelHLSL += " float vFace : VFACE;\n";
@@ -1375,12 +1396,17 @@ bool Program::linkVaryings()
if (mFragmentShader->mUsesFragCoord)
{
mPixelHLSL += " float rhw = 1.0 / input.gl_FragCoord.w;\n"
- " gl_FragCoord.x = (input.gl_FragCoord.x * rhw) * dx_Window.x + dx_Window.z;\n"
- " gl_FragCoord.y = (input.gl_FragCoord.y * rhw) * dx_Window.y + dx_Window.w;\n"
+ " gl_FragCoord.x = (input.gl_FragCoord.x * rhw) * dx_Viewport.x + dx_Viewport.z;\n"
+ " gl_FragCoord.y = (input.gl_FragCoord.y * rhw) * dx_Viewport.y + dx_Viewport.w;\n"
" gl_FragCoord.z = (input.gl_FragCoord.z * rhw) * dx_Depth.x + dx_Depth.y;\n"
" gl_FragCoord.w = rhw;\n";
}
+ if (mFragmentShader->mUsesPointCoord && sm3)
+ {
+ mPixelHLSL += " gl_PointCoord = float2(input.gl_PointCoord.x, 1.0 - input.gl_PointCoord.y);\n";
+ }
+
if (mFragmentShader->mUsesFrontFacing)
{
mPixelHLSL += " gl_FrontFacing = dx_PointsOrLines || (dx_FrontCCW ? (input.vFace >= 0.0) : (input.vFace <= 0.0));\n";
@@ -1447,10 +1473,6 @@ void Program::link()
return;
}
- Context *context = getContext();
- const char *vertexProfile = context->getVertexShaderProfile();
- const char *pixelProfile = context->getPixelShaderProfile();
-
mPixelHLSL = mFragmentShader->getHLSL();
mVertexHLSL = mVertexShader->getHLSL();
@@ -1459,6 +1481,10 @@ void Program::link()
return;
}
+ Context *context = getContext();
+ const char *vertexProfile = context->supportsShaderModel3() ? "vs_3_0" : "vs_2_0";
+ const char *pixelProfile = context->supportsShaderModel3() ? "ps_3_0" : "ps_2_0";
+
ID3DXBuffer *vertexBinary = compileToBinary(mVertexHLSL.c_str(), vertexProfile, &mConstantTableVS);
ID3DXBuffer *pixelBinary = compileToBinary(mPixelHLSL.c_str(), pixelProfile, &mConstantTablePS);
@@ -1503,7 +1529,7 @@ void Program::link()
mDepthRangeFarLocation = getUniformLocation("gl_DepthRange.far", true);
mDepthRangeDiffLocation = getUniformLocation("gl_DepthRange.diff", true);
mDxDepthLocation = getUniformLocation("dx_Depth", true);
- mDxWindowLocation = getUniformLocation("dx_Window", true);
+ mDxViewportLocation = getUniformLocation("dx_Viewport", true);
mDxHalfPixelSizeLocation = getUniformLocation("dx_HalfPixelSize", true);
mDxFrontCCWLocation = getUniformLocation("dx_FrontCCW", true);
mDxPointsOrLinesLocation = getUniformLocation("dx_PointsOrLines", true);
@@ -2355,13 +2381,13 @@ void Program::unlink(bool destroy)
{
if (mFragmentShader)
{
- mFragmentShader->detach();
+ mFragmentShader->release();
mFragmentShader = NULL;
}
if (mVertexShader)
{
- mVertexShader->detach();
+ mVertexShader->release();
mVertexShader = NULL;
}
}
@@ -2412,7 +2438,7 @@ void Program::unlink(bool destroy)
mDepthRangeNearLocation = -1;
mDepthRangeFarLocation = -1;
mDxDepthLocation = -1;
- mDxWindowLocation = -1;
+ mDxViewportLocation = -1;
mDxHalfPixelSizeLocation = -1;
mDxFrontCCWLocation = -1;
mDxPointsOrLinesLocation = -1;
@@ -2438,6 +2464,26 @@ bool Program::isValidated() const
return mValidated;
}
+void Program::release()
+{
+ mRefCount--;
+
+ if (mRefCount == 0 && mDeleteStatus)
+ {
+ mResourceManager->deleteProgram(mHandle);
+ }
+}
+
+void Program::addRef()
+{
+ mRefCount++;
+}
+
+unsigned int Program::getRefCount() const
+{
+ return mRefCount;
+}
+
unsigned int Program::getSerial() const
{
return mSerial;
@@ -2737,9 +2783,9 @@ GLint Program::getDxDepthLocation() const
return mDxDepthLocation;
}
-GLint Program::getDxWindowLocation() const
+GLint Program::getDxViewportLocation() const
{
- return mDxWindowLocation;
+ return mDxViewportLocation;
}
GLint Program::getDxHalfPixelSizeLocation() const
diff --git a/ANGLE/src/libGLESv2/Program.h b/ANGLE/src/libGLESv2/Program.h
index e52f20e..3021b7a 100644
--- a/ANGLE/src/libGLESv2/Program.h
+++ b/ANGLE/src/libGLESv2/Program.h
@@ -20,6 +20,7 @@
namespace gl
{
+class ResourceManager;
class FragmentShader;
class VertexShader;
@@ -55,7 +56,7 @@ struct UniformLocation
class Program
{
public:
- Program();
+ Program(ResourceManager *manager, GLuint handle);
~Program();
@@ -97,7 +98,7 @@ class Program
GLint getDepthRangeNearLocation() const;
GLint getDepthRangeFarLocation() const;
GLint getDxDepthLocation() const;
- GLint getDxWindowLocation() const;
+ GLint getDxViewportLocation() const;
GLint getDxHalfPixelSizeLocation() const;
GLint getDxFrontCCWLocation() const;
GLint getDxPointsOrLinesLocation() const;
@@ -119,6 +120,9 @@ class Program
GLint getActiveUniformCount();
GLint getActiveUniformMaxLength();
+ void addRef();
+ void release();
+ unsigned int getRefCount() const;
void flagForDeletion();
bool isFlaggedForDeletion() const;
@@ -204,7 +208,7 @@ class Program
GLint mDepthRangeNearLocation;
GLint mDepthRangeFarLocation;
GLint mDxDepthLocation;
- GLint mDxWindowLocation;
+ GLint mDxViewportLocation;
GLint mDxHalfPixelSizeLocation;
GLint mDxFrontCCWLocation;
GLint mDxPointsOrLinesLocation;
@@ -214,9 +218,14 @@ class Program
char *mInfoLog;
bool mValidated;
+ unsigned int mRefCount;
+
unsigned int mSerial;
static unsigned int mCurrentSerial;
+
+ ResourceManager *mResourceManager;
+ const GLuint mHandle;
};
}
diff --git a/ANGLE/src/libGLESv2/RefCountObject.cpp b/ANGLE/src/libGLESv2/RefCountObject.cpp
new file mode 100644
index 0000000..e3fd36e
--- /dev/null
+++ b/ANGLE/src/libGLESv2/RefCountObject.cpp
@@ -0,0 +1,51 @@
+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// RefCountObject.cpp: Defines the gl::RefCountObject base class that provides
+// lifecycle support for GL objects using the traditional BindObject scheme, but
+// that need to be reference counted for correct cross-context deletion.
+// (Concretely, textures, buffers and renderbuffers.)
+
+#include "RefCountObject.h"
+
+namespace gl
+{
+
+RefCountObject::RefCountObject(GLuint id)
+{
+ mId = id;
+ mRefCount = 0;
+}
+
+RefCountObject::~RefCountObject()
+{
+}
+
+void RefCountObject::addRef() const
+{
+ mRefCount++;
+}
+
+void RefCountObject::release() const
+{
+ ASSERT(mRefCount > 0);
+
+ if (--mRefCount == 0)
+ {
+ delete this;
+ }
+}
+
+void RefCountObjectBindingPointer::set(RefCountObject *newObject)
+{
+ // addRef first in case newObject == mObject and this is the last reference to it.
+ if (newObject != NULL) newObject->addRef();
+ if (mObject != NULL) mObject->release();
+
+ mObject = newObject;
+}
+
+}
diff --git a/ANGLE/src/libGLESv2/RefCountObject.h b/ANGLE/src/libGLESv2/RefCountObject.h
new file mode 100644
index 0000000..a149350
--- /dev/null
+++ b/ANGLE/src/libGLESv2/RefCountObject.h
@@ -0,0 +1,70 @@
+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// RefCountObject.h: Defines the gl::RefCountObject base class that provides
+// lifecycle support for GL objects using the traditional BindObject scheme, but
+// that need to be reference counted for correct cross-context deletion.
+// (Concretely, textures, buffers and renderbuffers.)
+
+#ifndef LIBGLESV2_REFCOUNTOBJECT_H_
+#define LIBGLESV2_REFCOUNTOBJECT_H_
+
+#include <cstddef>
+
+#define GL_APICALL
+#include <GLES2/gl2.h>
+
+#include "common/debug.h"
+
+namespace gl
+{
+
+class RefCountObject
+{
+ public:
+ explicit RefCountObject(GLuint id);
+ virtual ~RefCountObject();
+
+ virtual void addRef() const;
+ virtual void release() const;
+
+ GLuint id() const { return mId; }
+
+ private:
+ GLuint mId;
+
+ mutable std::size_t mRefCount;
+};
+
+class RefCountObjectBindingPointer
+{
+ protected:
+ RefCountObjectBindingPointer() : mObject(NULL) { }
+ ~RefCountObjectBindingPointer() { ASSERT(mObject == NULL); } // Objects have to be released before the resource manager is destroyed, so they must be explicitly cleaned up.
+
+ void set(RefCountObject *newObject);
+ RefCountObject *get() const { return mObject; }
+
+ public:
+ GLuint id() const { return (mObject != NULL) ? mObject->id() : 0; }
+ bool operator ! () const { return (get() == NULL); }
+
+ private:
+ RefCountObject *mObject;
+};
+
+template <class ObjectType>
+class BindingPointer : public RefCountObjectBindingPointer
+{
+ public:
+ void set(ObjectType *newObject) { RefCountObjectBindingPointer::set(newObject); }
+ ObjectType *get() const { return static_cast<ObjectType*>(RefCountObjectBindingPointer::get()); }
+ ObjectType *operator -> () const { return get(); }
+};
+
+}
+
+#endif // LIBGLESV2_REFCOUNTOBJECT_H_
diff --git a/ANGLE/src/libGLESv2/Renderbuffer.cpp b/ANGLE/src/libGLESv2/Renderbuffer.cpp
index edd38ec..0eb4637 100644
--- a/ANGLE/src/libGLESv2/Renderbuffer.cpp
+++ b/ANGLE/src/libGLESv2/Renderbuffer.cpp
@@ -15,73 +15,148 @@
namespace gl
{
-unsigned int Renderbuffer::mCurrentSerial = 1;
+unsigned int RenderbufferStorage::mCurrentSerial = 1;
-Renderbuffer::Renderbuffer()
+Renderbuffer::Renderbuffer(GLuint id, RenderbufferStorage *storage) : RefCountObject(id)
{
- mWidth = 0;
- mHeight = 0;
- mFormat = GL_RGBA4; // default format, needs to be one of the expected renderbuffer formats
- mSerial = issueSerial();
+ ASSERT(storage != NULL);
+ mStorage = storage;
}
Renderbuffer::~Renderbuffer()
{
+ delete mStorage;
+}
+
+bool Renderbuffer::isColorbuffer() const
+{
+ return mStorage->isColorbuffer();
+}
+
+bool Renderbuffer::isDepthbuffer() const
+{
+ return mStorage->isDepthbuffer();
+}
+
+bool Renderbuffer::isStencilbuffer() const
+{
+ return mStorage->isStencilbuffer();
+}
+
+IDirect3DSurface9 *Renderbuffer::getRenderTarget()
+{
+ return mStorage->getRenderTarget();
+}
+
+IDirect3DSurface9 *Renderbuffer::getDepthStencil()
+{
+ return mStorage->getDepthStencil();
+}
+
+int Renderbuffer::getWidth() const
+{
+ return mStorage->getWidth();
+}
+
+int Renderbuffer::getHeight() const
+{
+ return mStorage->getHeight();
+}
+
+GLenum Renderbuffer::getFormat() const
+{
+ return mStorage->getFormat();
+}
+
+D3DFORMAT Renderbuffer::getD3DFormat() const
+{
+ return mStorage->getD3DFormat();
+}
+
+unsigned int Renderbuffer::getSerial() const
+{
+ return mStorage->getSerial();
+}
+
+void Renderbuffer::setStorage(RenderbufferStorage *newStorage)
+{
+ ASSERT(newStorage != NULL);
+
+ delete mStorage;
+ mStorage = newStorage;
+}
+
+RenderbufferStorage::RenderbufferStorage()
+{
+ mSerial = issueSerial();
+}
+
+RenderbufferStorage::~RenderbufferStorage()
+{
}
-bool Renderbuffer::isColorbuffer()
+bool RenderbufferStorage::isColorbuffer() const
{
return false;
}
-bool Renderbuffer::isDepthbuffer()
+bool RenderbufferStorage::isDepthbuffer() const
{
return false;
}
-bool Renderbuffer::isStencilbuffer()
+bool RenderbufferStorage::isStencilbuffer() const
{
return false;
}
-IDirect3DSurface9 *Renderbuffer::getRenderTarget()
+IDirect3DSurface9 *RenderbufferStorage::getRenderTarget()
{
return NULL;
}
-IDirect3DSurface9 *Renderbuffer::getDepthStencil()
+IDirect3DSurface9 *RenderbufferStorage::getDepthStencil()
{
return NULL;
}
-int Renderbuffer::getWidth()
+int RenderbufferStorage::getWidth() const
{
return mWidth;
}
-int Renderbuffer::getHeight()
+int RenderbufferStorage::getHeight() const
{
return mHeight;
}
-void Renderbuffer::setSize(int width, int height)
+void RenderbufferStorage::setSize(int width, int height)
{
mWidth = width;
mHeight = height;
}
-
-GLenum Renderbuffer::getFormat()
+GLenum RenderbufferStorage::getFormat() const
{
return mFormat;
}
-unsigned int Renderbuffer::getSerial() const
+D3DFORMAT RenderbufferStorage::getD3DFormat() const
+{
+ return mD3DFormat;
+}
+
+GLsizei RenderbufferStorage::getSamples() const
+{
+ return mSamples;
+}
+
+unsigned int RenderbufferStorage::getSerial() const
{
return mSerial;
}
-unsigned int Renderbuffer::issueSerial()
+unsigned int RenderbufferStorage::issueSerial()
{
return mCurrentSerial++;
}
@@ -96,36 +171,59 @@ Colorbuffer::Colorbuffer(IDirect3DSurface9 *renderTarget) : mRenderTarget(render
renderTarget->GetDesc(&description);
setSize(description.Width, description.Height);
+ mD3DFormat = description.Format;
+ mSamples = es2dx::GetSamplesFromMultisampleType(description.MultiSampleType);
+ }
+ else
+ {
+ mD3DFormat = D3DFMT_UNKNOWN;
+ mSamples = 0;
}
-
}
-Colorbuffer::Colorbuffer(int width, int height, GLenum format)
+Colorbuffer::Colorbuffer(int width, int height, GLenum format, GLsizei samples)
{
IDirect3DDevice9 *device = getDevice();
mRenderTarget = NULL;
- HRESULT result = device->CreateRenderTarget(width, height, es2dx::ConvertRenderbufferFormat(format),
- D3DMULTISAMPLE_NONE, 0, FALSE, &mRenderTarget, NULL);
+ D3DFORMAT requestedFormat = es2dx::ConvertRenderbufferFormat(format);
+ int supportedSamples = getContext()->getNearestSupportedSamples(requestedFormat, samples);
- if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
+ if (supportedSamples == -1)
{
error(GL_OUT_OF_MEMORY);
return;
}
- ASSERT(SUCCEEDED(result));
+ if (width > 0 && height > 0)
+ {
+ HRESULT result = device->CreateRenderTarget(width, height, requestedFormat,
+ es2dx::GetMultisampleTypeFromSamples(supportedSamples), 0, FALSE, &mRenderTarget, NULL);
+
+ if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
+ {
+ error(GL_OUT_OF_MEMORY);
+
+ return;
+ }
+
+ ASSERT(SUCCEEDED(result));
+ }
if (mRenderTarget)
{
setSize(width, height);
mFormat = format;
+ mD3DFormat = requestedFormat;
+ mSamples = supportedSamples;
}
else
{
setSize(0, 0);
mFormat = GL_RGBA4;
+ mD3DFormat = D3DFMT_UNKNOWN;
+ mSamples = 0;
}
}
@@ -137,12 +235,12 @@ Colorbuffer::~Colorbuffer()
}
}
-bool Colorbuffer::isColorbuffer()
+bool Colorbuffer::isColorbuffer() const
{
return true;
}
-GLuint Colorbuffer::getRedSize()
+GLuint Colorbuffer::getRedSize() const
{
if (mRenderTarget)
{
@@ -155,7 +253,7 @@ GLuint Colorbuffer::getRedSize()
return 0;
}
-GLuint Colorbuffer::getGreenSize()
+GLuint Colorbuffer::getGreenSize() const
{
if (mRenderTarget)
{
@@ -168,7 +266,7 @@ GLuint Colorbuffer::getGreenSize()
return 0;
}
-GLuint Colorbuffer::getBlueSize()
+GLuint Colorbuffer::getBlueSize() const
{
if (mRenderTarget)
{
@@ -181,7 +279,7 @@ GLuint Colorbuffer::getBlueSize()
return 0;
}
-GLuint Colorbuffer::getAlphaSize()
+GLuint Colorbuffer::getAlphaSize() const
{
if (mRenderTarget)
{
@@ -199,7 +297,7 @@ IDirect3DSurface9 *Colorbuffer::getRenderTarget()
return mRenderTarget;
}
-Depthbuffer::Depthbuffer(IDirect3DSurface9 *depthStencil) : mDepthStencil(depthStencil)
+DepthStencilbuffer::DepthStencilbuffer(IDirect3DSurface9 *depthStencil) : mDepthStencil(depthStencil)
{
if (depthStencil)
{
@@ -209,18 +307,34 @@ Depthbuffer::Depthbuffer(IDirect3DSurface9 *depthStencil) : mDepthStencil(depthS
depthStencil->GetDesc(&description);
setSize(description.Width, description.Height);
- mFormat = GL_DEPTH_COMPONENT16; // If the renderbuffer parameters are queried, the calling function
- // will expect one of the valid renderbuffer formats for use in
- // glRenderbufferStorage
+ mFormat = (description.Format == D3DFMT_D16 ? GL_DEPTH_COMPONENT16 : GL_DEPTH24_STENCIL8_OES);
+ mSamples = es2dx::GetSamplesFromMultisampleType(description.MultiSampleType);
+ mD3DFormat = description.Format;
+ }
+ else
+ {
+ mD3DFormat = D3DFMT_UNKNOWN;
+ mSamples = 0;
}
}
-Depthbuffer::Depthbuffer(int width, int height)
+DepthStencilbuffer::DepthStencilbuffer(int width, int height, GLsizei samples)
{
IDirect3DDevice9 *device = getDevice();
mDepthStencil = NULL;
- HRESULT result = device->CreateDepthStencilSurface(width, height, D3DFMT_D24S8, D3DMULTISAMPLE_NONE, 0, FALSE, &mDepthStencil, 0);
+
+ int supportedSamples = getContext()->getNearestSupportedSamples(D3DFMT_D24S8, samples);
+
+ if (supportedSamples == -1)
+ {
+ error(GL_OUT_OF_MEMORY);
+
+ return;
+ }
+
+ HRESULT result = device->CreateDepthStencilSurface(width, height, D3DFMT_D24S8, es2dx::GetMultisampleTypeFromSamples(supportedSamples),
+ 0, FALSE, &mDepthStencil, 0);
if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
{
@@ -234,18 +348,20 @@ Depthbuffer::Depthbuffer(int width, int height)
if (mDepthStencil)
{
setSize(width, height);
- mFormat = GL_DEPTH_COMPONENT16; // If the renderbuffer parameters are queried, the calling function
- // will expect one of the valid renderbuffer formats for use in
- // glRenderbufferStorage
+ mFormat = GL_DEPTH24_STENCIL8_OES;
+ mD3DFormat = D3DFMT_D24S8;
+ mSamples = supportedSamples;
}
else
{
setSize(0, 0);
mFormat = GL_RGBA4; //default format
+ mD3DFormat = D3DFMT_UNKNOWN;
+ mSamples = 0;
}
}
-Depthbuffer::~Depthbuffer()
+DepthStencilbuffer::~DepthStencilbuffer()
{
if (mDepthStencil)
{
@@ -253,12 +369,17 @@ Depthbuffer::~Depthbuffer()
}
}
-bool Depthbuffer::isDepthbuffer()
+bool DepthStencilbuffer::isDepthbuffer() const
+{
+ return true;
+}
+
+bool DepthStencilbuffer::isStencilbuffer() const
{
return true;
}
-GLuint Depthbuffer::getDepthSize()
+GLuint DepthStencilbuffer::getDepthSize() const
{
if (mDepthStencil)
{
@@ -271,85 +392,93 @@ GLuint Depthbuffer::getDepthSize()
return 0;
}
-IDirect3DSurface9 *Depthbuffer::getDepthStencil()
+GLuint DepthStencilbuffer::getStencilSize() const
+{
+ if (mDepthStencil)
+ {
+ D3DSURFACE_DESC description;
+ mDepthStencil->GetDesc(&description);
+
+ return es2dx::GetStencilSize(description.Format);
+ }
+
+ return 0;
+}
+
+IDirect3DSurface9 *DepthStencilbuffer::getDepthStencil()
{
return mDepthStencil;
}
-Stencilbuffer::Stencilbuffer(IDirect3DSurface9 *depthStencil) : mDepthStencil(depthStencil)
+Depthbuffer::Depthbuffer(IDirect3DSurface9 *depthStencil) : DepthStencilbuffer(depthStencil)
{
if (depthStencil)
{
- depthStencil->AddRef();
-
- D3DSURFACE_DESC description;
- depthStencil->GetDesc(&description);
-
- setSize(description.Width, description.Height);
- mFormat = GL_STENCIL_INDEX8; // If the renderbuffer parameters are queried, the calling function
- // will expect one of the valid renderbuffer formats for use in
- // glRenderbufferStorage
+ mFormat = GL_DEPTH_COMPONENT16; // If the renderbuffer parameters are queried, the calling function
+ // will expect one of the valid renderbuffer formats for use in
+ // glRenderbufferStorage
}
}
-Stencilbuffer::Stencilbuffer(int width, int height)
+Depthbuffer::Depthbuffer(int width, int height, GLsizei samples) : DepthStencilbuffer(width, height, samples)
{
- IDirect3DDevice9 *device = getDevice();
-
- mDepthStencil = NULL;
- HRESULT result = device->CreateDepthStencilSurface(width, height, D3DFMT_D24S8, D3DMULTISAMPLE_NONE, 0, FALSE, &mDepthStencil, 0);
-
- if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
+ if (getDepthStencil())
{
- error(GL_OUT_OF_MEMORY);
-
- return;
+ mFormat = GL_DEPTH_COMPONENT16; // If the renderbuffer parameters are queried, the calling function
+ // will expect one of the valid renderbuffer formats for use in
+ // glRenderbufferStorage
}
+}
- ASSERT(SUCCEEDED(result));
+Depthbuffer::~Depthbuffer()
+{
+}
- if (mDepthStencil)
+bool Depthbuffer::isDepthbuffer() const
+{
+ return true;
+}
+
+bool Depthbuffer::isStencilbuffer() const
+{
+ return false;
+}
+
+Stencilbuffer::Stencilbuffer(IDirect3DSurface9 *depthStencil) : DepthStencilbuffer(depthStencil)
+{
+ if (depthStencil)
{
- setSize(width, height);
mFormat = GL_STENCIL_INDEX8; // If the renderbuffer parameters are queried, the calling function
// will expect one of the valid renderbuffer formats for use in
// glRenderbufferStorage
}
else
{
- setSize(0, 0);
mFormat = GL_RGBA4; //default format
}
}
-Stencilbuffer::~Stencilbuffer()
+Stencilbuffer::Stencilbuffer(int width, int height, GLsizei samples) : DepthStencilbuffer(width, height, samples)
{
- if (mDepthStencil)
+ if (getDepthStencil())
{
- mDepthStencil->Release();
+ mFormat = GL_STENCIL_INDEX8; // If the renderbuffer parameters are queried, the calling function
+ // will expect one of the valid renderbuffer formats for use in
+ // glRenderbufferStorage
}
}
-GLuint Stencilbuffer::getStencilSize()
+Stencilbuffer::~Stencilbuffer()
{
- if (mDepthStencil)
- {
- D3DSURFACE_DESC description;
- mDepthStencil->GetDesc(&description);
-
- return es2dx::GetStencilSize(description.Format);
- }
-
- return 0;
}
-bool Stencilbuffer::isStencilbuffer()
+bool Stencilbuffer::isDepthbuffer() const
{
- return true;
+ return false;
}
-IDirect3DSurface9 *Stencilbuffer::getDepthStencil()
+bool Stencilbuffer::isStencilbuffer() const
{
- return mDepthStencil;
+ return true;
}
}
diff --git a/ANGLE/src/libGLESv2/Renderbuffer.h b/ANGLE/src/libGLESv2/Renderbuffer.h
index 2c70ce9..cb8c06a 100644
--- a/ANGLE/src/libGLESv2/Renderbuffer.h
+++ b/ANGLE/src/libGLESv2/Renderbuffer.h
@@ -4,8 +4,9 @@
// found in the LICENSE file.
//
-// Renderbuffer.h: Defines the virtual gl::Renderbuffer class and its derived
-// classes Colorbuffer, Depthbuffer and Stencilbuffer. Implements GL renderbuffer
+// Renderbuffer.h: Defines the wrapper class gl::Renderbuffer, as well as the
+// class hierarchy used to store its contents: RenderbufferStorage, Colorbuffer,
+// DepthStencilbuffer, Depthbuffer and Stencilbuffer. Implements GL renderbuffer
// objects and related functionality. [OpenGL ES 2.0.24] section 4.4.3 page 108.
#ifndef LIBGLESV2_RENDERBUFFER_H_
@@ -16,26 +17,33 @@
#include <d3d9.h>
#include "common/angleutils.h"
+#include "libGLESv2/RefCountObject.h"
namespace gl
{
-class Renderbuffer
+
+// A class derived from RenderbufferStorage is created whenever glRenderbufferStorage
+// is called. The specific concrete type depends on whether the internal format is
+// colour depth, stencil or packed depth/stencil.
+class RenderbufferStorage
{
public:
- Renderbuffer();
+ RenderbufferStorage();
- virtual ~Renderbuffer();
+ virtual ~RenderbufferStorage() = 0;
- virtual bool isColorbuffer();
- virtual bool isDepthbuffer();
- virtual bool isStencilbuffer();
+ virtual bool isColorbuffer() const;
+ virtual bool isDepthbuffer() const;
+ virtual bool isStencilbuffer() const;
virtual IDirect3DSurface9 *getRenderTarget();
virtual IDirect3DSurface9 *getDepthStencil();
- virtual int getWidth();
- virtual int getHeight();
- GLenum getFormat();
+ virtual int getWidth() const;
+ virtual int getHeight() const;
+ virtual GLenum getFormat() const;
+ D3DFORMAT getD3DFormat() const;
+ GLsizei getSamples() const;
unsigned int getSerial() const;
static unsigned int issueSerial();
@@ -43,10 +51,12 @@ class Renderbuffer
protected:
void setSize(int width, int height);
GLenum mFormat;
+ D3DFORMAT mD3DFormat;
+ GLsizei mSamples;
unsigned int mSerial;
private:
- DISALLOW_COPY_AND_ASSIGN(Renderbuffer);
+ DISALLOW_COPY_AND_ASSIGN(RenderbufferStorage);
static unsigned int mCurrentSerial;
@@ -54,20 +64,52 @@ class Renderbuffer
int mHeight;
};
-class Colorbuffer : public Renderbuffer
+// Renderbuffer implements the GL renderbuffer object.
+// It's only a wrapper for a RenderbufferStorage, but the internal object
+// can change whenever glRenderbufferStorage is called.
+class Renderbuffer : public RefCountObject
+{
+ public:
+ Renderbuffer(GLuint id, RenderbufferStorage *storage);
+
+ ~Renderbuffer();
+
+ bool isColorbuffer() const;
+ bool isDepthbuffer() const;
+ bool isStencilbuffer() const;
+
+ IDirect3DSurface9 *getRenderTarget();
+ IDirect3DSurface9 *getDepthStencil();
+
+ int getWidth() const;
+ int getHeight() const;
+ GLenum getFormat() const;
+ D3DFORMAT getD3DFormat() const;
+ unsigned int getSerial() const;
+
+ void setStorage(RenderbufferStorage *newStorage);
+ RenderbufferStorage *getStorage() { return mStorage; }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(Renderbuffer);
+
+ RenderbufferStorage *mStorage;
+};
+
+class Colorbuffer : public RenderbufferStorage
{
public:
explicit Colorbuffer(IDirect3DSurface9 *renderTarget);
- Colorbuffer(int width, int height, GLenum format);
+ Colorbuffer(int width, int height, GLenum format, GLsizei samples);
~Colorbuffer();
- bool isColorbuffer();
+ bool isColorbuffer() const;
- GLuint getRedSize();
- GLuint getGreenSize();
- GLuint getBlueSize();
- GLuint getAlphaSize();
+ GLuint getRedSize() const;
+ GLuint getGreenSize() const;
+ GLuint getBlueSize() const;
+ GLuint getAlphaSize() const;
IDirect3DSurface9 *getRenderTarget();
@@ -78,42 +120,55 @@ class Colorbuffer : public Renderbuffer
DISALLOW_COPY_AND_ASSIGN(Colorbuffer);
};
-class Depthbuffer : public Renderbuffer
+class DepthStencilbuffer : public RenderbufferStorage
{
public:
- explicit Depthbuffer(IDirect3DSurface9 *depthStencil);
- Depthbuffer(int width, int height);
+ explicit DepthStencilbuffer(IDirect3DSurface9 *depthStencil);
+ DepthStencilbuffer(int width, int height, GLsizei samples);
- ~Depthbuffer();
+ ~DepthStencilbuffer();
- bool isDepthbuffer();
+ virtual bool isDepthbuffer() const;
+ virtual bool isStencilbuffer() const;
- GLuint getDepthSize();
+ GLuint getDepthSize() const;
+ GLuint getStencilSize() const;
IDirect3DSurface9 *getDepthStencil();
private:
- DISALLOW_COPY_AND_ASSIGN(Depthbuffer);
+ DISALLOW_COPY_AND_ASSIGN(DepthStencilbuffer);
IDirect3DSurface9 *mDepthStencil;
};
-class Stencilbuffer : public Renderbuffer
+class Depthbuffer : public DepthStencilbuffer
{
public:
- explicit Stencilbuffer(IDirect3DSurface9 *depthStencil);
- Stencilbuffer(int width, int height);
+ explicit Depthbuffer(IDirect3DSurface9 *depthStencil);
+ Depthbuffer(int width, int height, GLsizei samples);
- ~Stencilbuffer();
+ ~Depthbuffer();
+
+ bool isDepthbuffer() const;
+ bool isStencilbuffer() const;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(Depthbuffer);
+};
- bool isStencilbuffer();
+class Stencilbuffer : public DepthStencilbuffer
+{
+ public:
+ explicit Stencilbuffer(IDirect3DSurface9 *depthStencil);
+ Stencilbuffer(int width, int height, GLsizei samples);
- GLuint getStencilSize();
+ ~Stencilbuffer();
- IDirect3DSurface9 *getDepthStencil();
+ bool isDepthbuffer() const;
+ bool isStencilbuffer() const;
private:
DISALLOW_COPY_AND_ASSIGN(Stencilbuffer);
- IDirect3DSurface9 *mDepthStencil;
};
}
diff --git a/ANGLE/src/libGLESv2/ResourceManager.cpp b/ANGLE/src/libGLESv2/ResourceManager.cpp
new file mode 100644
index 0000000..12a86c1
--- /dev/null
+++ b/ANGLE/src/libGLESv2/ResourceManager.cpp
@@ -0,0 +1,340 @@
+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// ResourceManager.cpp: Implements the gl::ResourceManager class, which tracks and
+// retrieves objects which may be shared by multiple Contexts.
+
+#include "libGLESv2/ResourceManager.h"
+
+#include "libGLESv2/Buffer.h"
+#include "libGLESv2/Program.h"
+#include "libGLESv2/RenderBuffer.h"
+#include "libGLESv2/Shader.h"
+#include "libGLESv2/Texture.h"
+
+namespace gl
+{
+ResourceManager::ResourceManager()
+{
+ mRefCount = 1;
+}
+
+ResourceManager::~ResourceManager()
+{
+ while (!mBufferMap.empty())
+ {
+ deleteBuffer(mBufferMap.begin()->first);
+ }
+
+ while (!mProgramMap.empty())
+ {
+ deleteProgram(mProgramMap.begin()->first);
+ }
+
+ while (!mShaderMap.empty())
+ {
+ deleteShader(mShaderMap.begin()->first);
+ }
+
+ while (!mRenderbufferMap.empty())
+ {
+ deleteRenderbuffer(mRenderbufferMap.begin()->first);
+ }
+
+ while (!mTextureMap.empty())
+ {
+ deleteTexture(mTextureMap.begin()->first);
+ }
+}
+
+void ResourceManager::addRef()
+{
+ mRefCount++;
+}
+
+void ResourceManager::release()
+{
+ if (--mRefCount == 0)
+ {
+ delete this;
+ }
+}
+
+// Returns an unused buffer name
+GLuint ResourceManager::createBuffer()
+{
+ unsigned int handle = 1;
+
+ while (mBufferMap.find(handle) != mBufferMap.end())
+ {
+ handle++;
+ }
+
+ mBufferMap[handle] = NULL;
+
+ return handle;
+}
+
+// Returns an unused shader/program name
+GLuint ResourceManager::createShader(GLenum type)
+{
+ unsigned int handle = 1;
+
+ while (mShaderMap.find(handle) != mShaderMap.end() || mProgramMap.find(handle) != mProgramMap.end()) // Shared name space
+ {
+ handle++;
+ }
+
+ if (type == GL_VERTEX_SHADER)
+ {
+ mShaderMap[handle] = new VertexShader(this, handle);
+ }
+ else if (type == GL_FRAGMENT_SHADER)
+ {
+ mShaderMap[handle] = new FragmentShader(this, handle);
+ }
+ else UNREACHABLE();
+
+ return handle;
+}
+
+// Returns an unused program/shader name
+GLuint ResourceManager::createProgram()
+{
+ unsigned int handle = 1;
+
+ while (mProgramMap.find(handle) != mProgramMap.end() || mShaderMap.find(handle) != mShaderMap.end()) // Shared name space
+ {
+ handle++;
+ }
+
+ mProgramMap[handle] = new Program(this, handle);
+
+ return handle;
+}
+
+// Returns an unused texture name
+GLuint ResourceManager::createTexture()
+{
+ unsigned int handle = 1;
+
+ while (mTextureMap.find(handle) != mTextureMap.end())
+ {
+ handle++;
+ }
+
+ mTextureMap[handle] = NULL;
+
+ return handle;
+}
+
+// Returns an unused renderbuffer name
+GLuint ResourceManager::createRenderbuffer()
+{
+ unsigned int handle = 1;
+
+ while (mRenderbufferMap.find(handle) != mRenderbufferMap.end())
+ {
+ handle++;
+ }
+
+ mRenderbufferMap[handle] = NULL;
+
+ return handle;
+}
+
+void ResourceManager::deleteBuffer(GLuint buffer)
+{
+ BufferMap::iterator bufferObject = mBufferMap.find(buffer);
+
+ if (bufferObject != mBufferMap.end())
+ {
+ if (bufferObject->second) bufferObject->second->release();
+ mBufferMap.erase(bufferObject);
+ }
+}
+
+void ResourceManager::deleteShader(GLuint shader)
+{
+ ShaderMap::iterator shaderObject = mShaderMap.find(shader);
+
+ if (shaderObject != mShaderMap.end())
+ {
+ if (shaderObject->second->getRefCount() == 0)
+ {
+ delete shaderObject->second;
+ mShaderMap.erase(shaderObject);
+ }
+ else
+ {
+ shaderObject->second->flagForDeletion();
+ }
+ }
+}
+
+void ResourceManager::deleteProgram(GLuint program)
+{
+ ProgramMap::iterator programObject = mProgramMap.find(program);
+
+ if (programObject != mProgramMap.end())
+ {
+ if (programObject->second->getRefCount() == 0)
+ {
+ delete programObject->second;
+ mProgramMap.erase(programObject);
+ }
+ else
+ {
+ programObject->second->flagForDeletion();
+ }
+ }
+}
+
+void ResourceManager::deleteTexture(GLuint texture)
+{
+ TextureMap::iterator textureObject = mTextureMap.find(texture);
+
+ if (textureObject != mTextureMap.end())
+ {
+ if (textureObject->second) textureObject->second->release();
+ mTextureMap.erase(textureObject);
+ }
+}
+
+void ResourceManager::deleteRenderbuffer(GLuint renderbuffer)
+{
+ RenderbufferMap::iterator renderbufferObject = mRenderbufferMap.find(renderbuffer);
+
+ if (renderbufferObject != mRenderbufferMap.end())
+ {
+ if (renderbufferObject->second) renderbufferObject->second->release();
+ mRenderbufferMap.erase(renderbufferObject);
+ }
+}
+
+Buffer *ResourceManager::getBuffer(unsigned int handle)
+{
+ BufferMap::iterator buffer = mBufferMap.find(handle);
+
+ if (buffer == mBufferMap.end())
+ {
+ return NULL;
+ }
+ else
+ {
+ return buffer->second;
+ }
+}
+
+Shader *ResourceManager::getShader(unsigned int handle)
+{
+ ShaderMap::iterator shader = mShaderMap.find(handle);
+
+ if (shader == mShaderMap.end())
+ {
+ return NULL;
+ }
+ else
+ {
+ return shader->second;
+ }
+}
+
+Texture *ResourceManager::getTexture(unsigned int handle)
+{
+ if (handle == 0) return NULL;
+
+ TextureMap::iterator texture = mTextureMap.find(handle);
+
+ if (texture == mTextureMap.end())
+ {
+ return NULL;
+ }
+ else
+ {
+ return texture->second;
+ }
+}
+
+Program *ResourceManager::getProgram(unsigned int handle)
+{
+ ProgramMap::iterator program = mProgramMap.find(handle);
+
+ if (program == mProgramMap.end())
+ {
+ return NULL;
+ }
+ else
+ {
+ return program->second;
+ }
+}
+
+Renderbuffer *ResourceManager::getRenderbuffer(unsigned int handle)
+{
+ RenderbufferMap::iterator renderbuffer = mRenderbufferMap.find(handle);
+
+ if (renderbuffer == mRenderbufferMap.end())
+ {
+ return NULL;
+ }
+ else
+ {
+ return renderbuffer->second;
+ }
+}
+
+void ResourceManager::setRenderbuffer(GLuint handle, Renderbuffer *buffer)
+{
+ mRenderbufferMap[handle] = buffer;
+}
+
+void ResourceManager::checkBufferAllocation(unsigned int buffer)
+{
+ if (buffer != 0 && !getBuffer(buffer))
+ {
+ Buffer *bufferObject = new Buffer(buffer);
+ mBufferMap[buffer] = bufferObject;
+ bufferObject->addRef();
+ }
+}
+
+void ResourceManager::checkTextureAllocation(GLuint texture, SamplerType type)
+{
+ if (!getTexture(texture) && texture != 0)
+ {
+ Texture *textureObject;
+
+ if (type == SAMPLER_2D)
+ {
+ textureObject = new Texture2D(texture);
+ }
+ else if (type == SAMPLER_CUBE)
+ {
+ textureObject = new TextureCubeMap(texture);
+ }
+ else
+ {
+ UNREACHABLE();
+ return;
+ }
+
+ mTextureMap[texture] = textureObject;
+ textureObject->addRef();
+ }
+}
+
+void ResourceManager::checkRenderbufferAllocation(GLuint renderbuffer)
+{
+ if (renderbuffer != 0 && !getRenderbuffer(renderbuffer))
+ {
+ Renderbuffer *renderbufferObject = new Renderbuffer(renderbuffer, new Colorbuffer(0, 0, GL_RGBA4, 0));
+ mRenderbufferMap[renderbuffer] = renderbufferObject;
+ renderbufferObject->addRef();
+ }
+}
+
+}
diff --git a/ANGLE/src/libGLESv2/ResourceManager.h b/ANGLE/src/libGLESv2/ResourceManager.h
new file mode 100644
index 0000000..346e51f
--- /dev/null
+++ b/ANGLE/src/libGLESv2/ResourceManager.h
@@ -0,0 +1,92 @@
+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+// ResourceManager.h : Defines the ResourceManager class, which tracks objects
+// shared by multiple GL contexts.
+
+#ifndef LIBGLESV2_RESOURCEMANAGER_H_
+#define LIBGLESV2_RESOURCEMANAGER_H_
+
+#define GL_APICALL
+#include <GLES2/gl2.h>
+
+#include <map>
+
+#include "common/angleutils.h"
+
+namespace gl
+{
+class Buffer;
+class Shader;
+class Program;
+class Texture;
+class Renderbuffer;
+
+enum SamplerType
+{
+ SAMPLER_2D,
+ SAMPLER_CUBE,
+
+ SAMPLER_TYPE_COUNT
+};
+
+class ResourceManager
+{
+ public:
+ ResourceManager();
+ ~ResourceManager();
+
+ void addRef();
+ void release();
+
+ GLuint createBuffer();
+ GLuint createShader(GLenum type);
+ GLuint createProgram();
+ GLuint createTexture();
+ GLuint createRenderbuffer();
+
+ void deleteBuffer(GLuint buffer);
+ void deleteShader(GLuint shader);
+ void deleteProgram(GLuint program);
+ void deleteTexture(GLuint texture);
+ void deleteRenderbuffer(GLuint renderbuffer);
+
+ Buffer *getBuffer(GLuint handle);
+ Shader *getShader(GLuint handle);
+ Program *getProgram(GLuint handle);
+ Texture *getTexture(GLuint handle);
+ Renderbuffer *getRenderbuffer(GLuint handle);
+
+ void setRenderbuffer(GLuint handle, Renderbuffer *renderbuffer);
+
+ void checkBufferAllocation(unsigned int buffer);
+ void checkTextureAllocation(GLuint texture, SamplerType type);
+ void checkRenderbufferAllocation(GLuint renderbuffer);
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ResourceManager);
+
+ std::size_t mRefCount;
+
+ typedef std::map<GLuint, Buffer*> BufferMap;
+ BufferMap mBufferMap;
+
+ typedef std::map<GLuint, Shader*> ShaderMap;
+ ShaderMap mShaderMap;
+
+ typedef std::map<GLuint, Program*> ProgramMap;
+ ProgramMap mProgramMap;
+
+ typedef std::map<GLuint, Texture*> TextureMap;
+ TextureMap mTextureMap;
+
+ typedef std::map<GLuint, Renderbuffer*> RenderbufferMap;
+ RenderbufferMap mRenderbufferMap;
+};
+
+}
+
+#endif // LIBGLESV2_RESOURCEMANAGER_H_
diff --git a/ANGLE/src/libGLESv2/Shader.cpp b/ANGLE/src/libGLESv2/Shader.cpp
index 730c1b5..b73ef2a 100644
--- a/ANGLE/src/libGLESv2/Shader.cpp
+++ b/ANGLE/src/libGLESv2/Shader.cpp
@@ -21,7 +21,7 @@ namespace gl
void *Shader::mFragmentCompiler = NULL;
void *Shader::mVertexCompiler = NULL;
-Shader::Shader(Context *context, GLuint handle) : mHandle(handle), mContext(context)
+Shader::Shader(ResourceManager *manager, GLuint handle) : mHandle(handle), mResourceManager(manager)
{
mSource = NULL;
mHlsl = NULL;
@@ -35,21 +35,22 @@ Shader::Shader(Context *context, GLuint handle) : mHandle(handle), mContext(cont
if (result)
{
TBuiltInResource resources;
- resources.maxVertexAttribs = MAX_VERTEX_ATTRIBS;
- resources.maxVertexUniformVectors = MAX_VERTEX_UNIFORM_VECTORS;
- resources.maxVaryingVectors = MAX_VARYING_VECTORS;
- resources.maxVertexTextureImageUnits = MAX_VERTEX_TEXTURE_IMAGE_UNITS;
- resources.maxCombinedTextureImageUnits = MAX_COMBINED_TEXTURE_IMAGE_UNITS;
- resources.maxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS;
- resources.maxFragmentUniformVectors = MAX_FRAGMENT_UNIFORM_VECTORS;
- resources.maxDrawBuffers = MAX_DRAW_BUFFERS;
+ ShInitBuiltInResource(&resources);
+ resources.MaxVertexAttribs = MAX_VERTEX_ATTRIBS;
+ resources.MaxVertexUniformVectors = MAX_VERTEX_UNIFORM_VECTORS;
+ resources.MaxVaryingVectors = MAX_VARYING_VECTORS;
+ resources.MaxVertexTextureImageUnits = MAX_VERTEX_TEXTURE_IMAGE_UNITS;
+ resources.MaxCombinedTextureImageUnits = MAX_COMBINED_TEXTURE_IMAGE_UNITS;
+ resources.MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS;
+ resources.MaxFragmentUniformVectors = MAX_FRAGMENT_UNIFORM_VECTORS;
+ resources.MaxDrawBuffers = MAX_DRAW_BUFFERS;
mFragmentCompiler = ShConstructCompiler(EShLangFragment, EShSpecGLES2, &resources);
mVertexCompiler = ShConstructCompiler(EShLangVertex, EShSpecGLES2, &resources);
}
}
- mAttachCount = 0;
+ mRefCount = 0;
mDeleteStatus = false;
}
@@ -187,24 +188,24 @@ const char *Shader::getHLSL()
return mHlsl;
}
-void Shader::attach()
+void Shader::addRef()
{
- mAttachCount++;
+ mRefCount++;
}
-void Shader::detach()
+void Shader::release()
{
- mAttachCount--;
+ mRefCount--;
- if (mAttachCount == 0 && mDeleteStatus)
+ if (mRefCount == 0 && mDeleteStatus)
{
- mContext->deleteShader(mHandle);
+ mResourceManager->deleteShader(mHandle);
}
}
-bool Shader::isAttached() const
+unsigned int Shader::getRefCount() const
{
- return mAttachCount > 0;
+ return mRefCount;
}
bool Shader::isFlaggedForDeletion() const
@@ -262,6 +263,8 @@ void Shader::parseVaryings()
mUsesFragCoord = strstr(mHlsl, "GL_USES_FRAG_COORD") != NULL;
mUsesFrontFacing = strstr(mHlsl, "GL_USES_FRONT_FACING") != NULL;
+ mUsesPointSize = strstr(mHlsl, "GL_USES_POINT_SIZE") != NULL;
+ mUsesPointCoord = strstr(mHlsl, "GL_USES_POINT_COORD") != NULL;
}
}
@@ -415,7 +418,7 @@ bool Shader::compareVarying(const Varying &x, const Varying &y)
return false;
}
-VertexShader::VertexShader(Context *context, GLuint handle) : Shader(context, handle)
+VertexShader::VertexShader(ResourceManager *manager, GLuint handle) : Shader(manager, handle)
{
}
@@ -479,7 +482,7 @@ void VertexShader::parseAttributes()
}
}
-FragmentShader::FragmentShader(Context *context, GLuint handle) : Shader(context, handle)
+FragmentShader::FragmentShader(ResourceManager *manager, GLuint handle) : Shader(manager, handle)
{
}
diff --git a/ANGLE/src/libGLESv2/Shader.h b/ANGLE/src/libGLESv2/Shader.h
index 777c236..5eaa053 100644
--- a/ANGLE/src/libGLESv2/Shader.h
+++ b/ANGLE/src/libGLESv2/Shader.h
@@ -18,7 +18,7 @@
#include <list>
#include <vector>
-#include "libGLESv2/Context.h"
+#include "libGLESv2/ResourceManager.h"
namespace gl
{
@@ -45,7 +45,7 @@ class Shader
friend Program;
public:
- Shader(Context *context, GLuint handle);
+ Shader(ResourceManager *manager, GLuint handle);
virtual ~Shader();
@@ -63,9 +63,9 @@ class Shader
bool isCompiled();
const char *getHLSL();
- void attach();
- void detach();
- bool isAttached() const;
+ void addRef();
+ void release();
+ unsigned int getRefCount() const;
bool isFlaggedForDeletion() const;
void flagForDeletion();
@@ -82,8 +82,8 @@ class Shader
static bool compareVarying(const Varying &x, const Varying &y);
const GLuint mHandle;
- int mAttachCount; // Number of program objects this shader is attached to
- bool mDeleteStatus; // Flag to indicate that the shader can be deleted when no longer in use
+ unsigned int mRefCount; // Number of program objects this shader is attached to
+ bool mDeleteStatus; // Flag to indicate that the shader can be deleted when no longer in use
char *mSource;
char *mHlsl;
@@ -93,8 +93,10 @@ class Shader
bool mUsesFragCoord;
bool mUsesFrontFacing;
+ bool mUsesPointSize;
+ bool mUsesPointCoord;
- Context *mContext;
+ ResourceManager *mResourceManager;
static void *mFragmentCompiler;
static void *mVertexCompiler;
@@ -121,7 +123,7 @@ class VertexShader : public Shader
friend Program;
public:
- VertexShader(Context *context, GLuint handle);
+ VertexShader(ResourceManager *manager, GLuint handle);
~VertexShader();
@@ -140,7 +142,7 @@ class VertexShader : public Shader
class FragmentShader : public Shader
{
public:
- FragmentShader(Context *context, GLuint handle);
+ FragmentShader(ResourceManager *manager, GLuint handle);
~FragmentShader();
diff --git a/ANGLE/src/libGLESv2/Texture.cpp b/ANGLE/src/libGLESv2/Texture.cpp
index 4079d43..2e0b1e3 100644
--- a/ANGLE/src/libGLESv2/Texture.cpp
+++ b/ANGLE/src/libGLESv2/Texture.cpp
@@ -23,7 +23,7 @@ namespace gl
{
Texture::Image::Image()
- : width(0), height(0), dirty(false), surface(NULL)
+ : width(0), height(0), dirty(false), surface(NULL), format(GL_NONE)
{
}
@@ -32,13 +32,16 @@ Texture::Image::~Image()
if (surface) surface->Release();
}
-Texture::Texture(Context *context) : mContext(context)
+Texture::Texture(GLuint id) : RefCountObject(id)
{
mMinFilter = GL_NEAREST_MIPMAP_LINEAR;
mMagFilter = GL_LINEAR;
mWrapS = GL_REPEAT;
mWrapT = GL_REPEAT;
+ mWidth = 0;
+ mHeight = 0;
+
mDirtyMetaData = true;
mDirty = true;
mIsRenderable = false;
@@ -51,7 +54,8 @@ Texture::~Texture()
Blit *Texture::getBlitter()
{
- return mContext->getBlitter();
+ Context *context = getContext();
+ return context->getBlitter();
}
// Returns true on successful filter state update (valid enum parameter)
@@ -173,7 +177,15 @@ GLuint Texture::getHeight() const
// Selects an internal Direct3D 9 format for storing an Image
D3DFORMAT Texture::selectFormat(GLenum format)
{
- return D3DFMT_A8R8G8B8;
+ if (format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
+ format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)
+ {
+ return D3DFMT_DXT1;
+ }
+ else
+ {
+ return D3DFMT_A8R8G8B8;
+ }
}
int Texture::imagePitch(const Image &img) const
@@ -188,126 +200,282 @@ void Texture::loadImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei
{
GLsizei inputPitch = ComputePitch(width, format, type, unpackAlignment);
+ switch (format)
+ {
+ case GL_ALPHA:
+ loadAlphaImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
+ break;
+
+ case GL_LUMINANCE:
+ loadLuminanceImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
+ break;
+
+ case GL_LUMINANCE_ALPHA:
+ loadLuminanceAlphaImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
+ break;
+
+ case GL_RGB:
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ loadRGBUByteImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
+ break;
+
+ case GL_UNSIGNED_SHORT_5_6_5:
+ loadRGB565ImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
+ break;
+
+ default: UNREACHABLE();
+ }
+ break;
+
+ case GL_RGBA:
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ loadRGBAUByteImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
+ break;
+
+ case GL_UNSIGNED_SHORT_4_4_4_4:
+ loadRGBA4444ImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
+ break;
+
+ case GL_UNSIGNED_SHORT_5_5_5_1:
+ loadRGBA5551ImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
+ break;
+
+ default: UNREACHABLE();
+ }
+ break;
+ case GL_BGRA_EXT:
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ loadBGRAImageData(xoffset, yoffset, width, height, inputPitch, input, outputPitch, output);
+ break;
+
+ default: UNREACHABLE();
+ }
+ break;
+ default: UNREACHABLE();
+ }
+}
+
+void Texture::loadAlphaImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ size_t inputPitch, const void *input, size_t outputPitch, void *output) const
+{
+ const unsigned char *source = NULL;
+ unsigned char *dest = NULL;
+
for (int y = 0; y < height; y++)
{
- const unsigned char *source = static_cast<const unsigned char*>(input) + y * inputPitch;
- const unsigned short *source16 = reinterpret_cast<const unsigned short*>(source);
- unsigned char *dest = static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 4;
+ source = static_cast<const unsigned char*>(input) + y * inputPitch;
+ dest = static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 4;
+ for (int x = 0; x < width; x++)
+ {
+ dest[4 * x + 0] = 0;
+ dest[4 * x + 1] = 0;
+ dest[4 * x + 2] = 0;
+ dest[4 * x + 3] = source[x];
+ }
+ }
+}
+void Texture::loadLuminanceImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ size_t inputPitch, const void *input, size_t outputPitch, void *output) const
+{
+ const unsigned char *source = NULL;
+ unsigned char *dest = NULL;
+
+ for (int y = 0; y < height; y++)
+ {
+ source = static_cast<const unsigned char*>(input) + y * inputPitch;
+ dest = static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 4;
for (int x = 0; x < width; x++)
{
- unsigned char r;
- unsigned char g;
- unsigned char b;
- unsigned char a;
+ dest[4 * x + 0] = source[x];
+ dest[4 * x + 1] = source[x];
+ dest[4 * x + 2] = source[x];
+ dest[4 * x + 3] = 0xFF;
+ }
+ }
+}
- switch (format)
- {
- case GL_ALPHA:
- a = source[x];
- r = 0;
- g = 0;
- b = 0;
- break;
-
- case GL_LUMINANCE:
- r = source[x];
- g = source[x];
- b = source[x];
- a = 0xFF;
- break;
-
- case GL_LUMINANCE_ALPHA:
- r = source[2*x+0];
- g = source[2*x+0];
- b = source[2*x+0];
- a = source[2*x+1];
- break;
-
- case GL_RGB:
- switch (type)
- {
- case GL_UNSIGNED_BYTE:
- r = source[x * 3 + 0];
- g = source[x * 3 + 1];
- b = source[x * 3 + 2];
- a = 0xFF;
- break;
-
- case GL_UNSIGNED_SHORT_5_6_5:
- {
- unsigned short rgba = source16[x];
+void Texture::loadLuminanceAlphaImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ size_t inputPitch, const void *input, size_t outputPitch, void *output) const
+{
+ const unsigned char *source = NULL;
+ unsigned char *dest = NULL;
- a = 0xFF;
- b = ((rgba & 0x001F) << 3) | ((rgba & 0x001F) >> 2);
- g = ((rgba & 0x07E0) >> 3) | ((rgba & 0x07E0) >> 9);
- r = ((rgba & 0xF800) >> 8) | ((rgba & 0xF800) >> 13);
- }
- break;
+ for (int y = 0; y < height; y++)
+ {
+ source = static_cast<const unsigned char*>(input) + y * inputPitch;
+ dest = static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 4;
+ for (int x = 0; x < width; x++)
+ {
+ dest[4 * x + 0] = source[2*x+0];
+ dest[4 * x + 1] = source[2*x+0];
+ dest[4 * x + 2] = source[2*x+0];
+ dest[4 * x + 3] = source[2*x+1];
+ }
+ }
+}
- default: UNREACHABLE();
- }
- break;
+void Texture::loadRGBUByteImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ size_t inputPitch, const void *input, size_t outputPitch, void *output) const
+{
+ const unsigned char *source = NULL;
+ unsigned char *dest = NULL;
- case GL_RGBA:
- switch (type)
- {
- case GL_UNSIGNED_BYTE:
- r = source[x * 4 + 0];
- g = source[x * 4 + 1];
- b = source[x * 4 + 2];
- a = source[x * 4 + 3];
- break;
-
- case GL_UNSIGNED_SHORT_4_4_4_4:
- {
- unsigned short rgba = source16[x];
+ for (int y = 0; y < height; y++)
+ {
+ source = static_cast<const unsigned char*>(input) + y * inputPitch;
+ dest = static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 4;
+ for (int x = 0; x < width; x++)
+ {
+ dest[4 * x + 0] = source[x * 3 + 2];
+ dest[4 * x + 1] = source[x * 3 + 1];
+ dest[4 * x + 2] = source[x * 3 + 0];
+ dest[4 * x + 3] = 0xFF;
+ }
+ }
+}
- a = ((rgba & 0x000F) << 4) | ((rgba & 0x000F) >> 0);
- b = ((rgba & 0x00F0) << 0) | ((rgba & 0x00F0) >> 4);
- g = ((rgba & 0x0F00) >> 4) | ((rgba & 0x0F00) >> 8);
- r = ((rgba & 0xF000) >> 8) | ((rgba & 0xF000) >> 12);
- }
- break;
+void Texture::loadRGB565ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ size_t inputPitch, const void *input, size_t outputPitch, void *output) const
+{
+ const unsigned short *source = NULL;
+ unsigned char *dest = NULL;
- case GL_UNSIGNED_SHORT_5_5_5_1:
- {
- unsigned short rgba = source16[x];
+ for (int y = 0; y < height; y++)
+ {
+ source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
+ dest = static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 4;
+ for (int x = 0; x < width; x++)
+ {
+ unsigned short rgba = source[x];
+ dest[4 * x + 0] = ((rgba & 0x001F) << 3) | ((rgba & 0x001F) >> 2);
+ dest[4 * x + 1] = ((rgba & 0x07E0) >> 3) | ((rgba & 0x07E0) >> 9);
+ dest[4 * x + 2] = ((rgba & 0xF800) >> 8) | ((rgba & 0xF800) >> 13);
+ dest[4 * x + 3] = 0xFF;
+ }
+ }
+}
- a = (rgba & 0x0001) ? 0xFF : 0;
- b = ((rgba & 0x003E) << 2) | ((rgba & 0x003E) >> 3);
- g = ((rgba & 0x07C0) >> 3) | ((rgba & 0x07C0) >> 8);
- r = ((rgba & 0xF800) >> 8) | ((rgba & 0xF800) >> 13);
- }
- break;
+void Texture::loadRGBAUByteImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ size_t inputPitch, const void *input, size_t outputPitch, void *output) const
+{
+ const unsigned char *source = NULL;
+ unsigned char *dest = NULL;
- default: UNREACHABLE();
- }
- break;
- default: UNREACHABLE();
- }
+ for (int y = 0; y < height; y++)
+ {
+ source = static_cast<const unsigned char*>(input) + y * inputPitch;
+ dest = static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 4;
+ for (int x = 0; x < width; x++)
+ {
+ dest[4 * x + 0] = source[x * 4 + 2];
+ dest[4 * x + 1] = source[x * 4 + 1];
+ dest[4 * x + 2] = source[x * 4 + 0];
+ dest[4 * x + 3] = source[x * 4 + 3];
+ }
+ }
+}
+
+void Texture::loadRGBA4444ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ size_t inputPitch, const void *input, size_t outputPitch, void *output) const
+{
+ const unsigned short *source = NULL;
+ unsigned char *dest = NULL;
- dest[4 * x + 0] = b;
- dest[4 * x + 1] = g;
- dest[4 * x + 2] = r;
- dest[4 * x + 3] = a;
+ for (int y = 0; y < height; y++)
+ {
+ source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
+ dest = static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 4;
+ for (int x = 0; x < width; x++)
+ {
+ unsigned short rgba = source[x];
+ dest[4 * x + 0] = ((rgba & 0x00F0) << 0) | ((rgba & 0x00F0) >> 4);
+ dest[4 * x + 1] = ((rgba & 0x0F00) >> 4) | ((rgba & 0x0F00) >> 8);
+ dest[4 * x + 2] = ((rgba & 0xF000) >> 8) | ((rgba & 0xF000) >> 12);
+ dest[4 * x + 3] = ((rgba & 0x000F) << 4) | ((rgba & 0x000F) >> 0);
}
}
}
-void Texture::setImage(GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *img)
+void Texture::loadRGBA5551ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ size_t inputPitch, const void *input, size_t outputPitch, void *output) const
+{
+ const unsigned short *source = NULL;
+ unsigned char *dest = NULL;
+
+ for (int y = 0; y < height; y++)
+ {
+ source = reinterpret_cast<const unsigned short*>(static_cast<const unsigned char*>(input) + y * inputPitch);
+ dest = static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 4;
+ for (int x = 0; x < width; x++)
+ {
+ unsigned short rgba = source[x];
+ dest[4 * x + 0] = ((rgba & 0x003E) << 2) | ((rgba & 0x003E) >> 3);
+ dest[4 * x + 1] = ((rgba & 0x07C0) >> 3) | ((rgba & 0x07C0) >> 8);
+ dest[4 * x + 2] = ((rgba & 0xF800) >> 8) | ((rgba & 0xF800) >> 13);
+ dest[4 * x + 3] = (rgba & 0x0001) ? 0xFF : 0;
+ }
+ }
+}
+
+void Texture::loadBGRAImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ size_t inputPitch, const void *input, size_t outputPitch, void *output) const
+{
+ const unsigned char *source = NULL;
+ unsigned char *dest = NULL;
+
+ for (int y = 0; y < height; y++)
+ {
+ source = static_cast<const unsigned char*>(input) + y * inputPitch;
+ dest = static_cast<unsigned char*>(output) + (y + yoffset) * outputPitch + xoffset * 4;
+ memcpy(dest, source, width*4);
+ }
+}
+
+void Texture::createSurface(GLsizei width, GLsizei height, GLenum format, Image *img)
{
+ IDirect3DTexture9 *newTexture = NULL;
IDirect3DSurface9 *newSurface = NULL;
if (width != 0 && height != 0)
{
- HRESULT result = getDevice()->CreateOffscreenPlainSurface(width, height, selectFormat(format), D3DPOOL_SYSTEMMEM, &newSurface, NULL);
+ int levelToFetch = 0;
+ GLsizei requestWidth = width;
+ GLsizei requestHeight = height;
+ if (IsCompressed(format) && (width % 4 != 0 || height % 4 != 0))
+ {
+ bool isMult4 = false;
+ int upsampleCount = 0;
+ while (!isMult4)
+ {
+ requestWidth <<= 1;
+ requestHeight <<= 1;
+ upsampleCount++;
+ if (requestWidth % 4 == 0 && requestHeight % 4 == 0)
+ {
+ isMult4 = true;
+ }
+ }
+ levelToFetch = upsampleCount;
+ }
+
+ HRESULT result = getDevice()->CreateTexture(requestWidth, requestHeight, levelToFetch + 1, NULL, selectFormat(format),
+ D3DPOOL_SYSTEMMEM, &newTexture, NULL);
if (FAILED(result))
{
ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
return error(GL_OUT_OF_MEMORY);
}
+
+ newTexture->GetSurfaceLevel(levelToFetch, &newSurface);
+ newTexture->Release();
}
if (img->surface) img->surface->Release();
@@ -316,18 +484,23 @@ void Texture::setImage(GLsizei width, GLsizei height, GLenum format, GLenum type
img->width = width;
img->height = height;
img->format = format;
+}
- if (pixels != NULL && newSurface != NULL)
+void Texture::setImage(GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *img)
+{
+ createSurface(width, height, format, img);
+
+ if (pixels != NULL && img->surface != NULL)
{
D3DLOCKED_RECT locked;
- HRESULT result = newSurface->LockRect(&locked, NULL, 0);
+ HRESULT result = img->surface->LockRect(&locked, NULL, 0);
ASSERT(SUCCEEDED(result));
if (SUCCEEDED(result))
{
loadImageData(0, 0, width, height, format, type, unpackAlignment, pixels, locked.Pitch, locked.pBits);
- newSurface->UnlockRect();
+ img->surface->UnlockRect();
}
img->dirty = true;
@@ -336,9 +509,36 @@ void Texture::setImage(GLsizei width, GLsizei height, GLenum format, GLenum type
mDirtyMetaData = true;
}
-void Texture::subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *img)
+void Texture::setCompressedImage(GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels, Image *img)
{
- if (width + xoffset > img->width || height + yoffset > img->height) return error(GL_INVALID_VALUE);
+ createSurface(width, height, format, img);
+
+ if (pixels != NULL && img->surface != NULL)
+ {
+ D3DLOCKED_RECT locked;
+ HRESULT result = img->surface->LockRect(&locked, NULL, 0);
+
+ ASSERT(SUCCEEDED(result));
+
+ if (SUCCEEDED(result))
+ {
+ memcpy(locked.pBits, pixels, imageSize);
+ img->surface->UnlockRect();
+ }
+
+ img->dirty = true;
+ }
+
+ mDirtyMetaData = true;
+}
+
+bool Texture::subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *img)
+{
+ if (width + xoffset > img->width || height + yoffset > img->height)
+ {
+ error(GL_INVALID_VALUE);
+ return false;
+ }
D3DLOCKED_RECT locked;
HRESULT result = img->surface->LockRect(&locked, NULL, 0);
@@ -352,6 +552,47 @@ void Texture::subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei heig
}
img->dirty = true;
+ return true;
+}
+
+bool Texture::subImageCompressed(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels, Image *img)
+{
+ if (width + xoffset > img->width || height + yoffset > img->height)
+ {
+ error(GL_INVALID_VALUE);
+ return false;
+ }
+
+ if (format != getFormat())
+ {
+ error(GL_INVALID_OPERATION);
+ return false;
+ }
+
+ RECT updateRegion;
+ updateRegion.left = xoffset;
+ updateRegion.right = xoffset + width;
+ updateRegion.bottom = yoffset + height;
+ updateRegion.top = yoffset;
+
+ D3DLOCKED_RECT locked;
+ HRESULT result = img->surface->LockRect(&locked, &updateRegion, 0);
+
+ ASSERT(SUCCEEDED(result));
+
+ if (SUCCEEDED(result))
+ {
+ GLsizei inputPitch = ComputeCompressedPitch(width, format);
+ int rows = imageSize / inputPitch;
+ for (int i = 0; i < rows; ++i)
+ {
+ memcpy((void*)((BYTE*)locked.pBits + i * locked.Pitch), (void*)((BYTE*)pixels + i * inputPitch), inputPitch);
+ }
+ img->surface->UnlockRect();
+ }
+
+ img->dirty = true;
+ return true;
}
IDirect3DBaseTexture9 *Texture::getTexture()
@@ -442,7 +683,7 @@ int Texture::levelCount() const
return mBaseTexture ? mBaseTexture->GetLevelCount() : 0;
}
-Texture2D::Texture2D(Context *context) : Texture(context)
+Texture2D::Texture2D(GLuint id) : Texture(id)
{
mTexture = NULL;
mColorbufferProxy = NULL;
@@ -464,6 +705,11 @@ GLenum Texture2D::getTarget() const
return GL_TEXTURE_2D;
}
+GLenum Texture2D::getFormat() const
+{
+ return mImageArray[0].format;
+}
+
// While OpenGL doesn't check texture consistency until draw-time, D3D9 requires a complete texture
// for render-to-texture (such as CopyTexImage). We have no way of keeping individual inconsistent levels.
// Call this when a particular level of the texture must be defined with a specific format, width and height.
@@ -522,6 +768,13 @@ void Texture2D::setImage(GLint level, GLenum internalFormat, GLsizei width, GLsi
Texture::setImage(width, height, format, type, unpackAlignment, pixels, &mImageArray[level]);
}
+void Texture2D::setCompressedImage(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels)
+{
+ redefineTexture(level, internalFormat, width, height);
+
+ Texture::setCompressedImage(width, height, internalFormat, imageSize, pixels, &mImageArray[level]);
+}
+
void Texture2D::commitRect(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
{
ASSERT(mImageArray[level].surface != NULL);
@@ -559,17 +812,31 @@ void Texture2D::commitRect(GLint level, GLint xoffset, GLint yoffset, GLsizei wi
void Texture2D::subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels)
{
- Texture::subImage(xoffset, yoffset, width, height, format, type, unpackAlignment, pixels, &mImageArray[level]);
- commitRect(level, xoffset, yoffset, width, height);
+ if (Texture::subImage(xoffset, yoffset, width, height, format, type, unpackAlignment, pixels, &mImageArray[level]))
+ {
+ commitRect(level, xoffset, yoffset, width, height);
+ }
+}
+
+void Texture2D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels)
+{
+ if (Texture::subImageCompressed(xoffset, yoffset, width, height, format, imageSize, pixels, &mImageArray[level]))
+ {
+ commitRect(level, xoffset, yoffset, width, height);
+ }
}
-void Texture2D::copyImage(GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, Renderbuffer *source)
+void Texture2D::copyImage(GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source)
{
if (redefineTexture(level, internalFormat, width, height))
{
convertToRenderTarget();
pushTexture(mTexture, true);
}
+ else
+ {
+ needRenderTarget();
+ }
if (width != 0 && height != 0 && level < levelCount())
{
@@ -591,7 +858,7 @@ void Texture2D::copyImage(GLint level, GLenum internalFormat, GLint x, GLint y,
mImageArray[level].format = internalFormat;
}
-void Texture2D::copySubImage(GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Renderbuffer *source)
+void Texture2D::copySubImage(GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source)
{
if (xoffset + width > mImageArray[level].width || yoffset + height > mImageArray[level].height)
{
@@ -689,6 +956,11 @@ bool Texture2D::isComplete() const
return true;
}
+bool Texture2D::isCompressed() const
+{
+ return IsCompressed(getFormat());
+}
+
// Constructs a Direct3D 9 texture resource from the texture images, or returns an existing one
IDirect3DBaseTexture9 *Texture2D::createTexture()
{
@@ -871,16 +1143,17 @@ void Texture2D::generateMipmaps()
}
}
-Colorbuffer *Texture2D::getColorbuffer(GLenum target)
+Renderbuffer *Texture2D::getColorbuffer(GLenum target)
{
if (target != GL_TEXTURE_2D)
{
- return error(GL_INVALID_OPERATION, (Colorbuffer *)NULL);
+ return error(GL_INVALID_OPERATION, (Renderbuffer *)NULL);
}
if (mColorbufferProxy == NULL)
{
- mColorbufferProxy = new TextureColorbufferProxy(this, target);
+ mColorbufferProxy = new Renderbuffer(id(), new TextureColorbufferProxy(this, target));
+ mColorbufferProxy->addRef();
}
return mColorbufferProxy;
@@ -898,7 +1171,7 @@ IDirect3DSurface9 *Texture2D::getRenderTarget(GLenum target)
return renderTarget;
}
-TextureCubeMap::TextureCubeMap(Context *context) : Texture(context)
+TextureCubeMap::TextureCubeMap(GLuint id) : Texture(id)
{
mTexture = NULL;
@@ -927,6 +1200,11 @@ GLenum TextureCubeMap::getTarget() const
return GL_TEXTURE_CUBE_MAP;
}
+GLenum TextureCubeMap::getFormat() const
+{
+ return mImageArray[0][0].format;
+}
+
void TextureCubeMap::setImagePosX(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels)
{
setImage(0, level, internalFormat, width, height, format, type, unpackAlignment, pixels);
@@ -957,6 +1235,13 @@ void TextureCubeMap::setImageNegZ(GLint level, GLenum internalFormat, GLsizei wi
setImage(5, level, internalFormat, width, height, format, type, unpackAlignment, pixels);
}
+void TextureCubeMap::setCompressedImage(GLenum face, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels)
+{
+ redefineTexture(level, internalFormat, width);
+
+ Texture::setCompressedImage(width, height, internalFormat, imageSize, pixels, &mImageArray[faceIndex(face)][level]);
+}
+
void TextureCubeMap::commitRect(GLenum faceTarget, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
{
int face = faceIndex(faceTarget);
@@ -994,8 +1279,18 @@ void TextureCubeMap::commitRect(GLenum faceTarget, GLint level, GLint xoffset, G
void TextureCubeMap::subImage(GLenum face, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels)
{
- Texture::subImage(xoffset, yoffset, width, height, format, type, unpackAlignment, pixels, &mImageArray[faceIndex(face)][level]);
- commitRect(face, level, xoffset, yoffset, width, height);
+ if (Texture::subImage(xoffset, yoffset, width, height, format, type, unpackAlignment, pixels, &mImageArray[faceIndex(face)][level]))
+ {
+ commitRect(face, level, xoffset, yoffset, width, height);
+ }
+}
+
+void TextureCubeMap::subImageCompressed(GLenum face, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels)
+{
+ if (Texture::subImageCompressed(xoffset, yoffset, width, height, format, imageSize, pixels, &mImageArray[faceIndex(face)][level]))
+ {
+ commitRect(face, level, xoffset, yoffset, width, height);
+ }
}
// Tests for GL texture object completeness. [OpenGL ES 2.0.24] section 3.7.10 page 81.
@@ -1064,6 +1359,11 @@ bool TextureCubeMap::isComplete() const
return true;
}
+bool TextureCubeMap::isCompressed() const
+{
+ return IsCompressed(getFormat());
+}
+
// Constructs a Direct3D 9 texture resource from the texture images, or returns an existing one
IDirect3DBaseTexture9 *TextureCubeMap::createTexture()
{
@@ -1278,7 +1578,7 @@ bool TextureCubeMap::redefineTexture(GLint level, GLenum internalFormat, GLsizei
return !textureOkay;
}
-void TextureCubeMap::copyImage(GLenum face, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, Renderbuffer *source)
+void TextureCubeMap::copyImage(GLenum face, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source)
{
unsigned int faceindex = faceIndex(face);
@@ -1287,6 +1587,10 @@ void TextureCubeMap::copyImage(GLenum face, GLint level, GLenum internalFormat,
convertToRenderTarget();
pushTexture(mTexture, true);
}
+ else
+ {
+ needRenderTarget();
+ }
ASSERT(width == height);
@@ -1340,7 +1644,7 @@ IDirect3DSurface9 *TextureCubeMap::getCubeMapSurface(unsigned int faceIdentifier
return (SUCCEEDED(hr)) ? surface : NULL;
}
-void TextureCubeMap::copySubImage(GLenum face, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Renderbuffer *source)
+void TextureCubeMap::copySubImage(GLenum face, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source)
{
GLsizei size = mImageArray[faceIndex(face)][level].width;
@@ -1356,7 +1660,7 @@ void TextureCubeMap::copySubImage(GLenum face, GLint level, GLint xoffset, GLint
}
else
{
- getRenderTarget(face);
+ needRenderTarget();
}
if (level < levelCount())
@@ -1440,18 +1744,19 @@ void TextureCubeMap::generateMipmaps()
}
}
-Colorbuffer *TextureCubeMap::getColorbuffer(GLenum target)
+Renderbuffer *TextureCubeMap::getColorbuffer(GLenum target)
{
if (!IsCubemapTextureTarget(target))
{
- return error(GL_INVALID_OPERATION, (Colorbuffer *)NULL);
+ return error(GL_INVALID_OPERATION, (Renderbuffer *)NULL);
}
unsigned int face = faceIndex(target);
if (mFaceProxies[face] == NULL)
{
- mFaceProxies[face] = new TextureColorbufferProxy(this, target);
+ mFaceProxies[face] = new Renderbuffer(id(), new TextureColorbufferProxy(this, target));
+ mFaceProxies[face]->addRef();
}
return mFaceProxies[face];
@@ -1475,6 +1780,16 @@ Texture::TextureColorbufferProxy::TextureColorbufferProxy(Texture *texture, GLen
ASSERT(target == GL_TEXTURE_2D || IsCubemapTextureTarget(target));
}
+void Texture::TextureColorbufferProxy::addRef() const
+{
+ mTexture->addRef();
+}
+
+void Texture::TextureColorbufferProxy::release() const
+{
+ mTexture->release();
+}
+
IDirect3DSurface9 *Texture::TextureColorbufferProxy::getRenderTarget()
{
if (mRenderTarget) mRenderTarget->Release();
@@ -1484,14 +1799,19 @@ IDirect3DSurface9 *Texture::TextureColorbufferProxy::getRenderTarget()
return mRenderTarget;
}
-int Texture::TextureColorbufferProxy::getWidth()
+int Texture::TextureColorbufferProxy::getWidth() const
{
return mTexture->getWidth();
}
-int Texture::TextureColorbufferProxy::getHeight()
+int Texture::TextureColorbufferProxy::getHeight() const
{
return mTexture->getHeight();
}
+GLenum Texture::TextureColorbufferProxy::getFormat() const
+{
+ return mTexture->getFormat();
+}
+
}
diff --git a/ANGLE/src/libGLESv2/Texture.h b/ANGLE/src/libGLESv2/Texture.h
index 40fa11d..efa882c 100644
--- a/ANGLE/src/libGLESv2/Texture.h
+++ b/ANGLE/src/libGLESv2/Texture.h
@@ -23,7 +23,6 @@
namespace gl
{
-class Context;
class Blit;
enum
@@ -34,10 +33,10 @@ enum
MAX_TEXTURE_LEVELS = 12 // 1+log2 of MAX_TEXTURE_SIZE
};
-class Texture
+class Texture : public RefCountObject
{
public:
- explicit Texture(Context *context);
+ explicit Texture(GLuint id);
virtual ~Texture();
@@ -56,15 +55,19 @@ class Texture
GLuint getWidth() const;
GLuint getHeight() const;
+ virtual GLenum getFormat() const = 0;
virtual bool isComplete() const = 0;
+ virtual bool isCompressed() const = 0;
IDirect3DBaseTexture9 *getTexture();
- virtual Colorbuffer *getColorbuffer(GLenum target) = 0;
+ virtual Renderbuffer *getColorbuffer(GLenum target) = 0;
virtual void generateMipmaps() = 0;
bool isDirty() const;
+ static const GLuint INCOMPLETE_TEXTURE_ID = static_cast<GLuint>(-1); // Every texture takes an id at creation time. The value is arbitrary because it is never registered with the resource manager.
+
protected:
class TextureColorbufferProxy;
friend class TextureColorbufferProxy;
@@ -74,10 +77,14 @@ class Texture
TextureColorbufferProxy(Texture *texture, GLenum target);
// target is a 2D-like texture target (GL_TEXTURE_2D or one of the cube face targets)
+ virtual void addRef() const;
+ virtual void release() const;
+
virtual IDirect3DSurface9 *getRenderTarget();
- virtual int getWidth();
- virtual int getHeight();
+ virtual int getWidth() const;
+ virtual int getHeight() const;
+ virtual GLenum getFormat() const;
private:
Texture *mTexture;
@@ -102,13 +109,10 @@ class Texture
static D3DFORMAT selectFormat(GLenum format);
int imagePitch(const Image& img) const;
- GLenum mMinFilter;
- GLenum mMagFilter;
- GLenum mWrapS;
- GLenum mWrapT;
-
void setImage(GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *img);
- void subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *img);
+ bool subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *img);
+ void setCompressedImage(GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels, Image *img);
+ bool subImageCompressed(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels, Image *img);
void needRenderTarget();
@@ -128,45 +132,72 @@ class Texture
Blit *getBlitter();
+ int levelCount() const;
+
unsigned int mWidth;
unsigned int mHeight;
-
- int levelCount() const;
+ GLenum mMinFilter;
+ GLenum mMagFilter;
+ GLenum mWrapS;
+ GLenum mWrapT;
private:
DISALLOW_COPY_AND_ASSIGN(Texture);
- Context *mContext;
+ void loadImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type,
+ GLint unpackAlignment, const void *input, std::size_t outputPitch, void *output) const;
+
+ void loadAlphaImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
+ void loadLuminanceImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
+ void loadLuminanceAlphaImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
+ void loadRGBUByteImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
+ void loadRGB565ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
+ void loadRGBAUByteImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
+ void loadRGBA4444ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
+ void loadRGBA5551ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
+ void loadBGRAImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
+ size_t inputPitch, const void *input, size_t outputPitch, void *output) const;
IDirect3DBaseTexture9 *mBaseTexture; // This is a weak pointer. The derived class is assumed to own a strong pointer.
- bool mDirtyMetaData;
- bool mIsRenderable;
bool mDirty;
+ bool mDirtyMetaData;
+ bool mIsRenderable;
- void loadImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type,
- GLint unpackAlignment, const void *input, std::size_t outputPitch, void *output) const;
+ void createSurface(GLsizei width, GLsizei height, GLenum format, Image *img);
};
class Texture2D : public Texture
{
public:
- explicit Texture2D(Context *context);
+ explicit Texture2D(GLuint id);
~Texture2D();
GLenum getTarget() const;
+ GLenum getFormat() const;
void setImage(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
+ void setCompressedImage(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels);
void subImage(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
- void copyImage(GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, Renderbuffer *source);
- void copySubImage(GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Renderbuffer *source);
+ void subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels);
+ void copyImage(GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source);
+ void copySubImage(GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source);
bool isComplete() const;
+ bool isCompressed() const;
virtual void generateMipmaps();
- virtual Colorbuffer *getColorbuffer(GLenum target);
+ virtual Renderbuffer *getColorbuffer(GLenum target);
private:
DISALLOW_COPY_AND_ASSIGN(Texture2D);
@@ -174,30 +205,29 @@ class Texture2D : public Texture
virtual IDirect3DBaseTexture9 *createTexture();
virtual void updateTexture();
virtual IDirect3DBaseTexture9 *convertToRenderTarget();
+ virtual IDirect3DSurface9 *getRenderTarget(GLenum target);
virtual bool dirtyImageData() const;
+ bool redefineTexture(GLint level, GLenum internalFormat, GLsizei width, GLsizei height);
void commitRect(GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
Image mImageArray[MAX_TEXTURE_LEVELS];
IDirect3DTexture9 *mTexture;
- TextureColorbufferProxy *mColorbufferProxy;
-
- bool redefineTexture(GLint level, GLenum internalFormat, GLsizei width, GLsizei height);
-
- virtual IDirect3DSurface9 *getRenderTarget(GLenum target);
+ Renderbuffer *mColorbufferProxy;
};
class TextureCubeMap : public Texture
{
public:
- explicit TextureCubeMap(Context *context);
+ explicit TextureCubeMap(GLuint id);
~TextureCubeMap();
GLenum getTarget() const;
+ GLenum getFormat() const;
void setImagePosX(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
void setImageNegX(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
@@ -206,15 +236,19 @@ class TextureCubeMap : public Texture
void setImagePosZ(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
void setImageNegZ(GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
+ void setCompressedImage(GLenum face, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels);
+
void subImage(GLenum face, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels);
- void copyImage(GLenum face, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, Renderbuffer *source);
- void copySubImage(GLenum face, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Renderbuffer *source);
+ void subImageCompressed(GLenum face, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels);
+ void copyImage(GLenum face, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source);
+ void copySubImage(GLenum face, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, RenderbufferStorage *source);
bool isComplete() const;
+ bool isCompressed() const;
virtual void generateMipmaps();
- virtual Colorbuffer *getColorbuffer(GLenum target);
+ virtual Renderbuffer *getColorbuffer(GLenum target);
private:
DISALLOW_COPY_AND_ASSIGN(TextureCubeMap);
@@ -222,6 +256,7 @@ class TextureCubeMap : public Texture
virtual IDirect3DBaseTexture9 *createTexture();
virtual void updateTexture();
virtual IDirect3DBaseTexture9 *convertToRenderTarget();
+ virtual IDirect3DSurface9 *getRenderTarget(GLenum target);
virtual bool dirtyImageData() const;
@@ -241,9 +276,7 @@ class TextureCubeMap : public Texture
IDirect3DCubeTexture9 *mTexture;
- TextureColorbufferProxy *mFaceProxies[6];
-
- virtual IDirect3DSurface9 *getRenderTarget(GLenum target);
+ Renderbuffer *mFaceProxies[6];
};
}
diff --git a/ANGLE/src/libGLESv2/libGLESv2.cpp b/ANGLE/src/libGLESv2/libGLESv2.cpp
index a136bd3..25d083b 100644
--- a/ANGLE/src/libGLESv2/libGLESv2.cpp
+++ b/ANGLE/src/libGLESv2/libGLESv2.cpp
@@ -180,7 +180,7 @@ void __stdcall glBindFramebuffer(GLenum target, GLuint framebuffer)
try
{
- if (target != GL_FRAMEBUFFER)
+ if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
{
return error(GL_INVALID_ENUM);
}
@@ -189,7 +189,15 @@ void __stdcall glBindFramebuffer(GLenum target, GLuint framebuffer)
if (context)
{
- context->bindFramebuffer(framebuffer);
+ if (target == GL_READ_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)
+ {
+ context->bindReadFramebuffer(framebuffer);
+ }
+
+ if (target == GL_DRAW_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)
+ {
+ context->bindDrawFramebuffer(framebuffer);
+ }
}
}
catch(std::bad_alloc&)
@@ -559,7 +567,7 @@ GLenum __stdcall glCheckFramebufferStatus(GLenum target)
try
{
- if (target != GL_FRAMEBUFFER)
+ if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
{
return error(GL_INVALID_ENUM, 0);
}
@@ -568,7 +576,15 @@ GLenum __stdcall glCheckFramebufferStatus(GLenum target)
if (context)
{
- gl::Framebuffer *framebuffer = context->getFramebuffer();
+ gl::Framebuffer *framebuffer = NULL;
+ if (target == GL_READ_FRAMEBUFFER_ANGLE)
+ {
+ framebuffer = context->getReadFramebuffer();
+ }
+ else
+ {
+ framebuffer = context->getDrawFramebuffer();
+ }
return framebuffer->completeness();
}
@@ -720,22 +736,107 @@ void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum interna
try
{
- if (!gl::IsTextureTarget(target))
+ if (level < 0 || level > gl::MAX_TEXTURE_LEVELS)
{
- return error(GL_INVALID_ENUM);
+ return error(GL_INVALID_VALUE);
}
- if (level < 0 || level > gl::MAX_TEXTURE_LEVELS)
+ if (width < 0 || height < 0 || (level > 0 && !gl::isPow2(width)) || (level > 0 && !gl::isPow2(height)) || border != 0 || imageSize < 0)
{
return error(GL_INVALID_VALUE);
}
- if (width < 0 || height < 0 || (level > 0 && !gl::isPow2(width)) || (level > 0 && !gl::isPow2(height)) || border != 0 || imageSize < 0)
+ switch (target)
+ {
+ case GL_TEXTURE_2D:
+ if (width > (gl::MAX_TEXTURE_SIZE >> level) || height > (gl::MAX_TEXTURE_SIZE >> level))
+ {
+ return error(GL_INVALID_VALUE);
+ }
+ break;
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+ if (width != height)
+ {
+ return error(GL_INVALID_VALUE);
+ }
+
+ if (width > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level) || height > (gl::MAX_CUBE_MAP_TEXTURE_SIZE >> level))
+ {
+ return error(GL_INVALID_VALUE);
+ }
+ break;
+ default:
+ return error(GL_INVALID_ENUM);
+ }
+
+ switch (internalformat)
+ {
+ case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ break;
+ default:
+ return error(GL_INVALID_ENUM);
+ }
+
+ if (border != 0)
{
return error(GL_INVALID_VALUE);
}
- return error(GL_INVALID_ENUM); // ultimately we don't support compressed textures
+ gl::Context *context = gl::getContext();
+
+ if (context)
+ {
+ if (!context->supportsCompressedTextures())
+ {
+ return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
+ }
+
+ if (imageSize != gl::ComputeCompressedSize(width, height, internalformat))
+ {
+ return error(GL_INVALID_VALUE);
+ }
+
+ if (target == GL_TEXTURE_2D)
+ {
+ gl::Texture2D *texture = context->getTexture2D();
+
+ if (!texture)
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
+ texture->setCompressedImage(level, internalformat, width, height, imageSize, data);
+ }
+ else
+ {
+ gl::TextureCubeMap *texture = context->getTextureCubeMap();
+
+ if (!texture)
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
+ switch (target)
+ {
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+ texture->setCompressedImage(target, level, internalformat, width, height, imageSize, data);
+ break;
+ default: UNREACHABLE();
+ }
+ }
+ }
+
}
catch(std::bad_alloc&)
{
@@ -763,17 +864,95 @@ void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffs
return error(GL_INVALID_VALUE);
}
- if (xoffset < 0 || yoffset < 0 || width < 0 || height < 0 || (level > 0 && !gl::isPow2(width)) || (level > 0 && !gl::isPow2(height)) || imageSize < 0)
+ if (xoffset < 0 || yoffset < 0 || width < 0 || height < 0 ||
+ (level > 0 && !gl::isPow2(width)) || (level > 0 && !gl::isPow2(height)) || imageSize < 0)
{
return error(GL_INVALID_VALUE);
}
- if (xoffset != 0 || yoffset != 0)
+ switch (format)
{
- return error(GL_INVALID_OPERATION);
+ case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ break;
+ default:
+ return error(GL_INVALID_ENUM);
+ }
+
+ if (width == 0 || height == 0 || data == NULL)
+ {
+ return;
}
- return error(GL_INVALID_OPERATION); // The texture being operated on is not a compressed texture.
+ gl::Context *context = gl::getContext();
+
+ if (context)
+ {
+ if (!context->supportsCompressedTextures())
+ {
+ return error(GL_INVALID_ENUM); // in this case, it's as though the format switch has failed.
+ }
+
+ if (imageSize != gl::ComputeCompressedSize(width, height, format))
+ {
+ return error(GL_INVALID_VALUE);
+ }
+
+ if (xoffset % 4 != 0 || yoffset % 4 != 0)
+ {
+ return error(GL_INVALID_OPERATION); // we wait to check the offsets until this point, because the multiple-of-four restriction
+ // does not exist unless DXT1 textures are supported.
+ }
+
+ if (target == GL_TEXTURE_2D)
+ {
+ gl::Texture2D *texture = context->getTexture2D();
+
+ if (!texture)
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
+ if (!texture->isCompressed())
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
+ if ((width % 4 != 0 && width != texture->getWidth()) ||
+ (height % 4 != 0 && height != texture->getHeight()))
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
+ texture->subImageCompressed(level, xoffset, yoffset, width, height, format, imageSize, data);
+ }
+ else if (gl::IsCubemapTextureTarget(target))
+ {
+ gl::TextureCubeMap *texture = context->getTextureCubeMap();
+
+ if (!texture)
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
+ if (!texture->isCompressed())
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
+ if ((width % 4 != 0 && width != texture->getWidth()) ||
+ (height % 4 != 0 && height != texture->getHeight()))
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
+ texture->subImageCompressed(target, level, xoffset, yoffset, width, height, format, imageSize, data);
+ }
+ else
+ {
+ UNREACHABLE();
+ }
+ }
}
catch(std::bad_alloc&)
{
@@ -834,6 +1013,8 @@ void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalforma
case GL_LUMINANCE_ALPHA:
case GL_RGB:
case GL_RGBA:
+ case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // Compressed textures are not supported here, but if they are unsupported altogether,
+ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: // a different error is generated than otherwise. That is handled below.
break;
default:
return error(GL_INVALID_VALUE);
@@ -848,8 +1029,31 @@ void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalforma
if (context)
{
- gl::Renderbuffer *source = context->getFramebuffer()->getColorbuffer();
+ if (internalformat == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
+ internalformat == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)
+ {
+ if (context->supportsCompressedTextures())
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+ else
+ {
+ return error(GL_INVALID_ENUM);
+ }
+ }
+
+ gl::Framebuffer *framebuffer = context->getReadFramebuffer();
+ if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
+ {
+ return error(GL_INVALID_FRAMEBUFFER_OPERATION);
+ }
+ if (context->getReadFramebufferHandle() != 0 && framebuffer->getColorbuffer()->getSamples() != 0)
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
+ gl::Colorbuffer *source = framebuffer->getColorbuffer();
if (target == GL_TEXTURE_2D)
{
gl::Texture2D *texture = context->getTexture2D();
@@ -858,6 +1062,11 @@ void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalforma
{
return error(GL_INVALID_OPERATION);
}
+
+ if (texture->isCompressed())
+ {
+ return error(GL_INVALID_OPERATION);
+ }
texture->copyImage(level, internalformat, x, y, width, height, source);
}
@@ -870,6 +1079,11 @@ void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalforma
return error(GL_INVALID_OPERATION);
}
+ if (texture->isCompressed())
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
texture->copyImage(target, level, internalformat, x, y, width, height, source);
}
else
@@ -916,8 +1130,18 @@ void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GL
if (context)
{
- gl::Renderbuffer *source = context->getFramebuffer()->getColorbuffer();
+ gl::Framebuffer *framebuffer = context->getReadFramebuffer();
+ if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
+ {
+ return error(GL_INVALID_FRAMEBUFFER_OPERATION);
+ }
+
+ if (context->getReadFramebufferHandle() != 0 && framebuffer->getColorbuffer()->getSamples() != 0)
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+ gl::Colorbuffer *source = framebuffer->getColorbuffer();
if (target == GL_TEXTURE_2D)
{
gl::Texture2D *texture = context->getTexture2D();
@@ -927,6 +1151,11 @@ void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GL
return error(GL_INVALID_OPERATION);
}
+ if (texture->isCompressed())
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
texture->copySubImage(level, xoffset, yoffset, x, y, width, height, source);
}
else if (gl::IsCubemapTextureTarget(target))
@@ -938,6 +1167,11 @@ void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GL
return error(GL_INVALID_OPERATION);
}
+ if (texture->isCompressed())
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
texture->copySubImage(target, level, xoffset, yoffset, x, y, width, height, source);
}
else
@@ -1559,7 +1793,8 @@ void __stdcall glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenu
try
{
- if (target != GL_FRAMEBUFFER || renderbuffertarget != GL_RENDERBUFFER)
+ if ((target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
+ || renderbuffertarget != GL_RENDERBUFFER)
{
return error(GL_INVALID_ENUM);
}
@@ -1568,9 +1803,20 @@ void __stdcall glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenu
if (context)
{
- gl::Framebuffer *framebuffer = context->getFramebuffer();
+ gl::Framebuffer *framebuffer = NULL;
+ GLuint framebufferHandle = 0;
+ if (target == GL_READ_FRAMEBUFFER_ANGLE)
+ {
+ framebuffer = context->getReadFramebuffer();
+ framebufferHandle = context->getReadFramebufferHandle();
+ }
+ else
+ {
+ framebuffer = context->getDrawFramebuffer();
+ framebufferHandle = context->getDrawFramebufferHandle();
+ }
- if (context->getFramebufferHandle() == 0 || !framebuffer)
+ if (framebufferHandle == 0 || !framebuffer)
{
return error(GL_INVALID_OPERATION);
}
@@ -1604,7 +1850,7 @@ void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum t
try
{
- if (target != GL_FRAMEBUFFER)
+ if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
{
return error(GL_INVALID_ENUM);
}
@@ -1636,6 +1882,11 @@ void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum t
return error(GL_INVALID_OPERATION);
}
+ if (tex->isCompressed())
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
switch (textarget)
{
case GL_TEXTURE_2D:
@@ -1667,9 +1918,20 @@ void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum t
}
}
- gl::Framebuffer *framebuffer = context->getFramebuffer();
+ gl::Framebuffer *framebuffer = NULL;
+ GLuint framebufferHandle = 0;
+ if (target == GL_READ_FRAMEBUFFER_ANGLE)
+ {
+ framebuffer = context->getReadFramebuffer();
+ framebufferHandle = context->getReadFramebufferHandle();
+ }
+ else
+ {
+ framebuffer = context->getDrawFramebuffer();
+ framebufferHandle = context->getDrawFramebufferHandle();
+ }
- if (context->getFramebufferHandle() == 0 || !framebuffer)
+ if (framebufferHandle == 0 || !framebuffer)
{
return error(GL_INVALID_OPERATION);
}
@@ -1770,6 +2032,11 @@ void __stdcall glGenerateMipmap(GLenum target)
return error(GL_INVALID_ENUM);
}
+ if (texture->isCompressed())
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
texture->generateMipmaps();
}
}
@@ -2225,14 +2492,29 @@ void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attac
if (context)
{
- if (context->getFramebufferHandle() == 0)
+ if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
{
- return error(GL_INVALID_OPERATION);
+ return error(GL_INVALID_ENUM);
}
- if (target != GL_FRAMEBUFFER)
+ gl::Framebuffer *framebuffer = NULL;
+ if (target == GL_READ_FRAMEBUFFER_ANGLE)
{
- return error(GL_INVALID_ENUM);
+ if(context->getReadFramebufferHandle() == 0)
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
+ framebuffer = context->getReadFramebuffer();
+ }
+ else
+ {
+ if (context->getDrawFramebufferHandle() == 0)
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
+ framebuffer = context->getDrawFramebuffer();
}
GLenum attachmentType;
@@ -2240,16 +2522,16 @@ void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attac
switch (attachment)
{
case GL_COLOR_ATTACHMENT0:
- attachmentType = context->getFramebuffer()->getColorbufferType();
- attachmentHandle = context->getFramebuffer()->getColorbufferHandle();
+ attachmentType = framebuffer->getColorbufferType();
+ attachmentHandle = framebuffer->getColorbufferHandle();
break;
case GL_DEPTH_ATTACHMENT:
- attachmentType = context->getFramebuffer()->getDepthbufferType();
- attachmentHandle = context->getFramebuffer()->getDepthbufferHandle();
+ attachmentType = framebuffer->getDepthbufferType();
+ attachmentHandle = framebuffer->getDepthbufferHandle();
break;
case GL_STENCIL_ATTACHMENT:
- attachmentType = context->getFramebuffer()->getStencilbufferType();
- attachmentHandle = context->getFramebuffer()->getStencilbufferHandle();
+ attachmentType = framebuffer->getStencilbufferType();
+ attachmentHandle = framebuffer->getStencilbufferHandle();
break;
default: return error(GL_INVALID_ENUM);
}
@@ -2508,7 +2790,7 @@ void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint*
case GL_RENDERBUFFER_RED_SIZE:
if (renderbuffer->isColorbuffer())
{
- *params = static_cast<gl::Colorbuffer*>(renderbuffer)->getRedSize();
+ *params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getRedSize();
}
else
{
@@ -2518,7 +2800,7 @@ void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint*
case GL_RENDERBUFFER_GREEN_SIZE:
if (renderbuffer->isColorbuffer())
{
- *params = static_cast<gl::Colorbuffer*>(renderbuffer)->getGreenSize();
+ *params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getGreenSize();
}
else
{
@@ -2528,7 +2810,7 @@ void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint*
case GL_RENDERBUFFER_BLUE_SIZE:
if (renderbuffer->isColorbuffer())
{
- *params = static_cast<gl::Colorbuffer*>(renderbuffer)->getBlueSize();
+ *params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getBlueSize();
}
else
{
@@ -2538,7 +2820,7 @@ void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint*
case GL_RENDERBUFFER_ALPHA_SIZE:
if (renderbuffer->isColorbuffer())
{
- *params = static_cast<gl::Colorbuffer*>(renderbuffer)->getAlphaSize();
+ *params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getAlphaSize();
}
else
{
@@ -2548,7 +2830,7 @@ void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint*
case GL_RENDERBUFFER_DEPTH_SIZE:
if (renderbuffer->isDepthbuffer())
{
- *params = static_cast<gl::Depthbuffer*>(renderbuffer)->getDepthSize();
+ *params = static_cast<gl::Depthbuffer*>(renderbuffer->getStorage())->getDepthSize();
}
else
{
@@ -2558,13 +2840,25 @@ void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint*
case GL_RENDERBUFFER_STENCIL_SIZE:
if (renderbuffer->isStencilbuffer())
{
- *params = static_cast<gl::Stencilbuffer*>(renderbuffer)->getStencilSize();
+ *params = static_cast<gl::Stencilbuffer*>(renderbuffer->getStorage())->getStencilSize();
}
else
{
*params = 0;
}
break;
+ case GL_RENDERBUFFER_SAMPLES_ANGLE:
+ {
+ if (context->getMaxSupportedSamples() != 0)
+ {
+ *params = renderbuffer->getStorage()->getSamples();
+ }
+ else
+ {
+ return error(GL_INVALID_ENUM);
+ }
+ }
+ break;
default:
return error(GL_INVALID_ENUM);
}
@@ -2993,7 +3287,7 @@ void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
return error(GL_INVALID_VALUE);
}
- gl::AttributeState attribState = context->getVertexAttribState(index);
+ const gl::AttributeState &attribState = context->getVertexAttribState(index);
switch (pname)
{
@@ -3013,7 +3307,7 @@ void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
*params = (GLfloat)(attribState.mNormalized ? GL_TRUE : GL_FALSE);
break;
case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
- *params = (GLfloat)attribState.mBoundBuffer;
+ *params = (GLfloat)attribState.mBoundBuffer.id();
break;
case GL_CURRENT_VERTEX_ATTRIB:
for (int i = 0; i < 4; ++i)
@@ -3046,7 +3340,7 @@ void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
return error(GL_INVALID_VALUE);
}
- gl::AttributeState attribState = context->getVertexAttribState(index);
+ const gl::AttributeState &attribState = context->getVertexAttribState(index);
switch (pname)
{
@@ -3066,7 +3360,7 @@ void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
*params = (attribState.mNormalized ? GL_TRUE : GL_FALSE);
break;
case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
- *params = attribState.mBoundBuffer;
+ *params = attribState.mBoundBuffer.id();
break;
case GL_CURRENT_VERTEX_ATTRIB:
for (int i = 0; i < 4; ++i)
@@ -3481,6 +3775,17 @@ void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLe
return error(GL_INVALID_OPERATION);
}
break;
+ case GL_BGRA_EXT:
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
+ case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
+ break;
+ default:
+ return error(GL_INVALID_OPERATION);
+ }
+ break;
case gl::IMPLEMENTATION_COLOR_READ_FORMAT:
switch (type)
{
@@ -3521,10 +3826,10 @@ void __stdcall glReleaseShaderCompiler(void)
}
}
-void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
+void __stdcall glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
{
- TRACE("(GLenum target = 0x%X, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
- target, internalformat, width, height);
+ TRACE("(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
+ target, samples, internalformat, width, height);
try
{
@@ -3543,12 +3848,15 @@ void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsiz
case GL_RGB5_A1:
case GL_RGB565:
case GL_STENCIL_INDEX8:
+ case GL_DEPTH24_STENCIL8_OES:
+ case GL_RGB8_OES:
+ case GL_RGBA8_OES:
break;
default:
return error(GL_INVALID_ENUM);
}
- if (width < 0 || height < 0 || width > gl::MAX_RENDERBUFFER_SIZE || height > gl::MAX_RENDERBUFFER_SIZE)
+ if (width < 0 || height < 0 || width > gl::MAX_RENDERBUFFER_SIZE || height > gl::MAX_RENDERBUFFER_SIZE || samples < 0)
{
return error(GL_INVALID_VALUE);
}
@@ -3557,7 +3865,13 @@ void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsiz
if (context)
{
- if (context->getRenderbufferHandle() == 0)
+ if (samples > context->getMaxSupportedSamples())
+ {
+ return error(GL_INVALID_VALUE);
+ }
+
+ GLuint handle = context->getRenderbufferHandle();
+ if (handle == 0)
{
return error(GL_INVALID_OPERATION);
}
@@ -3565,15 +3879,20 @@ void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsiz
switch (internalformat)
{
case GL_DEPTH_COMPONENT16:
- context->setRenderbuffer(new gl::Depthbuffer(width, height));
+ context->setRenderbufferStorage(new gl::Depthbuffer(width, height, samples));
break;
case GL_RGBA4:
case GL_RGB5_A1:
case GL_RGB565:
- context->setRenderbuffer(new gl::Colorbuffer(width, height, internalformat));
+ case GL_RGB8_OES:
+ case GL_RGBA8_OES:
+ context->setRenderbufferStorage(new gl::Colorbuffer(width, height, internalformat, samples));
break;
case GL_STENCIL_INDEX8:
- context->setRenderbuffer(new gl::Stencilbuffer(width, height));
+ context->setRenderbufferStorage(new gl::Stencilbuffer(width, height, samples));
+ break;
+ case GL_DEPTH24_STENCIL8_OES:
+ context->setRenderbufferStorage(new gl::DepthStencilbuffer(width, height, samples));
break;
default:
return error(GL_INVALID_ENUM);
@@ -3586,6 +3905,11 @@ void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsiz
}
}
+void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
+{
+ glRenderbufferStorageMultisampleANGLE(target, 0, internalformat, width, height);
+}
+
void __stdcall glSampleCoverage(GLclampf value, GLboolean invert)
{
TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
@@ -3958,6 +4282,18 @@ void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GL
return error(GL_INVALID_ENUM);
}
break;
+ case GL_BGRA_EXT:
+ switch (type)
+ {
+ case GL_UNSIGNED_BYTE:
+ break;
+ default:
+ return error(GL_INVALID_ENUM);
+ }
+ break;
+ case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: // error cases for compressed textures are handled below
+ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ break;
default:
return error(GL_INVALID_VALUE);
}
@@ -3971,6 +4307,19 @@ void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GL
if (context)
{
+ if (internalformat == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
+ internalformat == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)
+ {
+ if (context->supportsCompressedTextures())
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+ else
+ {
+ return error(GL_INVALID_ENUM);
+ }
+ }
+
if (target == GL_TEXTURE_2D)
{
gl::Texture2D *texture = context->getTexture2D();
@@ -4146,6 +4495,11 @@ void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint
return error(GL_INVALID_OPERATION);
}
+ if (texture->isCompressed())
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
}
else if (gl::IsCubemapTextureTarget(target))
@@ -4157,6 +4511,11 @@ void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint
return error(GL_INVALID_OPERATION);
}
+ if (texture->isCompressed())
+ {
+ return error(GL_INVALID_OPERATION);
+ }
+
texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
}
else
@@ -4965,7 +5324,7 @@ void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLbo
if (context)
{
- context->setVertexAttribState(index, context->getArrayBufferHandle(), size, type, (normalized == GL_TRUE), stride, ptr);
+ context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);
}
}
catch(std::bad_alloc&)
@@ -4998,6 +5357,54 @@ void __stdcall glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
}
}
+void __stdcall glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
+ GLbitfield mask, GLenum filter)
+{
+ TRACE("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, "
+ "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, "
+ "GLbitfield mask = 0x%X, GLenum filter = 0x%X)",
+ srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter);
+
+ try
+ {
+ switch (filter)
+ {
+ case GL_NEAREST:
+ break;
+ default:
+ return error(GL_INVALID_ENUM);
+ }
+
+ if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)
+ {
+ return error(GL_INVALID_VALUE);
+ }
+
+ if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
+ {
+ ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation");
+ return error(GL_INVALID_OPERATION);
+ }
+
+ gl::Context *context = gl::getContext();
+
+ if (context)
+ {
+ if (context->getReadFramebufferHandle() == context->getDrawFramebufferHandle())
+ {
+ ERR("Blits with the same source and destination framebuffer are not supported by this implementation.");
+ return error(GL_INVALID_OPERATION);
+ }
+
+ context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask);
+ }
+ }
+ catch(std::bad_alloc&)
+ {
+ return error(GL_OUT_OF_MEMORY);
+ }
+}
+
void __stdcall glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
GLint border, GLenum format, GLenum type, const GLvoid* pixels)
{
@@ -5027,6 +5434,7 @@ __eglMustCastToProperFunctionPointerType __stdcall glGetProcAddress(const char *
static const Extension glExtensions[] =
{
{"glTexImage3DOES", (__eglMustCastToProperFunctionPointerType)glTexImage3DOES},
+ {"glBlitFramebufferANGLE", (__eglMustCastToProperFunctionPointerType)glBlitFramebufferANGLE},
};
for (int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++)
diff --git a/ANGLE/src/libGLESv2/libGLESv2.def b/ANGLE/src/libGLESv2/libGLESv2.def
index 0aaaa67..a043ed8 100644
--- a/ANGLE/src/libGLESv2/libGLESv2.def
+++ b/ANGLE/src/libGLESv2/libGLESv2.def
@@ -144,11 +144,13 @@ EXPORTS
glViewport @142
; Extensions
- glTexImage3DOES @143
+ glTexImage3DOES @143
+ glBlitFramebufferANGLE @149
+ glRenderbufferStorageMultisampleANGLE @150
; EGL dependencies
- glCreateContext @144 NONAME
- glDestroyContext @145 NONAME
- glMakeCurrent @146 NONAME
- glGetCurrentContext @147 NONAME
+ glCreateContext @144 NONAME
+ glDestroyContext @145 NONAME
+ glMakeCurrent @146 NONAME
+ glGetCurrentContext @147 NONAME
glGetProcAddress @148 NONAME \ No newline at end of file
diff --git a/ANGLE/src/libGLESv2/libGLESv2.vcproj b/ANGLE/src/libGLESv2/libGLESv2.vcproj
index e994e05..f9e34d0 100644
--- a/ANGLE/src/libGLESv2/libGLESv2.vcproj
+++ b/ANGLE/src/libGLESv2/libGLESv2.vcproj
@@ -217,10 +217,18 @@
>
</File>
<File
+ RelativePath=".\RefCountObject.cpp"
+ >
+ </File>
+ <File
RelativePath=".\Renderbuffer.cpp"
>
</File>
<File
+ RelativePath=".\ResourceManager.cpp"
+ >
+ </File>
+ <File
RelativePath=".\Shader.cpp"
>
</File>
@@ -299,10 +307,18 @@
>
</File>
<File
+ RelativePath=".\RefCountObject.h"
+ >
+ </File>
+ <File
RelativePath=".\Renderbuffer.h"
>
</File>
<File
+ RelativePath=".\ResourceManager.h"
+ >
+ </File>
+ <File
RelativePath=".\Shader.h"
>
</File>
diff --git a/ANGLE/src/libGLESv2/main.h b/ANGLE/src/libGLESv2/main.h
index dec112a..7f9c880 100644
--- a/ANGLE/src/libGLESv2/main.h
+++ b/ANGLE/src/libGLESv2/main.h
@@ -11,6 +11,7 @@
#define GL_APICALL
#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
#include "common/debug.h"
#include "libEGL/Display.h"
diff --git a/ANGLE/src/libGLESv2/utilities.cpp b/ANGLE/src/libGLESv2/utilities.cpp
index f584588..7fc2bc4 100644
--- a/ANGLE/src/libGLESv2/utilities.cpp
+++ b/ANGLE/src/libGLESv2/utilities.cpp
@@ -183,6 +183,49 @@ GLsizei ComputePitch(GLsizei width, GLenum format, GLenum type, GLint alignment)
return (rawPitch + alignment - 1) & ~(alignment - 1);
}
+GLsizei ComputeCompressedPitch(GLsizei width, GLenum format)
+{
+ switch (format)
+ {
+ case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ break;
+ default:
+ return 0;
+ }
+
+ ASSERT(width % 4 == 0);
+
+ return 8 * width / 4;
+}
+
+GLsizei ComputeCompressedSize(GLsizei width, GLsizei height, GLenum format)
+{
+ switch (format)
+ {
+ case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ break;
+ default:
+ return 0;
+ }
+
+ return 8 * (GLsizei)ceil((float)width / 4.0f) * (GLsizei)ceil((float)height / 4.0f);
+}
+
+bool IsCompressed(GLenum format)
+{
+ if(format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
+ format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
// Returns the size, in bytes, of a single texel in an Image
int ComputePixelSize(GLenum format, GLenum type)
{
@@ -196,6 +239,7 @@ int ComputePixelSize(GLenum format, GLenum type)
case GL_LUMINANCE_ALPHA: return sizeof(unsigned char) * 2;
case GL_RGB: return sizeof(unsigned char) * 3;
case GL_RGBA: return sizeof(unsigned char) * 4;
+ case GL_BGRA_EXT: return sizeof(unsigned char) * 4;
default: UNREACHABLE();
}
break;
@@ -228,6 +272,7 @@ bool CheckTextureFormatType(GLenum format, GLenum type)
switch (format)
{
case GL_RGBA:
+ case GL_BGRA_EXT:
case GL_RGB:
case GL_ALPHA:
case GL_LUMINANCE:
@@ -599,12 +644,31 @@ D3DFORMAT ConvertRenderbufferFormat(GLenum format)
switch (format)
{
case GL_RGBA4:
- case GL_RGB5_A1: return D3DFMT_A8R8G8B8;
+ case GL_RGB5_A1:
+ case GL_RGBA8_OES: return D3DFMT_A8R8G8B8;
case GL_RGB565: return D3DFMT_R5G6B5;
+ case GL_RGB8_OES: return D3DFMT_X8R8G8B8;
case GL_DEPTH_COMPONENT16:
- case GL_STENCIL_INDEX8: return D3DFMT_D24S8;
+ case GL_STENCIL_INDEX8:
+ case GL_DEPTH24_STENCIL8_OES: return D3DFMT_D24S8;
default: UNREACHABLE(); return D3DFMT_A8R8G8B8;
}
}
+GLsizei GetSamplesFromMultisampleType(D3DMULTISAMPLE_TYPE type)
+{
+ if (type == D3DMULTISAMPLE_NONMASKABLE)
+ return 0;
+ else
+ return type;
+}
+
+D3DMULTISAMPLE_TYPE GetMultisampleTypeFromSamples(GLsizei samples)
+{
+ if (samples <= 1)
+ return D3DMULTISAMPLE_NONE;
+ else
+ return (D3DMULTISAMPLE_TYPE)samples;
+}
+
}
diff --git a/ANGLE/src/libGLESv2/utilities.h b/ANGLE/src/libGLESv2/utilities.h
index 6e6c140..b6c8ce5 100644
--- a/ANGLE/src/libGLESv2/utilities.h
+++ b/ANGLE/src/libGLESv2/utilities.h
@@ -11,6 +11,7 @@
#define GL_APICALL
#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
#include <d3d9.h>
namespace gl
@@ -28,6 +29,9 @@ int AllocateFirstFreeBits(unsigned int *bits, unsigned int allocationSize, unsig
int ComputePixelSize(GLenum format, GLenum type);
GLsizei ComputePitch(GLsizei width, GLenum format, GLenum type, GLint alignment);
+GLsizei ComputeCompressedPitch(GLsizei width, GLenum format);
+GLsizei ComputeCompressedSize(GLsizei width, GLsizei height, GLenum format);
+bool IsCompressed(GLenum format);
bool IsCubemapTextureTarget(GLenum target);
bool IsTextureTarget(GLenum target);
bool CheckTextureFormatType(GLenum format, GLenum type);
@@ -56,6 +60,8 @@ unsigned int GetStencilSize(D3DFORMAT stencilFormat);
bool ConvertPrimitiveType(GLenum primitiveType, GLsizei primitiveCount,
D3DPRIMITIVETYPE *d3dPrimitiveType, int *d3dPrimitiveCount);
D3DFORMAT ConvertRenderbufferFormat(GLenum format);
+D3DMULTISAMPLE_TYPE GetMultisampleTypeFromSamples(GLsizei samples);
+GLsizei GetSamplesFromMultisampleType(D3DMULTISAMPLE_TYPE type);
}