From 4fd74ca8444da6491d5ec5f5e2b569c09cba2b3a Mon Sep 17 00:00:00 2001 From: assiduous Date: Mon, 23 Dec 2019 21:24:13 -0800 Subject: Disabled SetRenderTarget(0, nullptr, nullptr) usage (fixed https://github.com/DiligentGraphics/DiligentCore/issues/81) --- .../GraphicsEngine/include/DeviceContextBase.h | 144 ++++++++------------- Graphics/GraphicsEngine/include/SwapChainBase.h | 42 ------ Graphics/GraphicsEngine/interface/APIInfo.h | 2 +- Graphics/GraphicsEngine/interface/DeviceContext.h | 26 +--- Graphics/GraphicsEngine/interface/GraphicsTypes.h | 6 +- 5 files changed, 56 insertions(+), 164 deletions(-) (limited to 'Graphics/GraphicsEngine') diff --git a/Graphics/GraphicsEngine/include/DeviceContextBase.h b/Graphics/GraphicsEngine/include/DeviceContextBase.h index a9bba8bd..dee85899 100644 --- a/Graphics/GraphicsEngine/include/DeviceContextBase.h +++ b/Graphics/GraphicsEngine/include/DeviceContextBase.h @@ -30,12 +30,10 @@ #include "DeviceContext.h" #include "DeviceObjectBase.h" -#include "Defines.h" #include "ResourceMapping.h" #include "Sampler.h" #include "ObjectBase.h" #include "DebugUtilities.h" -#include "SwapChain.h" #include "ValidatedCast.h" #include "GraphicsAccessories.h" #include "TextureBase.h" @@ -165,19 +163,10 @@ public: virtual void GenerateMips(ITextureView* pTexView) override = 0; - /// Sets the strong pointer to the swap chain - virtual void SetSwapChain(ISwapChain* pSwapChain) override final { m_pSwapChain = pSwapChain; } - virtual void ResolveTextureSubresource(ITexture* pSrcTexture, ITexture* pDstTexture, const ResolveTextureSubresourceAttribs& ResolveAttribs) override = 0; - /// Returns the swap chain - ISwapChain* GetSwapChain() { return m_pSwapChain; } - - /// Returns true if currently bound frame buffer is the default frame buffer - inline bool IsDefaultFBBound() { return m_IsDefaultFramebufferBound; } - /// Returns currently bound pipeline state and blend factors inline void GetPipelineState(IPipelineState** ppPSO, float* BlendFactors, Uint32& StencilRef); @@ -194,6 +183,10 @@ public: bool IsDeferred() const { return m_bIsDeferred; } + /// Checks if a texture is bound as a render target or depth-stencil buffer and + /// resets render targets if it is. + bool UnbindTextureFromFramebuffer(TextureImplType* pTexture, bool bShowMessage); + protected: inline bool SetBlendFactors(const float* BlendFactors, int Dummy); @@ -210,10 +203,6 @@ protected: /// Checks if the texture is currently bound as depth-stencil buffer. bool CheckIfBoundAsDepthStencil(TextureImplType* pTexture); - /// Checks if the texture is bound as a render target or depth-stencil buffer and - /// resets render targets if it is. - bool UnbindTextureFromFramebuffer(TextureImplType* pTexture, bool bShowMessage); - #ifdef DEVELOPMENT // clang-format off @@ -248,10 +237,6 @@ protected: /// Strong reference to the device. RefCntAutoPtr m_pDevice; - /// Strong reference to the swap chain. Swap chain holds - /// weak reference to the immediate context. - RefCntAutoPtr m_pSwapChain; - /// Vertex streams. Every stream holds strong reference to the buffer VertexStreamInfo m_VertexStreams[MaxBufferSlots]; @@ -298,9 +283,6 @@ protected: Uint32 m_FramebufferHeight = 0; /// Number of array slices in the currently bound framebuffer Uint32 m_FramebufferSlices = 0; - /// Flag indicating if default render target & depth-stencil - /// buffer are currently bound - bool m_IsDefaultFramebufferBound = false; /// Strong references to the bound depth stencil view. /// Use final texture view implementation type to avoid virtual calls to AddRef()/Release() @@ -411,7 +393,6 @@ template inline void DeviceContextBase::InvalidateState() { DeviceContextBase::ClearStateCache(); - m_IsDefaultFramebufferBound = false; } template @@ -541,33 +522,17 @@ template inline bool DeviceContextBase:: SetRenderTargets(Uint32 NumRenderTargets, ITextureView* ppRenderTargets[], ITextureView* pDepthStencil) { + if (NumRenderTargets == 0 && pDepthStencil == nullptr) + { + ResetRenderTargets(); + return false; + } + bool bBindRenderTargets = false; m_FramebufferWidth = 0; m_FramebufferHeight = 0; m_FramebufferSlices = 0; - ITextureView* pDefaultRTV = nullptr; - bool IsDefaultFrambuffer = NumRenderTargets == 0 && pDepthStencil == nullptr; - bBindRenderTargets = (m_IsDefaultFramebufferBound != IsDefaultFrambuffer); - m_IsDefaultFramebufferBound = IsDefaultFrambuffer; - if (m_IsDefaultFramebufferBound) - { - VERIFY(m_pSwapChain, "Swap chain is not initialized in the device context"); - - pDefaultRTV = m_pSwapChain->GetCurrentBackBufferRTV(); - pDepthStencil = m_pSwapChain->GetDepthBufferDSV(); - if (pDefaultRTV != nullptr) - { - NumRenderTargets = 1; - ppRenderTargets = &pDefaultRTV; - } - - const auto& SwapChainDesc = m_pSwapChain->GetDesc(); - m_FramebufferWidth = SwapChainDesc.Width; - m_FramebufferHeight = SwapChainDesc.Height; - m_FramebufferSlices = 1; - } - if (NumRenderTargets != m_NumBoundRenderTargets) { bBindRenderTargets = true; @@ -764,29 +729,42 @@ bool DeviceContextBase::UnbindTextureFromFr if (pTexture == nullptr) return false; - if (pTexture->IsInKnownState() && !pTexture->CheckState(RESOURCE_STATE_RENDER_TARGET) && !pTexture->CheckState(RESOURCE_STATE_DEPTH_WRITE)) - return false; + const auto& TexDesc = pTexture->GetDesc(); bool bResetRenderTargets = false; - if (CheckIfBoundAsRenderTarget(pTexture)) + if (TexDesc.BindFlags & BIND_RENDER_TARGET) { - if (bShowMessage) + if (CheckIfBoundAsRenderTarget(pTexture)) { - LOG_INFO_MESSAGE("Texture '", pTexture->GetDesc().Name, - "' is currently bound as render target and will be unset along with all " - "other render targets and depth-stencil buffer. " - "Call SetRenderTargets() to reset the render targets."); - } + if (bShowMessage) + { + LOG_INFO_MESSAGE("Texture '", TexDesc.Name, + "' is currently bound as render target and will be unset along with all " + "other render targets and depth-stencil buffer. " + "Call SetRenderTargets() to reset the render targets.\n" + "To silence this message, explicitly unbind the texture with " + "SetRenderTargets(0, nullptr, nullptr, RESOURCE_STATE_TRANSITION_MODE_NONE)"); + } - bResetRenderTargets = true; + bResetRenderTargets = true; + } } - else if (CheckIfBoundAsDepthStencil(pTexture)) + + if (TexDesc.BindFlags & BIND_DEPTH_STENCIL) { - LOG_INFO_MESSAGE("Texture '", pTexture->GetDesc().Name, - "' is currently bound as depth buffer and will be unset along with " - "all render targets. Call SetRenderTargets() to reset the render targets."); + if (CheckIfBoundAsDepthStencil(pTexture)) + { + if (bShowMessage) + { + LOG_INFO_MESSAGE("Texture '", TexDesc.Name, + "' is currently bound as depth buffer and will be unset along with " + "all render targets. Call SetRenderTargets() to reset the render targets.\n" + "To silence this message, explicitly unbind the texture with " + "SetRenderTargets(0, nullptr, nullptr, RESOURCE_STATE_TRANSITION_MODE_NONE)"); + } - bResetRenderTargets = true; + bResetRenderTargets = true; + } } if (bResetRenderTargets) @@ -808,11 +786,10 @@ void DeviceContextBase::ResetRenderTargets( VERIFY(m_pBoundRenderTargets[rt] == nullptr, "Non-null render target found"); } #endif - m_NumBoundRenderTargets = 0; - m_FramebufferWidth = 0; - m_FramebufferHeight = 0; - m_FramebufferSlices = 0; - m_IsDefaultFramebufferBound = false; + m_NumBoundRenderTargets = 0; + m_FramebufferWidth = 0; + m_FramebufferHeight = 0; + m_FramebufferSlices = 0; m_pBoundDepthStencil.Release(); } @@ -1188,41 +1165,22 @@ inline void DeviceContextBase:: TEXTURE_FORMAT BoundRTVFormats[8] = {TEX_FORMAT_UNKNOWN}; TEXTURE_FORMAT BoundDSVFormat = TEX_FORMAT_UNKNOWN; - Uint32 NumBoundRTVs = 0; - if (m_IsDefaultFramebufferBound) + + for (Uint32 rt = 0; rt < m_NumBoundRenderTargets; ++rt) { - if (m_pSwapChain) - { - BoundRTVFormats[0] = m_pSwapChain->GetDesc().ColorBufferFormat; - BoundDSVFormat = m_pSwapChain->GetDesc().DepthBufferFormat; - NumBoundRTVs = 1; - } + if (auto* pRT = m_pBoundRenderTargets[rt].RawPtr()) + BoundRTVFormats[rt] = pRT->GetDesc().Format; else - { - LOG_WARNING_MESSAGE("Failed to get bound render targets and depth-stencil buffer: " - "swap chain is not initialized in the device context"); - return; - } + BoundRTVFormats[rt] = TEX_FORMAT_UNKNOWN; } - else - { - NumBoundRTVs = m_NumBoundRenderTargets; - for (Uint32 rt = 0; rt < NumBoundRTVs; ++rt) - { - if (auto* pRT = m_pBoundRenderTargets[rt].RawPtr()) - BoundRTVFormats[rt] = pRT->GetDesc().Format; - else - BoundRTVFormats[rt] = TEX_FORMAT_UNKNOWN; - } - BoundDSVFormat = m_pBoundDepthStencil ? m_pBoundDepthStencil->GetDesc().Format : TEX_FORMAT_UNKNOWN; - } + BoundDSVFormat = m_pBoundDepthStencil ? m_pBoundDepthStencil->GetDesc().Format : TEX_FORMAT_UNKNOWN; const auto& PSODesc = m_pPipelineState->GetDesc(); const auto& GraphicsPipeline = PSODesc.GraphicsPipeline; - if (GraphicsPipeline.NumRenderTargets != NumBoundRTVs) + if (GraphicsPipeline.NumRenderTargets != m_NumBoundRenderTargets) { - LOG_WARNING_MESSAGE("Number of currently bound render targets (", NumBoundRTVs, + LOG_WARNING_MESSAGE("Number of currently bound render targets (", m_NumBoundRenderTargets, ") does not match the number of outputs specified by the PSO '", PSODesc.Name, "' (", Uint32{GraphicsPipeline.NumRenderTargets}, ")."); } @@ -1234,7 +1192,7 @@ inline void DeviceContextBase:: "' (", GetTextureFormatAttribs(GraphicsPipeline.DSVFormat).Name, ")."); } - for (Uint32 rt = 0; rt < NumBoundRTVs; ++rt) + for (Uint32 rt = 0; rt < m_NumBoundRenderTargets; ++rt) { auto BoundFmt = BoundRTVFormats[rt]; auto PSOFmt = GraphicsPipeline.RTVFormats[rt]; diff --git a/Graphics/GraphicsEngine/include/SwapChainBase.h b/Graphics/GraphicsEngine/include/SwapChainBase.h index 46766e65..1a4558f7 100644 --- a/Graphics/GraphicsEngine/include/SwapChainBase.h +++ b/Graphics/GraphicsEngine/include/SwapChainBase.h @@ -101,48 +101,6 @@ protected: return false; } - template - bool UnbindRenderTargets(DeviceContextImplType* pImmediateCtx, - ITextureView* ppBackBufferRTVs[], - Uint32 NumBackBufferRTVs, - ITextureView* pDSV) - { - bool RebindRenderTargets = false; - bool UnbindRenderTargets = false; - if (m_SwapChainDesc.IsPrimary) - { - RebindRenderTargets = UnbindRenderTargets = pImmediateCtx->IsDefaultFBBound(); - } - else - { - std::array pBoundRTVs = {}; - RefCntAutoPtr pBoundDSV; - Uint32 NumRenderTargets = 0; - pImmediateCtx->GetRenderTargets(NumRenderTargets, pBoundRTVs.data(), &pBoundDSV); - for (Uint32 i = 0; i < NumRenderTargets; ++i) - { - for (Uint32 j = 0; j < NumBackBufferRTVs; ++j) - { - if (pBoundRTVs[i] == ppBackBufferRTVs[j]) - UnbindRenderTargets = true; - } - } - if (pBoundDSV == pDSV) - UnbindRenderTargets = true; - - for (auto pRTV : pBoundRTVs) - { - if (pRTV != nullptr) - pRTV->Release(); - } - } - - if (UnbindRenderTargets) - pImmediateCtx->ResetRenderTargets(); - - return RebindRenderTargets; - } - /// Strong reference to the render device RefCntAutoPtr m_pRenderDevice; diff --git a/Graphics/GraphicsEngine/interface/APIInfo.h b/Graphics/GraphicsEngine/interface/APIInfo.h index 4f75eaaa..6fe95f42 100644 --- a/Graphics/GraphicsEngine/interface/APIInfo.h +++ b/Graphics/GraphicsEngine/interface/APIInfo.h @@ -26,7 +26,7 @@ /// \file /// Diligent API information -#define DILIGENT_API_VERSION 240045 +#define DILIGENT_API_VERSION 240046 #include "../../../Primitives/interface/BasicTypes.h" diff --git a/Graphics/GraphicsEngine/interface/DeviceContext.h b/Graphics/GraphicsEngine/interface/DeviceContext.h index 098b7402..9a9b9396 100644 --- a/Graphics/GraphicsEngine/interface/DeviceContext.h +++ b/Graphics/GraphicsEngine/interface/DeviceContext.h @@ -773,7 +773,7 @@ public: virtual void SetScissorRects(Uint32 NumRects, const Rect* pRects, Uint32 RTWidth, Uint32 RTHeight) = 0; - /// Binds one or more render targets and the depth-stencil buffer to the pipeline. It also + /// Binds one or more render targets and the depth-stencil buffer to the context. It also /// sets the viewport to match the first non-null render target or depth-stencil buffer. /// \param [in] NumRenderTargets - Number of render targets to bind. @@ -789,10 +789,6 @@ public: /// and depth-stencil views. Thus these views (and consequently referenced textures) /// cannot be released until they are unbound from the context.\n /// Any render targets not defined by this call are set to nullptr.\n\n - /// You can set the default render target and depth stencil using the - /// following call: - /// - /// pContext->SetRenderTargets(0, nullptr, nullptr); /// /// \remarks When StateTransitionMode is Diligent::RESOURCE_STATE_TRANSITION_MODE_TRANSITION, the method will /// transition all render targets in known states to Diligent::RESOURCE_STATE_REDER_TARGET, @@ -1129,25 +1125,7 @@ public: /// The texture must be created with MISC_TEXTURE_FLAG_GENERATE_MIPS flag. virtual void GenerateMips(ITextureView* pTextureView) = 0; - - /// Sets the swap chain in the device context. - - /// The swap chain is used by the device context to work with the - /// default framebuffer. Specifically, if the swap chain is set in the context, - /// the following commands can be used: - /// * SetRenderTargets(0, nullptr, nullptr) - to bind the default back buffer & depth buffer - /// * SetViewports(1, nullptr, 0, 0) - to set the viewport to match the size of the back buffer - /// * ClearRenderTarget(nullptr, color) - to clear the default back buffer - /// * ClearDepthStencil(nullptr, ...) - to clear the default depth buffer - /// The swap chain is automatically initialized for immediate and all deferred contexts - /// by factory functions EngineFactoryD3D11Impl::CreateSwapChainD3D11(), - /// EngineFactoryD3D12Impl::CreateSwapChainD3D12(), and EngineFactoryOpenGLImpl::CreateDeviceAndSwapChainGL(). - /// However, when the engine is initialized by attaching to existing d3d11/d3d12 device or OpenGL/GLES context, the - /// swap chain needs to be set manually if the device context will be using any of the commands above.\n - /// Device context keeps strong reference to the swap chain. - virtual void SetSwapChain(ISwapChain* pSwapChain) = 0; - - + /// Finishes the current frame and releases dynamic resources allocated by the context. /// For immediate context, this method is called automatically by ISwapChain::Present() of the primary diff --git a/Graphics/GraphicsEngine/interface/GraphicsTypes.h b/Graphics/GraphicsEngine/interface/GraphicsTypes.h index 6bff6a93..9dd2dd8c 100644 --- a/Graphics/GraphicsEngine/interface/GraphicsTypes.h +++ b/Graphics/GraphicsEngine/interface/GraphicsTypes.h @@ -1236,10 +1236,8 @@ namespace Diligent /// Default stencil value, which is used as optimized stencil clear value in D3D12 Uint8 DefaultStencilValue = 0; - /// Indicates if this is a primary swap chain. The back buffer and depth-stencil - /// buffer of the primary swap are set by SetRenderTargets(0, nullptr, nullptr) - /// call. Also, when Present() is called for the primary swap chain, the engine - /// releases stale resources. There must only be one primary swap chain. + /// Indicates if this is a primary swap chain. When Present() is called + /// for the primary swap chain, the engine releases stale resources. bool IsPrimary = true; SwapChainDesc()noexcept{} -- cgit v1.2.3