diff options
| author | Egor Yusov <egor.yusov@gmail.com> | 2019-11-10 20:00:34 +0000 |
|---|---|---|
| committer | Egor Yusov <egor.yusov@gmail.com> | 2019-11-10 20:00:34 +0000 |
| commit | 99454f9aff426d652b4a166894b72d7b706f4287 (patch) | |
| tree | 6c588236cf41e15850ccd1e3a91535991ba86255 /Graphics/GraphicsEngineOpenGL | |
| parent | Fixed release build error (diff) | |
| download | DiligentCore-99454f9aff426d652b4a166894b72d7b706f4287.tar.gz DiligentCore-99454f9aff426d652b4a166894b72d7b706f4287.zip | |
Implemented ResolveTextureSubresource in GL backend (fixed https://github.com/DiligentGraphics/DiligentCore/issues/108)
Diffstat (limited to 'Graphics/GraphicsEngineOpenGL')
14 files changed, 261 insertions, 79 deletions
diff --git a/Graphics/GraphicsEngineOpenGL/include/FBOCache.h b/Graphics/GraphicsEngineOpenGL/include/FBOCache.h index ee5f416c..ddedcccc 100644 --- a/Graphics/GraphicsEngineOpenGL/include/FBOCache.h +++ b/Graphics/GraphicsEngineOpenGL/include/FBOCache.h @@ -32,6 +32,8 @@ namespace Diligent { +class TextureViewGLImpl; + class FBOCache { public: @@ -44,8 +46,8 @@ public: FBOCache& operator = ( FBOCache&&) = delete; const GLObjectWrappers::GLFrameBufferObj& GetFBO(Uint32 NumRenderTargets, - ITextureView* ppRenderTargets[], - ITextureView* pDepthStencil, + TextureViewGLImpl* ppRTVs[], + TextureViewGLImpl* pDSV, class GLContextState& ContextState); void OnReleaseTexture(ITexture* pTexture); @@ -55,28 +57,19 @@ private: { // Using pointers is not reliable! - Uint32 NumRenderTargets; + Uint32 NumRenderTargets = 0; // Unique IDs of textures bound as render targets - Diligent::UniqueIdentifier RTIds[MaxRenderTargets]; - TextureViewDesc RTVDescs[MaxRenderTargets]; + UniqueIdentifier RTIds [MaxRenderTargets] = {}; + TextureViewDesc RTVDescs[MaxRenderTargets]; // Unique IDs of texture bound as depth stencil - Diligent::UniqueIdentifier DSId; - TextureViewDesc DSVDesc; + UniqueIdentifier DSId = 0; + TextureViewDesc DSVDesc = {}; - mutable size_t Hash; + mutable size_t Hash = 0; bool operator == (const FBOCacheKey &Key)const; - - FBOCacheKey() : - NumRenderTargets( 0 ), - DSId(0), - Hash(0) - { - for( int rt = 0; rt < MaxRenderTargets; ++rt ) - RTIds[rt] = 0; - } }; struct FBOCacheKeyHashFunc diff --git a/Graphics/GraphicsEngineOpenGL/include/GLContextState.h b/Graphics/GraphicsEngineOpenGL/include/GLContextState.h index 6d5b2b90..a11a2efa 100644 --- a/Graphics/GraphicsEngineOpenGL/include/GLContextState.h +++ b/Graphics/GraphicsEngineOpenGL/include/GLContextState.h @@ -84,6 +84,11 @@ public: // Resetting VAO after that with BindVAO(GLVertexArrayObj::Null()) will still have the effect because // null VAO's ID is 0, not -1. } + + void InvalidateFBO() + { + m_FBOId = -1; + } bool IsValidVAOBound()const {return m_VAOId > 0;} void SetCurrentGLContext(GLContext::NativeGLContextType Context) { m_CurrentGLContext = Context; } diff --git a/Graphics/GraphicsEngineOpenGL/include/RenderDeviceGLImpl.h b/Graphics/GraphicsEngineOpenGL/include/RenderDeviceGLImpl.h index 234a1c73..c9c232f8 100644 --- a/Graphics/GraphicsEngineOpenGL/include/RenderDeviceGLImpl.h +++ b/Graphics/GraphicsEngineOpenGL/include/RenderDeviceGLImpl.h @@ -107,6 +107,8 @@ public: void OnDestroyPSO(IPipelineState* pPSO); void OnDestroyBuffer(IBuffer* pBuffer); + void CreateDummyTexture(const TextureDesc& TexDesc, RESOURCE_STATE InitialState, class TextureBaseGL** ppTexture); + size_t GetCommandQueueCount()const { return 1; } Uint64 GetCommandQueueMask()const { return Uint64{1};} diff --git a/Graphics/GraphicsEngineOpenGL/include/SwapChainGLImpl.h b/Graphics/GraphicsEngineOpenGL/include/SwapChainGLImpl.h index 0479e43b..f84a8f47 100644 --- a/Graphics/GraphicsEngineOpenGL/include/SwapChainGLImpl.h +++ b/Graphics/GraphicsEngineOpenGL/include/SwapChainGLImpl.h @@ -63,10 +63,16 @@ public: virtual GLuint GetDefaultFBO()const override final{ return 0; } /// Implementation of ISwapChain::GetCurrentBackBufferRTV() in OpenGL backend. - virtual ITextureView* GetCurrentBackBufferRTV()override final{return nullptr;} + virtual ITextureView* GetCurrentBackBufferRTV()override final{return m_pRenderTargetView;} /// Implementation of ISwapChain::GetDepthBufferDSV() in OpenGL backend. - virtual ITextureView* GetDepthBufferDSV()override final{return nullptr;} + virtual ITextureView* GetDepthBufferDSV()override final{return m_pDepthStencilView;} + +private: + void CreateDummyBuffers(RenderDeviceGLImpl* pRenderDeviceGL); + + RefCntAutoPtr<TextureViewGLImpl> m_pRenderTargetView; + RefCntAutoPtr<TextureViewGLImpl> m_pDepthStencilView; }; } diff --git a/Graphics/GraphicsEngineOpenGL/include/Texture2D_OGL.h b/Graphics/GraphicsEngineOpenGL/include/Texture2D_OGL.h index c74446c2..b554fca9 100644 --- a/Graphics/GraphicsEngineOpenGL/include/Texture2D_OGL.h +++ b/Graphics/GraphicsEngineOpenGL/include/Texture2D_OGL.h @@ -47,6 +47,14 @@ public: const TextureDesc& TexDesc, GLuint GLTextureHandle, bool bIsDeviceInternal = false); + + /// This constructor is used to create a dummy texture object for the default framebuffer. + Texture2D_OGL(IReferenceCounters* pRefCounters, + FixedBlockMemoryAllocator& TexViewObjAllocator, + class RenderDeviceGLImpl* pDeviceGL, + const TextureDesc& TexDesc, + bool bIsDeviceInternal = false); + ~Texture2D_OGL(); /// Implementation of TextureBaseGL::UpdateData() for 2D texture. diff --git a/Graphics/GraphicsEngineOpenGL/include/TextureBaseGL.h b/Graphics/GraphicsEngineOpenGL/include/TextureBaseGL.h index 7d7215ee..59fb23f9 100644 --- a/Graphics/GraphicsEngineOpenGL/include/TextureBaseGL.h +++ b/Graphics/GraphicsEngineOpenGL/include/TextureBaseGL.h @@ -61,6 +61,14 @@ public: GLenum BindTarget, bool bIsDeviceInternal); + /// Initializes a dummy texture (dummy textures are used by the swap chain to + /// proxy default framebuffer). + TextureBaseGL(IReferenceCounters* pRefCounters, + FixedBlockMemoryAllocator& TexViewObjAllocator, + RenderDeviceGLImpl* pDeviceGL, + const TextureDesc& TexDesc, + bool bIsDeviceInternal); + ~TextureBaseGL(); virtual void QueryInterface( const INTERFACE_ID& IID, IObject** ppInterface )override; diff --git a/Graphics/GraphicsEngineOpenGL/include/TextureViewGLImpl.h b/Graphics/GraphicsEngineOpenGL/include/TextureViewGLImpl.h index c60c00c7..e98fae4e 100644 --- a/Graphics/GraphicsEngineOpenGL/include/TextureViewGLImpl.h +++ b/Graphics/GraphicsEngineOpenGL/include/TextureViewGLImpl.h @@ -46,7 +46,7 @@ public: const struct TextureViewDesc& ViewDesc, class TextureBaseGL* pTexture, bool bCreateGLViewTex, - bool bIsDefaultView ); + bool bIsDefaultView); ~TextureViewGLImpl(); virtual void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface )override final; diff --git a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp index 9358ad1e..898f0fb1 100644 --- a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp @@ -329,7 +329,7 @@ namespace Diligent VERIFY(NumRenderTargets < static_cast<Uint32>(CtxCaps.m_iMaxDrawBuffers), "This device only supports ", CtxCaps.m_iMaxDrawBuffers, " draw buffers, but ", NumRenderTargets, " are being set"); NumRenderTargets = std::min(NumRenderTargets, static_cast<Uint32>(CtxCaps.m_iMaxDrawBuffers)); - ITextureView* pBoundRTVs[MaxRenderTargets] = {}; + TextureViewGLImpl* pBoundRTVs[MaxRenderTargets] = {}; for (Uint32 rt = 0; rt < NumRenderTargets; ++rt) pBoundRTVs[rt] = m_pBoundRenderTargets[rt]; @@ -1138,6 +1138,74 @@ namespace Diligent const ResolveTextureSubresourceAttribs& ResolveAttribs) { TDeviceContextBase::ResolveTextureSubresource(pSrcTexture, pDstTexture, ResolveAttribs); + auto* pSrcTexGl = ValidatedCast<TextureBaseGL>(pSrcTexture); + auto* pDstTexGl = ValidatedCast<TextureBaseGL>(pDstTexture); + const auto& SrcTexDesc = pSrcTexGl->GetDesc(); + //const auto& DstTexDesc = pDstTexGl->GetDesc(); + auto CurrentNativeGLContext = m_ContextState.GetCurrentGLContext(); + auto& FBOCache = m_pDevice->GetFBOCache(CurrentNativeGLContext); + + { + TextureViewDesc SrcTexViewDesc; + SrcTexViewDesc.ViewType = TEXTURE_VIEW_RENDER_TARGET; + SrcTexViewDesc.MostDetailedMip = ResolveAttribs.SrcMipLevel; + SrcTexViewDesc.FirstArraySlice = ResolveAttribs.SrcSlice; + TextureViewGLImpl SrcTexView + { + nullptr, // pRefCounters + m_pDevice, + SrcTexViewDesc, + pSrcTexGl, + false, // bCreateGLViewTex + false // bIsDefaultView + }; + + TextureViewGLImpl* pSrcViews[] = {&SrcTexView}; + const auto& SrcFBO = FBOCache.GetFBO(1, pSrcViews, nullptr, m_ContextState); + glBindFramebuffer(GL_READ_FRAMEBUFFER, SrcFBO); + DEV_CHECK_GL_ERROR("Failed to bind FBO as read framebuffer"); + } + + if (pDstTexGl->GetGLHandle()) + { + TextureViewDesc DstTexViewDesc; + DstTexViewDesc.ViewType = TEXTURE_VIEW_RENDER_TARGET; + DstTexViewDesc.MostDetailedMip = ResolveAttribs.DstMipLevel; + DstTexViewDesc.FirstArraySlice = ResolveAttribs.DstSlice; + TextureViewGLImpl DstTexView + { + nullptr, // pRefCounters + m_pDevice, + DstTexViewDesc, + pDstTexGl, + false, // bCreateGLViewTex + false // bIsDefaultView + }; + + TextureViewGLImpl* pDstViews[] = {&DstTexView}; + const auto& DstFBO = FBOCache.GetFBO(1, pDstViews, nullptr, m_ContextState); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, DstFBO); + DEV_CHECK_GL_ERROR("Failed to bind FBO as draw framebuffer"); + } + else + { + auto* pSwapChainGL = m_pSwapChain.RawPtr<ISwapChainGL>(); + GLuint DefaultFBOHandle = pSwapChainGL->GetDefaultFBO(); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, DefaultFBOHandle); + DEV_CHECK_GL_ERROR("Failed to bind default FBO as draw framebuffer"); + } + + const auto& MipAttribs = GetMipLevelProperties(SrcTexDesc, ResolveAttribs.SrcMipLevel); + glBlitFramebuffer(0, 0, static_cast<GLint>(MipAttribs.LogicalWidth), static_cast<GLint>(MipAttribs.LogicalHeight), + 0, 0, static_cast<GLint>(MipAttribs.LogicalWidth), static_cast<GLint>(MipAttribs.LogicalHeight), + GL_COLOR_BUFFER_BIT, + GL_NEAREST // Filter is ignored + ); + DEV_CHECK_GL_ERROR("glBlitFramebuffer() failed when resolving multi-sampled texture"); + + // Restore original FBO + m_ContextState.InvalidateFBO(); + CommitRenderTargets(); } } diff --git a/Graphics/GraphicsEngineOpenGL/src/FBOCache.cpp b/Graphics/GraphicsEngineOpenGL/src/FBOCache.cpp index 65cf6cd4..4d4eb55a 100644 --- a/Graphics/GraphicsEngineOpenGL/src/FBOCache.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/FBOCache.cpp @@ -104,94 +104,86 @@ void FBOCache::OnReleaseTexture(ITexture *pTexture) m_TexIdToKey.erase(EqualRange.first, EqualRange.second); } -const GLObjectWrappers::GLFrameBufferObj& FBOCache::GetFBO( Uint32 NumRenderTargets, - ITextureView *ppRenderTargets[], - ITextureView *pDepthStencil, - GLContextState &ContextState ) +const GLObjectWrappers::GLFrameBufferObj& FBOCache::GetFBO(Uint32 NumRenderTargets, + TextureViewGLImpl* ppRTVs[], + TextureViewGLImpl* pDSV, + GLContextState& ContextState ) { // Pop null render targets from the end of the list - while( NumRenderTargets > 0 && ppRenderTargets[NumRenderTargets - 1] == nullptr ) + while (NumRenderTargets > 0 && ppRTVs[NumRenderTargets - 1] == nullptr) --NumRenderTargets; - VERIFY(NumRenderTargets != 0 || pDepthStencil != nullptr, "At least one render target or a depth-stencil buffer must be provided"); + VERIFY(NumRenderTargets != 0 || pDSV != nullptr, "At least one render target or a depth-stencil buffer must be provided"); // Lock the cache ThreadingTools::LockHelper CacheLock(m_CacheLockFlag); // Construct the key FBOCacheKey Key; - VERIFY( NumRenderTargets < MaxRenderTargets, "Too many render targets being set" ); + VERIFY(NumRenderTargets < MaxRenderTargets, "Too many render targets are being set"); NumRenderTargets = std::min( NumRenderTargets, MaxRenderTargets ); Key.NumRenderTargets = NumRenderTargets; - for( Uint32 rt = 0; rt < NumRenderTargets; ++rt ) + for (Uint32 rt = 0; rt < NumRenderTargets; ++rt) { - auto *pRTView = ppRenderTargets[rt]; - if( !pRTView ) + auto* pRTView = ppRTVs[rt]; + if (pRTView == nullptr) continue; - auto *pTex = pRTView->GetTexture(); - CHECK_DYNAMIC_TYPE( TextureBaseGL, pTex ); - auto *pTexGL = static_cast<TextureBaseGL*>(pTex); - pTexGL->TextureMemoryBarrier( + auto* pColorTexGL = pRTView->GetTexture<TextureBaseGL>(); + pColorTexGL->TextureMemoryBarrier( GL_FRAMEBUFFER_BARRIER_BIT,// Reads and writes via framebuffer object attachments after the // barrier will reflect data written by shaders prior to the barrier. // Additionally, framebuffer writes issued after the barrier will wait // on the completion of all shader writes issued prior to the barrier. ContextState); - Key.RTIds[rt] = pTexGL->GetUniqueID(); + Key.RTIds[rt] = pColorTexGL->GetUniqueID(); Key.RTVDescs[rt] = pRTView->GetDesc(); } - if( pDepthStencil ) + if (pDSV) { - auto *pTex = pDepthStencil->GetTexture(); - CHECK_DYNAMIC_TYPE( TextureBaseGL, pTex ); - auto *pTexGL = static_cast<TextureBaseGL*>(pTex); - pTexGL->TextureMemoryBarrier( GL_FRAMEBUFFER_BARRIER_BIT, ContextState ); - Key.DSId = pTexGL->GetUniqueID(); - Key.DSVDesc = pDepthStencil->GetDesc(); + auto* pDepthTexGL = pDSV->GetTexture<TextureBaseGL>(); + pDepthTexGL->TextureMemoryBarrier(GL_FRAMEBUFFER_BARRIER_BIT, ContextState); + Key.DSId = pDepthTexGL->GetUniqueID(); + Key.DSVDesc = pDSV->GetDesc(); } // Try to find FBO in the map auto It = m_Cache.find(Key); - if( It != m_Cache.end() ) + if (It != m_Cache.end()) { return It->second; } else { - // Create new FBO + // Create a new FBO GLObjectWrappers::GLFrameBufferObj NewFBO(true); ContextState.BindFBO(NewFBO); - // Initialize FBO - for( Uint32 rt = 0; rt < NumRenderTargets; ++rt ) + // Initialize the FBO + for (Uint32 rt = 0; rt < NumRenderTargets; ++rt) { - if( auto *pRTView = ppRenderTargets[rt] ) + if (auto* pRTView = ppRTVs[rt]) { - auto *pTexture = pRTView->GetTexture(); - const auto &ViewDesc = pRTView->GetDesc(); - CHECK_DYNAMIC_TYPE( TextureBaseGL, pTexture ); - auto *pTexGL = static_cast<TextureBaseGL*>(pTexture); - pTexGL->AttachToFramebuffer( ViewDesc, GL_COLOR_ATTACHMENT0 + rt ); + const auto& RTVDesc = pRTView->GetDesc(); + auto* pColorTexGL = pRTView->GetTexture<TextureBaseGL>(); + pColorTexGL->AttachToFramebuffer( RTVDesc, GL_COLOR_ATTACHMENT0 + rt ); } } - if( auto *pDSView = pDepthStencil ) + if (pDSV != nullptr) { - auto *pTexture = pDSView->GetTexture(); - const auto &ViewDesc = pDSView->GetDesc(); - CHECK_DYNAMIC_TYPE( TextureBaseGL, pTexture ); - auto *pTexGL = static_cast<TextureBaseGL*>(pTexture); + const auto& DSVDesc = pDSV->GetDesc(); + auto* pDepthTexGL = pDSV->GetTexture<TextureBaseGL>(); GLenum AttachmentPoint = 0; - if( ViewDesc.Format == TEX_FORMAT_D32_FLOAT || - ViewDesc.Format == TEX_FORMAT_D16_UNORM ) + if (DSVDesc.Format == TEX_FORMAT_D32_FLOAT || + DSVDesc.Format == TEX_FORMAT_D16_UNORM) { #ifdef _DEBUG { - const auto GLTexFmt = pTexGL->GetGLTexFormat(); + const auto GLTexFmt = pDepthTexGL->GetGLTexFormat(); VERIFY( GLTexFmt == GL_DEPTH_COMPONENT32F || GLTexFmt == GL_DEPTH_COMPONENT16, "Inappropriate internal texture format (", GLTexFmt, ") for depth attachment. " "GL_DEPTH_COMPONENT32F or GL_DEPTH_COMPONENT16 is expected"); @@ -199,12 +191,12 @@ const GLObjectWrappers::GLFrameBufferObj& FBOCache::GetFBO( Uint32 NumRenderTarg #endif AttachmentPoint = GL_DEPTH_ATTACHMENT; } - else if( ViewDesc.Format == TEX_FORMAT_D32_FLOAT_S8X24_UINT || - ViewDesc.Format == TEX_FORMAT_D24_UNORM_S8_UINT ) + else if (DSVDesc.Format == TEX_FORMAT_D32_FLOAT_S8X24_UINT || + DSVDesc.Format == TEX_FORMAT_D24_UNORM_S8_UINT) { #ifdef _DEBUG { - const auto GLTexFmt = pTexGL->GetGLTexFormat(); + const auto GLTexFmt = pDepthTexGL->GetGLTexFormat(); VERIFY( GLTexFmt == GL_DEPTH24_STENCIL8 || GLTexFmt == GL_DEPTH32F_STENCIL8, "Inappropriate internal texture format (", GLTexFmt, ") for depth-stencil attachment. " "GL_DEPTH24_STENCIL8 or GL_DEPTH32F_STENCIL8 is expected"); @@ -214,9 +206,9 @@ const GLObjectWrappers::GLFrameBufferObj& FBOCache::GetFBO( Uint32 NumRenderTarg } else { - UNEXPECTED( GetTextureFormatAttribs(ViewDesc.Format).Name, " is not valid depth-stencil view format" ); + UNEXPECTED( GetTextureFormatAttribs(DSVDesc.Format).Name, " is not valid depth-stencil view format" ); } - pTexGL->AttachToFramebuffer( ViewDesc, AttachmentPoint ); + pDepthTexGL->AttachToFramebuffer(DSVDesc, AttachmentPoint); } // We now need to set mapping between shader outputs and @@ -247,9 +239,9 @@ const GLObjectWrappers::GLFrameBufferObj& FBOCache::GetFBO( Uint32 NumRenderTarg CHECK_GL_ERROR( "Failed to set draw buffers via glDrawBuffers()" ); GLenum Status = glCheckFramebufferStatus(GL_FRAMEBUFFER); - if( Status != GL_FRAMEBUFFER_COMPLETE ) + if (Status != GL_FRAMEBUFFER_COMPLETE) { - const Char *StatusString = "Unknown"; + const Char* StatusString = "Unknown"; switch( Status ) { case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: StatusString = "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT"; break; @@ -267,11 +259,11 @@ const GLObjectWrappers::GLFrameBufferObj& FBOCache::GetFBO( Uint32 NumRenderTarg auto NewElems = m_Cache.emplace( std::make_pair(Key, std::move(NewFBO)) ); // New element must be actually inserted VERIFY( NewElems.second, "New element was not inserted" ); - if( Key.DSId ) + if (Key.DSId != 0) m_TexIdToKey.insert( std::make_pair(Key.DSId, Key) ); - for( Uint32 rt = 0; rt < NumRenderTargets; ++rt ) + for (Uint32 rt = 0; rt < NumRenderTargets; ++rt) { - if( Key.RTIds[rt] ) + if (Key.RTIds[rt] != 0) m_TexIdToKey.insert( std::make_pair(Key.RTIds[rt], Key) ); } diff --git a/Graphics/GraphicsEngineOpenGL/src/GLContextState.cpp b/Graphics/GraphicsEngineOpenGL/src/GLContextState.cpp index ee125649..4afc6ea5 100644 --- a/Graphics/GraphicsEngineOpenGL/src/GLContextState.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/GLContextState.cpp @@ -32,7 +32,6 @@ #include "RenderDeviceGLImpl.h" using namespace GLObjectWrappers; -using namespace Diligent; namespace Diligent { diff --git a/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp index b8b28665..c9b5825a 100644 --- a/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/RenderDeviceGLImpl.cpp @@ -301,6 +301,29 @@ void RenderDeviceGLImpl::CreateTextureFromGLHandle(Uint32 GLHandle, const Textur ); } +void RenderDeviceGLImpl :: CreateDummyTexture(const TextureDesc& TexDesc, RESOURCE_STATE InitialState, TextureBaseGL** ppTexture) +{ + CreateDeviceObject( "texture", TexDesc, ppTexture, + [&]() + { + TextureBaseGL* pTextureOGL = nullptr; + switch(TexDesc.Type) + { + case RESOURCE_DIM_TEX_2D: + pTextureOGL = NEW_RC_OBJ(m_TexObjAllocator, "Dummy Texture2D_OGL instance", Texture2D_OGL) + (m_TexViewObjAllocator, this, TexDesc); + break; + + default: LOG_ERROR_AND_THROW( "Unsupported texture type." ); + } + + pTextureOGL->QueryInterface( IID_Texture, reinterpret_cast<IObject**>(ppTexture) ); + pTextureOGL->CreateDefaultViews(); + OnCreateDeviceObject( pTextureOGL ); + } + ); +} + void RenderDeviceGLImpl :: CreateSampler(const SamplerDesc& SamplerDesc, ISampler **ppSampler, bool bIsDeviceInternal) { CreateDeviceObject( "sampler", SamplerDesc, ppSampler, diff --git a/Graphics/GraphicsEngineOpenGL/src/SwapChainGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/SwapChainGLImpl.cpp index d5ad07b9..e227ac3d 100644 --- a/Graphics/GraphicsEngineOpenGL/src/SwapChainGLImpl.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/SwapChainGLImpl.cpp @@ -67,6 +67,30 @@ SwapChainGLImpl::SwapChainGLImpl(IReferenceCounters* pRefCounters, #else # error Unsupported platform #endif + + CreateDummyBuffers(pRenderDeviceGL); +} + +void SwapChainGLImpl::CreateDummyBuffers(RenderDeviceGLImpl* pRenderDeviceGL) +{ + TextureDesc ColorBuffDesc; + ColorBuffDesc.Type = RESOURCE_DIM_TEX_2D; + ColorBuffDesc.Name = "Main color buffer stub"; + ColorBuffDesc.Width = m_SwapChainDesc.Width; + ColorBuffDesc.Height = m_SwapChainDesc.Height; + ColorBuffDesc.Format = m_SwapChainDesc.ColorBufferFormat; + ColorBuffDesc.BindFlags = BIND_RENDER_TARGET; + RefCntAutoPtr<TextureBaseGL> pDummyColorBuffer; + pRenderDeviceGL->CreateDummyTexture(ColorBuffDesc, RESOURCE_STATE_RENDER_TARGET, &pDummyColorBuffer); + m_pRenderTargetView = ValidatedCast<TextureViewGLImpl>(pDummyColorBuffer->GetDefaultView(TEXTURE_VIEW_RENDER_TARGET)); + + TextureDesc DepthBuffDesc = ColorBuffDesc; + DepthBuffDesc.Name = "Main depth buffer stub"; + DepthBuffDesc.Format = m_SwapChainDesc.DepthBufferFormat; + DepthBuffDesc.BindFlags = BIND_DEPTH_STENCIL; + RefCntAutoPtr<TextureBaseGL> pDummyDepthBuffer; + pRenderDeviceGL->CreateDummyTexture(DepthBuffDesc, RESOURCE_STATE_DEPTH_WRITE, &pDummyDepthBuffer); + m_pDepthStencilView = ValidatedCast<TextureViewGLImpl>(pDummyDepthBuffer->GetDefaultView(TEXTURE_VIEW_DEPTH_STENCIL)); } SwapChainGLImpl::~SwapChainGLImpl() @@ -100,6 +124,8 @@ void SwapChainGLImpl::Resize( Uint32 NewWidth, Uint32 NewHeight ) if( TSwapChainBase::Resize( NewWidth, NewHeight ) ) { + CreateDummyBuffers(m_pRenderDevice.RawPtr<RenderDeviceGLImpl>()); + auto pDeviceContext = m_wpDeviceContext.Lock(); VERIFY( pDeviceContext, "Immediate context has been released" ); if( pDeviceContext ) diff --git a/Graphics/GraphicsEngineOpenGL/src/Texture2D_OGL.cpp b/Graphics/GraphicsEngineOpenGL/src/Texture2D_OGL.cpp index ff8ff138..ce2e32a2 100644 --- a/Graphics/GraphicsEngineOpenGL/src/Texture2D_OGL.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/Texture2D_OGL.cpp @@ -122,11 +122,37 @@ Texture2D_OGL::Texture2D_OGL( IReferenceCounters* pRefCounters, const TextureDesc& TexDesc, GLuint GLTextureHandle, bool bIsDeviceInternal) : - TextureBaseGL(pRefCounters, TexViewObjAllocator, pDeviceGL, GLState, TexDesc, GLTextureHandle, - TexDesc.SampleCount > 1 ? GL_TEXTURE_2D_MULTISAMPLE : GL_TEXTURE_2D, bIsDeviceInternal) + TextureBaseGL + { + pRefCounters, + TexViewObjAllocator, + pDeviceGL, + GLState, + TexDesc, + GLTextureHandle, + TexDesc.SampleCount > 1 ? GL_TEXTURE_2D_MULTISAMPLE : GL_TEXTURE_2D, + bIsDeviceInternal + } +{ +} + +Texture2D_OGL::Texture2D_OGL( IReferenceCounters* pRefCounters, + FixedBlockMemoryAllocator& TexViewObjAllocator, + RenderDeviceGLImpl* pDeviceGL, + const TextureDesc& TexDesc, + bool bIsDeviceInternal) : + TextureBaseGL + { + pRefCounters, + TexViewObjAllocator, + pDeviceGL, + TexDesc, + bIsDeviceInternal + } { } + Texture2D_OGL::~Texture2D_OGL() { } diff --git a/Graphics/GraphicsEngineOpenGL/src/TextureBaseGL.cpp b/Graphics/GraphicsEngineOpenGL/src/TextureBaseGL.cpp index d7b0abe2..1803153e 100644 --- a/Graphics/GraphicsEngineOpenGL/src/TextureBaseGL.cpp +++ b/Graphics/GraphicsEngineOpenGL/src/TextureBaseGL.cpp @@ -177,12 +177,38 @@ TextureBaseGL::TextureBaseGL(IReferenceCounters* pRefCounters, const TextureDesc& TexDesc, GLuint GLTextureHandle, GLenum BindTarget, - bool bIsDeviceInternal/* = false*/) : - TTextureBase( pRefCounters, TexViewObjAllocator, pDeviceGL, GetTextureDescFromGLHandle(GLState, TexDesc, GLTextureHandle, BindTarget), bIsDeviceInternal ), + bool bIsDeviceInternal/* = false*/) : + TTextureBase + { + pRefCounters, + TexViewObjAllocator, + pDeviceGL, + GetTextureDescFromGLHandle(GLState, TexDesc, GLTextureHandle, BindTarget), + bIsDeviceInternal + }, // Create texture object wrapper, but use external texture handle - m_GlTexture(true, GLObjectWrappers::GLTextureCreateReleaseHelper(GLTextureHandle)), - m_BindTarget(BindTarget), - m_GLTexFormat( GetTextureInternalFormat(GLState, BindTarget, m_GlTexture, TexDesc.Format) ) + m_GlTexture {true, GLObjectWrappers::GLTextureCreateReleaseHelper(GLTextureHandle)}, + m_BindTarget {BindTarget}, + m_GLTexFormat {GetTextureInternalFormat(GLState, BindTarget, m_GlTexture, TexDesc.Format)} +{ +} + +TextureBaseGL::TextureBaseGL(IReferenceCounters* pRefCounters, + FixedBlockMemoryAllocator& TexViewObjAllocator, + RenderDeviceGLImpl* pDeviceGL, + const TextureDesc& TexDesc, + bool bIsDeviceInternal) : + TTextureBase + { + pRefCounters, + TexViewObjAllocator, + pDeviceGL, + TexDesc, + bIsDeviceInternal + }, + m_GlTexture {false}, + m_BindTarget {0 }, + m_GLTexFormat{0 } { } |
