diff options
author | Iain Merrick <husky@google.com> | 2010-09-13 16:35:48 +0100 |
---|---|---|
committer | Iain Merrick <husky@google.com> | 2010-09-16 12:10:42 +0100 |
commit | 5abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306 (patch) | |
tree | ddce1aa5e3b6967a69691892e500897558ff8ab6 /ANGLE | |
parent | 12bec63ec71e46baba27f0bd9bd9d8067683690a (diff) | |
download | external_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')
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, ¤tDisplayMode); - - 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, ¤tDisplayMode); + + 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, ¤tDisplayMode); + + 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); } |