diff options
| author | Egor Yusov <egor.yusov@gmail.com> | 2018-11-27 17:09:18 +0000 |
|---|---|---|
| committer | Egor Yusov <egor.yusov@gmail.com> | 2018-11-27 17:09:18 +0000 |
| commit | b3e4bdd0e87902a7f85505fa9c74abafcd5e7ef5 (patch) | |
| tree | e2617ff059189250a54e469be3919d0c85087e64 /Graphics | |
| parent | Updated texture view creation error reporting (diff) | |
| download | DiligentCore-b3e4bdd0e87902a7f85505fa9c74abafcd5e7ef5.tar.gz DiligentCore-b3e4bdd0e87902a7f85505fa9c74abafcd5e7ef5.zip | |
Improved const-correctness; updated comments; added DRAW_FLAG_VERIFY_STATES and DISPATCH_FLAG_VERIFY_STATES flags
Diffstat (limited to 'Graphics')
21 files changed, 278 insertions, 153 deletions
diff --git a/Graphics/GraphicsEngine/include/BufferViewBase.h b/Graphics/GraphicsEngine/include/BufferViewBase.h index c672fa43..f43835d3 100644 --- a/Graphics/GraphicsEngine/include/BufferViewBase.h +++ b/Graphics/GraphicsEngine/include/BufferViewBase.h @@ -80,6 +80,18 @@ public: return m_pBuffer; } + template<typename BufferType> + BufferType* GetBuffer() + { + return ValidatedCast<BufferType>(m_pBuffer); + } + + template<typename BufferType> + BufferType* GetBuffer()const + { + return ValidatedCast<BufferType>(m_pBuffer); + } + protected: /// Pointer to the buffer diff --git a/Graphics/GraphicsEngine/include/PipelineStateBase.h b/Graphics/GraphicsEngine/include/PipelineStateBase.h index c8451585..05bb2997 100644 --- a/Graphics/GraphicsEngine/include/PipelineStateBase.h +++ b/Graphics/GraphicsEngine/include/PipelineStateBase.h @@ -229,9 +229,9 @@ public: // This function only compares shader resource layout hashes, so // it can potentially give false negatives - bool IsIncompatibleWith(IPipelineState* pPSO)const + bool IsIncompatibleWith(const IPipelineState* pPSO)const { - return m_ShaderResourceLayoutHash != ValidatedCast<PipelineStateBase>(pPSO)->m_ShaderResourceLayoutHash; + return m_ShaderResourceLayoutHash != ValidatedCast<const PipelineStateBase>(pPSO)->m_ShaderResourceLayoutHash; } virtual void BindShaderResources( IResourceMapping* pResourceMapping, Uint32 Flags )override diff --git a/Graphics/GraphicsEngine/include/ShaderResourceBindingBase.h b/Graphics/GraphicsEngine/include/ShaderResourceBindingBase.h index 822d44b9..034fb4d0 100644 --- a/Graphics/GraphicsEngine/include/ShaderResourceBindingBase.h +++ b/Graphics/GraphicsEngine/include/ShaderResourceBindingBase.h @@ -63,6 +63,18 @@ public: return m_pPSO; } + template<typename PSOType> + PSOType* GetPipelineState() + { + return ValidatedCast<PSOType>(m_pPSO); + } + + template<typename PSOType> + PSOType* GetPipelineState()const + { + return ValidatedCast<PSOType>(m_pPSO); + } + protected: /// Strong reference to PSO. We must use strong reference, because diff --git a/Graphics/GraphicsEngine/interface/DeviceContext.h b/Graphics/GraphicsEngine/interface/DeviceContext.h index 8559e85c..60898af7 100644 --- a/Graphics/GraphicsEngine/interface/DeviceContext.h +++ b/Graphics/GraphicsEngine/interface/DeviceContext.h @@ -67,7 +67,16 @@ enum DRAW_FLAGS : Uint8 /// Transition indirect draw arguments buffer to RESOURCE_STATE_INDIRECT_ARGUMENT state (see Diligent::RESOURCE_STATE). /// If the buffer is in unknown state, this flag has no effect. - DRAW_FLAG_TRANSITION_INDIRECT_ARGS_BUFFER = 0x04 + DRAW_FLAG_TRANSITION_INDIRECT_ARGS_BUFFER = 0x04, + + /// Verify the sate of vertex, index or indirect args buffer if it is not being transitioned. + /// State verification is only performed in debug and development builds and the + /// flag has no effect in release build. + /// If any of Diligent::DRAW_FLAG_TRANSITION_VERTEX_BUFFERS, Diligent::DRAW_FLAG_TRANSITION_INDEX_BUFFER + /// or Diligent::DRAW_FLAG_TRANSITION_INDIRECT_ARGS_BUFFER flags is not set, it is recommended to set + /// Diligent::DRAW_FLAG_VERIFY_STATES flag unless the resources are used in multiple threads simultaneously and the + /// application explicitly manages the states. + DRAW_FLAG_VERIFY_STATES = 0x08 }; /// Defines the draw command attributes @@ -161,7 +170,12 @@ enum DISPATCH_FLAGS : Uint8 /// Transition indirect dispatch arguments buffer to RESOURCE_STATE_INDIRECT_ARGUMENT state (see Diligent::RESOURCE_STATE). /// If the buffer is in unknown state, this flag has no effect. - DISPATCH_FLAG_TRANSITION_INDIRECT_ARGS_BUFFER = 0x01 + DISPATCH_FLAG_TRANSITION_INDIRECT_ARGS_BUFFER = 0x01, + + /// Verify the sate of indirect args buffer if it is not being transitioned. + /// State verification is only performed in debug and development builds and the + /// flag has no effect in release build. + DISPATCH_FLAG_VERIFY_STATES = 0x02 }; /// Describes dispatch command arguments. @@ -332,9 +346,16 @@ public: /// Transitions shader resources to the require states. /// \param [in] pPipelineState - Pipeline state object that was used to create the shader resource binding. /// \param [in] pShaderResourceBinding - Shader resource binding whose resources will be transitioned. - /// \remarks This method explicitly transitiones all resources to the correct states. + /// \remarks This method explicitly transitiones all resources to correct states. /// If this method was called, there is no need to specify Diligent::COMMIT_SHADER_RESOURCES_FLAG_TRANSITION_RESOURCES /// when calling IDeviceContext::CommitShaderResources() + /// + /// \remarks Resource state transitioning is not thread safe. As the method may alter the states + /// of resources referenced by the shader resource binding, no other thread is allowed to read or + /// write these states. + /// + /// If the application intends to use the same resources in other threads simultaneously, it needs to + /// explicitly manage the states using IDeviceContext::TransitionResourceStates() method. virtual void TransitionShaderResources(IPipelineState* pPipelineState, IShaderResourceBinding* pShaderResourceBinding) = 0; /// Commits shader resources to the device context @@ -348,11 +369,36 @@ public: /// \remarks Pipeline state object that was used to create the shader resource binding must be bound /// to the pipeline when CommitShaderResources() is called. If no pipeline state object is bound /// or the pipeline state object does not match shader resource binding, the method will fail.\n - /// If Diligent::COMMIT_SHADER_RESOURCES_FLAG_TRANSITION_RESOURCES flag is specified, - /// the engine will also transition all shader resources to the correct state. If the flag - /// is not specified, it is assumed that all resources are already in correct states.\n - /// Resources can be explicitly transitioned to the required states by calling - /// IDeviceContext::TransitionShaderResources() + /// If Diligent::COMMIT_SHADER_RESOURCES_FLAG_TRANSITION_RESOURCES flag is set, + /// the engine will also transition all shader resources to correct states. If the flag + /// is not set, it is assumed that all resources are already in correct states.\n + /// Resources can be explicitly transitioned to required states by calling + /// IDeviceContext::TransitionShaderResources() or IDeviceContext::TransitionResourceStates().\n + /// + /// \remarks Automatic resource state transitioning is not thread-safe. + /// + /// - If Diligent::COMMIT_SHADER_RESOURCES_FLAG_TRANSITION_RESOURCES flag is set, the method may alter the states + /// of resources referenced by the shader resource binding and no other thread is allowed to read or write these states. + /// + /// - If Diligent::COMMIT_SHADER_RESOURCES_FLAG_VERIFY_STATES flag is set, the method will read the states, so no other thread + /// should alter the states using any of the methods below:\n + /// - IBuffer::SetState()\n + /// - ITexture::SetState()\n + /// - IDeviceContext::TransitionShaderResources()\n + /// - IDeviceContext::TransitionResourceStates() when StateTransitionDesc::UpdateResourceState is set to true\n + /// - IDeviceContext::CommitShaderResources() when Diligent::COMMIT_SHADER_RESOURCES_FLAG_TRANSITION_RESOURCES flag is set\n + /// - IDeviceContext::Draw() when any of Diligent::DRAW_FLAG_TRANSITION_VERTEX_BUFFERS, + /// Diligent::DRAW_FLAG_TRANSITION_INDEX_BUFFER or Diligent::DRAW_FLAG_TRANSITION_INDIRECT_ARGS_BUFFER flags is set\n + /// - IDeviceContext::Dispatch() when Diligent::DISPATCH_FLAG_TRANSITION_INDIRECT_ARGS_BUFFER flag is set\n + /// It is safe for other threads to read the states. + /// + /// - If none of Diligent::COMMIT_SHADER_RESOURCES_FLAG_TRANSITION_RESOURCES or + /// Diligent::COMMIT_SHADER_RESOURCES_FLAG_VERIFY_STATES flags is set, the method does not access the states of resources. + /// + /// If the application intends to use the same resources in other threads simultaneously, it should manage the states + /// manually by setting the state to Diligent::RESOURCE_STATE_UNKNOWN (which will disable automatic state + /// management) using IBuffer::SetState() or ITexture::SetState() and explicitly transitioning the states with + /// IDeviceContext::TransitionResourceStates(). See IDeviceContext::TransitionResourceStates() for details. virtual void CommitShaderResources(IShaderResourceBinding* pShaderResourceBinding, Uint32 Flags) = 0; /// Sets the stencil reference value @@ -471,13 +517,29 @@ public: /// Executes a draw command - /// \param [in] DrawAttribs - Structure describing draw command attributes, see DrawAttribs for details. + /// \param [in] DrawAttribs - Structure describing draw command attributes, see Diligent::DrawAttribs for details. + /// + /// \remarks If any of Diligent::DRAW_FLAG_TRANSITION_VERTEX_BUFFERS, Diligent::DRAW_FLAG_TRANSITION_INDEX_BUFFER + /// or Diligent::DRAW_FLAG_TRANSITION_INDIRECT_ARGS_BUFFER flags is set, the method may transition the + /// state of the corresponding resource. This is not a thread safe operation, so no other thread is allowed + /// to read or write the state of the same resource. + /// + /// If Diligent::DRAW_FLAG_VERIFY_STATES flag is set, the method reads the state of vertex/index/indirect + /// draw args buffer, so no other threads are allowed to alter the states of the same resources. + /// It is OK to read these states. + /// + /// If none of Diligent::DRAW_FLAG_TRANSITION_VERTEX_BUFFERS, Diligent::DRAW_FLAG_TRANSITION_INDEX_BUFFER + /// or Diligent::DRAW_FLAG_TRANSITION_INDIRECT_ARGS_BUFFER or Diligent::DRAW_FLAG_VERIFY_STATES flags is + /// specified, the method does not access the resource states and is safe to use simulateneously. + /// + /// If the application intends to use the same resources in other threads simultaneously, it needs to + /// explicitly manage the states using IDeviceContext::TransitionResourceStates() method. virtual void Draw(DrawAttribs &DrawAttribs) = 0; /// Executes a dispatch compute command /// \param [in] DispatchAttrs - Structure describing dispatch command attributes, - /// see DispatchComputeAttribs for details. + /// see Diligent::DispatchComputeAttribs for details. virtual void DispatchCompute(const DispatchComputeAttribs &DispatchAttrs) = 0; /// Clears a depth-stencil view @@ -673,7 +735,37 @@ public: /// \param [in] pResourceBarriers - Pointer to the array of resource barriers /// \remarks When both old and new states are RESOURCE_STATE_UNORDERED_ACCESS, the engine /// executes UAV barrier on the resource. The barrier makes sure that all UAV accesses - /// (reads or writes) are complete before any future UAV accesses (read or write) can begin. + /// (reads or writes) are complete before any future UAV accesses (read or write) can begin.\n + /// + /// There are two main usage scenarios for this method: + /// 1. An application knows specifics of resource state transitions not available to the engine. + /// For example, only single mip level needs to be transitioned. + /// 2. An application manages resource states in multiple threads in parallel. + /// + /// The method always reads the states of all resources to transition. If the state of a resource is managed + /// by multiple threads in parallel, the resource must first be transitioned to unknown state + /// (Diligent::RESOURCE_STATE_UNKNOWN) to disable automatic state management in the engine. + /// + /// When StateTransitionDesc::UpdateResourceState is set to true, the method may update the state of the + /// corresponding resource which is not thread safe. No other threads should read or write the sate of that + /// resource. + + /// \note The following methods modify resource states: + /// - IBuffer::SetState()\n + /// - ITexture::SetState()\n + /// - IDeviceContext::TransitionShaderResources()\n + /// - IDeviceContext::TransitionResourceStates() when StateTransitionDesc::UpdateResourceState is set to true\n + /// - IDeviceContext::CommitShaderResources() when Diligent::COMMIT_SHADER_RESOURCES_FLAG_TRANSITION_RESOURCES flag is set\n + /// - IDeviceContext::Draw() when any of Diligent::DRAW_FLAG_TRANSITION_VERTEX_BUFFERS, + /// Diligent::DRAW_FLAG_TRANSITION_INDEX_BUFFER or Diligent::DRAW_FLAG_TRANSITION_INDIRECT_ARGS_BUFFER flags is set\n + /// - IDeviceContext::Dispatch() when Diligent::DISPATCH_FLAG_TRANSITION_INDIRECT_ARGS_BUFFER flag is set\n + /// + /// The following methods read resource states: + /// - IBuffer::GetState()\n + /// - ITexture::GetState()\n + /// - IDeviceContext::CommitShaderResources() when Diligent::COMMIT_SHADER_RESOURCES_FLAG_VERIFY_STATES flag is set\n + /// - IDeviceContext::Draw() when Diligent::DRAW_FLAG_VERIFY_STATES flag is set\n + /// - IDeviceContext::Dispatch() when Diligent::DISPATCH_FLAG_VERIFY_STATES flag is set\n virtual void TransitionResourceStates(Uint32 BarrierCount, StateTransitionDesc* pResourceBarriers) = 0; }; diff --git a/Graphics/GraphicsEngineD3D11/include/DeviceContextD3D11Impl.h b/Graphics/GraphicsEngineD3D11/include/DeviceContextD3D11Impl.h index 4a8a0fb1..a21630a8 100755 --- a/Graphics/GraphicsEngineD3D11/include/DeviceContextD3D11Impl.h +++ b/Graphics/GraphicsEngineD3D11/include/DeviceContextD3D11Impl.h @@ -151,10 +151,10 @@ public: private:
/// Commits d3d11 index buffer to d3d11 device context.
- void CommitD3D11IndexBuffer(VALUE_TYPE IndexType, bool TransitionBuffer);
+ void CommitD3D11IndexBuffer(VALUE_TYPE IndexType, bool TransitionBuffer, bool VerifyState);
/// Commits d3d11 vertex buffers to d3d11 device context.
- void CommitD3D11VertexBuffers(class PipelineStateD3D11Impl* pPipelineStateD3D11, bool TransitionBuffers);
+ void CommitD3D11VertexBuffers(class PipelineStateD3D11Impl* pPipelineStateD3D11, bool TransitionBuffers, bool VerifyStates);
/// Helper template function used to facilitate resource unbinding
template<typename TD3D11ResourceViewType,
@@ -190,7 +190,7 @@ private: template<bool TransitionResources,
bool CommitResources>
- void TransitionAndCommitShaderResources(IPipelineState* pPSO, IShaderResourceBinding* pShaderResourceBinding);
+ void TransitionAndCommitShaderResources(IPipelineState* pPSO, IShaderResourceBinding* pShaderResourceBinding, bool VerifyStates);
void ClearStateCache();
diff --git a/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp index bf8845b3..2d6d14d1 100755 --- a/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp +++ b/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp @@ -148,7 +148,7 @@ namespace Diligent // http://diligentgraphics.com/diligent-engine/architecture/d3d11/committing-shader-resources-to-the-gpu-pipeline/
template<bool TransitionResources, bool CommitResources>
- void DeviceContextD3D11Impl::TransitionAndCommitShaderResources(IPipelineState* pPSO, IShaderResourceBinding* pShaderResourceBinding)
+ void DeviceContextD3D11Impl::TransitionAndCommitShaderResources(IPipelineState* pPSO, IShaderResourceBinding* pShaderResourceBinding, bool VerifyStates)
{
VERIFY_EXPR(pPSO != nullptr);
static_assert(TransitionResources || CommitResources, "At least one of TransitionResources or CommitResources flags is expected to be true");
@@ -264,7 +264,7 @@ namespace Diligent }
}
#ifdef DEVELOPMENT
- else
+ else if (VerifyStates)
{
if (const auto* pTexture = ValidatedCast<TextureBaseD3D11>(UAVRes.pTexture))
{
@@ -404,7 +404,7 @@ namespace Diligent }
}
#ifdef DEVELOPMENT
- else
+ else if (VerifyStates)
{
VERIFY_EXPR(CommitResources);
const auto& CB = CachedCBs[cb];
@@ -503,7 +503,7 @@ namespace Diligent }
}
#ifdef DEVELOPMENT
- else
+ else if (VerifyStates)
{
VERIFY_EXPR(CommitResources);
if (const auto* pTexture = ValidatedCast<TextureBaseD3D11>(SRVRes.pTexture))
@@ -614,7 +614,7 @@ namespace Diligent {
DEV_CHECK_ERR(pPipelineState != nullptr, "Pipeline state must not be null");
DEV_CHECK_ERR(pShaderResourceBinding != nullptr, "Shader resource binding must not be null");
- TransitionAndCommitShaderResources<true, false>(pPipelineState, pShaderResourceBinding);
+ TransitionAndCommitShaderResources<true, false>(pPipelineState, pShaderResourceBinding, false);
}
void DeviceContextD3D11Impl::CommitShaderResources(IShaderResourceBinding* pShaderResourceBinding, Uint32 Flags)
@@ -623,9 +623,9 @@ namespace Diligent return;
if (Flags & COMMIT_SHADER_RESOURCES_FLAG_TRANSITION_RESOURCES)
- TransitionAndCommitShaderResources<true, true>(m_pPipelineState, pShaderResourceBinding);
+ TransitionAndCommitShaderResources<true, true>(m_pPipelineState, pShaderResourceBinding, false);
else
- TransitionAndCommitShaderResources<false, true>(m_pPipelineState, pShaderResourceBinding);
+ TransitionAndCommitShaderResources<false, true>(m_pPipelineState, pShaderResourceBinding, Flags & COMMIT_SHADER_RESOURCES_FLAG_VERIFY_STATES);
}
void DeviceContextD3D11Impl::SetStencilRef(Uint32 StencilRef)
@@ -654,7 +654,7 @@ namespace Diligent }
}
- void DeviceContextD3D11Impl::CommitD3D11IndexBuffer(VALUE_TYPE IndexType, bool TransitionBuffer)
+ void DeviceContextD3D11Impl::CommitD3D11IndexBuffer(VALUE_TYPE IndexType, bool TransitionBuffer, bool VerifyState)
{
if (!m_pIndexBuffer)
{
@@ -672,7 +672,7 @@ namespace Diligent }
}
#ifdef DEVELOPMENT
- else
+ else if (VerifyState)
{
if (pBuffD3D11->IsInKnownState() && pBuffD3D11->CheckState(RESOURCE_STATE_UNORDERED_ACCESS))
{
@@ -708,7 +708,7 @@ namespace Diligent m_bCommittedD3D11IBUpToDate = true;
}
- void DeviceContextD3D11Impl::CommitD3D11VertexBuffers(PipelineStateD3D11Impl* pPipelineStateD3D11, bool TransitionBuffers)
+ void DeviceContextD3D11Impl::CommitD3D11VertexBuffers(PipelineStateD3D11Impl* pPipelineStateD3D11, bool TransitionBuffers, bool VerifyStates)
{
VERIFY( m_NumVertexStreams <= MaxBufferSlots, "Too many buffers are being set" );
UINT NumBuffersToSet = std::max(m_NumVertexStreams, m_NumCommittedD3D11VBs );
@@ -733,7 +733,7 @@ namespace Diligent }
}
#ifdef DEVELOPMENT
- else
+ else if (VerifyStates)
{
if (pBuffD3D11Impl != nullptr && pBuffD3D11Impl->IsInKnownState() && pBuffD3D11Impl->CheckState(RESOURCE_STATE_UNORDERED_ACCESS))
{
@@ -784,12 +784,12 @@ namespace Diligent if (!DvpVerifyDrawArguments(drawAttribs))
return;
#endif
-
+ const bool VerifyStates = drawAttribs.Flags & DRAW_FLAG_VERIFY_STATES;
auto* pd3d11InputLayout = m_pPipelineState->GetD3D11InputLayout();
if (pd3d11InputLayout != nullptr && !m_bCommittedD3D11VBsUpToDate)
{
DEV_CHECK_ERR( m_NumVertexStreams >= m_pPipelineState->GetNumBufferSlotsUsed(), "Currently bound pipeline state '", m_pPipelineState->GetDesc().Name, "' expects ", m_pPipelineState->GetNumBufferSlotsUsed(), " input buffer slots, but only ", m_NumVertexStreams, " is bound");
- CommitD3D11VertexBuffers(m_pPipelineState, drawAttribs.Flags & DRAW_FLAG_TRANSITION_VERTEX_BUFFERS);
+ CommitD3D11VertexBuffers(m_pPipelineState, drawAttribs.Flags & DRAW_FLAG_TRANSITION_VERTEX_BUFFERS, VerifyStates);
}
if (drawAttribs.IsIndexed)
@@ -798,7 +798,7 @@ namespace Diligent m_bCommittedD3D11IBUpToDate = false;
if (!m_bCommittedD3D11IBUpToDate)
{
- CommitD3D11IndexBuffer(drawAttribs.IndexType, drawAttribs.Flags & DRAW_FLAG_TRANSITION_INDEX_BUFFER);
+ CommitD3D11IndexBuffer(drawAttribs.IndexType, drawAttribs.Flags & DRAW_FLAG_TRANSITION_INDEX_BUFFER, VerifyStates);
}
}
diff --git a/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.h b/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.h index 8f36d9c0..23fd4a93 100644 --- a/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.h +++ b/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.h @@ -173,8 +173,8 @@ public: Int64 GetCurrentFrameNumber()const {return m_ContextFrameNumber; } private: - void CommitD3D12IndexBuffer(VALUE_TYPE IndexType, bool TransitionBuffer); - void CommitD3D12VertexBuffers(class GraphicsContext &GraphCtx, bool TransitionBuffers); + void CommitD3D12IndexBuffer(VALUE_TYPE IndexType, bool TransitionBuffer, bool VerifyState); + void CommitD3D12VertexBuffers(class GraphicsContext &GraphCtx, bool TransitionBuffers, bool VerifyStates); void TransitionD3D12VertexBuffers(class GraphicsContext &GraphCtx); void CommitRenderTargets(); void CommitViewports(); diff --git a/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.h b/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.h index 233ca058..b27dc22d 100644 --- a/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.h +++ b/Graphics/GraphicsEngineD3D12/include/PipelineStateD3D12Impl.h @@ -60,7 +60,8 @@ public: ShaderResourceCacheD3D12* CommitAndTransitionShaderResources(IShaderResourceBinding* pShaderResourceBinding, class CommandContext& Ctx, bool CommitResources, - bool TransitionResources)const; + bool TransitionResources, + bool ValidateStates)const; const RootSignature& GetRootSignature()const{return m_RootSig;} diff --git a/Graphics/GraphicsEngineD3D12/include/RootSignature.h b/Graphics/GraphicsEngineD3D12/include/RootSignature.h index 6c99d1a4..10dedc84 100644 --- a/Graphics/GraphicsEngineD3D12/include/RootSignature.h +++ b/Graphics/GraphicsEngineD3D12/include/RootSignature.h @@ -313,12 +313,14 @@ public: void (RootSignature::*CommitDescriptorHandles)(class RenderDeviceD3D12Impl* pRenderDeviceD3D12, ShaderResourceCacheD3D12& ResourceCache, class CommandContext& Ctx, - bool IsCompute)const = nullptr; + bool IsCompute, + bool ValidateStates)const = nullptr; void (RootSignature::*TransitionAndCommitDescriptorHandles)(class RenderDeviceD3D12Impl* pRenderDeviceD3D12, ShaderResourceCacheD3D12& ResourceCache, class CommandContext& Ctx, - bool IsCompute)const = nullptr; + bool IsCompute, + bool ValidateStates)const = nullptr; void TransitionResources(ShaderResourceCacheD3D12& ResourceCache, class CommandContext& Ctx)const; @@ -474,13 +476,15 @@ private: void CommitDescriptorHandlesInternal_SM(class RenderDeviceD3D12Impl* pRenderDeviceD3D12, ShaderResourceCacheD3D12& ResourceCache, class CommandContext& Ctx, - bool IsCompute)const; + bool IsCompute, + bool ValidateStates)const; template<bool PerformResourceTransitions> // Commits descriptor handles for static, mutable, and dynamic variables void CommitDescriptorHandlesInternal_SMD(class RenderDeviceD3D12Impl* pRenderDeviceD3D12, ShaderResourceCacheD3D12& ResourceCache, class CommandContext& Ctx, - bool IsCompute)const; + bool IsCompute, + bool ValidateStates)const; }; } diff --git a/Graphics/GraphicsEngineD3D12/include/ShaderD3D12Impl.h b/Graphics/GraphicsEngineD3D12/include/ShaderD3D12Impl.h index 9b26c9c9..b34469d8 100644 --- a/Graphics/GraphicsEngineD3D12/include/ShaderD3D12Impl.h +++ b/Graphics/GraphicsEngineD3D12/include/ShaderD3D12Impl.h @@ -78,7 +78,7 @@ public: const ShaderResourceCacheD3D12& GetStaticResCache() const { return m_StaticResCache; } #ifdef DEVELOPMENT - bool DvpVerifyStaticResourceBindings(); + bool DvpVerifyStaticResourceBindings()const; #endif private: diff --git a/Graphics/GraphicsEngineD3D12/include/ShaderResourceBindingD3D12Impl.h b/Graphics/GraphicsEngineD3D12/include/ShaderResourceBindingD3D12Impl.h index 2685dde2..f6a9b7c6 100644 --- a/Graphics/GraphicsEngineD3D12/include/ShaderResourceBindingD3D12Impl.h +++ b/Graphics/GraphicsEngineD3D12/include/ShaderResourceBindingD3D12Impl.h @@ -64,7 +64,7 @@ public: ShaderResourceCacheD3D12& GetResourceCache(){return m_ShaderResourceCache;} #ifdef DEVELOPMENT - void dvpVerifyResourceBindings(const PipelineStateD3D12Impl* pPSO); + void dvpVerifyResourceBindings(const PipelineStateD3D12Impl* pPSO)const; #endif bool StaticResourcesInitialized()const{return m_bStaticResourcesInitialized;} diff --git a/Graphics/GraphicsEngineD3D12/include/ShaderResourceCacheD3D12.h b/Graphics/GraphicsEngineD3D12/include/ShaderResourceCacheD3D12.h index fb7a08d5..b4149d03 100644 --- a/Graphics/GraphicsEngineD3D12/include/ShaderResourceCacheD3D12.h +++ b/Graphics/GraphicsEngineD3D12/include/ShaderResourceCacheD3D12.h @@ -236,9 +236,9 @@ public: // Returns CPU descriptor handle of a shader visible descriptor heap allocation template<D3D12_DESCRIPTOR_HEAP_TYPE HeapType> - D3D12_CPU_DESCRIPTOR_HANDLE GetShaderVisibleTableCPUDescriptorHandle(Uint32 RootParamInd, Uint32 OffsetFromTableStart = 0) + D3D12_CPU_DESCRIPTOR_HANDLE GetShaderVisibleTableCPUDescriptorHandle(Uint32 RootParamInd, Uint32 OffsetFromTableStart = 0) const { - auto &RootParam = GetRootTable(RootParamInd); + const auto& RootParam = GetRootTable(RootParamInd); VERIFY(HeapType == RootParam.DbgGetHeapType(), "Invalid descriptor heap type"); D3D12_CPU_DESCRIPTOR_HANDLE CPUDescriptorHandle = {0}; @@ -269,9 +269,9 @@ public: // Returns GPU descriptor handle of a shader visible descriptor table template<D3D12_DESCRIPTOR_HEAP_TYPE HeapType> - D3D12_GPU_DESCRIPTOR_HANDLE GetShaderVisibleTableGPUDescriptorHandle(Uint32 RootParamInd, Uint32 OffsetFromTableStart = 0) + D3D12_GPU_DESCRIPTOR_HANDLE GetShaderVisibleTableGPUDescriptorHandle(Uint32 RootParamInd, Uint32 OffsetFromTableStart = 0) const { - auto &RootParam = GetRootTable(RootParamInd); + const auto& RootParam = GetRootTable(RootParamInd); VERIFY(RootParam.m_TableStartOffset != InvalidDescriptorOffset, "GPU descriptor handle must never be requested for dynamic resources"); VERIFY(OffsetFromTableStart < RootParam.m_NumResources, "Offset is out of range"); diff --git a/Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.h b/Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.h index d51da654..575284c4 100644 --- a/Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.h +++ b/Graphics/GraphicsEngineD3D12/include/ShaderResourceLayoutD3D12.h @@ -219,7 +219,7 @@ public: ShaderResourceCacheD3D12& DstCache)const; #ifdef DEVELOPMENT - bool dvpVerifyBindings(ShaderResourceCacheD3D12& ResourceCache)const; + bool dvpVerifyBindings(const ShaderResourceCacheD3D12& ResourceCache)const; #endif IObject& GetOwner(){return m_Owner;} diff --git a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp index 02b87b13..2a9f5aa6 100644 --- a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp @@ -121,12 +121,12 @@ namespace Diligent if (m_State.NumCommands != 0) { LOG_ERROR_MESSAGE(m_bIsDeferred ? - "There are outstanding commands in deferred context #", m_ContextId, " being destroyed, which indicates that FinishCommandList() has not been called." : - "There are outstanding commands in the immediate context being destroyed, which indicates the context has not been Flush()'ed.", + "There are outstanding commands in deferred context #", m_ContextId, " being destroyed, which indicates that FinishCommandList() has not been called." : + "There are outstanding commands in the immediate context being destroyed, which indicates the context has not been Flush()'ed.", " This is unexpected and may result in synchronization errors"); } - if(m_bIsDeferred) + if (m_bIsDeferred) { if (m_CurrCmdCtx) { @@ -171,7 +171,7 @@ namespace Diligent bool CommitStates = false; bool CommitScissor = false; - if(!m_pPipelineState) + if (!m_pPipelineState) { // If no pipeline state is bound, we are working with the fresh command // list. We have to commit the states set in the context that are not @@ -228,8 +228,8 @@ namespace Diligent VERIFY_EXPR(pPipelineState != nullptr); auto& Ctx = GetCmdContext(); - auto *pPipelineStateD3D12 = ValidatedCast<PipelineStateD3D12Impl>(pPipelineState); - pPipelineStateD3D12->CommitAndTransitionShaderResources(pShaderResourceBinding, Ctx, false, true); + auto* pPipelineStateD3D12 = ValidatedCast<PipelineStateD3D12Impl>(pPipelineState); + pPipelineStateD3D12->CommitAndTransitionShaderResources(pShaderResourceBinding, Ctx, false, true, false); } void DeviceContextD3D12Impl::CommitShaderResources(IShaderResourceBinding* pShaderResourceBinding, Uint32 Flags) @@ -238,7 +238,7 @@ namespace Diligent return; auto& Ctx = GetCmdContext(); - m_State.pCommittedResourceCache = m_pPipelineState->CommitAndTransitionShaderResources(pShaderResourceBinding, Ctx, true, (Flags & COMMIT_SHADER_RESOURCES_FLAG_TRANSITION_RESOURCES)!=0); + m_State.pCommittedResourceCache = m_pPipelineState->CommitAndTransitionShaderResources(pShaderResourceBinding, Ctx, true, (Flags & COMMIT_SHADER_RESOURCES_FLAG_TRANSITION_RESOURCES)!=0, (Flags & COMMIT_SHADER_RESOURCES_FLAG_VERIFY_STATES)!=0); } void DeviceContextD3D12Impl::SetStencilRef(Uint32 StencilRef) @@ -257,7 +257,7 @@ namespace Diligent } } - void DeviceContextD3D12Impl::CommitD3D12IndexBuffer(VALUE_TYPE IndexType, bool TransitionBuffer) + void DeviceContextD3D12Impl::CommitD3D12IndexBuffer(VALUE_TYPE IndexType, bool TransitionBuffer, bool VerifyState) { VERIFY( m_pIndexBuffer != nullptr, "Index buffer is not set up for indexed draw command" ); @@ -294,7 +294,7 @@ namespace Diligent GraphicsCtx.TransitionResource(pBuffD3D12, RESOURCE_STATE_INDEX_BUFFER); } #ifdef DEVELOPMENT - else + else if(VerifyState) { if (pBuffD3D12->IsInKnownState() && !pBuffD3D12->CheckState(RESOURCE_STATE_INDEX_BUFFER)) { @@ -336,7 +336,7 @@ namespace Diligent } } - void DeviceContextD3D12Impl::CommitD3D12VertexBuffers(GraphicsContext& GraphCtx, bool TransitionBuffers) + void DeviceContextD3D12Impl::CommitD3D12VertexBuffers(GraphicsContext& GraphCtx, bool TransitionBuffers, bool VerifyStates) { // Do not initialize array with zeroes for performance reasons D3D12_VERTEX_BUFFER_VIEW VBViews[MaxBufferSlots];// = {} @@ -364,7 +364,7 @@ namespace Diligent GraphCtx.TransitionResource(pBufferD3D12, RESOURCE_STATE_VERTEX_BUFFER); } #ifdef DEVELOPMENT - else + else if (VerifyStates) { if (pBufferD3D12->IsInKnownState() && !pBufferD3D12->CheckState(RESOURCE_STATE_VERTEX_BUFFER)) { @@ -406,23 +406,24 @@ namespace Diligent return; #endif + const bool VerifyStates = (drawAttribs.Flags & DRAW_FLAG_VERIFY_STATES) != 0; auto& GraphCtx = GetCmdContext().AsGraphicsContext(); - if( drawAttribs.IsIndexed ) + if (drawAttribs.IsIndexed) { - if( m_State.CommittedIBFormat != drawAttribs.IndexType ) + if (m_State.CommittedIBFormat != drawAttribs.IndexType) m_State.bCommittedD3D12IBUpToDate = false; - bool TransitionIndexBuffer = (drawAttribs.Flags & DRAW_FLAG_TRANSITION_INDEX_BUFFER) != 0; + const bool TransitionIndexBuffer = (drawAttribs.Flags & DRAW_FLAG_TRANSITION_INDEX_BUFFER) != 0; if (m_State.bCommittedD3D12IBUpToDate) { BufferD3D12Impl *pBuffD3D12 = static_cast<BufferD3D12Impl *>(m_pIndexBuffer.RawPtr()); - if(TransitionIndexBuffer) + if (TransitionIndexBuffer) { if (pBuffD3D12->IsInKnownState() && !pBuffD3D12->CheckState(RESOURCE_STATE_INDEX_BUFFER)) GraphCtx.TransitionResource(pBuffD3D12, RESOURCE_STATE_INDEX_BUFFER); } #ifdef DEVELOPMENT - else + else if (VerifyStates) { if (pBuffD3D12->IsInKnownState() && !pBuffD3D12->CheckState(RESOURCE_STATE_INDEX_BUFFER)) { @@ -435,11 +436,11 @@ namespace Diligent } else { - CommitD3D12IndexBuffer(drawAttribs.IndexType, TransitionIndexBuffer); + CommitD3D12IndexBuffer(drawAttribs.IndexType, TransitionIndexBuffer, VerifyStates); } } - bool TransitionVertexBuffers = (drawAttribs.Flags & DRAW_FLAG_TRANSITION_VERTEX_BUFFERS) != 0; + const bool TransitionVertexBuffers = (drawAttribs.Flags & DRAW_FLAG_TRANSITION_VERTEX_BUFFERS) != 0; if (m_State.bCommittedD3D12VBsUpToDate) { if (TransitionVertexBuffers) @@ -447,7 +448,7 @@ namespace Diligent TransitionD3D12VertexBuffers(GraphCtx); } #ifdef DEVELOPMENT - else + else if (VerifyStates) { for( Uint32 Buff = 0; Buff < m_NumVertexStreams; ++Buff ) { @@ -465,7 +466,7 @@ namespace Diligent } else { - CommitD3D12VertexBuffers(GraphCtx, TransitionVertexBuffers); + CommitD3D12VertexBuffers(GraphCtx, TransitionVertexBuffers, VerifyStates); } GraphCtx.SetRootSignature( m_pPipelineState->GetD3D12RootSignature() ); @@ -474,7 +475,7 @@ namespace Diligent { m_pPipelineState->GetRootSignature().CommitRootViews(*m_State.pCommittedResourceCache, GraphCtx, false, this); } -#ifdef _DEBUG +#ifdef DEVELOPMENT else { if( m_pPipelineState->dbgContainsShaderResources() ) @@ -483,7 +484,7 @@ namespace Diligent #endif - auto *pIndirectDrawAttribsD3D12 = ValidatedCast<BufferD3D12Impl>(drawAttribs.pIndirectDrawAttribs); + auto* pIndirectDrawAttribsD3D12 = ValidatedCast<BufferD3D12Impl>(drawAttribs.pIndirectDrawAttribs); if (pIndirectDrawAttribsD3D12 != nullptr) { #ifdef DEVELOPMENT @@ -497,7 +498,7 @@ namespace Diligent GraphCtx.TransitionResource(pIndirectDrawAttribsD3D12, RESOURCE_STATE_INDIRECT_ARGUMENT); } #ifdef DEVELOPMENT - else + else if (VerifyStates) { if (pIndirectDrawAttribsD3D12->IsInKnownState() && !pIndirectDrawAttribsD3D12->CheckState(RESOURCE_STATE_INDIRECT_ARGUMENT)) { @@ -559,7 +560,7 @@ namespace Diligent ComputeCtx.TransitionResource(pBufferD3D12, RESOURCE_STATE_INDIRECT_ARGUMENT); } #ifdef DEVELOPMENT - else + else if (DispatchAttrs.Flags & DISPATCH_FLAG_VERIFY_STATES) { if (pBufferD3D12->IsInKnownState() && !pBufferD3D12->CheckState(RESOURCE_STATE_INDIRECT_ARGUMENT)) { diff --git a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp index dd61c552..3c027dad 100644 --- a/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/PipelineStateD3D12Impl.cpp @@ -292,7 +292,8 @@ bool PipelineStateD3D12Impl::IsCompatibleWith(const IPipelineState* pPSO)const ShaderResourceCacheD3D12* PipelineStateD3D12Impl::CommitAndTransitionShaderResources(IShaderResourceBinding* pShaderResourceBinding, CommandContext& Ctx, bool CommitResources, - bool TransitionResources)const + bool TransitionResources, + bool ValidateStates)const { #ifdef DEVELOPMENT if (pShaderResourceBinding == nullptr && dbgContainsShaderResources()) @@ -316,15 +317,13 @@ ShaderResourceCacheD3D12* PipelineStateD3D12Impl::CommitAndTransitionShaderResou } #ifdef DEVELOPMENT + if (IsIncompatibleWith(pResBindingD3D12Impl->GetPipelineState())) { - auto* pRefPSO = pResBindingD3D12Impl->GetPipelineState(); - if ( IsIncompatibleWith(pRefPSO) ) - { - LOG_ERROR_MESSAGE("Shader resource binding is incompatible with the pipeline state '", m_Desc.Name, "'. Operation will be ignored."); - return nullptr; - } + LOG_ERROR_MESSAGE("Shader resource binding is incompatible with the pipeline state '", m_Desc.Name, "'. Operation will be ignored."); + return nullptr; } + if( (m_RootSig.GetTotalSrvCbvUavSlots(SHADER_VARIABLE_TYPE_STATIC) != 0 || m_RootSig.GetTotalRootViews(SHADER_VARIABLE_TYPE_STATIC) != 0) && !pResBindingD3D12Impl->StaticResourcesInitialized() ) { @@ -343,9 +342,9 @@ ShaderResourceCacheD3D12* PipelineStateD3D12Impl::CommitAndTransitionShaderResou Ctx.AsGraphicsContext().SetRootSignature( GetD3D12RootSignature() ); if(TransitionResources) - (m_RootSig.*m_RootSig.TransitionAndCommitDescriptorHandles)(m_pDevice, ResourceCache, Ctx, m_Desc.IsComputePipeline); + (m_RootSig.*m_RootSig.TransitionAndCommitDescriptorHandles)(m_pDevice, ResourceCache, Ctx, m_Desc.IsComputePipeline, ValidateStates); else - (m_RootSig.*m_RootSig.CommitDescriptorHandles)(m_pDevice, ResourceCache, Ctx, m_Desc.IsComputePipeline); + (m_RootSig.*m_RootSig.CommitDescriptorHandles)(m_pDevice, ResourceCache, Ctx, m_Desc.IsComputePipeline, ValidateStates); } else { diff --git a/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp b/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp index 67369355..bddff4af 100644 --- a/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp +++ b/Graphics/GraphicsEngineD3D12/src/RootSignature.cpp @@ -685,7 +685,7 @@ void TransitionResource(CommandContext& Ctx, { VERIFY(RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_SRV, "Unexpected descriptor range type"); auto* pBuffViewD3D12 = Res.pObject.RawPtr<BufferViewD3D12Impl>(); - auto* pBuffToTransition = ValidatedCast<BufferD3D12Impl>(pBuffViewD3D12->GetBuffer()); + auto* pBuffToTransition = pBuffViewD3D12->GetBuffer<BufferD3D12Impl>(); if (pBuffToTransition->IsInKnownState() && !pBuffToTransition->CheckState(RESOURCE_STATE_SHADER_RESOURCE)) Ctx.TransitionResource(pBuffToTransition, RESOURCE_STATE_SHADER_RESOURCE ); } @@ -695,7 +695,7 @@ void TransitionResource(CommandContext& Ctx, { VERIFY(RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_UAV, "Unexpected descriptor range type"); auto* pBuffViewD3D12 = Res.pObject.RawPtr<BufferViewD3D12Impl>(); - auto* pBuffToTransition = ValidatedCast<BufferD3D12Impl>(pBuffViewD3D12->GetBuffer()); + auto* pBuffToTransition = pBuffViewD3D12->GetBuffer<BufferD3D12Impl>(); if (pBuffToTransition->IsInKnownState()) { // We must always call TransitionResource() even when the state is already @@ -709,7 +709,7 @@ void TransitionResource(CommandContext& Ctx, { VERIFY(RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_SRV, "Unexpected descriptor range type"); auto* pTexViewD3D12 = Res.pObject.RawPtr<TextureViewD3D12Impl>(); - auto* pTexToTransition = ValidatedCast<TextureD3D12Impl>(pTexViewD3D12->GetTexture()); + auto* pTexToTransition = pTexViewD3D12->GetTexture<TextureD3D12Impl>(); if (pTexToTransition->IsInKnownState() && !pTexToTransition->CheckState(RESOURCE_STATE_SHADER_RESOURCE)) Ctx.TransitionResource(pTexToTransition, RESOURCE_STATE_SHADER_RESOURCE ); } @@ -719,7 +719,7 @@ void TransitionResource(CommandContext& Ctx, { VERIFY(RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_UAV, "Unexpected descriptor range type"); auto* pTexViewD3D12 = Res.pObject.RawPtr<TextureViewD3D12Impl>(); - auto* pTexToTransition = ValidatedCast<TextureD3D12Impl>(pTexViewD3D12->GetTexture()); + auto* pTexToTransition = pTexViewD3D12->GetTexture<TextureD3D12Impl>(); if (pTexToTransition->IsInKnownState()) { // We must always call TransitionResource() even when the state is already @@ -741,9 +741,9 @@ void TransitionResource(CommandContext& Ctx, } -#ifdef _DEBUG -void DbgVerifyResourceState(ShaderResourceCacheD3D12::Resource& Res, - D3D12_DESCRIPTOR_RANGE_TYPE RangeType) +#ifdef DEVELOPMENT +void DvpVerifyResourceState(const ShaderResourceCacheD3D12::Resource& Res, + D3D12_DESCRIPTOR_RANGE_TYPE RangeType) { switch (Res.Type) { @@ -751,49 +751,49 @@ void DbgVerifyResourceState(ShaderResourceCacheD3D12::Resource& Res, { VERIFY(RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_CBV, "Unexpected descriptor range type"); // Not using QueryInterface() for the sake of efficiency - auto* pBufferD3D12 = Res.pObject.RawPtr<BufferD3D12Impl>(); + const auto* pBufferD3D12 = Res.pObject.RawPtr<const BufferD3D12Impl>(); if (pBufferD3D12->IsInKnownState() && !pBufferD3D12->CheckState(RESOURCE_STATE_CONSTANT_BUFFER)) - LOG_ERROR_MESSAGE("Resource \"", pBufferD3D12->GetDesc().Name, "\" is not in RESOURCE_STATE_CONSTANT_BUFFER state. Did you forget to call TransitionShaderResources() or specify COMMIT_SHADER_RESOURCES_FLAG_TRANSITION_RESOURCES flag in a call to CommitShaderResources()?" ); + LOG_ERROR_MESSAGE("Resource '", pBufferD3D12->GetDesc().Name, "' is not in RESOURCE_STATE_CONSTANT_BUFFER state. Did you forget to call TransitionShaderResources() or specify COMMIT_SHADER_RESOURCES_FLAG_TRANSITION_RESOURCES flag in a call to CommitShaderResources()?" ); } break; case CachedResourceType::BufSRV: { VERIFY(RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_SRV, "Unexpected descriptor range type"); - auto* pBuffViewD3D12 = Res.pObject.RawPtr<BufferViewD3D12Impl>(); - auto* pBufferD3D12 = ValidatedCast<BufferD3D12Impl>(pBuffViewD3D12->GetBuffer()); + const auto* pBuffViewD3D12 = Res.pObject.RawPtr<const BufferViewD3D12Impl>(); + const auto* pBufferD3D12 = pBuffViewD3D12->GetBuffer<const BufferD3D12Impl>(); if (pBufferD3D12->IsInKnownState() && !pBufferD3D12->CheckState(RESOURCE_STATE_SHADER_RESOURCE)) - LOG_ERROR_MESSAGE("Resource \"", pBufferD3D12->GetDesc().Name, "\" is not in RESOURCE_STATE_SHADER_RESOURCE state. Did you forget to call TransitionShaderResources() or specify COMMIT_SHADER_RESOURCES_FLAG_TRANSITION_RESOURCES flag in a call to CommitShaderResources()?" ); + LOG_ERROR_MESSAGE("Resource '", pBufferD3D12->GetDesc().Name, "' is not in RESOURCE_STATE_SHADER_RESOURCE state. Did you forget to call TransitionShaderResources() or specify COMMIT_SHADER_RESOURCES_FLAG_TRANSITION_RESOURCES flag in a call to CommitShaderResources()?" ); } break; case CachedResourceType::BufUAV: { VERIFY(RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_UAV, "Unexpected descriptor range type"); - auto* pBuffViewD3D12 = Res.pObject.RawPtr<BufferViewD3D12Impl>(); - auto* pBufferD3D12 = ValidatedCast<BufferD3D12Impl>(pBuffViewD3D12->GetBuffer()); + const auto* pBuffViewD3D12 = Res.pObject.RawPtr<const BufferViewD3D12Impl>(); + const auto* pBufferD3D12 = pBuffViewD3D12->GetBuffer<const BufferD3D12Impl>(); if (pBufferD3D12->IsInKnownState() && !pBufferD3D12->CheckState(RESOURCE_STATE_UNORDERED_ACCESS)) - LOG_ERROR_MESSAGE("Resource \"", pBufferD3D12->GetDesc().Name, "\" is not in RESOURCE_STATE_UNORDERED_ACCESS state. Did you forget to call TransitionShaderResources() or specify COMMIT_SHADER_RESOURCES_FLAG_TRANSITION_RESOURCES flag in a call to CommitShaderResources()?" ); + LOG_ERROR_MESSAGE("Resource '", pBufferD3D12->GetDesc().Name, "' is not in RESOURCE_STATE_UNORDERED_ACCESS state. Did you forget to call TransitionShaderResources() or specify COMMIT_SHADER_RESOURCES_FLAG_TRANSITION_RESOURCES flag in a call to CommitShaderResources()?" ); } break; case CachedResourceType::TexSRV: { VERIFY(RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_SRV, "Unexpected descriptor range type"); - auto* pTexViewD3D12 = Res.pObject.RawPtr<TextureViewD3D12Impl>(); - auto* pTexD3D12 = ValidatedCast<TextureD3D12Impl>(pTexViewD3D12->GetTexture()); + const auto* pTexViewD3D12 = Res.pObject.RawPtr<const TextureViewD3D12Impl>(); + const auto* pTexD3D12 = pTexViewD3D12->GetTexture<TextureD3D12Impl>(); if (pTexD3D12->IsInKnownState() && !pTexD3D12->CheckState(RESOURCE_STATE_SHADER_RESOURCE)) - LOG_ERROR_MESSAGE("Resource \"", pTexD3D12->GetDesc().Name, "\" is not in RESOURCE_STATE_SHADER_RESOURCE state. Did you forget to call TransitionShaderResources() or specify COMMIT_SHADER_RESOURCES_FLAG_TRANSITION_RESOURCES flag in a call to CommitShaderResources()?" ); + LOG_ERROR_MESSAGE("Resource '", pTexD3D12->GetDesc().Name, "' is not in RESOURCE_STATE_SHADER_RESOURCE state. Did you forget to call TransitionShaderResources() or specify COMMIT_SHADER_RESOURCES_FLAG_TRANSITION_RESOURCES flag in a call to CommitShaderResources()?" ); } break; case CachedResourceType::TexUAV: { VERIFY(RangeType == D3D12_DESCRIPTOR_RANGE_TYPE_UAV, "Unexpected descriptor range type"); - auto* pTexViewD3D12 = Res.pObject.RawPtr<TextureViewD3D12Impl>(); - auto* pTexD3D12 = ValidatedCast<TextureD3D12Impl>(pTexViewD3D12->GetTexture()); + const auto* pTexViewD3D12 = Res.pObject.RawPtr<const TextureViewD3D12Impl>(); + const auto* pTexD3D12 = pTexViewD3D12->GetTexture<const TextureD3D12Impl>(); if (pTexD3D12->IsInKnownState() && !pTexD3D12->CheckState(RESOURCE_STATE_UNORDERED_ACCESS)) - LOG_ERROR_MESSAGE("Resource \"", pTexD3D12->GetDesc().Name, "\" is not in RESOURCE_STATE_UNORDERED_ACCESS state. Did you forget to call TransitionShaderResources() or specify COMMIT_SHADER_RESOURCES_FLAG_TRANSITION_RESOURCES flag in a call to CommitShaderResources()?" ); + LOG_ERROR_MESSAGE("Resource '", pTexD3D12->GetDesc().Name, "' is not in RESOURCE_STATE_UNORDERED_ACCESS state. Did you forget to call TransitionShaderResources() or specify COMMIT_SHADER_RESOURCES_FLAG_TRANSITION_RESOURCES flag in a call to CommitShaderResources()?" ); } break; @@ -807,7 +807,7 @@ void DbgVerifyResourceState(ShaderResourceCacheD3D12::Resource& Res, VERIFY(Res.pObject == nullptr && Res.CPUDescriptorHandle.ptr == 0, "Bound resource is unexpected"); } } -#endif +#endif // DEVELOPMENT template<class TOperation> __forceinline void RootSignature::RootParamsManager::ProcessRootTables(TOperation Operation)const @@ -825,7 +825,7 @@ __forceinline void RootSignature::RootParamsManager::ProcessRootTables(TOperatio bool IsResourceTable = d3d12Table.pDescriptorRanges[0].RangeType != D3D12_DESCRIPTOR_RANGE_TYPE_SAMPLER; D3D12_DESCRIPTOR_HEAP_TYPE dbgHeapType = D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES; #ifdef _DEBUG - dbgHeapType = IsResourceTable ? D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV : D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER; + dbgHeapType = IsResourceTable ? D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV : D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER; #endif Operation(RootInd, RootTable, D3D12Param, IsResourceTable, dbgHeapType); } @@ -861,33 +861,34 @@ template<bool PerformResourceTransitions> void RootSignature::CommitDescriptorHandlesInternal_SMD(RenderDeviceD3D12Impl* pRenderDeviceD3D12, ShaderResourceCacheD3D12& ResourceCache, CommandContext& Ctx, - bool IsCompute)const + bool IsCompute, + bool ValidateStates)const { auto *pd3d12Device = pRenderDeviceD3D12->GetD3D12Device(); Uint32 NumDynamicCbvSrvUavDescriptors = m_TotalSrvCbvUavSlots[SHADER_VARIABLE_TYPE_DYNAMIC]; - Uint32 NumDynamicSamplerDescriptors = m_TotalSamplerSlots[SHADER_VARIABLE_TYPE_DYNAMIC]; + Uint32 NumDynamicSamplerDescriptors = m_TotalSamplerSlots [SHADER_VARIABLE_TYPE_DYNAMIC]; VERIFY_EXPR(NumDynamicCbvSrvUavDescriptors > 0 || NumDynamicSamplerDescriptors > 0); DescriptorHeapAllocation DynamicCbvSrvUavDescriptors, DynamicSamplerDescriptors; - if(NumDynamicCbvSrvUavDescriptors) + if (NumDynamicCbvSrvUavDescriptors) DynamicCbvSrvUavDescriptors = Ctx.AllocateDynamicGPUVisibleDescriptor(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, NumDynamicCbvSrvUavDescriptors); - if(NumDynamicSamplerDescriptors) + if (NumDynamicSamplerDescriptors) DynamicSamplerDescriptors = Ctx.AllocateDynamicGPUVisibleDescriptor(D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, NumDynamicSamplerDescriptors); CommandContext::ShaderDescriptorHeaps Heaps(ResourceCache.GetSrvCbvUavDescriptorHeap(), ResourceCache.GetSamplerDescriptorHeap()); - if(Heaps.pSamplerHeap == nullptr) + if (Heaps.pSamplerHeap == nullptr) Heaps.pSamplerHeap = DynamicSamplerDescriptors.GetDescriptorHeap(); - if(Heaps.pSrvCbvUavHeap == nullptr) + if (Heaps.pSrvCbvUavHeap == nullptr) Heaps.pSrvCbvUavHeap = DynamicCbvSrvUavDescriptors.GetDescriptorHeap(); - if(NumDynamicCbvSrvUavDescriptors) + if (NumDynamicCbvSrvUavDescriptors) VERIFY(DynamicCbvSrvUavDescriptors.GetDescriptorHeap() == Heaps.pSrvCbvUavHeap, "Inconsistent CbvSrvUav descriptor heaps" ); - if(NumDynamicSamplerDescriptors) + if (NumDynamicSamplerDescriptors) VERIFY(DynamicSamplerDescriptors.GetDescriptorHeap() == Heaps.pSamplerHeap, "Inconsistent Sampler descriptor heaps" ); - if(Heaps) + if (Heaps) Ctx.SetDescriptorHeaps(Heaps); // Offset to the beginning of the current dynamic CBV_SRV_UAV/SAMPLER table from @@ -896,7 +897,7 @@ void RootSignature::CommitDescriptorHandlesInternal_SMD(RenderDeviceD3D12Impl* Uint32 DynamicSamplerTblOffset = 0; m_RootParams.ProcessRootTables( - [&](Uint32 RootInd, const RootParameter &RootTable, const D3D12_ROOT_PARAMETER& D3D12Param, bool IsResourceTable, D3D12_DESCRIPTOR_HEAP_TYPE dbgHeapType ) + [&](Uint32 RootInd, const RootParameter& RootTable, const D3D12_ROOT_PARAMETER& D3D12Param, bool IsResourceTable, D3D12_DESCRIPTOR_HEAP_TYPE dbgHeapType) { D3D12_GPU_DESCRIPTOR_HANDLE RootTableGPUDescriptorHandle; bool IsDynamicTable = RootTable.GetShaderVariableType() == SHADER_VARIABLE_TYPE_DYNAMIC; @@ -921,16 +922,16 @@ void RootSignature::CommitDescriptorHandlesInternal_SMD(RenderDeviceD3D12Impl* Ctx.GetCommandList()->SetGraphicsRootDescriptorTable(RootInd, RootTableGPUDescriptorHandle); ProcessCachedTableResources(RootInd, D3D12Param, ResourceCache, dbgHeapType, - [&](UINT OffsetFromTableStart, const D3D12_DESCRIPTOR_RANGE &range, ShaderResourceCacheD3D12::Resource &Res) + [&](UINT OffsetFromTableStart, const D3D12_DESCRIPTOR_RANGE& range, ShaderResourceCacheD3D12::Resource& Res) { if(PerformResourceTransitions) { TransitionResource(Ctx, Res, range.RangeType); } -#ifdef _DEBUG - else +#ifdef DEVELOPMENT + else if(ValidateStates) { - DbgVerifyResourceState(Res, range.RangeType); + DvpVerifyResourceState(Res, range.RangeType); } #endif @@ -940,7 +941,7 @@ void RootSignature::CommitDescriptorHandlesInternal_SMD(RenderDeviceD3D12Impl* { VERIFY( DynamicCbvSrvUavTblOffset < NumDynamicCbvSrvUavDescriptors, "Not enough space in the descriptor heap allocation"); - if( Res.CPUDescriptorHandle.ptr != 0 ) + if (Res.CPUDescriptorHandle.ptr != 0) pd3d12Device->CopyDescriptorsSimple(1, DynamicCbvSrvUavDescriptors.GetCpuHandle(DynamicCbvSrvUavTblOffset), Res.CPUDescriptorHandle, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); else LOG_ERROR_MESSAGE("No valid CbvSrvUav descriptor handle found for root parameter ", RootInd, ", descriptor slot ", OffsetFromTableStart); @@ -951,7 +952,7 @@ void RootSignature::CommitDescriptorHandlesInternal_SMD(RenderDeviceD3D12Impl* { VERIFY( DynamicSamplerTblOffset < NumDynamicSamplerDescriptors, "Not enough space in the descriptor heap allocation"); - if( Res.CPUDescriptorHandle.ptr != 0 ) + if (Res.CPUDescriptorHandle.ptr != 0) pd3d12Device->CopyDescriptorsSimple(1, DynamicSamplerDescriptors.GetCpuHandle(DynamicSamplerTblOffset), Res.CPUDescriptorHandle, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER); else LOG_ERROR_MESSAGE("No valid sampler descriptor handle found for root parameter ", RootInd, ", descriptor slot ", OffsetFromTableStart); @@ -972,7 +973,8 @@ template<bool PerformResourceTransitions> void RootSignature::CommitDescriptorHandlesInternal_SM(RenderDeviceD3D12Impl* pRenderDeviceD3D12, ShaderResourceCacheD3D12& ResourceCache, CommandContext& Ctx, - bool IsCompute)const + bool IsCompute, + bool ValidateStates)const { VERIFY_EXPR(m_TotalSrvCbvUavSlots[SHADER_VARIABLE_TYPE_DYNAMIC] == 0 && m_TotalSamplerSlots[SHADER_VARIABLE_TYPE_DYNAMIC] == 0); @@ -981,7 +983,7 @@ void RootSignature::CommitDescriptorHandlesInternal_SM(RenderDeviceD3D12Impl* Ctx.SetDescriptorHeaps(Heaps); m_RootParams.ProcessRootTables( - [&](Uint32 RootInd, const RootParameter &RootTable, const D3D12_ROOT_PARAMETER& D3D12Param, bool IsResourceTable, D3D12_DESCRIPTOR_HEAP_TYPE dbgHeapType ) + [&](Uint32 RootInd, const RootParameter& RootTable, const D3D12_ROOT_PARAMETER& D3D12Param, bool IsResourceTable, D3D12_DESCRIPTOR_HEAP_TYPE dbgHeapType ) { VERIFY(RootTable.GetShaderVariableType() != SHADER_VARIABLE_TYPE_DYNAMIC, "Unexpected dynamic resource"); @@ -990,7 +992,7 @@ void RootSignature::CommitDescriptorHandlesInternal_SM(RenderDeviceD3D12Impl* ResourceCache.GetShaderVisibleTableGPUDescriptorHandle<D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER>(RootInd); VERIFY(RootTableGPUDescriptorHandle.ptr != 0, "Unexpected null GPU descriptor handle"); - if(IsCompute) + if (IsCompute) Ctx.GetCommandList()->SetComputeRootDescriptorTable(RootInd, RootTableGPUDescriptorHandle); else Ctx.GetCommandList()->SetGraphicsRootDescriptorTable(RootInd, RootTableGPUDescriptorHandle); @@ -998,19 +1000,19 @@ void RootSignature::CommitDescriptorHandlesInternal_SM(RenderDeviceD3D12Impl* if(PerformResourceTransitions) { ProcessCachedTableResources(RootInd, D3D12Param, ResourceCache, dbgHeapType, - [&](UINT OffsetFromTableStart, const D3D12_DESCRIPTOR_RANGE &range, ShaderResourceCacheD3D12::Resource &Res) + [&](UINT OffsetFromTableStart, const D3D12_DESCRIPTOR_RANGE& range, ShaderResourceCacheD3D12::Resource& Res) { TransitionResource(Ctx, Res, range.RangeType); } ); } -#ifdef _DEBUG - else +#ifdef DEVELOPMENT + else if(ValidateStates) { ProcessCachedTableResources(RootInd, D3D12Param, ResourceCache, dbgHeapType, - [&](UINT OffsetFromTableStart, const D3D12_DESCRIPTOR_RANGE &range, ShaderResourceCacheD3D12::Resource &Res) + [&](UINT OffsetFromTableStart, const D3D12_DESCRIPTOR_RANGE& range, const ShaderResourceCacheD3D12::Resource &Res) { - DbgVerifyResourceState(Res, range.RangeType); + DvpVerifyResourceState(Res, range.RangeType); } ); } @@ -1024,7 +1026,7 @@ void RootSignature::TransitionResources(ShaderResourceCacheD3D12& ResourceCache, CommandContext& Ctx)const { m_RootParams.ProcessRootTables( - [&](Uint32 RootInd, const RootParameter &RootTable, const D3D12_ROOT_PARAMETER& D3D12Param, bool IsResourceTable, D3D12_DESCRIPTOR_HEAP_TYPE dbgHeapType ) + [&](Uint32 RootInd, const RootParameter& RootTable, const D3D12_ROOT_PARAMETER& D3D12Param, bool IsResourceTable, D3D12_DESCRIPTOR_HEAP_TYPE dbgHeapType ) { ProcessCachedTableResources(RootInd, D3D12Param, ResourceCache, dbgHeapType, [&](UINT OffsetFromTableStart, const D3D12_DESCRIPTOR_RANGE &range, ShaderResourceCacheD3D12::Resource &Res) @@ -1042,7 +1044,7 @@ void RootSignature::CommitRootViews(ShaderResourceCacheD3D12& ResourceCache, bool IsCompute, DeviceContextD3D12Impl* pCtx)const { - for(Uint32 rv = 0; rv < m_RootParams.GetNumRootViews(); ++rv) + for (Uint32 rv = 0; rv < m_RootParams.GetNumRootViews(); ++rv) { auto& RootView = m_RootParams.GetRootView(rv); auto RootInd = RootView.GetRootIndex(); diff --git a/Graphics/GraphicsEngineD3D12/src/ShaderD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/ShaderD3D12Impl.cpp index dd7a1c55..171ab81a 100644 --- a/Graphics/GraphicsEngineD3D12/src/ShaderD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/ShaderD3D12Impl.cpp @@ -62,7 +62,7 @@ ShaderD3D12Impl::~ShaderD3D12Impl() IMPLEMENT_QUERY_INTERFACE( ShaderD3D12Impl, IID_ShaderD3D12, TShaderBase ) #ifdef DEVELOPMENT -bool ShaderD3D12Impl::DvpVerifyStaticResourceBindings() +bool ShaderD3D12Impl::DvpVerifyStaticResourceBindings()const { return m_StaticResLayout.dvpVerifyBindings(m_StaticResCache); } diff --git a/Graphics/GraphicsEngineD3D12/src/ShaderResourceBindingD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/ShaderResourceBindingD3D12Impl.cpp index ca2e161c..a76c9f58 100644 --- a/Graphics/GraphicsEngineD3D12/src/ShaderResourceBindingD3D12Impl.cpp +++ b/Graphics/GraphicsEngineD3D12/src/ShaderResourceBindingD3D12Impl.cpp @@ -136,9 +136,9 @@ IShaderVariable* ShaderResourceBindingD3D12Impl::GetVariable(SHADER_TYPE ShaderT #ifdef DEVELOPMENT -void ShaderResourceBindingD3D12Impl::dvpVerifyResourceBindings(const PipelineStateD3D12Impl* pPSO) +void ShaderResourceBindingD3D12Impl::dvpVerifyResourceBindings(const PipelineStateD3D12Impl* pPSO)const { - auto* pRefPSO = ValidatedCast<PipelineStateD3D12Impl>(GetPipelineState()); + auto* pRefPSO = GetPipelineState<const PipelineStateD3D12Impl>(); if (pPSO->IsIncompatibleWith(pRefPSO)) { LOG_ERROR("Shader resource binding is incompatible with the pipeline state \"", pPSO->GetDesc().Name, '\"'); diff --git a/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp b/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp index acba699f..c3ae8c12 100644 --- a/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp +++ b/Graphics/GraphicsEngineD3D12/src/ShaderResourceLayoutD3D12.cpp @@ -795,19 +795,19 @@ void ShaderResourceLayoutD3D12::CopyStaticResourceDesriptorHandles(const ShaderR #ifdef DEVELOPMENT -bool ShaderResourceLayoutD3D12::dvpVerifyBindings(ShaderResourceCacheD3D12& ResourceCache)const +bool ShaderResourceLayoutD3D12::dvpVerifyBindings(const ShaderResourceCacheD3D12& ResourceCache)const { bool BindingsOK = true; for (SHADER_VARIABLE_TYPE VarType = SHADER_VARIABLE_TYPE_STATIC; VarType < SHADER_VARIABLE_TYPE_NUM_TYPES; VarType = static_cast<SHADER_VARIABLE_TYPE>(VarType+1)) { for (Uint32 r=0; r < GetCbvSrvUavCount(VarType); ++r) { - const auto &res = GetSrvCbvUav(VarType, r); + const auto& res = GetSrvCbvUav(VarType, r); VERIFY(res.Attribs.GetVariableType() == VarType, "Unexpected variable type"); for (Uint32 ArrInd = 0; ArrInd < res.Attribs.BindCount; ++ArrInd) { - const auto &CachedRes = ResourceCache.GetRootTable(res.RootIndex).GetResource(res.OffsetFromTableStart + ArrInd, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, m_pResources->GetShaderType()); + const auto& CachedRes = ResourceCache.GetRootTable(res.RootIndex).GetResource(res.OffsetFromTableStart + ArrInd, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, m_pResources->GetShaderType()); if (CachedRes.pObject) VERIFY(CachedRes.Type == res.GetResType(), "Inconsistent cached resource types"); else @@ -824,13 +824,14 @@ bool ShaderResourceLayoutD3D12::dvpVerifyBindings(ShaderResourceCacheD3D12& Reso if (res.Attribs.BindCount > 1 && res.ValidSamplerAssigned()) { // Verify that if single sampler is used for all texture array elements, all samplers set in the resource views are consistent - const auto& SamInfo = const_cast<ShaderResourceLayoutD3D12*>(this)->GetAssignedSampler(res); + const auto& SamInfo = GetAssignedSampler(res); if (SamInfo.Attribs.BindCount == 1) { const auto& CachedSampler = ResourceCache.GetRootTable(SamInfo.RootIndex).GetResource(SamInfo.OffsetFromTableStart, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, m_pResources->GetShaderType()); - if (auto* pTexView = CachedRes.pObject.RawPtr<const ITextureView>()) + // Conversion must always succeed as the type is verified when resource is bound to the variable + if (const auto* pTexView = CachedRes.pObject.RawPtr<const TextureViewD3D12Impl>()) { - auto* pSampler = const_cast<ITextureView*>(pTexView)->GetSampler(); + const auto* pSampler = pTexView->GetSampler(); if (pSampler != nullptr && CachedSampler.pObject != nullptr && CachedSampler.pObject != pSampler) { LOG_ERROR_MESSAGE( "All elements of texture array '", res.Attribs.Name, "' in shader '", GetShaderName(), "' share the same sampler. However, the sampler set in view for element ", ArrInd, " does not match bound sampler. This may cause incorrect behavior on GL platform." ); @@ -841,7 +842,7 @@ bool ShaderResourceLayoutD3D12::dvpVerifyBindings(ShaderResourceCacheD3D12& Reso #ifdef _DEBUG { - auto ShdrVisibleHeapCPUDescriptorHandle = ResourceCache.GetShaderVisibleTableCPUDescriptorHandle<D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV>(res.RootIndex, res.OffsetFromTableStart + ArrInd); + const auto ShdrVisibleHeapCPUDescriptorHandle = ResourceCache.GetShaderVisibleTableCPUDescriptorHandle<D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV>(res.RootIndex, res.OffsetFromTableStart + ArrInd); if (ResourceCache.DbgGetContentType() == ShaderResourceCacheD3D12::DbgCacheContentType::StaticShaderResources) { VERIFY(ShdrVisibleHeapCPUDescriptorHandle.ptr == 0, "Static shader resources of a shader should not be assigned shader visible descriptor space"); @@ -877,7 +878,7 @@ bool ShaderResourceLayoutD3D12::dvpVerifyBindings(ShaderResourceCacheD3D12& Reso for (Uint32 ArrInd = 0; ArrInd < SamInfo.Attribs.BindCount; ++ArrInd) { - const auto &CachedSampler = ResourceCache.GetRootTable(SamInfo.RootIndex).GetResource(SamInfo.OffsetFromTableStart + ArrInd, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, m_pResources->GetShaderType()); + const auto& CachedSampler = ResourceCache.GetRootTable(SamInfo.RootIndex).GetResource(SamInfo.OffsetFromTableStart + ArrInd, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, m_pResources->GetShaderType()); if (CachedSampler.pObject) VERIFY(CachedSampler.Type == CachedResourceType::Sampler, "Incorrect cached sampler type"); else @@ -890,7 +891,7 @@ bool ShaderResourceLayoutD3D12::dvpVerifyBindings(ShaderResourceCacheD3D12& Reso #ifdef _DEBUG { - auto ShdrVisibleHeapCPUDescriptorHandle = ResourceCache.GetShaderVisibleTableCPUDescriptorHandle<D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER>(SamInfo.RootIndex, SamInfo.OffsetFromTableStart + ArrInd); + const auto ShdrVisibleHeapCPUDescriptorHandle = ResourceCache.GetShaderVisibleTableCPUDescriptorHandle<D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER>(SamInfo.RootIndex, SamInfo.OffsetFromTableStart + ArrInd); if (ResourceCache.DbgGetContentType() == ShaderResourceCacheD3D12::DbgCacheContentType::StaticShaderResources) { VERIFY(ShdrVisibleHeapCPUDescriptorHandle.ptr == 0, "Static shader resources of a shader should not be assigned shader visible descriptor space"); @@ -914,12 +915,12 @@ bool ShaderResourceLayoutD3D12::dvpVerifyBindings(ShaderResourceCacheD3D12& Reso for (Uint32 s=0; s < GetSamplerCount(VarType); ++s) { - const auto &sam = GetSampler(VarType, s); + const auto& sam = GetSampler(VarType, s); VERIFY(sam.Attribs.GetVariableType() == VarType, "Unexpected sampler variable type"); for (Uint32 ArrInd = 0; ArrInd < sam.Attribs.BindCount; ++ArrInd) { - const auto &CachedSampler = ResourceCache.GetRootTable(sam.RootIndex).GetResource(sam.OffsetFromTableStart + ArrInd, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, m_pResources->GetShaderType()); + const auto& CachedSampler = ResourceCache.GetRootTable(sam.RootIndex).GetResource(sam.OffsetFromTableStart + ArrInd, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, m_pResources->GetShaderType()); if (CachedSampler.pObject) VERIFY(CachedSampler.Type == CachedResourceType::Sampler, "Incorrect cached sampler type"); else @@ -954,7 +955,7 @@ const Char* ShaderResourceLayoutD3D12::GetShaderName()const auto NumShaders = pPSOD3D12->GetNumShaders(); for (Uint32 s = 0; s < NumShaders; ++s) { - const auto &ShaderDesc = ppShaders[s]->GetDesc(); + const auto& ShaderDesc = ppShaders[s]->GetDesc(); if(ShaderDesc.ShaderType == m_pResources->GetShaderType()) return ShaderDesc.Name; } diff --git a/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h b/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h index 0dea061f..a1d645af 100644 --- a/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h +++ b/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h @@ -214,7 +214,7 @@ public: private: void CommitRenderPassAndFramebuffer(); - void CommitVkVertexBuffers(bool TransitionBuffers); + void CommitVkVertexBuffers(bool TransitionBuffers, bool VerifyStates); void TransitionVkVertexBuffers(); void CommitViewports(); void CommitScissorRects(); diff --git a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp index 71648849..de99f36f 100644 --- a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp +++ b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp @@ -306,7 +306,7 @@ namespace Diligent } } - void DeviceContextVkImpl::CommitVkVertexBuffers(bool TransitionBuffers) + void DeviceContextVkImpl::CommitVkVertexBuffers(bool TransitionBuffers, bool VerifyStates) { #ifdef DEVELOPMENT if (m_NumVertexStreams < m_pPipelineState->GetNumBufferSlotsUsed()) @@ -342,7 +342,7 @@ namespace Diligent } } #ifdef DEVELOPMENT - else + else if (VerifyStates) { if (pBufferVk->IsInKnownState() && !pBufferVk->CheckState(RESOURCE_STATE_VERTEX_BUFFER)) { @@ -379,9 +379,9 @@ namespace Diligent { std::stringstream ss; ss << "Active render pass is incomaptible with PSO '" << m_pPipelineState->GetDesc().Name << "'. " - "This indicates the mismatch between the number and/or format of bound render targets and/or depth stencil buffer " - "and the PSO. Vulkand requires exact match.\n" - " Bound render targets (" << m_NumBoundRenderTargets << "):"; + "This indicates the mismatch between the number and/or format of bound render targets and/or depth stencil buffer " + "and the PSO. Vulkand requires exact match.\n" + " Bound render targets (" << m_NumBoundRenderTargets << "):"; Uint32 SampleCount = 0; for (Uint32 rt = 0; rt < m_NumBoundRenderTargets; ++rt) { @@ -425,6 +425,7 @@ namespace Diligent EnsureVkCmdBuffer(); + const bool VerifyStates = drawAttribs.Flags & DRAW_FLAG_VERIFY_STATES; if ( drawAttribs.IsIndexed ) { #ifdef DEVELOPMENT @@ -448,7 +449,7 @@ namespace Diligent } } #ifdef DEVELOPMENT - else + else if (VerifyStates) { if (pBuffVk->IsInKnownState() && !pBuffVk->CheckState(RESOURCE_STATE_INDEX_BUFFER)) { @@ -472,7 +473,7 @@ namespace Diligent TransitionVkVertexBuffers(); } #ifdef DEVELOPMENT - else + else if (VerifyStates) { for (Uint32 slot = 0; slot < m_NumVertexStreams; ++slot ) { @@ -490,7 +491,7 @@ namespace Diligent } else { - CommitVkVertexBuffers(TransitionVertexBuffers); + CommitVkVertexBuffers(TransitionVertexBuffers, VerifyStates); } if (m_DescrSetBindInfo.DynamicOffsetCount != 0) m_pPipelineState->BindDescriptorSetsWithDynamicOffsets(this, m_DescrSetBindInfo); @@ -520,7 +521,7 @@ namespace Diligent } } #ifdef DEVELOPMENT - else + else if (VerifyStates) { if (pIndirectDrawAttribsVk->IsInKnownState() && !pIndirectDrawAttribsVk->CheckState(RESOURCE_STATE_INDIRECT_ARGUMENT)) { @@ -598,7 +599,7 @@ namespace Diligent pBufferVk->DvpVerifyDynamicAllocation(this); #endif - if(DispatchAttrs.Flags & DISPATCH_FLAG_TRANSITION_INDIRECT_ARGS_BUFFER) + if (DispatchAttrs.Flags & DISPATCH_FLAG_TRANSITION_INDIRECT_ARGS_BUFFER) { // Buffer memory barries must be executed outside of render pass if (pBufferVk->IsInKnownState()) @@ -611,7 +612,7 @@ namespace Diligent } } #ifdef DEVELOPMENT - else + else if (DispatchAttrs.Flags & DISPATCH_FLAG_VERIFY_STATES) { if (pBufferVk->IsInKnownState() && !pBufferVk->CheckState(RESOURCE_STATE_INDIRECT_ARGUMENT)) { |
