summaryrefslogtreecommitdiffstats
path: root/Graphics
diff options
context:
space:
mode:
authorEgor Yusov <egor.yusov@gmail.com>2018-11-21 06:01:03 +0000
committerEgor Yusov <egor.yusov@gmail.com>2018-11-21 06:01:03 +0000
commit47eb24bb2abc8741667ae0fc7423515c93057e37 (patch)
tree609daaa99f5a8cedb3473e192df9ce78fc81fa9b /Graphics
parentImplemented explicit state transitions in D3D11 backend (closed https://githu... (diff)
downloadDiligentCore-47eb24bb2abc8741667ae0fc7423515c93057e37.tar.gz
DiligentCore-47eb24bb2abc8741667ae0fc7423515c93057e37.zip
Added explicit control of vertex buffer, index buffer and indirect draw arguments buffer transitions to the API
Diffstat (limited to 'Graphics')
-rw-r--r--Graphics/GraphicsEngine/interface/DeviceContext.h38
-rwxr-xr-xGraphics/GraphicsEngineD3D11/include/DeviceContextD3D11Impl.h4
-rwxr-xr-xGraphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp47
-rw-r--r--Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.h4
-rw-r--r--Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp133
-rw-r--r--Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h2
-rw-r--r--Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp135
7 files changed, 301 insertions, 62 deletions
diff --git a/Graphics/GraphicsEngine/interface/DeviceContext.h b/Graphics/GraphicsEngine/interface/DeviceContext.h
index 6c5b0d85..62adfd72 100644
--- a/Graphics/GraphicsEngine/interface/DeviceContext.h
+++ b/Graphics/GraphicsEngine/interface/DeviceContext.h
@@ -51,6 +51,25 @@ namespace Diligent
static constexpr INTERFACE_ID IID_DeviceContext =
{ 0xdc92711b, 0xa1be, 0x4319, { 0xb2, 0xbd, 0xc6, 0x62, 0xd1, 0xcc, 0x19, 0xe4 } };
+/// Draw command flags
+enum DRAW_FLAGS : Uint8
+{
+ /// Perform no state transitions
+ DRAW_FLAG_NONE = 0x00,
+
+ /// Transition vertex buffers to RESOURCE_STATE_VERTEX_BUFFER state (see Diligent::RESOURCE_STATE).
+ /// Vertex buffers in unknown state will not be transitioned.
+ DRAW_FLAG_TRANSITION_VERTEX_BUFFERS = 0x01,
+
+ /// Transition index buffer to RESOURCE_STATE_INDEX_BUFFER state (see Diligent::RESOURCE_STATE).
+ /// If the index buffer is in unknown state, this flag has no effect.
+ DRAW_FLAG_TRANSITION_INDEX_BUFFER = 0x02,
+
+ /// 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
+};
+
/// Defines the draw command attributes
/// This structure is used by IRenderDevice::Draw()
@@ -72,6 +91,9 @@ struct DrawAttribs
/// Allowed values: VT_UINT16 and VT_UINT32. Ignored if DrawAttribs::IsIndexed is False.
VALUE_TYPE IndexType = VT_UNDEFINED;
+ /// Additional flags controlling the draw command behavior, see Diligent::DRAW_FLAGS.
+ Uint8 Flags = DRAW_FLAG_NONE;
+
/// Number of instances to draw. If more than one instance is specified,
/// instanced draw call will be performed.
Uint32 NumInstances = 1;
@@ -111,6 +133,7 @@ struct DrawAttribs
/// NumVertices | 0
/// IsIndexed | False
/// IndexType | VT_UNDEFINED
+ /// Flags | DRAW_FLAG_NONE
/// NumInstances | 1
/// BaseVertex | 0
/// IndirectDrawArgsOffset | 0
@@ -129,6 +152,18 @@ enum CLEAR_DEPTH_STENCIL_FLAGS : Int32
CLEAR_STENCIL_FLAG = 0x02 ///< Clear stencil part of the buffer
};
+
+/// Dispatch compute command flags
+enum DISPATCH_FLAGS : Uint8
+{
+ /// Perform no state transitions
+ DISPATCH_FLAG_FLAG_NONE = 0x00,
+
+ /// 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
+};
+
/// Describes dispatch command arguments.
/// [Dispatch]: https://msdn.microsoft.com/en-us/library/windows/desktop/ff476405(v=vs.85).aspx
@@ -149,6 +184,9 @@ struct DispatchComputeAttribs
/// of the buffer to the dispatch command arguments. Ignored otherwise
Uint32 DispatchArgsByteOffset;
+ /// Flags controlling the dispatch command behavior, see Diligent::DISPATCH_FLAGS.
+ Uint8 Flags = DISPATCH_FLAG_FLAG_NONE;
+
/// Initializes the structure to perform non-indirect dispatch command
/// \param [in] GroupsX - Number of groups dispatched in X direction. Default value is 1.
diff --git a/Graphics/GraphicsEngineD3D11/include/DeviceContextD3D11Impl.h b/Graphics/GraphicsEngineD3D11/include/DeviceContextD3D11Impl.h
index a858d543..661dd405 100755
--- a/Graphics/GraphicsEngineD3D11/include/DeviceContextD3D11Impl.h
+++ b/Graphics/GraphicsEngineD3D11/include/DeviceContextD3D11Impl.h
@@ -117,10 +117,10 @@ public:
private:
/// Commits d3d11 index buffer to the d3d11 device context.
- void CommitD3D11IndexBuffer(VALUE_TYPE IndexType);
+ void CommitD3D11IndexBuffer(VALUE_TYPE IndexType, bool TransitionBuffer);
/// Commits d3d11 vertex buffers to the d3d11 device context.
- void CommitD3D11VertexBuffers(class PipelineStateD3D11Impl* pPipelineStateD3D11);
+ void CommitD3D11VertexBuffers(class PipelineStateD3D11Impl* pPipelineStateD3D11, bool TransitionBuffers);
/// Helper template function used to facilitate resource unbinding
template<typename TD3D11ResourceViewType,
diff --git a/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp
index dee55fc8..b240fa1f 100755
--- a/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp
+++ b/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp
@@ -653,7 +653,7 @@ namespace Diligent
}
}
- void DeviceContextD3D11Impl::CommitD3D11IndexBuffer(VALUE_TYPE IndexType)
+ void DeviceContextD3D11Impl::CommitD3D11IndexBuffer(VALUE_TYPE IndexType, bool TransitionBuffer)
{
if( !m_pIndexBuffer )
{
@@ -662,11 +662,25 @@ namespace Diligent
}
BufferD3D11Impl* pBuffD3D11 = m_pIndexBuffer.RawPtr<BufferD3D11Impl>();
- if( pBuffD3D11->IsInKnownState() && pBuffD3D11->CheckState(RESOURCE_STATE_UNORDERED_ACCESS) )
+ if (TransitionBuffer)
{
- UnbindResourceFromUAV(pBuffD3D11, pBuffD3D11->m_pd3d11Buffer);
- pBuffD3D11->ClearState(RESOURCE_STATE_UNORDERED_ACCESS);
+ if( pBuffD3D11->IsInKnownState() && pBuffD3D11->CheckState(RESOURCE_STATE_UNORDERED_ACCESS) )
+ {
+ UnbindResourceFromUAV(pBuffD3D11, pBuffD3D11->m_pd3d11Buffer);
+ pBuffD3D11->ClearState(RESOURCE_STATE_UNORDERED_ACCESS);
+ }
+ }
+#ifdef DEVELOPMENT
+ else
+ {
+ if( pBuffD3D11->IsInKnownState() && pBuffD3D11->CheckState(RESOURCE_STATE_UNORDERED_ACCESS) )
+ {
+ LOG_ERROR_MESSAGE("Buffer '", pBuffD3D11->GetDesc().Name, "' used as index buffer is in RESOURCE_STATE_UNORDERED_ACCESS state."
+ " Use DRAW_FLAG_TRANSITION_INDEX_BUFFER flag or explicitly transition the buffer to RESOURCE_STATE_INDEX_BUFFER state.");
+
+ }
}
+#endif
if( m_CommittedD3D11IndexBuffer != pBuffD3D11->m_pd3d11Buffer ||
m_CommittedIBFormat != IndexType ||
@@ -693,7 +707,7 @@ namespace Diligent
m_bCommittedD3D11IBUpToDate = true;
}
- void DeviceContextD3D11Impl::CommitD3D11VertexBuffers(PipelineStateD3D11Impl* pPipelineStateD3D11)
+ void DeviceContextD3D11Impl::CommitD3D11VertexBuffers(PipelineStateD3D11Impl* pPipelineStateD3D11, bool TransitionBuffers)
{
VERIFY( m_NumVertexStreams <= MaxBufferSlots, "Too many buffers are being set" );
UINT NumBuffersToSet = std::max(m_NumVertexStreams, m_NumCommittedD3D11VBs );
@@ -709,11 +723,24 @@ namespace Diligent
auto Stride = Strides[Slot];
auto Offset = CurrStream.Offset;
- if(pBuffD3D11Impl != nullptr && pBuffD3D11Impl->IsInKnownState() && pBuffD3D11Impl->CheckState(RESOURCE_STATE_UNORDERED_ACCESS))
+ if (TransitionBuffers)
{
- UnbindResourceFromUAV(pBuffD3D11Impl, pd3d11Buffer);
- pBuffD3D11Impl->ClearState(RESOURCE_STATE_UNORDERED_ACCESS);
+ if (pBuffD3D11Impl != nullptr && pBuffD3D11Impl->IsInKnownState() && pBuffD3D11Impl->CheckState(RESOURCE_STATE_UNORDERED_ACCESS))
+ {
+ UnbindResourceFromUAV(pBuffD3D11Impl, pd3d11Buffer);
+ pBuffD3D11Impl->ClearState(RESOURCE_STATE_UNORDERED_ACCESS);
+ }
}
+#ifdef DEVELOPMENT
+ else
+ {
+ if (pBuffD3D11Impl != nullptr && pBuffD3D11Impl->IsInKnownState() && pBuffD3D11Impl->CheckState(RESOURCE_STATE_UNORDERED_ACCESS))
+ {
+ LOG_ERROR_MESSAGE("Buffer '", pBuffD3D11Impl->GetDesc().Name, "' used as vertex buffer at slot ", Slot, " is in RESOURCE_STATE_UNORDERED_ACCESS state. "
+ "Use DRAW_FLAG_TRANSITION_VERTEX_BUFFER flag or explicitly transition the buffer to RESOURCE_STATE_VERTEX_BUFFER state.");
+ }
+ }
+#endif
// It is safe to perform raw pointer check because device context keeps
// all buffers alive.
@@ -761,7 +788,7 @@ namespace Diligent
if( pd3d11InputLayout != nullptr && !m_bCommittedD3D11VBsUpToDate )
{
VERIFY( 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);
+ CommitD3D11VertexBuffers(m_pPipelineState, drawAttribs.Flags & DRAW_FLAG_TRANSITION_VERTEX_BUFFERS);
}
if( drawAttribs.IsIndexed )
@@ -770,7 +797,7 @@ namespace Diligent
m_bCommittedD3D11IBUpToDate = false;
if(!m_bCommittedD3D11IBUpToDate)
{
- CommitD3D11IndexBuffer(drawAttribs.IndexType);
+ CommitD3D11IndexBuffer(drawAttribs.IndexType, drawAttribs.Flags & DRAW_FLAG_TRANSITION_INDEX_BUFFER);
}
}
diff --git a/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.h b/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.h
index c8e63264..f0bc93b5 100644
--- a/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.h
+++ b/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.h
@@ -161,8 +161,8 @@ public:
Int64 GetCurrentFrameNumber()const {return m_ContextFrameNumber; }
private:
- void CommitD3D12IndexBuffer(VALUE_TYPE IndexType);
- void CommitD3D12VertexBuffers(class GraphicsContext &GraphCtx);
+ void CommitD3D12IndexBuffer(VALUE_TYPE IndexType, bool TransitionBuffer);
+ void CommitD3D12VertexBuffers(class GraphicsContext &GraphCtx, bool TransitionBuffers);
void TransitionD3D12VertexBuffers(class GraphicsContext &GraphCtx);
void CommitRenderTargets();
void CommitViewports();
diff --git a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp
index 76e37ff5..494986d3 100644
--- a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp
+++ b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp
@@ -257,7 +257,7 @@ namespace Diligent
}
}
- void DeviceContextD3D12Impl::CommitD3D12IndexBuffer(VALUE_TYPE IndexType)
+ void DeviceContextD3D12Impl::CommitD3D12IndexBuffer(VALUE_TYPE IndexType, bool TransitionBuffer)
{
VERIFY( m_pIndexBuffer != nullptr, "Index buffer is not set up for indexed draw command" );
@@ -287,8 +287,24 @@ namespace Diligent
pBuffD3D12->DvpVerifyDynamicAllocation(this);
#endif
auto& GraphicsCtx = GetCmdContext().AsGraphicsContext();
- if (pBuffD3D12->IsInKnownState() && !pBuffD3D12->CheckState(RESOURCE_STATE_INDEX_BUFFER))
- GraphicsCtx.TransitionResource(pBuffD3D12, RESOURCE_STATE_INDEX_BUFFER);
+
+ if (TransitionBuffer)
+ {
+ if (pBuffD3D12->IsInKnownState() && !pBuffD3D12->CheckState(RESOURCE_STATE_INDEX_BUFFER))
+ GraphicsCtx.TransitionResource(pBuffD3D12, RESOURCE_STATE_INDEX_BUFFER);
+ }
+#ifdef DEVELOPMENT
+ else
+ {
+ if (pBuffD3D12->IsInKnownState() && !pBuffD3D12->CheckState(RESOURCE_STATE_INDEX_BUFFER))
+ {
+ LOG_ERROR_MESSAGE("Buffer '", pBuffD3D12->GetDesc().Name, "' used as index buffer must be in RESOURCE_STATE_INDEX_BUFFER "
+ "state. Actual buffer state: ", GetResourceStateString(pBuffD3D12->GetState()),
+ ". Use DRAW_FLAG_TRANSITION_INDEX_BUFFER flag or explicitly transition the buffer to the required state.");
+
+ }
+ }
+#endif
size_t BuffDataStartByteOffset;
auto *pd3d12Buff = pBuffD3D12->GetD3D12Buffer(BuffDataStartByteOffset, this);
@@ -311,7 +327,7 @@ namespace Diligent
void DeviceContextD3D12Impl::TransitionD3D12VertexBuffers(GraphicsContext& GraphCtx)
{
- for( UINT Buff = 0; Buff < m_NumVertexStreams; ++Buff )
+ for( Uint32 Buff = 0; Buff < m_NumVertexStreams; ++Buff )
{
auto& CurrStream = m_VertexStreams[Buff];
auto* pBufferD3D12 = CurrStream.pBuffer.RawPtr();
@@ -320,7 +336,7 @@ namespace Diligent
}
}
- void DeviceContextD3D12Impl::CommitD3D12VertexBuffers(GraphicsContext& GraphCtx)
+ void DeviceContextD3D12Impl::CommitD3D12VertexBuffers(GraphicsContext& GraphCtx, bool TransitionBuffers)
{
// Do not initialize array with zeroes for performance reasons
D3D12_VERTEX_BUFFER_VIEW VBViews[MaxBufferSlots];// = {}
@@ -342,8 +358,22 @@ namespace Diligent
#endif
}
- if (pBufferD3D12->IsInKnownState() && !pBufferD3D12->CheckState(RESOURCE_STATE_VERTEX_BUFFER))
- GraphCtx.TransitionResource(pBufferD3D12, RESOURCE_STATE_VERTEX_BUFFER);
+ if (TransitionBuffers)
+ {
+ if (pBufferD3D12->IsInKnownState() && !pBufferD3D12->CheckState(RESOURCE_STATE_VERTEX_BUFFER))
+ GraphCtx.TransitionResource(pBufferD3D12, RESOURCE_STATE_VERTEX_BUFFER);
+ }
+#ifdef DEVELOPMENT
+ else
+ {
+ if (pBufferD3D12->IsInKnownState() && !pBufferD3D12->CheckState(RESOURCE_STATE_VERTEX_BUFFER))
+ {
+ LOG_ERROR_MESSAGE("Buffer '", pBufferD3D12->GetDesc().Name, "' used as vertex buffer at slot ", Buff, " must be in "
+ "RESOURCE_STATE_VERTEX_BUFFER state. Actual buffer state: ", GetResourceStateString(pBufferD3D12->GetState()),
+ ". Use DRAW_FLAG_TRANSITION_VERTEX_BUFFERS flag or explicitly transition the buffer to the required state.");
+ }
+ }
+#endif
// Device context keeps strong references to all vertex buffers.
// When a buffer is unbound, a reference to D3D12 resource is added to the context,
@@ -382,20 +412,61 @@ namespace Diligent
if( m_State.CommittedIBFormat != drawAttribs.IndexType )
m_State.bCommittedD3D12IBUpToDate = false;
+ bool TransitionIndexBuffer = (drawAttribs.Flags & DRAW_FLAG_TRANSITION_INDEX_BUFFER) != 0;
if (m_State.bCommittedD3D12IBUpToDate)
{
BufferD3D12Impl *pBuffD3D12 = static_cast<BufferD3D12Impl *>(m_pIndexBuffer.RawPtr());
- if (pBuffD3D12->IsInKnownState() && !pBuffD3D12->CheckState(RESOURCE_STATE_INDEX_BUFFER))
- GraphCtx.TransitionResource(pBuffD3D12, RESOURCE_STATE_INDEX_BUFFER);
+ if(TransitionIndexBuffer)
+ {
+ if (pBuffD3D12->IsInKnownState() && !pBuffD3D12->CheckState(RESOURCE_STATE_INDEX_BUFFER))
+ GraphCtx.TransitionResource(pBuffD3D12, RESOURCE_STATE_INDEX_BUFFER);
+ }
+#ifdef DEVELOPMENT
+ else
+ {
+ if (pBuffD3D12->IsInKnownState() && !pBuffD3D12->CheckState(RESOURCE_STATE_INDEX_BUFFER))
+ {
+ LOG_ERROR_MESSAGE("Buffer '", pBuffD3D12->GetDesc().Name, "' used as index buffer must be in RESOURCE_STATE_INDEX_BUFFER "
+ "state. Actual buffer state: ", GetResourceStateString(pBuffD3D12->GetState()),
+ ". Use DRAW_FLAG_TRANSITION_INDEX_BUFFER flag or explicitly transition the buffer to the required state.");
+ }
+ }
+#endif
}
else
- CommitD3D12IndexBuffer(drawAttribs.IndexType);
+ {
+ CommitD3D12IndexBuffer(drawAttribs.IndexType, TransitionIndexBuffer);
+ }
}
+ bool TransitionVertexBuffers = (drawAttribs.Flags & DRAW_FLAG_TRANSITION_VERTEX_BUFFERS) != 0;
if (m_State.bCommittedD3D12VBsUpToDate)
- TransitionD3D12VertexBuffers(GraphCtx);
+ {
+ if (TransitionVertexBuffers)
+ {
+ TransitionD3D12VertexBuffers(GraphCtx);
+ }
+#ifdef DEVELOPMENT
+ else
+ {
+ for( Uint32 Buff = 0; Buff < m_NumVertexStreams; ++Buff )
+ {
+ auto& CurrStream = m_VertexStreams[Buff];
+ auto* pBufferD3D12 = CurrStream.pBuffer.RawPtr();
+ if (pBufferD3D12 != nullptr && pBufferD3D12->IsInKnownState() && !pBufferD3D12->CheckState(RESOURCE_STATE_VERTEX_BUFFER))
+ {
+ LOG_ERROR_MESSAGE("Buffer '", pBufferD3D12->GetDesc().Name, "' used as vertex buffer at slot ", Buff, " must be in "
+ "RESOURCE_STATE_VERTEX_BUFFER state. Actual buffer state: ", GetResourceStateString(pBufferD3D12->GetState()),
+ ". Use DRAW_FLAG_TRANSITION_VERTEX_BUFFERS flag or explicitly transition the buffer to the required state.");
+ }
+ }
+ }
+#endif
+ }
else
- CommitD3D12VertexBuffers(GraphCtx);
+ {
+ CommitD3D12VertexBuffers(GraphCtx, TransitionVertexBuffers);
+ }
GraphCtx.SetRootSignature( m_pPipelineState->GetD3D12RootSignature() );
@@ -420,8 +491,23 @@ namespace Diligent
pIndirectDrawAttribsD3D12->DvpVerifyDynamicAllocation(this);
#endif
- if (pIndirectDrawAttribsD3D12->IsInKnownState() && !pIndirectDrawAttribsD3D12->CheckState(RESOURCE_STATE_INDIRECT_ARGUMENT))
- GraphCtx.TransitionResource(pIndirectDrawAttribsD3D12, RESOURCE_STATE_INDIRECT_ARGUMENT);
+ if (drawAttribs.Flags & DRAW_FLAG_TRANSITION_INDIRECT_ARGS_BUFFER)
+ {
+ if (pIndirectDrawAttribsD3D12->IsInKnownState() && !pIndirectDrawAttribsD3D12->CheckState(RESOURCE_STATE_INDIRECT_ARGUMENT))
+ GraphCtx.TransitionResource(pIndirectDrawAttribsD3D12, RESOURCE_STATE_INDIRECT_ARGUMENT);
+ }
+#ifdef DEVELOPMENT
+ else
+ {
+ if (pIndirectDrawAttribsD3D12->IsInKnownState() && !pIndirectDrawAttribsD3D12->CheckState(RESOURCE_STATE_INDIRECT_ARGUMENT))
+ {
+ LOG_ERROR_MESSAGE("Buffer '", pIndirectDrawAttribsD3D12->GetDesc().Name, "' used as indirect draw arguments buffer must be in RESOURCE_STATE_INDIRECT_ARGUMENT "
+ "state. Actual buffer state: ", GetResourceStateString(pIndirectDrawAttribsD3D12->GetState()),
+ ". Use DRAW_FLAG_TRANSITION_INDIRECT_ARGS_BUFFER flag or explicitly transition the buffer to the required state.");
+ }
+ }
+#endif
+
size_t BuffDataStartByteOffset;
ID3D12Resource *pd3d12ArgsBuff = pIndirectDrawAttribsD3D12->GetD3D12Buffer(BuffDataStartByteOffset, this);
GraphCtx.ExecuteIndirect(drawAttribs.IsIndexed ? m_pDrawIndexedIndirectSignature : m_pDrawIndirectSignature, pd3d12ArgsBuff, drawAttribs.IndirectDrawArgsOffset + BuffDataStartByteOffset);
@@ -467,8 +553,23 @@ namespace Diligent
pBufferD3D12->DvpVerifyDynamicAllocation(this);
#endif
- if (pBufferD3D12->IsInKnownState() && !pBufferD3D12->CheckState(RESOURCE_STATE_INDIRECT_ARGUMENT))
- ComputeCtx.TransitionResource(pBufferD3D12, RESOURCE_STATE_INDIRECT_ARGUMENT);
+ if (DispatchAttrs.Flags & DISPATCH_FLAG_TRANSITION_INDIRECT_ARGS_BUFFER)
+ {
+ if (pBufferD3D12->IsInKnownState() && !pBufferD3D12->CheckState(RESOURCE_STATE_INDIRECT_ARGUMENT))
+ ComputeCtx.TransitionResource(pBufferD3D12, RESOURCE_STATE_INDIRECT_ARGUMENT);
+ }
+#ifdef DEVELOPMENT
+ else
+ {
+ if (pBufferD3D12->IsInKnownState() && !pBufferD3D12->CheckState(RESOURCE_STATE_INDIRECT_ARGUMENT))
+ {
+ LOG_ERROR_MESSAGE("Buffer '", pBufferD3D12->GetDesc().Name, "' used as indirect dispatch arguments buffer must be in RESOURCE_STATE_INDIRECT_ARGUMENT "
+ "state. Actual buffer state: ", GetResourceStateString(pBufferD3D12->GetState()),
+ ". Use DISPATCH_FLAG_TRANSITION_INDIRECT_ARGS_BUFFER flag or explicitly transition the buffer to the required state.");
+ }
+ }
+#endif
+
size_t BuffDataStartByteOffset;
ID3D12Resource *pd3d12ArgsBuff = pBufferD3D12->GetD3D12Buffer(BuffDataStartByteOffset, this);
ComputeCtx.ExecuteIndirect(m_pDispatchIndirectSignature, pd3d12ArgsBuff, DispatchAttrs.DispatchArgsByteOffset + BuffDataStartByteOffset);
diff --git a/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h b/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h
index e75c7deb..0dc9371a 100644
--- a/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h
+++ b/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h
@@ -198,7 +198,7 @@ public:
private:
void CommitRenderPassAndFramebuffer();
- void CommitVkVertexBuffers();
+ void CommitVkVertexBuffers(bool TransitionBuffers);
void TransitionVkVertexBuffers();
void CommitViewports();
void CommitScissorRects();
diff --git a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp
index 5e2402f7..e8316daf 100644
--- a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp
@@ -306,7 +306,7 @@ namespace Diligent
}
}
- void DeviceContextVkImpl::CommitVkVertexBuffers()
+ void DeviceContextVkImpl::CommitVkVertexBuffers(bool TransitionBuffers)
{
#ifdef DEVELOPMENT
if (m_NumVertexStreams < m_pPipelineState->GetNumBufferSlotsUsed())
@@ -329,15 +329,31 @@ namespace Diligent
pBufferVk->DvpVerifyDynamicAllocation(this);
#endif
}
- if (pBufferVk->IsInKnownState())
+
+ if (TransitionBuffers)
{
- if (!pBufferVk->CheckState(RESOURCE_STATE_VERTEX_BUFFER))
+ if (pBufferVk->IsInKnownState())
{
- TransitionBufferState(*pBufferVk, RESOURCE_STATE_UNKNOWN, RESOURCE_STATE_VERTEX_BUFFER, true);
+ if (!pBufferVk->CheckState(RESOURCE_STATE_VERTEX_BUFFER))
+ {
+ TransitionBufferState(*pBufferVk, RESOURCE_STATE_UNKNOWN, RESOURCE_STATE_VERTEX_BUFFER, true);
+ }
+ VERIFY_EXPR(pBufferVk->CheckAccessFlags(VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT));
}
- VERIFY_EXPR(pBufferVk->CheckAccessFlags(VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT));
}
-
+#ifdef DEVELOPMENT
+ else
+ {
+ if (pBufferVk->IsInKnownState() && !pBufferVk->CheckState(RESOURCE_STATE_VERTEX_BUFFER))
+ {
+ LOG_ERROR_MESSAGE("Buffer '", pBufferVk->GetDesc().Name, "' used as vertex buffer at slot ", slot, " must be in "
+ "RESOURCE_STATE_VERTEX_BUFFER state. Actual buffer state: ", GetResourceStateString(pBufferVk->GetState()),
+ ". Use DRAW_FLAG_TRANSITION_VERTEX_BUFFERS flag or explicitly transition the buffer to the required state.");
+
+ }
+ }
+#endif
+
// Device context keeps strong references to all vertex buffers.
vkVertexBuffers[slot] = pBufferVk->GetVkBuffer();
@@ -400,7 +416,7 @@ namespace Diligent
LOG_ERROR_MESSAGE(ss.str());
}
- void DeviceContextVkImpl::Draw( DrawAttribs &drawAttribs )
+ void DeviceContextVkImpl::Draw( DrawAttribs& drawAttribs )
{
#ifdef DEVELOPMENT
if (!DvpVerifyDrawArguments(drawAttribs))
@@ -420,25 +436,62 @@ namespace Diligent
#endif
BufferVkImpl *pBuffVk = m_pIndexBuffer.RawPtr<BufferVkImpl>();
- if (pBuffVk->IsInKnownState())
+ if (drawAttribs.Flags & DRAW_FLAG_TRANSITION_INDEX_BUFFER)
+ {
+ if (pBuffVk->IsInKnownState())
+ {
+ if (!pBuffVk->CheckState(RESOURCE_STATE_INDEX_BUFFER))
+ {
+ TransitionBufferState(*pBuffVk, RESOURCE_STATE_UNKNOWN, RESOURCE_STATE_INDEX_BUFFER, true);
+ }
+ VERIFY_EXPR(pBuffVk->CheckAccessFlags(VK_ACCESS_INDEX_READ_BIT));
+ }
+ }
+#ifdef DEVELOPMENT
+ else
{
- if (!pBuffVk->CheckState(RESOURCE_STATE_INDEX_BUFFER))
+ if (pBuffVk->IsInKnownState() && !pBuffVk->CheckState(RESOURCE_STATE_INDEX_BUFFER))
{
- TransitionBufferState(*pBuffVk, RESOURCE_STATE_UNKNOWN, RESOURCE_STATE_INDEX_BUFFER, true);
+ LOG_ERROR_MESSAGE("Buffer '", pBuffVk->GetDesc().Name, "' used as index buffer must be in RESOURCE_STATE_INDEX_BUFFER "
+ "state. Actual buffer state: ", GetResourceStateString(pBuffVk->GetState()),
+ ". Use DRAW_FLAG_TRANSITION_INDEX_BUFFER flag or explicitly transition the buffer to the required state.");
}
- VERIFY_EXPR(pBuffVk->CheckAccessFlags(VK_ACCESS_INDEX_READ_BIT));
}
+#endif
DEV_CHECK_ERR(drawAttribs.IndexType == VT_UINT16 || drawAttribs.IndexType == VT_UINT32, "Unsupported index format. Only R16_UINT and R32_UINT are allowed.");
VkIndexType vkIndexType = drawAttribs.IndexType == VT_UINT16 ? VK_INDEX_TYPE_UINT16 : VK_INDEX_TYPE_UINT32;
m_CommandBuffer.BindIndexBuffer(pBuffVk->GetVkBuffer(), m_IndexDataStartOffset + pBuffVk->GetDynamicOffset(m_ContextId, this), vkIndexType);
}
+ auto TransitionVertexBuffers = (drawAttribs.Flags & DRAW_FLAG_TRANSITION_VERTEX_BUFFERS) != 0;
if (m_State.CommittedVBsUpToDate)
- TransitionVkVertexBuffers();
+ {
+ if (TransitionVertexBuffers)
+ {
+ TransitionVkVertexBuffers();
+ }
+#ifdef DEVELOPMENT
+ else
+ {
+ for (Uint32 slot = 0; slot < m_NumVertexStreams; ++slot )
+ {
+ auto& CurrStream = m_VertexStreams[slot];
+ auto* pBufferVk = CurrStream.pBuffer.RawPtr();
+ if (pBufferVk != nullptr && pBufferVk->IsInKnownState() && !pBufferVk->CheckState(RESOURCE_STATE_VERTEX_BUFFER))
+ {
+ LOG_ERROR_MESSAGE("Buffer '", pBufferVk->GetDesc().Name, "' used as vertex buffer at slot ", slot, " must be in "
+ "RESOURCE_STATE_VERTEX_BUFFER state. Actual buffer state: ", GetResourceStateString(pBufferVk->GetState()),
+ ". Use DRAW_FLAG_TRANSITION_VERTEX_BUFFERS flag or explicitly transition the buffer to the required state.");
+ }
+ }
+ }
+#endif
+ }
else
- CommitVkVertexBuffers();
-
+ {
+ CommitVkVertexBuffers(TransitionVertexBuffers);
+ }
if (m_DescrSetBindInfo.DynamicOffsetCount != 0)
m_pPipelineState->BindDescriptorSetsWithDynamicOffsets(this, m_DescrSetBindInfo);
#if 0
@@ -455,14 +508,28 @@ namespace Diligent
if (pIndirectDrawAttribsVk != nullptr)
{
// Buffer memory barries must be executed outside of render pass
- if (pIndirectDrawAttribsVk->IsInKnownState())
+ if(drawAttribs.Flags & DRAW_FLAG_TRANSITION_INDIRECT_ARGS_BUFFER)
+ {
+ if (pIndirectDrawAttribsVk->IsInKnownState())
+ {
+ if (!pIndirectDrawAttribsVk->CheckState(RESOURCE_STATE_INDIRECT_ARGUMENT))
+ {
+ TransitionBufferState(*pIndirectDrawAttribsVk, RESOURCE_STATE_UNKNOWN, RESOURCE_STATE_INDIRECT_ARGUMENT, true);
+ }
+ VERIFY_EXPR(pIndirectDrawAttribsVk->CheckAccessFlags(VK_ACCESS_INDIRECT_COMMAND_READ_BIT));
+ }
+ }
+#ifdef DEVELOPMENT
+ else
{
- if (!pIndirectDrawAttribsVk->CheckState(RESOURCE_STATE_INDIRECT_ARGUMENT))
+ if (pIndirectDrawAttribsVk->IsInKnownState() && !pIndirectDrawAttribsVk->CheckState(RESOURCE_STATE_INDIRECT_ARGUMENT))
{
- TransitionBufferState(*pIndirectDrawAttribsVk, RESOURCE_STATE_UNKNOWN, RESOURCE_STATE_INDIRECT_ARGUMENT, true);
+ LOG_ERROR_MESSAGE("Buffer '", pIndirectDrawAttribsVk->GetDesc().Name, "' used as indirect draw arguments buffer must be in RESOURCE_STATE_INDIRECT_ARGUMENT "
+ "state. Actual buffer state: ", GetResourceStateString(pIndirectDrawAttribsVk->GetState()),
+ ". Use DRAW_FLAG_TRANSITION_INDIRECT_ARGS_BUFFER flag or explicitly transition the buffer to the required state.");
}
- VERIFY_EXPR(pIndirectDrawAttribsVk->CheckAccessFlags(VK_ACCESS_INDIRECT_COMMAND_READ_BIT));
}
+#endif
}
#ifdef DEVELOPMENT
@@ -480,14 +547,6 @@ namespace Diligent
if (pIndirectDrawAttribsVk->GetDesc().Usage == USAGE_DYNAMIC)
pIndirectDrawAttribsVk->DvpVerifyDynamicAllocation(this);
#endif
- if (pIndirectDrawAttribsVk->IsInKnownState())
- {
- if (!pIndirectDrawAttribsVk->CheckState(RESOURCE_STATE_INDIRECT_ARGUMENT))
- {
- TransitionBufferState(*pIndirectDrawAttribsVk, RESOURCE_STATE_UNKNOWN, RESOURCE_STATE_INDIRECT_ARGUMENT, true);
- }
- VERIFY_EXPR(pIndirectDrawAttribsVk->CheckAccessFlags(VK_ACCESS_INDIRECT_COMMAND_READ_BIT));
- }
if ( drawAttribs.IsIndexed )
m_CommandBuffer.DrawIndexedIndirect(pIndirectDrawAttribsVk->GetVkBuffer(), pIndirectDrawAttribsVk->GetDynamicOffset(m_ContextId, this) + drawAttribs.IndirectDrawArgsOffset, 1, 0);
@@ -539,15 +598,29 @@ namespace Diligent
pBufferVk->DvpVerifyDynamicAllocation(this);
#endif
- // Buffer memory barries must be executed outside of render pass
- if (pBufferVk->IsInKnownState())
+ if(DispatchAttrs.Flags & DISPATCH_FLAG_TRANSITION_INDIRECT_ARGS_BUFFER)
{
- if (!pBufferVk->CheckState(RESOURCE_STATE_INDIRECT_ARGUMENT))
+ // Buffer memory barries must be executed outside of render pass
+ if (pBufferVk->IsInKnownState())
{
- TransitionBufferState(*pBufferVk, RESOURCE_STATE_UNKNOWN, RESOURCE_STATE_INDIRECT_ARGUMENT, true);
+ if (!pBufferVk->CheckState(RESOURCE_STATE_INDIRECT_ARGUMENT))
+ {
+ TransitionBufferState(*pBufferVk, RESOURCE_STATE_UNKNOWN, RESOURCE_STATE_INDIRECT_ARGUMENT, true);
+ }
+ VERIFY_EXPR(pBufferVk->CheckAccessFlags(VK_ACCESS_INDIRECT_COMMAND_READ_BIT));
}
- VERIFY_EXPR(pBufferVk->CheckAccessFlags(VK_ACCESS_INDIRECT_COMMAND_READ_BIT));
}
+#ifdef DEVELOPMENT
+ else
+ {
+ if (pBufferVk->IsInKnownState() && !pBufferVk->CheckState(RESOURCE_STATE_INDIRECT_ARGUMENT))
+ {
+ LOG_ERROR_MESSAGE("Buffer '", pBufferVk->GetDesc().Name, "' used as indirect dispatch arguments buffer must be in RESOURCE_STATE_INDIRECT_ARGUMENT "
+ "state. Actual buffer state: ", GetResourceStateString(pBufferVk->GetState()),
+ ". Use DISPATCH_FLAG_TRANSITION_INDIRECT_ARGS_BUFFER flag or explicitly transition the buffer to the required state.");
+ }
+ }
+#endif
m_CommandBuffer.DispatchIndirect(pBufferVk->GetVkBuffer(), pBufferVk->GetDynamicOffset(m_ContextId, this) + DispatchAttrs.DispatchArgsByteOffset);
}