summaryrefslogtreecommitdiffstats
path: root/Graphics
diff options
context:
space:
mode:
authorassiduous <assiduous@diligentgraphics.com>2019-12-19 18:11:08 +0000
committerassiduous <assiduous@diligentgraphics.com>2019-12-19 18:11:08 +0000
commitc32095993f3e5734b3b6a112aeef0a9536db8f7d (patch)
tree998e0cf73c2417606913152cf53286cc22d4afde /Graphics
parentAdded CopyTexture tests (diff)
downloadDiligentCore-c32095993f3e5734b3b6a112aeef0a9536db8f7d.tar.gz
DiligentCore-c32095993f3e5734b3b6a112aeef0a9536db8f7d.zip
Added ClearRenderTarget test; fixed issue with bound render targets in D3D12 and Vk backends
Diffstat (limited to 'Graphics')
-rw-r--r--Graphics/GraphicsEngine/include/DeviceContextBase.h80
-rwxr-xr-xGraphics/GraphicsEngineD3D11/include/DeviceContextD3D11Impl.h2
-rw-r--r--Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp7
-rw-r--r--Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h3
-rw-r--r--Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp12
5 files changed, 98 insertions, 6 deletions
diff --git a/Graphics/GraphicsEngine/include/DeviceContextBase.h b/Graphics/GraphicsEngine/include/DeviceContextBase.h
index c822dacf..d357c4f6 100644
--- a/Graphics/GraphicsEngine/include/DeviceContextBase.h
+++ b/Graphics/GraphicsEngine/include/DeviceContextBase.h
@@ -190,7 +190,7 @@ public:
/// Returns the render device
IRenderDevice* GetDevice() { return m_pDevice; }
- inline void ResetRenderTargets();
+ virtual void ResetRenderTargets();
bool IsDeferred() const { return m_bIsDeferred; }
@@ -204,6 +204,17 @@ protected:
/// Clears all cached resources
inline void ClearStateCache();
+ /// Checks if the texture is currently bound as a render target.
+ bool CheckIfBoundAsRenderTarget(TextureImplType* pTexture);
+
+ /// 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
bool DvpVerifyDrawArguments (const DrawAttribs& Attribs)const;
@@ -722,7 +733,72 @@ inline void DeviceContextBase<BaseInterface, ImplementationTraits>::ClearStateCa
}
template <typename BaseInterface, typename ImplementationTraits>
-inline void DeviceContextBase<BaseInterface, ImplementationTraits>::ResetRenderTargets()
+bool DeviceContextBase<BaseInterface, ImplementationTraits>::CheckIfBoundAsRenderTarget(TextureImplType* pTexture)
+{
+ if (pTexture == nullptr)
+ return false;
+
+ for (Uint32 rt = 0; rt < m_NumBoundRenderTargets; ++rt)
+ {
+ if (m_pBoundRenderTargets[rt] && m_pBoundRenderTargets[rt]->GetTexture() == pTexture)
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+template <typename BaseInterface, typename ImplementationTraits>
+bool DeviceContextBase<BaseInterface, ImplementationTraits>::CheckIfBoundAsDepthStencil(TextureImplType* pTexture)
+{
+ if (pTexture == nullptr)
+ return false;
+
+ return m_pBoundDepthStencil && m_pBoundDepthStencil->GetTexture() == pTexture;
+}
+
+template <typename BaseInterface, typename ImplementationTraits>
+bool DeviceContextBase<BaseInterface, ImplementationTraits>::UnbindTextureFromFramebuffer(TextureImplType* pTexture, bool bShowMessage)
+{
+ if (pTexture == nullptr)
+ return false;
+
+ if (pTexture->IsInKnownState() && !pTexture->CheckState(RESOURCE_STATE_RENDER_TARGET) && !pTexture->CheckState(RESOURCE_STATE_DEPTH_WRITE))
+ return false;
+
+ bool bResetRenderTargets = false;
+ if (CheckIfBoundAsRenderTarget(pTexture))
+ {
+ if (bShowMessage)
+ {
+ 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.");
+ }
+
+ bResetRenderTargets = true;
+ }
+ else if (CheckIfBoundAsDepthStencil(pTexture))
+ {
+ 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.");
+
+ bResetRenderTargets = true;
+ }
+
+ if (bResetRenderTargets)
+ {
+ ResetRenderTargets();
+ }
+
+ return bResetRenderTargets;
+}
+
+template <typename BaseInterface, typename ImplementationTraits>
+void DeviceContextBase<BaseInterface, ImplementationTraits>::ResetRenderTargets()
{
for (Uint32 rt = 0; rt < m_NumBoundRenderTargets; ++rt)
m_pBoundRenderTargets[rt].Release();
diff --git a/Graphics/GraphicsEngineD3D11/include/DeviceContextD3D11Impl.h b/Graphics/GraphicsEngineD3D11/include/DeviceContextD3D11Impl.h
index d455fc85..1ec8f096 100755
--- a/Graphics/GraphicsEngineD3D11/include/DeviceContextD3D11Impl.h
+++ b/Graphics/GraphicsEngineD3D11/include/DeviceContextD3D11Impl.h
@@ -221,7 +221,7 @@ public:
void ReleaseCommittedShaderResources();
/// Unbinds all render targets. Used when resizing the swap chain.
- void ResetRenderTargets();
+ virtual void ResetRenderTargets() override final;
/// Number of different shader types (Vertex, Pixel, Geometry, Domain, Hull, Compute)
static constexpr int NumShaderTypes = 6;
diff --git a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp
index 5b5b10cb..7812afe0 100644
--- a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp
+++ b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp
@@ -1260,6 +1260,13 @@ void DeviceContextD3D12Impl::CopyTextureRegion(TextureD3D12Impl* pS
Uint32 DstZ,
RESOURCE_STATE_TRANSITION_MODE DstTextureTransitionMode)
{
+ // We must unbind the textures from framebuffer because
+ // we will transition their states. If we later try to commit
+ // them as render targets (e.g. from SetPipelineState()), a
+ // state mismatch error will occur.
+ UnbindTextureFromFramebuffer(pSrcTexture, true);
+ UnbindTextureFromFramebuffer(pDstTexture, true);
+
auto& CmdCtx = GetCmdContext();
if (pSrcTexture->GetDesc().Usage == USAGE_STAGING)
{
diff --git a/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h b/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h
index aa4085f1..7430ee9a 100644
--- a/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h
+++ b/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h
@@ -295,7 +295,8 @@ public:
VulkanDynamicAllocation AllocateDynamicSpace(Uint32 SizeInBytes, Uint32 Alignment);
- void ResetRenderTargets();
+ virtual void ResetRenderTargets() override final;
+
Int64 GetContextFrameNumber() const { return m_ContextFrameNumber; }
GenerateMipsVkHelper& GetGenerateMipsHelper() { return *m_GenerateMipsHelper; }
diff --git a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp
index 135b5844..165f3bdd 100644
--- a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp
@@ -1407,8 +1407,16 @@ void DeviceContextVkImpl::CopyTexture(const CopyTextureAttribs& CopyAttribs)
{
TDeviceContextBase::CopyTexture(CopyAttribs);
- auto* pSrcTexVk = ValidatedCast<TextureVkImpl>(CopyAttribs.pSrcTexture);
- auto* pDstTexVk = ValidatedCast<TextureVkImpl>(CopyAttribs.pDstTexture);
+ auto* pSrcTexVk = ValidatedCast<TextureVkImpl>(CopyAttribs.pSrcTexture);
+ auto* pDstTexVk = ValidatedCast<TextureVkImpl>(CopyAttribs.pDstTexture);
+
+ // We must unbind the textures from framebuffer because
+ // we will transition their states. If we later try to commit
+ // them as render targets (e.g. from SetPipelineState()), a
+ // state mismatch error will occur.
+ UnbindTextureFromFramebuffer(pSrcTexVk, true);
+ UnbindTextureFromFramebuffer(pDstTexVk, true);
+
const auto& SrcTexDesc = pSrcTexVk->GetDesc();
const auto& DstTexDesc = pDstTexVk->GetDesc();
auto* pSrcBox = CopyAttribs.pSrcBox;