summaryrefslogtreecommitdiffstats
path: root/Graphics
diff options
context:
space:
mode:
authorEgor Yusov <egor.yusov@gmail.com>2018-11-21 03:38:52 +0000
committerEgor Yusov <egor.yusov@gmail.com>2018-11-21 03:38:52 +0000
commit3d9f381db2749ec19e5f49b9d095da95445cb806 (patch)
tree73c50e25aebfc353b348de3edfeb76f3090ac625 /Graphics
parentImplemented explicit layout transitions in Vulkan backend (diff)
downloadDiligentCore-3d9f381db2749ec19e5f49b9d095da95445cb806.tar.gz
DiligentCore-3d9f381db2749ec19e5f49b9d095da95445cb806.zip
Implemented explicit state transitions in D3D11 backend (closed https://github.com/DiligentGraphics/DiligentCore/issues/6)
Diffstat (limited to 'Graphics')
-rw-r--r--Graphics/GraphicsAccessories/interface/GraphicsAccessories.h2
-rw-r--r--Graphics/GraphicsAccessories/src/GraphicsAccessories.cpp57
-rw-r--r--Graphics/GraphicsEngine/include/DeviceContextBase.h46
-rw-r--r--Graphics/GraphicsEngineD3D11/include/BufferD3D11Impl.h19
-rw-r--r--Graphics/GraphicsEngineD3D11/include/TextureBaseD3D11.h18
-rw-r--r--Graphics/GraphicsEngineD3D11/src/BufferD3D11Impl.cpp2
-rwxr-xr-xGraphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp217
-rw-r--r--Graphics/GraphicsEngineD3D11/src/TextureBaseD3D11.cpp1
-rw-r--r--Graphics/GraphicsEngineD3D12/src/CommandContext.cpp24
-rw-r--r--Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp5
-rw-r--r--Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp44
11 files changed, 302 insertions, 133 deletions
diff --git a/Graphics/GraphicsAccessories/interface/GraphicsAccessories.h b/Graphics/GraphicsAccessories/interface/GraphicsAccessories.h
index 89641c1c..36a0b0fa 100644
--- a/Graphics/GraphicsAccessories/interface/GraphicsAccessories.h
+++ b/Graphics/GraphicsAccessories/interface/GraphicsAccessories.h
@@ -282,4 +282,6 @@ inline bool IsAnisotropicFilter(FILTER_TYPE FilterType)
FilterType == FILTER_TYPE_MAXIMUM_ANISOTROPIC;
}
+bool VerifyResourceStates(RESOURCE_STATE State, bool IsTexture);
+
}
diff --git a/Graphics/GraphicsAccessories/src/GraphicsAccessories.cpp b/Graphics/GraphicsAccessories/src/GraphicsAccessories.cpp
index 3a51a2c2..0f316e5c 100644
--- a/Graphics/GraphicsAccessories/src/GraphicsAccessories.cpp
+++ b/Graphics/GraphicsAccessories/src/GraphicsAccessories.cpp
@@ -815,6 +815,7 @@ String GetResourceStateString( RESOURCE_STATE State )
auto lsb = State & ~(State-1);
const auto* StateFlagString = GetResourceStateFlagString(static_cast<RESOURCE_STATE>(lsb));
str.append(StateFlagString);
+ State = static_cast<RESOURCE_STATE>(State & ~lsb);
}
return str;
}
@@ -841,4 +842,60 @@ Uint32 ComputeMipLevelsCount( Uint32 Width, Uint32 Height, Uint32 Depth )
return ComputeMipLevelsCount( std::max(std::max( Width, Height ), Depth) );
}
+bool VerifyResourceStates(RESOURCE_STATE State, bool IsTexture)
+{
+ static_assert(RESOURCE_STATE_MAX_BIT == 0x8000, "Please update this function to handle the new resource state");
+
+#define VERIFY_EXCLUSIVE_STATE(ExclusiveState)\
+if ( (State & ExclusiveState) != 0 && (State & ~ExclusiveState) != 0 )\
+{\
+ LOG_ERROR_MESSAGE("State ", GetResourceStateString(State), " is invalid: " #ExclusiveState " can't be combined with any other state");\
+ return false;\
+}
+
+ VERIFY_EXCLUSIVE_STATE(RESOURCE_STATE_UNDEFINED);
+ VERIFY_EXCLUSIVE_STATE(RESOURCE_STATE_UNORDERED_ACCESS);
+ VERIFY_EXCLUSIVE_STATE(RESOURCE_STATE_RENDER_TARGET);
+ VERIFY_EXCLUSIVE_STATE(RESOURCE_STATE_DEPTH_WRITE);
+ VERIFY_EXCLUSIVE_STATE(RESOURCE_STATE_COPY_DEST);
+ VERIFY_EXCLUSIVE_STATE(RESOURCE_STATE_RESOLVE_DEST);
+ VERIFY_EXCLUSIVE_STATE(RESOURCE_STATE_PRESENT);
+#undef VERIFY_EXCLUSIVE_STATE
+
+ if (IsTexture)
+ {
+ if (State &
+ (RESOURCE_STATE_VERTEX_BUFFER |
+ RESOURCE_STATE_CONSTANT_BUFFER |
+ RESOURCE_STATE_INDEX_BUFFER |
+ RESOURCE_STATE_STREAM_OUT |
+ RESOURCE_STATE_INDIRECT_ARGUMENT))
+ {
+ LOG_ERROR_MESSAGE("State ", GetResourceStateString(State), " is invalid: states RESOURCE_STATE_VERTEX_BUFFER, "
+ "RESOURCE_STATE_CONSTANT_BUFFER, RESOURCE_STATE_INDEX_BUFFER, RESOURCE_STATE_STREAM_OUT, "
+ "RESOURCE_STATE_INDIRECT_ARGUMENT are not applicable to a texture");
+ return false;
+ }
+ }
+ else
+ {
+ if (State &
+ (RESOURCE_STATE_RENDER_TARGET |
+ RESOURCE_STATE_DEPTH_WRITE |
+ RESOURCE_STATE_DEPTH_READ |
+ RESOURCE_STATE_RESOLVE_SOURCE |
+ RESOURCE_STATE_RESOLVE_DEST |
+ RESOURCE_STATE_PRESENT))
+ {
+ LOG_ERROR_MESSAGE("State ", GetResourceStateString(State), " is invalid: states RESOURCE_STATE_RENDER_TARGET, "
+ "RESOURCE_STATE_DEPTH_WRITE, RESOURCE_STATE_DEPTH_READ, RESOURCE_STATE_RESOLVE_SOURCE, "
+ "RESOURCE_STATE_RESOLVE_DEST, RESOURCE_STATE_PRESENT are not applicable to a buffer");
+ return false;
+
+ }
+ }
+
+ return true;
+}
+
}
diff --git a/Graphics/GraphicsEngine/include/DeviceContextBase.h b/Graphics/GraphicsEngine/include/DeviceContextBase.h
index b7851dae..23861605 100644
--- a/Graphics/GraphicsEngine/include/DeviceContextBase.h
+++ b/Graphics/GraphicsEngine/include/DeviceContextBase.h
@@ -146,6 +146,7 @@ protected:
#ifdef DEVELOPMENT
bool DvpVerifyDrawArguments(const DrawAttribs& drawAttribs);
bool DvpVerifyDispatchArguments(const DispatchComputeAttribs &DispatchAttrs);
+ void DvpVerifyStateTransitionDesc(const StateTransitionDesc& Barrier);
#endif
/// Strong reference to the device.
@@ -693,6 +694,51 @@ inline bool DeviceContextBase<BaseInterface, BufferImplType, TextureViewImplType
return true;
}
+template<typename BaseInterface, typename BufferImplType, typename TextureViewImplType, typename PipelineStateImplType>
+void DeviceContextBase<BaseInterface, BufferImplType, TextureViewImplType, PipelineStateImplType> :: DvpVerifyStateTransitionDesc(const StateTransitionDesc& Barrier)
+{
+ DEV_CHECK_ERR((Barrier.pTexture != nullptr) ^ (Barrier.pBuffer != nullptr), "Exactly one of pTexture or pBuffer members of StateTransitionDesc must not be null");
+ DEV_CHECK_ERR(Barrier.NewState != RESOURCE_STATE_UNKNOWN, "New resource state can't be unknown");
+ if (Barrier.pTexture)
+ {
+ const auto& TexDesc = Barrier.pTexture->GetDesc();
+
+ DEV_CHECK_ERR(VerifyResourceStates(Barrier.NewState, true), "Invlaid new state specified for texture '", TexDesc.Name, "'");
+ auto OldState = Barrier.OldState != RESOURCE_STATE_UNKNOWN ? Barrier.OldState : Barrier.pTexture->GetState();
+ DEV_CHECK_ERR(OldState != RESOURCE_STATE_UNKNOWN, "The state of texture '", TexDesc.Name, "' is unknown to the engine and is not explicitly specified in the barrier");
+ DEV_CHECK_ERR(VerifyResourceStates(OldState, true), "Invlaid old state specified for texture '", TexDesc.Name, "'");
+
+ DEV_CHECK_ERR(Barrier.FirstMipLevel < TexDesc.MipLevels, "First mip level (", Barrier.FirstMipLevel, ") specified by the barrier is "
+ "out of range. Texture '", TexDesc.Name, "' has only ", TexDesc.MipLevels, " mip level(s)");
+ DEV_CHECK_ERR(Barrier.MipLevelsCount == StateTransitionDesc::RemainingMipLevels || Barrier.FirstMipLevel + Barrier.MipLevelsCount < TexDesc.MipLevels,
+ "Mip level range ", Barrier.FirstMipLevel, "..", Barrier.FirstMipLevel+Barrier.MipLevelsCount-1, " "
+ "specified by the barrier is out of range. Texture '", TexDesc.Name, "' has only ", TexDesc.MipLevels, " mip level(s)");
+
+ DEV_CHECK_ERR(Barrier.FirstArraySlice < TexDesc.ArraySize, "First array slice (", Barrier.FirstArraySlice, ") specified by the barrier is "
+ "out of range. Array size of texture '", TexDesc.Name, "' is ", TexDesc.ArraySize);
+ DEV_CHECK_ERR(Barrier.ArraySliceCount == StateTransitionDesc::RemainingArraySlices || Barrier.FirstArraySlice + Barrier.ArraySliceCount < TexDesc.ArraySize,
+ "Array slice range ", Barrier.FirstArraySlice, "..", Barrier.FirstArraySlice+Barrier.ArraySliceCount-1, " "
+ "specified by the barrier is out of range. Array size of texture '", TexDesc.Name, "' is ", TexDesc.ArraySize);
+
+ auto DevType = m_pDevice->GetDeviceCaps().DevType;
+ if (DevType != DeviceType::D3D12 && DevType != DeviceType::Vulkan)
+ {
+ DEV_CHECK_ERR(Barrier.FirstMipLevel == 0 && (Barrier.MipLevelsCount == StateTransitionDesc::RemainingMipLevels || Barrier.MipLevelsCount == TexDesc.MipLevels),
+ "Failed to transition texture '", TexDesc.Name, "': only whole resources can be transitioned on this device");
+ DEV_CHECK_ERR(Barrier.FirstArraySlice == 0 && (Barrier.ArraySliceCount == StateTransitionDesc::RemainingArraySlices || Barrier.ArraySliceCount == TexDesc.ArraySize),
+ "Failed to transition texture '", TexDesc.Name, "': only whole resources can be transitioned on this device");
+ }
+ }
+ else
+ {
+ const auto& BuffDesc = Barrier.pBuffer->GetDesc();
+ DEV_CHECK_ERR(VerifyResourceStates(Barrier.NewState, false), "Invlaid new state specified for buffer '", BuffDesc.Name, "'");
+ auto OldState = Barrier.OldState != RESOURCE_STATE_UNKNOWN ? Barrier.OldState : Barrier.pBuffer->GetState();
+ DEV_CHECK_ERR(OldState != RESOURCE_STATE_UNKNOWN, "The state of buffer '", BuffDesc.Name, "' is unknown to the engine and is not explicitly specified in the barrier");
+ DEV_CHECK_ERR(VerifyResourceStates(OldState, false), "Invlaid old state specified for buffer '", BuffDesc.Name, "'");
+ }
+}
+
#endif
diff --git a/Graphics/GraphicsEngineD3D11/include/BufferD3D11Impl.h b/Graphics/GraphicsEngineD3D11/include/BufferD3D11Impl.h
index 80fed967..c0d47666 100644
--- a/Graphics/GraphicsEngineD3D11/include/BufferD3D11Impl.h
+++ b/Graphics/GraphicsEngineD3D11/include/BufferD3D11Impl.h
@@ -37,17 +37,6 @@ namespace Diligent
class FixedBlockMemoryAllocator;
-enum class D3D11BufferState
-{
- Undefined = 0x00,
- ShaderResource = 0x01,
- ConstantBuffer = 0x02,
- VertexBuffer = 0x04,
- IndexBuffer = 0x08,
- UnorderedAccess = 0x10,
- AnyInput = ShaderResource | ConstantBuffer | VertexBuffer | IndexBuffer
-};
-
/// Implementation of the Diligent::IBufferD3D11 interface
class BufferD3D11Impl final : public BufferBase<IBufferD3D11, RenderDeviceD3D11Impl, BufferViewD3D11Impl, FixedBlockMemoryAllocator>
{
@@ -79,10 +68,8 @@ public:
virtual void* GetNativeHandle()override final { return GetD3D11Buffer(); }
- void ResetState(D3D11BufferState State){m_State = static_cast<Uint32>(State);}
- void AddState(D3D11BufferState State) {m_State |= static_cast<Uint32>(State);}
- void ClearState(D3D11BufferState State){m_State &= ~static_cast<Uint32>(State);}
- bool CheckState(D3D11BufferState State){return (m_State & static_cast<Uint32>(State)) ? true : false;}
+ void AddState (RESOURCE_STATE State){m_State = static_cast<RESOURCE_STATE>(m_State | State);}
+ void ClearState(RESOURCE_STATE State){m_State = static_cast<RESOURCE_STATE>(m_State & ~static_cast<Uint32>(State));}
private:
virtual void CreateViewInternal( const struct BufferViewDesc &ViewDesc, IBufferView **ppView, bool bIsDefaultView )override;
@@ -92,8 +79,6 @@ private:
friend class DeviceContextD3D11Impl;
CComPtr<ID3D11Buffer> m_pd3d11Buffer; ///< D3D11 buffer object
-
- Uint32 m_State = static_cast<Uint32>(D3D11BufferState::Undefined);
};
}
diff --git a/Graphics/GraphicsEngineD3D11/include/TextureBaseD3D11.h b/Graphics/GraphicsEngineD3D11/include/TextureBaseD3D11.h
index 662220a4..f17bba70 100644
--- a/Graphics/GraphicsEngineD3D11/include/TextureBaseD3D11.h
+++ b/Graphics/GraphicsEngineD3D11/include/TextureBaseD3D11.h
@@ -37,16 +37,6 @@ namespace Diligent
class FixedBlockMemoryAllocator;
-enum class D3D11TextureState
-{
- Undefined = 0x0,
- ShaderResource = 0x1,
- RenderTarget = 0x2,
- DepthStencil = 0x4,
- UnorderedAccess = 0x8,
- Output = RenderTarget | DepthStencil | UnorderedAccess
-};
-
/// Base implementation of the Diligent::ITextureD3D11 interface
class TextureBaseD3D11 : public TextureBase<ITextureD3D11, RenderDeviceD3D11Impl, TextureViewD3D11Impl, FixedBlockMemoryAllocator>
{
@@ -90,10 +80,8 @@ public:
Uint32 DstY,
Uint32 DstZ);
- void ResetState(D3D11TextureState State){m_State = static_cast<Uint32>(State);}
- void AddState(D3D11TextureState State) {m_State |= static_cast<Uint32>(State);}
- void ClearState(D3D11TextureState State){m_State &= ~static_cast<Uint32>(State);}
- bool CheckState(D3D11TextureState State){return (m_State & static_cast<Uint32>(State)) ? true : false;}
+ void AddState (RESOURCE_STATE State){m_State = static_cast<RESOURCE_STATE>(m_State | State);}
+ void ClearState(RESOURCE_STATE State){m_State = static_cast<RESOURCE_STATE>(m_State & ~static_cast<Uint32>(State));}
protected:
void CreateViewInternal( const struct TextureViewDesc &ViewDesc, ITextureView **ppView, bool bIsDefaultView )override final;
@@ -108,8 +96,6 @@ protected:
friend class RenderDeviceD3D11Impl;
/// D3D11 texture
CComPtr<ID3D11Resource> m_pd3d11Texture;
-
- Uint32 m_State = static_cast<Uint32>(D3D11TextureState::Undefined);
};
}
diff --git a/Graphics/GraphicsEngineD3D11/src/BufferD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/BufferD3D11Impl.cpp
index 28940739..d0888937 100644
--- a/Graphics/GraphicsEngineD3D11/src/BufferD3D11Impl.cpp
+++ b/Graphics/GraphicsEngineD3D11/src/BufferD3D11Impl.cpp
@@ -103,6 +103,8 @@ BufferD3D11Impl :: BufferD3D11Impl(IReferenceCounters* pRefCounters,
auto hr = m_pd3d11Buffer->SetPrivateData(WKPDID_D3DDebugObjectName, static_cast<UINT>(strlen(m_Desc.Name)), m_Desc.Name);
DEV_CHECK_ERR(SUCCEEDED(hr), "Failed to set buffer name");
}
+
+ SetState(RESOURCE_STATE_UNDEFINED);
}
static BufferDesc BuffDescFromD3D11Buffer(ID3D11Buffer *pd3d11Buffer, BufferDesc BuffDesc)
diff --git a/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp
index 9b586f70..dee55fc8 100755
--- a/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp
+++ b/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp
@@ -244,38 +244,38 @@ namespace Diligent
// individually, or not rely on the state and check current context bindings
if(TransitionResources)
{
- if ( auto* pTexture = const_cast<TextureBaseD3D11*>(UAVRes.pTexture) )
+ if ( auto* pTexture = ValidatedCast<TextureBaseD3D11>(UAVRes.pTexture) )
{
- if( !pTexture->CheckState(D3D11TextureState::UnorderedAccess) )
+ if( pTexture->IsInKnownState() && !pTexture->CheckState(RESOURCE_STATE_UNORDERED_ACCESS) )
{
- if( pTexture->CheckState(D3D11TextureState::ShaderResource) )
+ if( pTexture->CheckState(RESOURCE_STATE_SHADER_RESOURCE) )
UnbindTextureFromInput( pTexture, UAVRes.pd3d11Resource );
- pTexture->ResetState(D3D11TextureState::UnorderedAccess);
+ pTexture->SetState(RESOURCE_STATE_UNORDERED_ACCESS);
}
}
- else if( auto* pBuffer = const_cast<BufferD3D11Impl*>(UAVRes.pBuffer) )
+ else if( auto* pBuffer = ValidatedCast<BufferD3D11Impl>(UAVRes.pBuffer) )
{
- if( !pBuffer->CheckState(D3D11BufferState::UnorderedAccess) )
+ if( pBuffer->IsInKnownState() && !pBuffer->CheckState(RESOURCE_STATE_UNORDERED_ACCESS) )
{
- if( pBuffer->CheckState(D3D11BufferState::AnyInput) )
+ if( (pBuffer->GetState() & RESOURCE_STATE_GENERIC_READ) != 0 )
UnbindBufferFromInput( pBuffer, UAVRes.pd3d11Resource );
- pBuffer->ResetState(D3D11BufferState::UnorderedAccess);
+ pBuffer->SetState(RESOURCE_STATE_UNORDERED_ACCESS);
}
}
}
#ifdef DEVELOPMENT
else
{
- if ( auto* pTexture = const_cast<TextureBaseD3D11*>(UAVRes.pTexture) )
+ if ( auto* pTexture = ValidatedCast<TextureBaseD3D11>(UAVRes.pTexture) )
{
- if( !pTexture->CheckState(D3D11TextureState::UnorderedAccess) )
+ if( pTexture->IsInKnownState () && !pTexture->CheckState(RESOURCE_STATE_UNORDERED_ACCESS) )
{
LOG_ERROR_MESSAGE("Texture \"", pTexture->GetDesc().Name, "\" has not been transitioned to Unordered Access state. Did you forget to call TransitionResources()?");
}
}
- else if( auto* pBuffer = const_cast<BufferD3D11Impl*>(UAVRes.pBuffer) )
+ else if( auto* pBuffer = ValidatedCast<BufferD3D11Impl>(UAVRes.pBuffer) )
{
- if( !pBuffer->CheckState(D3D11BufferState::UnorderedAccess) )
+ if( pBuffer->IsInKnownState() && !pBuffer->CheckState(RESOURCE_STATE_UNORDERED_ACCESS) )
{
LOG_ERROR_MESSAGE("Buffer \"", pBuffer->GetDesc().Name, "\" has not been transitioned to Unordered Access state. Did you forget to call TransitionResources()?");
}
@@ -384,23 +384,23 @@ namespace Diligent
if(TransitionResources)
{
auto &CB = CachedCBs[cb];
- if( auto* pBuff = const_cast<BufferD3D11Impl*>(CB.pBuff.RawPtr()) )
+ if( auto* pBuff = CB.pBuff.RawPtr<BufferD3D11Impl>() )
{
// WARNING! This code is not thread-safe. If several threads change
// the buffer state, the results will be undefined.
// The solution may be to keep track of the state for each thread
// individually, or not rely on the state and check current context bindings
- if(!pBuff->CheckState(D3D11BufferState::ConstantBuffer))
+ if(pBuff->IsInKnownState() && !pBuff->CheckState(RESOURCE_STATE_CONSTANT_BUFFER))
{
- if( pBuff->CheckState(D3D11BufferState::UnorderedAccess) )
+ if( pBuff->CheckState(RESOURCE_STATE_UNORDERED_ACCESS) )
{
// Even though we have unbound resources from UAV, we only checked shader
// stages active in current PSO, so we still may need to unbind the resource
// from UAV (for instance, unbind resource from CS UAV when running draw command).
UnbindResourceFromUAV( pBuff, d3d11CBs[cb] );
- pBuff->ClearState(D3D11BufferState::UnorderedAccess);
+ pBuff->ClearState(RESOURCE_STATE_UNORDERED_ACCESS);
}
- pBuff->AddState(D3D11BufferState::ConstantBuffer);
+ pBuff->AddState(RESOURCE_STATE_CONSTANT_BUFFER);
}
}
}
@@ -409,9 +409,9 @@ namespace Diligent
{
VERIFY_EXPR(CommitResources);
auto &CB = CachedCBs[cb];
- if( auto* pBuff = const_cast<BufferD3D11Impl*>(CB.pBuff.RawPtr()) )
+ if( auto* pBuff = CB.pBuff.RawPtr<BufferD3D11Impl>() )
{
- if (!pBuff->CheckState(D3D11BufferState::ConstantBuffer))
+ if (pBuff->IsInKnownState() && !pBuff->CheckState(RESOURCE_STATE_CONSTANT_BUFFER))
{
LOG_ERROR_MESSAGE("Buffer \"", pBuff->GetDesc().Name, "\" has not been transitioned to Constant Buffer state. Did you forget to call TransitionResources()?");
}
@@ -472,33 +472,34 @@ namespace Diligent
{
if (auto* pTexture = const_cast<TextureBaseD3D11*>(SRVRes.pTexture))
{
- if( !pTexture->CheckState(D3D11TextureState::ShaderResource) )
+ if( pTexture->IsInKnownState() && !pTexture->CheckState(RESOURCE_STATE_SHADER_RESOURCE) )
{
- if( pTexture->CheckState(D3D11TextureState::UnorderedAccess) )
+ if( pTexture->CheckState(RESOURCE_STATE_UNORDERED_ACCESS) )
{
// Even though we have unbound resources from UAV, we only checked shader
// stages active in current PSO, so we still may need to unbind the resource
// from UAV (for instance, unbind resource from CS UAV when running draw command).
UnbindResourceFromUAV(pTexture, SRVRes.pd3d11Resource);
- pTexture->ClearState(D3D11TextureState::UnorderedAccess);
+ pTexture->ClearState(RESOURCE_STATE_UNORDERED_ACCESS);
}
- if( pTexture->CheckState(D3D11TextureState::RenderTarget) )
+ // Clearing RESOURCE_STATE_UNORDERED_ACCESS flag may result in RESOURCE_STATE_UNKNOWN state
+ if( pTexture->IsInKnownState() && pTexture->CheckState(RESOURCE_STATE_RENDER_TARGET) )
UnbindTextureFromRenderTarget(pTexture);
- if( pTexture->CheckState(D3D11TextureState::DepthStencil) )
+ if( pTexture->IsInKnownState() && pTexture->CheckState(RESOURCE_STATE_DEPTH_WRITE) )
UnbindTextureFromDepthStencil(pTexture);
- pTexture->ResetState(D3D11TextureState::ShaderResource);
+ pTexture->SetState(RESOURCE_STATE_SHADER_RESOURCE);
}
}
- else if(auto* pBuffer = const_cast<BufferD3D11Impl*>(SRVRes.pBuffer))
+ else if(auto* pBuffer = ValidatedCast<BufferD3D11Impl>(SRVRes.pBuffer))
{
- if( !pBuffer->CheckState(D3D11BufferState::ShaderResource) )
+ if( pBuffer->IsInKnownState() && !pBuffer->CheckState(RESOURCE_STATE_SHADER_RESOURCE) )
{
- if( pBuffer->CheckState(D3D11BufferState::UnorderedAccess) )
+ if( pBuffer->CheckState(RESOURCE_STATE_UNORDERED_ACCESS) )
{
UnbindResourceFromUAV( pBuffer, SRVRes.pd3d11Resource );
- pBuffer->ClearState(D3D11BufferState::UnorderedAccess);
+ pBuffer->ClearState(RESOURCE_STATE_UNORDERED_ACCESS);
}
- pBuffer->AddState(D3D11BufferState::ShaderResource);
+ pBuffer->AddState(RESOURCE_STATE_SHADER_RESOURCE);
}
}
}
@@ -506,16 +507,16 @@ namespace Diligent
else
{
VERIFY_EXPR(CommitResources);
- if (auto* pTexture = const_cast<TextureBaseD3D11*>(SRVRes.pTexture))
+ if (auto* pTexture = ValidatedCast<TextureBaseD3D11>(SRVRes.pTexture))
{
- if( !pTexture->CheckState(D3D11TextureState::ShaderResource) )
+ if( pTexture->IsInKnownState() && !pTexture->CheckState(RESOURCE_STATE_SHADER_RESOURCE) )
{
LOG_ERROR_MESSAGE("Texture \"", pTexture->GetDesc().Name, "\" has not been transitioned to Shader Resource state. Did you forget to call TransitionResources()?");
}
}
- else if(auto* pBuffer = const_cast<BufferD3D11Impl*>(SRVRes.pBuffer))
+ else if(auto* pBuffer = ValidatedCast<BufferD3D11Impl>(SRVRes.pBuffer))
{
- if( !pBuffer->CheckState(D3D11BufferState::ShaderResource) )
+ if( pBuffer->IsInKnownState() && !pBuffer->CheckState(RESOURCE_STATE_SHADER_RESOURCE) )
{
LOG_ERROR_MESSAGE("Texture \"", pBuffer->GetDesc().Name, "\" has not been transitioned to Shader Resource state. Did you forget to call TransitionResources()?");
}
@@ -661,10 +662,10 @@ namespace Diligent
}
BufferD3D11Impl* pBuffD3D11 = m_pIndexBuffer.RawPtr<BufferD3D11Impl>();
- if( pBuffD3D11->CheckState( D3D11BufferState::UnorderedAccess ) )
+ if( pBuffD3D11->IsInKnownState() && pBuffD3D11->CheckState(RESOURCE_STATE_UNORDERED_ACCESS) )
{
UnbindResourceFromUAV(pBuffD3D11, pBuffD3D11->m_pd3d11Buffer);
- pBuffD3D11->ClearState( D3D11BufferState::UnorderedAccess );
+ pBuffD3D11->ClearState(RESOURCE_STATE_UNORDERED_ACCESS);
}
if( m_CommittedD3D11IndexBuffer != pBuffD3D11->m_pd3d11Buffer ||
@@ -688,7 +689,7 @@ namespace Diligent
m_pd3d11DeviceContext->IASetIndexBuffer( pBuffD3D11->m_pd3d11Buffer, D3D11IndexFmt, m_IndexDataStartOffset );
}
- pBuffD3D11->AddState(D3D11BufferState::IndexBuffer);
+ pBuffD3D11->AddState(RESOURCE_STATE_INDEX_BUFFER);
m_bCommittedD3D11IBUpToDate = true;
}
@@ -708,10 +709,10 @@ namespace Diligent
auto Stride = Strides[Slot];
auto Offset = CurrStream.Offset;
- if(pBuffD3D11Impl != nullptr && pBuffD3D11Impl->CheckState( D3D11BufferState::UnorderedAccess ))
+ if(pBuffD3D11Impl != nullptr && pBuffD3D11Impl->IsInKnownState() && pBuffD3D11Impl->CheckState(RESOURCE_STATE_UNORDERED_ACCESS))
{
UnbindResourceFromUAV(pBuffD3D11Impl, pd3d11Buffer);
- pBuffD3D11Impl->ClearState( D3D11BufferState::UnorderedAccess );
+ pBuffD3D11Impl->ClearState(RESOURCE_STATE_UNORDERED_ACCESS);
}
// It is safe to perform raw pointer check because device context keeps
@@ -727,7 +728,7 @@ namespace Diligent
m_CommittedD3D11VBOffsets[Slot] = Offset;
if (pBuffD3D11Impl)
- pBuffD3D11Impl->AddState( D3D11BufferState::VertexBuffer );
+ pBuffD3D11Impl->AddState(RESOURCE_STATE_VERTEX_BUFFER);
}
}
@@ -1147,21 +1148,21 @@ namespace Diligent
if( !pTexture )return;
UnbindResourceView( m_CommittedD3D11SRVs, m_CommittedD3D11SRVResources, m_NumCommittedSRVs, pd3d11Resource, SetSRVMethods );
- pTexture->ClearState(D3D11TextureState::ShaderResource);
+ pTexture->ClearState(RESOURCE_STATE_SHADER_RESOURCE);
}
void DeviceContextD3D11Impl::UnbindBufferFromInput( BufferD3D11Impl* pBuffer, ID3D11Resource* pd3d11Buffer )
{
VERIFY( pBuffer, "Null buffer provided" );
- if( !pBuffer )return;
-
- if( pBuffer->CheckState(D3D11BufferState::ShaderResource) )
+ if( !pBuffer || !pBuffer->IsInKnownState())return;
+
+ if( pBuffer->CheckState(RESOURCE_STATE_SHADER_RESOURCE) )
{
UnbindResourceView( m_CommittedD3D11SRVs, m_CommittedD3D11SRVResources, m_NumCommittedSRVs, pd3d11Buffer, SetSRVMethods );
- pBuffer->ClearState( D3D11BufferState::ShaderResource );
+ pBuffer->ClearState(RESOURCE_STATE_SHADER_RESOURCE);
}
- if( pBuffer->CheckState(D3D11BufferState::IndexBuffer) )
+ if( pBuffer->IsInKnownState() && pBuffer->CheckState(RESOURCE_STATE_INDEX_BUFFER) )
{
auto pd3d11IndBuffer = ValidatedCast<BufferD3D11Impl>( pBuffer )->GetD3D11Buffer();
if( pd3d11IndBuffer == m_CommittedD3D11IndexBuffer )
@@ -1178,10 +1179,10 @@ namespace Diligent
{
dbgVerifyCommittedIndexBuffer();
}
- pBuffer->ClearState( D3D11BufferState::IndexBuffer );
+ pBuffer->ClearState(RESOURCE_STATE_INDEX_BUFFER);
}
- if( pBuffer->CheckState( D3D11BufferState::VertexBuffer ) )
+ if( pBuffer->IsInKnownState() && pBuffer->CheckState(RESOURCE_STATE_VERTEX_BUFFER) )
{
auto pd3d11VB = ValidatedCast<BufferD3D11Impl>( pBuffer )->GetD3D11Buffer();
for( Uint32 Slot = 0; Slot < m_NumCommittedD3D11VBs; ++Slot )
@@ -1204,10 +1205,10 @@ namespace Diligent
{
dbgVerifyCommittedVertexBuffers();
}
- pBuffer->ClearState( D3D11BufferState::VertexBuffer );
+ pBuffer->ClearState(RESOURCE_STATE_VERTEX_BUFFER);
}
- if( pBuffer->CheckState( D3D11BufferState::ConstantBuffer ) )
+ if( pBuffer->IsInKnownState() && pBuffer->CheckState(RESOURCE_STATE_CONSTANT_BUFFER) )
{
for( Int32 ShaderTypeInd = 0; ShaderTypeInd < NumShaderTypes; ++ShaderTypeInd )
{
@@ -1228,7 +1229,7 @@ namespace Diligent
{
dbgVerifyCommittedCBs();
}
- pBuffer->ClearState( D3D11BufferState::ConstantBuffer );
+ pBuffer->ClearState(RESOURCE_STATE_CONSTANT_BUFFER);
}
}
@@ -1266,7 +1267,7 @@ namespace Diligent
CommitRenderTargets();
}
- pTexture->ClearState(D3D11TextureState::RenderTarget);
+ pTexture->ClearState(RESOURCE_STATE_RENDER_TARGET);
}
void DeviceContextD3D11Impl::UnbindTextureFromDepthStencil(TextureBaseD3D11* pTexD3D11)
@@ -1279,7 +1280,7 @@ namespace Diligent
m_pBoundDepthStencil.Release();
CommitRenderTargets();
}
- pTexD3D11->ClearState(D3D11TextureState::DepthStencil);
+ pTexD3D11->ClearState(RESOURCE_STATE_DEPTH_WRITE);
}
void DeviceContextD3D11Impl::ResetRenderTargets()
@@ -1297,13 +1298,15 @@ namespace Diligent
{
auto* pTex = ValidatedCast<TextureBaseD3D11>(ppRenderTargets[RT]->GetTexture());
UnbindTextureFromInput( pTex, pTex->GetD3D11Texture() );
- pTex->ResetState(D3D11TextureState::RenderTarget);
+ if (pTex->IsInKnownState())
+ pTex->SetState(RESOURCE_STATE_RENDER_TARGET);
}
if( pDepthStencil )
{
auto* pTex = ValidatedCast<TextureBaseD3D11>(pDepthStencil->GetTexture());
UnbindTextureFromInput( pTex, pTex->GetD3D11Texture() );
- pTex->ResetState(D3D11TextureState::DepthStencil);
+ if (pTex->IsInKnownState())
+ pTex->SetState(RESOURCE_STATE_DEPTH_WRITE);
}
CommitRenderTargets();
@@ -1569,7 +1572,111 @@ namespace Diligent
void DeviceContextD3D11Impl::TransitionResourceStates(Uint32 BarrierCount, StateTransitionDesc* pResourceBarriers)
{
+ for(Uint32 i=0; i < BarrierCount; ++i)
+ {
+ const auto& Barrier = pResourceBarriers[i];
+#ifdef DEVELOPMENT
+ DvpVerifyStateTransitionDesc(Barrier);
+#endif
+ DEV_CHECK_ERR((Barrier.pTexture != nullptr) ^ (Barrier.pBuffer != nullptr), "Exactly one of pTexture or pBuffer must not be null");
+ DEV_CHECK_ERR(Barrier.NewState != RESOURCE_STATE_UNKNOWN, "New resource state can't be unknown");
+
+ if (Barrier.pTexture)
+ {
+ auto* pTextureD3D11Impl = ValidatedCast<TextureBaseD3D11>(Barrier.pTexture);
+ auto OldState = Barrier.OldState;
+ if (OldState == RESOURCE_STATE_UNKNOWN)
+ {
+ if (pTextureD3D11Impl->IsInKnownState())
+ {
+ OldState = pTextureD3D11Impl->GetState();
+ }
+ else
+ {
+ LOG_ERROR_MESSAGE("Failed to transition the state of texture '", pTextureD3D11Impl->GetDesc().Name, "' because the buffer state is unknown and is not explicitly specified");
+ continue;
+ }
+ }
+ else
+ {
+ if (pTextureD3D11Impl->IsInKnownState() && pTextureD3D11Impl->GetState() != OldState)
+ {
+ LOG_ERROR_MESSAGE("The state ", GetResourceStateString(pTextureD3D11Impl->GetState()), " of texture '",
+ pTextureD3D11Impl->GetDesc().Name, "' does not match the old state ", GetResourceStateString(OldState),
+ " specified by the barrier");
+ }
+ }
+
+ if ((Barrier.NewState & RESOURCE_STATE_UNORDERED_ACCESS) != 0)
+ {
+ DEV_CHECK_ERR((Barrier.NewState & RESOURCE_STATE_GENERIC_READ) == 0, "Unordered access state is not compatible with any input state");
+ UnbindTextureFromInput(pTextureD3D11Impl, pTextureD3D11Impl->GetD3D11Texture());
+ }
+
+ if ((Barrier.NewState & RESOURCE_STATE_GENERIC_READ) != 0)
+ {
+ if ((OldState & RESOURCE_STATE_RENDER_TARGET) !=0 )
+ UnbindTextureFromRenderTarget(pTextureD3D11Impl);
+
+ if ((OldState & RESOURCE_STATE_DEPTH_WRITE) !=0 )
+ UnbindTextureFromDepthStencil(pTextureD3D11Impl);
+
+ if ((OldState & RESOURCE_STATE_UNORDERED_ACCESS) != 0)
+ {
+ UnbindResourceFromUAV(pTextureD3D11Impl, pTextureD3D11Impl->GetD3D11Texture());
+ pTextureD3D11Impl->ClearState(RESOURCE_STATE_UNORDERED_ACCESS);
+ }
+ }
+ if (Barrier.UpdateResourceState)
+ {
+ pTextureD3D11Impl->SetState(Barrier.NewState);
+ }
+ }
+ else
+ {
+ VERIFY_EXPR(Barrier.pBuffer);
+ auto* pBufferD3D11Impl = ValidatedCast<BufferD3D11Impl>(Barrier.pBuffer);
+ auto OldState = Barrier.OldState;
+ if (OldState == RESOURCE_STATE_UNKNOWN)
+ {
+ if (pBufferD3D11Impl->IsInKnownState())
+ {
+ OldState = pBufferD3D11Impl->GetState();
+ }
+ else
+ {
+ LOG_ERROR_MESSAGE("Failed to transition the state of buffer '", pBufferD3D11Impl->GetDesc().Name, "' because the buffer state is unknown and is not explicitly specified");
+ continue;
+ }
+ }
+ else
+ {
+ if (pBufferD3D11Impl->IsInKnownState() && pBufferD3D11Impl->GetState() != OldState)
+ {
+ LOG_ERROR_MESSAGE("The state ", GetResourceStateString(pBufferD3D11Impl->GetState()), " of buffer '",
+ pBufferD3D11Impl->GetDesc().Name, "' does not match the old state ", GetResourceStateString(OldState),
+ " specified by the barrier");
+ }
+ }
+
+ if ((Barrier.NewState & RESOURCE_STATE_UNORDERED_ACCESS) != 0)
+ {
+ DEV_CHECK_ERR((Barrier.NewState & RESOURCE_STATE_GENERIC_READ) == 0, "Unordered access state is not compatible with any input state");
+ UnbindBufferFromInput(pBufferD3D11Impl, pBufferD3D11Impl->m_pd3d11Buffer);
+ }
+
+ if ((Barrier.NewState & RESOURCE_STATE_GENERIC_READ) != 0)
+ {
+ UnbindResourceFromUAV(pBufferD3D11Impl, pBufferD3D11Impl->m_pd3d11Buffer);
+ }
+
+ if (Barrier.UpdateResourceState)
+ {
+ pBufferD3D11Impl->SetState(Barrier.NewState);
+ }
+ }
+ }
}
#ifdef VERIFY_CONTEXT_BINDINGS
diff --git a/Graphics/GraphicsEngineD3D11/src/TextureBaseD3D11.cpp b/Graphics/GraphicsEngineD3D11/src/TextureBaseD3D11.cpp
index cb257437..c53da496 100644
--- a/Graphics/GraphicsEngineD3D11/src/TextureBaseD3D11.cpp
+++ b/Graphics/GraphicsEngineD3D11/src/TextureBaseD3D11.cpp
@@ -41,6 +41,7 @@ TextureBaseD3D11 :: TextureBaseD3D11(IReferenceCounters* pRefCounters,
{
if( TexDesc.Usage == USAGE_STATIC && InitData.pSubResources == nullptr )
LOG_ERROR_AND_THROW("Static Texture must be initialized with data at creation time");
+ SetState(RESOURCE_STATE_UNDEFINED);
}
IMPLEMENT_QUERY_INTERFACE( TextureBaseD3D11, IID_TextureD3D11, TTextureBase )
diff --git a/Graphics/GraphicsEngineD3D12/src/CommandContext.cpp b/Graphics/GraphicsEngineD3D12/src/CommandContext.cpp
index f6c1e281..8d6d5d9c 100644
--- a/Graphics/GraphicsEngineD3D12/src/CommandContext.cpp
+++ b/Graphics/GraphicsEngineD3D12/src/CommandContext.cpp
@@ -238,7 +238,7 @@ void CommandContext::TransitionResource(const StateTransitionDesc& Barrier)
// D3D12_RESOURCE_STATE_GENERIC_READ state
if (pBufferD3D12Impl->GetDesc().Usage == USAGE_DYNAMIC && (pBufferD3D12Impl->GetDesc().BindFlags & (BIND_SHADER_RESOURCE|BIND_UNORDERED_ACCESS)) == 0)
{
- DEV_CHECK_ERR(pBufferD3D12Impl->GetState() == D3D12_RESOURCE_STATE_GENERIC_READ, "Dynamic buffers that cannot be bound as SRV or UAV are expected to always be in D3D12_RESOURCE_STATE_GENERIC_READ state");
+ DEV_CHECK_ERR(pBufferD3D12Impl->GetState() == RESOURCE_STATE_GENERIC_READ, "Dynamic buffers that cannot be bound as SRV or UAV are expected to always be in D3D12_RESOURCE_STATE_GENERIC_READ state");
VERIFY( (Barrier.NewState & RESOURCE_STATE_GENERIC_READ) == Barrier.NewState, "Dynamic buffers can only transition to one of RESOURCE_STATE_GENERIC_READ states");
}
#endif
@@ -274,21 +274,13 @@ void CommandContext::TransitionResource(const StateTransitionDesc& Barrier)
if (pTextureD3D12Impl)
{
const auto& TexDesc = pTextureD3D12Impl->GetDesc();
-#ifdef DEVELOPMENT
- {
- DEV_CHECK_ERR(Barrier.FirstMipLevel < TexDesc.MipLevels, "First mip level (", Barrier.FirstMipLevel, ") specified by the barrier is "
- "out of range. Texture \'", TexDesc.Name, "\' has only ", TexDesc.MipLevels, " mip level(s)");
- DEV_CHECK_ERR(Barrier.MipLevelsCount == StateTransitionDesc::RemainingMipLevels || Barrier.FirstMipLevel + Barrier.MipLevelsCount < TexDesc.MipLevels,
- "Mip level range ", Barrier.FirstMipLevel, "..", Barrier.FirstMipLevel+Barrier.MipLevelsCount-1, " "
- "specified by the barrier is out of range. Texture \'", TexDesc.Name, "\' has only ", TexDesc.MipLevels, " mip level(s)");
-
- DEV_CHECK_ERR(Barrier.FirstArraySlice < TexDesc.ArraySize, "First array slice (", Barrier.FirstArraySlice, ") specified by the barrier is "
- "out of range. Array size of texture \'", TexDesc.Name, "\' is ", TexDesc.ArraySize);
- DEV_CHECK_ERR(Barrier.ArraySliceCount == StateTransitionDesc::RemainingArraySlices || Barrier.FirstArraySlice + Barrier.ArraySliceCount < TexDesc.ArraySize,
- "Array slice range ", Barrier.FirstArraySlice, "..", Barrier.FirstArraySlice+Barrier.ArraySliceCount-1, " "
- "specified by the barrier is out of range. Array size of texture \'", TexDesc.Name, "\' is ", TexDesc.ArraySize);
- }
-#endif
+ VERIFY(Barrier.FirstMipLevel < TexDesc.MipLevels, "First mip level is out of range");
+ VERIFY(Barrier.MipLevelsCount == StateTransitionDesc::RemainingMipLevels || Barrier.FirstMipLevel + Barrier.MipLevelsCount < TexDesc.MipLevels,
+ "Invalid mip level range ");
+ VERIFY(Barrier.FirstArraySlice < TexDesc.ArraySize, "First array slice is out of range");
+ VERIFY(Barrier.ArraySliceCount == StateTransitionDesc::RemainingArraySlices || Barrier.FirstArraySlice + Barrier.ArraySliceCount < TexDesc.ArraySize,
+ "Invalid array slice range ");
+
if (Barrier.FirstMipLevel == 0 && (Barrier.MipLevelsCount == StateTransitionDesc::RemainingMipLevels || Barrier.MipLevelsCount == TexDesc.MipLevels) &&
Barrier.FirstArraySlice == 0 && (Barrier.ArraySliceCount == StateTransitionDesc::RemainingArraySlices || Barrier.ArraySliceCount == TexDesc.ArraySize))
{
diff --git a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp
index 48f875e9..76e37ff5 100644
--- a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp
+++ b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp
@@ -1120,7 +1120,12 @@ namespace Diligent
{
auto& CmdCtx = GetCmdContext();
for(Uint32 i = 0; i < BarrierCount; ++i)
+ {
+#ifdef DEVELOPMENT
+ DvpVerifyStateTransitionDesc(pResourceBarriers[i]);
+#endif
CmdCtx.TransitionResource(pResourceBarriers[i]);
+ }
}
void DeviceContextD3D12Impl::TransitionTextureState(ITexture *pTexture, D3D12_RESOURCE_STATES State)
diff --git a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp
index d9cc8bf6..5e2402f7 100644
--- a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp
@@ -1648,9 +1648,6 @@ namespace Diligent
void DeviceContextVkImpl::TransitionBufferState(BufferVkImpl& BufferVk, RESOURCE_STATE OldState, RESOURCE_STATE NewState, bool UpdateBufferState)
{
- DEV_CHECK_ERR(BufferVk.m_VulkanBuffer != VK_NULL_HANDLE, "Cannot transition suballocated buffer");
- VERIFY_EXPR(BufferVk.GetDynamicOffset(m_ContextId, this) == 0);
-
EnsureVkCmdBuffer();
if (OldState == RESOURCE_STATE_UNKNOWN)
{
@@ -1673,15 +1670,20 @@ namespace Diligent
" specified by the barrier");
}
}
- DEV_CHECK_ERR((OldState & NewState) != NewState, "The buffer is already in requested state");
- auto vkBuff = BufferVk.GetVkBuffer();
- auto OldAccessFlags = ResourceStateFlagsToVkAccessFlags(OldState);
- auto NewAccessFlags = ResourceStateFlagsToVkAccessFlags(NewState);
- m_CommandBuffer.BufferMemoryBarrier(vkBuff, OldAccessFlags, NewAccessFlags);
- if (UpdateBufferState)
+ if ((OldState & NewState) != NewState)
{
- BufferVk.SetState(NewState);
+ DEV_CHECK_ERR(BufferVk.m_VulkanBuffer != VK_NULL_HANDLE, "Cannot transition suballocated buffer");
+ VERIFY_EXPR(BufferVk.GetDynamicOffset(m_ContextId, this) == 0);
+
+ auto vkBuff = BufferVk.GetVkBuffer();
+ auto OldAccessFlags = ResourceStateFlagsToVkAccessFlags(OldState);
+ auto NewAccessFlags = ResourceStateFlagsToVkAccessFlags(NewState);
+ m_CommandBuffer.BufferMemoryBarrier(vkBuff, OldAccessFlags, NewAccessFlags);
+ if (UpdateBufferState)
+ {
+ BufferVk.SetState(NewState);
+ }
}
}
@@ -1704,28 +1706,12 @@ namespace Diligent
for(Uint32 i=0; i < BarrierCount; ++i)
{
const auto& Barrier = pResourceBarriers[i];
- DEV_CHECK_ERR( (Barrier.pTexture != nullptr) ^ (Barrier.pBuffer != nullptr), "Exactly one of pTexture or pBuffer must not be null");
- DEV_CHECK_ERR(Barrier.NewState != RESOURCE_STATE_UNKNOWN, "New resource state can't be unknown");
+#ifdef DEVELOPMENT
+ DvpVerifyStateTransitionDesc(Barrier);
+#endif
if (Barrier.pTexture)
{
auto* pTextureVkImpl = ValidatedCast<TextureVkImpl>(Barrier.pTexture);
-#ifdef DEVELOPMENT
- {
- const auto& TexDesc = pTextureVkImpl->GetDesc();
- DEV_CHECK_ERR(Barrier.FirstMipLevel < TexDesc.MipLevels, "First mip level (", Barrier.FirstMipLevel, ") specified by the barrier is "
- "out of range. Texture \'", TexDesc.Name, "\' has only ", TexDesc.MipLevels, " mip level(s)");
- DEV_CHECK_ERR(Barrier.MipLevelsCount == StateTransitionDesc::RemainingMipLevels || Barrier.FirstMipLevel + Barrier.MipLevelsCount < TexDesc.MipLevels,
- "Mip level range ", Barrier.FirstMipLevel, "..", Barrier.FirstMipLevel+Barrier.MipLevelsCount-1, " "
- "specified by the barrier is out of range. Texture \'", TexDesc.Name, "\' has only ", TexDesc.MipLevels, " mip level(s)");
-
- DEV_CHECK_ERR(Barrier.FirstArraySlice < TexDesc.ArraySize, "First array slice (", Barrier.FirstArraySlice, ") specified by the barrier is "
- "out of range. Array size of texture \'", TexDesc.Name, "\' is ", TexDesc.ArraySize);
- DEV_CHECK_ERR(Barrier.ArraySliceCount == StateTransitionDesc::RemainingArraySlices || Barrier.FirstArraySlice + Barrier.ArraySliceCount < TexDesc.ArraySize,
- "Array slice range ", Barrier.FirstArraySlice, "..", Barrier.FirstArraySlice+Barrier.ArraySliceCount-1, " "
- "specified by the barrier is out of range. Array size of texture \'", TexDesc.Name, "\' is ", TexDesc.ArraySize);
- }
-#endif
-
VkImageSubresourceRange SubResRange;
SubResRange.aspectMask = 0;
SubResRange.baseMipLevel = Barrier.FirstMipLevel;