summaryrefslogtreecommitdiffstats
path: root/Graphics
diff options
context:
space:
mode:
authorEgor Yusov <egor.yusov@gmail.com>2019-09-09 00:42:51 +0000
committerEgor Yusov <egor.yusov@gmail.com>2019-09-09 00:42:51 +0000
commitd06553e2b4700aa026acd4445a598eadf10dfb35 (patch)
tree534c3761a92cfb93d370b75f29f6b720a10c64a8 /Graphics
parentRenamed IDeviceContext::Wait to IDeviceContext::WaitForFence (updated API ver... (diff)
downloadDiligentCore-d06553e2b4700aa026acd4445a598eadf10dfb35.tar.gz
DiligentCore-d06553e2b4700aa026acd4445a598eadf10dfb35.zip
Added IDeviceContext::WaitForIdle() method (updated API version to 240028)
Diffstat (limited to 'Graphics')
-rw-r--r--Graphics/GraphicsEngine/interface/APIInfo.h2
-rw-r--r--Graphics/GraphicsEngine/interface/DeviceContext.h9
-rwxr-xr-xGraphics/GraphicsEngineD3D11/include/DeviceContextD3D11Impl.h6
-rwxr-xr-xGraphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp26
-rw-r--r--Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.h6
-rw-r--r--Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp6
-rw-r--r--Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp2
-rw-r--r--Graphics/GraphicsEngineMetal/include/DeviceContextMtlImpl.h6
-rw-r--r--Graphics/GraphicsEngineMetal/src/DeviceContextMtlImpl.mm8
-rw-r--r--Graphics/GraphicsEngineNextGenBase/include/RenderDeviceNextGenBase.h48
-rw-r--r--Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.h6
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp6
-rw-r--r--Graphics/GraphicsEngineOpenGL/src/GLProgramResources.cpp2
-rw-r--r--Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h6
-rw-r--r--Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp6
-rw-r--r--Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp2
16 files changed, 108 insertions, 39 deletions
diff --git a/Graphics/GraphicsEngine/interface/APIInfo.h b/Graphics/GraphicsEngine/interface/APIInfo.h
index 82ff31e0..d4215993 100644
--- a/Graphics/GraphicsEngine/interface/APIInfo.h
+++ b/Graphics/GraphicsEngine/interface/APIInfo.h
@@ -26,7 +26,7 @@
/// \file
/// Diligent API information
-#define DILIGENT_API_VERSION 240027
+#define DILIGENT_API_VERSION 240028
#include "../../../Primitives/interface/BasicTypes.h"
diff --git a/Graphics/GraphicsEngine/interface/DeviceContext.h b/Graphics/GraphicsEngine/interface/DeviceContext.h
index ea40f058..b3b9dbb7 100644
--- a/Graphics/GraphicsEngine/interface/DeviceContext.h
+++ b/Graphics/GraphicsEngine/interface/DeviceContext.h
@@ -821,6 +821,15 @@ public:
virtual void WaitForFence(IFence* pFence, Uint64 Value, bool FlushContext) = 0;
+ /// Submits all outstanding commands for execution to the GPU and waits until they are complete.
+
+ /// \remarks Only immediate contexts can be idled.\n
+ /// The methods implicitly flushes the context (see IDeviceContext::Flush()), so an
+ /// application must explicitly reset the PSO and bind all required shader resources after
+ /// idling the context.\n
+ virtual void WaitForIdle() = 0;
+
+
/// Submits all pending commands in the context for execution to the command queue.
/// \remarks Only immediate contexts can be flushed.\n
diff --git a/Graphics/GraphicsEngineD3D11/include/DeviceContextD3D11Impl.h b/Graphics/GraphicsEngineD3D11/include/DeviceContextD3D11Impl.h
index 940529b4..86ca2fb2 100755
--- a/Graphics/GraphicsEngineD3D11/include/DeviceContextD3D11Impl.h
+++ b/Graphics/GraphicsEngineD3D11/include/DeviceContextD3D11Impl.h
@@ -103,8 +103,6 @@ public:
virtual void ClearRenderTarget(ITextureView* pView, const float* RGBA, RESOURCE_STATE_TRANSITION_MODE StateTransitionMode)override final;
- virtual void Flush()override final;
-
virtual void UpdateBuffer(IBuffer* pBuffer,
Uint32 Offset,
Uint32 Size,
@@ -158,6 +156,10 @@ public:
virtual void WaitForFence(IFence* pFence, Uint64 Value, bool FlushContext)override final;
+ virtual void WaitForIdle()override final;
+
+ virtual void Flush()override final;
+
virtual ID3D11DeviceContext* GetD3D11DeviceContext()override final { return m_pd3d11DeviceContext; }
void CommitRenderTargets();
diff --git a/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp b/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp
index 72e26117..e3543bac 100755
--- a/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp
+++ b/Graphics/GraphicsEngineD3D11/src/DeviceContextD3D11Impl.cpp
@@ -1747,20 +1747,28 @@ namespace Diligent
#endif
}
- void DeviceContextD3D11Impl::SignalFence(IFence* pFence, Uint64 Value)
+
+ static CComPtr<ID3D11Query> CreateD3D11QueryEvent(ID3D11Device* pd3d11Device)
{
- VERIFY(!m_bIsDeferred, "Fence can only be signaled from immediate context");
- auto* pd3d11Device = m_pDevice.RawPtr<RenderDeviceD3D11Impl>()->GetD3D11Device();
D3D11_QUERY_DESC QueryDesc = {};
QueryDesc.Query = D3D11_QUERY_EVENT; // Determines whether or not the GPU is finished processing commands.
// When the GPU is finished processing commands ID3D11DeviceContext::GetData will
// return S_OK, and pData will point to a BOOL with a value of TRUE. When using this
// type of query, ID3D11DeviceContext::Begin is disabled.
QueryDesc.MiscFlags = 0;
+
CComPtr<ID3D11Query> pd3d11Query;
auto hr = pd3d11Device->CreateQuery(&QueryDesc, &pd3d11Query);
DEV_CHECK_ERR(SUCCEEDED(hr), "Failed to create D3D11 query");
VERIFY_EXPR(pd3d11Query);
+ return pd3d11Query;
+ }
+
+ void DeviceContextD3D11Impl::SignalFence(IFence* pFence, Uint64 Value)
+ {
+ VERIFY(!m_bIsDeferred, "Fence can only be signaled from immediate context");
+ auto* pd3d11Device = m_pDevice.RawPtr<RenderDeviceD3D11Impl>()->GetD3D11Device();
+ CComPtr<ID3D11Query> pd3d11Query = CreateD3D11QueryEvent(pd3d11Device);
m_pd3d11DeviceContext->End(pd3d11Query);
auto* pFenceD3D11Impl = ValidatedCast<FenceD3D11Impl>(pFence);
pFenceD3D11Impl->AddPendingQuery(m_pd3d11DeviceContext, std::move(pd3d11Query), Value);
@@ -1775,6 +1783,18 @@ namespace Diligent
pFenceD3D11Impl->Wait(Value, FlushContext);
}
+ void DeviceContextD3D11Impl::WaitForIdle()
+ {
+ VERIFY(!m_bIsDeferred, "Only immediate contexts can be idled");
+ Flush();
+ auto* pd3d11Device = m_pDevice.RawPtr<RenderDeviceD3D11Impl>()->GetD3D11Device();
+ CComPtr<ID3D11Query> pd3d11Query = CreateD3D11QueryEvent(pd3d11Device);
+ m_pd3d11DeviceContext->End(pd3d11Query);
+ BOOL Data;
+ while (m_pd3d11DeviceContext->GetData(pd3d11Query, &Data, sizeof(Data), 0) != S_OK)
+ std::this_thread::yield();
+ }
+
void DeviceContextD3D11Impl::ClearStateCache()
{
TDeviceContextBase::ClearStateCache();
diff --git a/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.h b/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.h
index b9f57598..0d973062 100644
--- a/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.h
+++ b/Graphics/GraphicsEngineD3D12/include/DeviceContextD3D12Impl.h
@@ -104,8 +104,6 @@ public:
virtual void ClearRenderTarget( ITextureView* pView, const float* RGBA, RESOURCE_STATE_TRANSITION_MODE StateTransitionMode )override final;
- virtual void Flush()override final;
-
virtual void UpdateBuffer(IBuffer* pBuffer,
Uint32 Offset,
Uint32 Size,
@@ -156,6 +154,10 @@ public:
virtual void WaitForFence(IFence* pFence, Uint64 Value, bool FlushContext)override final;
+ virtual void WaitForIdle()override final;
+
+ virtual void Flush()override final;
+
virtual void TransitionTextureState(ITexture *pTexture, D3D12_RESOURCE_STATES State)override final;
virtual void TransitionBufferState(IBuffer *pBuffer, D3D12_RESOURCE_STATES State)override final;
diff --git a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp
index b31bedef..78e81459 100644
--- a/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp
+++ b/Graphics/GraphicsEngineD3D12/src/DeviceContextD3D12Impl.cpp
@@ -1580,6 +1580,12 @@ namespace Diligent
pFenceD3D12->WaitForCompletion(Value);
}
+ void DeviceContextD3D12Impl::WaitForIdle()
+ {
+ VERIFY(!m_bIsDeferred, "Only immediate contexts can be idled");
+ Flush();
+ m_pDevice.RawPtr<RenderDeviceD3D12Impl>()->IdleCommandQueue(m_CommandQueueId, true);
+ }
void DeviceContextD3D12Impl::TransitionResourceStates(Uint32 BarrierCount, StateTransitionDesc* pResourceBarriers)
{
diff --git a/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp b/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp
index e34b637a..22ed2bc8 100644
--- a/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp
+++ b/Graphics/GraphicsEngineD3D12/src/RenderDeviceD3D12Impl.cpp
@@ -202,7 +202,7 @@ void RenderDeviceD3D12Impl::SignalFences(Uint32 QueueIndex, std::vector<std::pai
void RenderDeviceD3D12Impl::IdleGPU()
{
- IdleCommandQueues(true);
+ IdleAllCommandQueues(true);
ReleaseStaleResources();
}
diff --git a/Graphics/GraphicsEngineMetal/include/DeviceContextMtlImpl.h b/Graphics/GraphicsEngineMetal/include/DeviceContextMtlImpl.h
index ab0e6a3b..96b1ca0f 100644
--- a/Graphics/GraphicsEngineMetal/include/DeviceContextMtlImpl.h
+++ b/Graphics/GraphicsEngineMetal/include/DeviceContextMtlImpl.h
@@ -99,8 +99,6 @@ public:
virtual void ClearRenderTarget(ITextureView* pView, const float* RGBA, RESOURCE_STATE_TRANSITION_MODE StateTransitionMode)override final;
- virtual void Flush()override final;
-
virtual void UpdateBuffer(IBuffer* pBuffer,
Uint32 Offset,
Uint32 Size,
@@ -154,6 +152,10 @@ public:
virtual void WaitForFence(IFence* pFence, Uint64 Value, bool FlushContext)override final;
+ virtual void WaitForIdle()override final;
+
+ virtual void Flush()override final;
+
private:
};
diff --git a/Graphics/GraphicsEngineMetal/src/DeviceContextMtlImpl.mm b/Graphics/GraphicsEngineMetal/src/DeviceContextMtlImpl.mm
index 7c4aeacd..a104efb2 100644
--- a/Graphics/GraphicsEngineMetal/src/DeviceContextMtlImpl.mm
+++ b/Graphics/GraphicsEngineMetal/src/DeviceContextMtlImpl.mm
@@ -384,6 +384,14 @@ namespace Diligent
LOG_ERROR_MESSAGE("DeviceContextMtlImpl::Wait() is not implemented");
}
+ void DeviceContextMtlImpl::WaitForIdle()
+ {
+ VERIFY(!m_bIsDeferred, "Only immediate contexts can be idled");
+ Flush();
+
+ LOG_ERROR_MESSAGE("DeviceContextMtlImpl::WaitForIdle() is not implemented");
+ }
+
void DeviceContextMtlImpl::TransitionResourceStates(Uint32 BarrierCount, StateTransitionDesc* pResourceBarriers)
{
LOG_ERROR_MESSAGE("DeviceContextMtlImpl::TransitionResourceStates() is not implemented");
diff --git a/Graphics/GraphicsEngineNextGenBase/include/RenderDeviceNextGenBase.h b/Graphics/GraphicsEngineNextGenBase/include/RenderDeviceNextGenBase.h
index 3f7b42d1..ea1c726c 100644
--- a/Graphics/GraphicsEngineNextGenBase/include/RenderDeviceNextGenBase.h
+++ b/Graphics/GraphicsEngineNextGenBase/include/RenderDeviceNextGenBase.h
@@ -145,37 +145,41 @@ public:
Queue.ReleaseQueue.Purge(CompletedFenceValue);
}
- void IdleCommandQueues(bool ReleaseResources)
+ void IdleCommandQueue(size_t QueueIdx, bool ReleaseResources)
{
- for(size_t q=0; q < m_CmdQueueCount; ++q)
- {
- auto& Queue = m_CommandQueues[q];
+ VERIFY_EXPR(QueueIdx < m_CmdQueueCount);
+ auto& Queue = m_CommandQueues[QueueIdx];
- Uint64 CmdBufferNumber = 0;
- Uint64 FenceValue = 0;
- {
- std::lock_guard<std::mutex> Lock(Queue.Mtx);
-
- if (ReleaseResources)
- {
- // Increment command buffer number before idling the queue.
- // This will make sure that any resource released while this function
- // is running will be associated with the next command buffer submission.
- CmdBufferNumber = static_cast<Uint64>(Queue.NextCmdBufferNumber);
- Atomics::AtomicIncrement(Queue.NextCmdBufferNumber);
- }
-
- FenceValue = Queue.CmdQueue->WaitForIdle();
- }
+ Uint64 CmdBufferNumber = 0;
+ Uint64 FenceValue = 0;
+ {
+ std::lock_guard<std::mutex> Lock(Queue.Mtx);
if (ReleaseResources)
{
- Queue.ReleaseQueue.DiscardStaleResources(CmdBufferNumber, FenceValue);
- Queue.ReleaseQueue.Purge(Queue.CmdQueue->GetCompletedFenceValue());
+ // Increment command buffer number before idling the queue.
+ // This will make sure that any resource released while this function
+ // is running will be associated with the next command buffer submission.
+ CmdBufferNumber = static_cast<Uint64>(Queue.NextCmdBufferNumber);
+ Atomics::AtomicIncrement(Queue.NextCmdBufferNumber);
}
+
+ FenceValue = Queue.CmdQueue->WaitForIdle();
+ }
+
+ if (ReleaseResources)
+ {
+ Queue.ReleaseQueue.DiscardStaleResources(CmdBufferNumber, FenceValue);
+ Queue.ReleaseQueue.Purge(Queue.CmdQueue->GetCompletedFenceValue());
}
}
+ void IdleAllCommandQueues(bool ReleaseResources)
+ {
+ for(size_t q=0; q < m_CmdQueueCount; ++q)
+ IdleCommandQueue(q, ReleaseResources);
+ }
+
struct SubmittedCommandBufferInfo
{
Uint64 CmdBufferNumber = 0;
diff --git a/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.h b/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.h
index 7b1931b1..601976ee 100644
--- a/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.h
+++ b/Graphics/GraphicsEngineOpenGL/include/DeviceContextGLImpl.h
@@ -95,8 +95,6 @@ public:
virtual void ClearRenderTarget(ITextureView* pView, const float* RGBA, RESOURCE_STATE_TRANSITION_MODE StateTransitionMode)override final;
- virtual void Flush()override final;
-
virtual void UpdateBuffer(IBuffer* pBuffer,
Uint32 Offset,
Uint32 Size,
@@ -152,6 +150,10 @@ public:
virtual void WaitForFence(IFence* pFence, Uint64 Value, bool FlushContext)override final;
+ virtual void WaitForIdle()override final;
+
+ virtual void Flush()override final;
+
virtual bool UpdateCurrentGLContext()override final;
void BindProgramResources(Uint32& NewMemoryBarriers, IShaderResourceBinding* pResBinding);
diff --git a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp
index 23836746..94537d40 100644
--- a/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp
+++ b/Graphics/GraphicsEngineOpenGL/src/DeviceContextGLImpl.cpp
@@ -1082,6 +1082,12 @@ namespace Diligent
pFenceGLImpl->Wait(Value, FlushContext);
}
+ void DeviceContextGLImpl::WaitForIdle()
+ {
+ VERIFY(!m_bIsDeferred, "Only immediate contexts can be idled");
+ glFinish();
+ }
+
bool DeviceContextGLImpl::UpdateCurrentGLContext()
{
auto* pRenderDeviceGL = m_pDevice.RawPtr<RenderDeviceGLImpl>();
diff --git a/Graphics/GraphicsEngineOpenGL/src/GLProgramResources.cpp b/Graphics/GraphicsEngineOpenGL/src/GLProgramResources.cpp
index 1850255d..a8f55e27 100644
--- a/Graphics/GraphicsEngineOpenGL/src/GLProgramResources.cpp
+++ b/Graphics/GraphicsEngineOpenGL/src/GLProgramResources.cpp
@@ -583,7 +583,7 @@ namespace Diligent
if ( strcmp(LastBlock.Name, Name.data()) == 0)
{
ArraySize = std::max(ArraySize, static_cast<GLint>(LastBlock.ArraySize));
- VERIFY(static_cast<GLuint>(SBIndex) == LastBlock.SBIndex + Ind, "Storage block indices are expected to be continuous");
+ VERIFY(static_cast<GLint>(SBIndex) == LastBlock.SBIndex + Ind, "Storage block indices are expected to be continuous");
LastBlock.ArraySize = ArraySize;
continue;
}
diff --git a/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h b/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h
index a7f02919..c220a8e5 100644
--- a/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h
+++ b/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h
@@ -112,8 +112,6 @@ public:
virtual void ClearRenderTarget( ITextureView* pView, const float* RGBA, RESOURCE_STATE_TRANSITION_MODE StateTransitionMode )override final;
- virtual void Flush()override final;
-
virtual void UpdateBuffer(IBuffer* pBuffer,
Uint32 Offset,
Uint32 Size,
@@ -161,6 +159,10 @@ public:
virtual void WaitForFence(IFence* pFence, Uint64 Value, bool FlushContext)override final;
+ virtual void WaitForIdle()override final;
+
+ virtual void Flush()override final;
+
// Transitions texture subresources from OldState to NewState, and optionally updates
// internal texture state.
// If OldState == RESOURCE_STATE_UNKNOWN, internal texture state is used as old state.
diff --git a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp
index 2a8cafde..4e87d6d4 100644
--- a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp
@@ -1925,6 +1925,12 @@ namespace Diligent
pFenceVk->Wait(Value);
}
+ void DeviceContextVkImpl::WaitForIdle()
+ {
+ VERIFY(!m_bIsDeferred, "Only immediate contexts can be idled");
+ Flush();
+ m_pDevice.RawPtr<RenderDeviceVkImpl>()->IdleCommandQueue(m_CommandQueueId, true);
+ }
void DeviceContextVkImpl::TransitionImageLayout(ITexture* pTexture, VkImageLayout NewLayout)
{
diff --git a/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp
index 271af6e0..ca9b3200 100644
--- a/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp
@@ -281,7 +281,7 @@ Uint64 RenderDeviceVkImpl::ExecuteCommandBuffer(Uint32 QueueIndex, const VkSubmi
void RenderDeviceVkImpl::IdleGPU()
{
- IdleCommandQueues(true);
+ IdleAllCommandQueues(true);
m_LogicalVkDevice->WaitIdle();
ReleaseStaleResources();
}