summaryrefslogtreecommitdiffstats
path: root/Graphics/GraphicsEngineVulkan
diff options
context:
space:
mode:
authorEgor Yusov <egor.yusov@gmail.com>2018-07-22 02:46:57 +0000
committerEgor Yusov <egor.yusov@gmail.com>2018-07-22 02:46:57 +0000
commit2dfbbae491090f3b0f0e622791515c59f3948ee0 (patch)
tree898621085fe8253e7e52dc81ff03904931dcb36f /Graphics/GraphicsEngineVulkan
parentDisabled D3D11 fence for now to fix build (diff)
downloadDiligentCore-2dfbbae491090f3b0f0e622791515c59f3948ee0.tar.gz
DiligentCore-2dfbbae491090f3b0f0e622791515c59f3948ee0.zip
Implemented IFence interface in all backends
Diffstat (limited to 'Graphics/GraphicsEngineVulkan')
-rw-r--r--Graphics/GraphicsEngineVulkan/include/CommandQueueVkImpl.h18
-rw-r--r--Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h11
-rw-r--r--Graphics/GraphicsEngineVulkan/include/FenceVkImpl.h21
-rw-r--r--Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.h4
-rw-r--r--Graphics/GraphicsEngineVulkan/interface/CommandQueueVk.h3
-rw-r--r--Graphics/GraphicsEngineVulkan/interface/FenceVk.h3
-rw-r--r--Graphics/GraphicsEngineVulkan/src/CommandQueueVkImpl.cpp58
-rw-r--r--Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp14
-rw-r--r--Graphics/GraphicsEngineVulkan/src/FenceVkImpl.cpp61
-rw-r--r--Graphics/GraphicsEngineVulkan/src/RenderDeviceFactoryVk.cpp8
-rw-r--r--Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp23
11 files changed, 145 insertions, 79 deletions
diff --git a/Graphics/GraphicsEngineVulkan/include/CommandQueueVkImpl.h b/Graphics/GraphicsEngineVulkan/include/CommandQueueVkImpl.h
index eab3d101..b1ec606f 100644
--- a/Graphics/GraphicsEngineVulkan/include/CommandQueueVkImpl.h
+++ b/Graphics/GraphicsEngineVulkan/include/CommandQueueVkImpl.h
@@ -32,7 +32,7 @@
#include "CommandQueueVk.h"
#include "ObjectBase.h"
#include "VulkanUtilities/VulkanLogicalDevice.h"
-#include "VulkanUtilities/VulkanFencePool.h"
+#include "FenceVkImpl.h"
namespace Diligent
{
@@ -65,23 +65,25 @@ public:
virtual void IdleGPU()override final;
virtual Uint64 GetCompletedFenceValue()override final;
+
+ virtual void SignalFence(VkFence vkFence)override final;
+
+ void SetFence(RefCntAutoPtr<FenceVkImpl> pFence){m_pFence = std::move(pFence);}
+
private:
// A value that will be signaled by the command queue next
Atomics::AtomicInt64 m_NextFenceValue;
- // Last fence value that is known to be completed by the GPU
- volatile Uint64 m_LastCompletedFenceValue = 0;
-
std::shared_ptr<VulkanUtilities::VulkanLogicalDevice> m_LogicalDevice;
const VkQueue m_VkQueue;
const uint32_t m_QueueFamilyIndex;
- VulkanUtilities::VulkanFencePool m_FencePool;
- // Queue of fences signaled right after a command buffer has been
+ // Fence is signaled right after a command buffer has been
// submitted to the command queue for execution.
- // All command buffers with fence value less or equal to the signaled value
+ // All command buffers with fence value less than or equal to the signaled value
// are guaranteed to be finished by the GPU
- std::deque<std::pair<Uint64, VulkanUtilities::FenceWrapper>> m_PendingFences;
+ RefCntAutoPtr<FenceVkImpl> m_pFence;
+
std::mutex m_QueueMutex;
};
diff --git a/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h b/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h
index 0e40553c..26e74a25 100644
--- a/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h
+++ b/Graphics/GraphicsEngineVulkan/include/DeviceContextVkImpl.h
@@ -93,6 +93,8 @@ public:
virtual void ExecuteCommandList(class ICommandList* pCommandList)override final;
+ virtual void SignalFence(IFence* pFence, Uint64 Value)override final;
+
void TransitionImageLayout(class TextureVkImpl &TextureVk, VkImageLayout NewLayout);
void TransitionImageLayout(class TextureVkImpl &TextureVk, VkImageLayout OldLayout, VkImageLayout NewLayout, const VkImageSubresourceRange& SubresRange);
virtual void TransitionImageLayout(ITexture* pTexture, VkImageLayout NewLayout)override final;
@@ -199,9 +201,12 @@ private:
VulkanUtilities::VulkanCommandBufferPool m_CmdPool;
// Semaphores are not owned by the command context
- std::vector<VkSemaphore> m_WaitSemaphores;
- std::vector<VkPipelineStageFlags> m_WaitDstStageMasks;
- std::vector<VkSemaphore> m_SignalSemaphores;
+ std::vector<VkSemaphore> m_WaitSemaphores;
+ std::vector<VkPipelineStageFlags> m_WaitDstStageMasks;
+ std::vector<VkSemaphore> m_SignalSemaphores;
+
+ // List of fences to signal next time the command context is flushed
+ std::vector<std::pair<Uint64, RefCntAutoPtr<IFence> > > m_PendingFences;
std::unordered_map<BufferVkImpl*, VulkanUtilities::VulkanUploadAllocation> m_UploadAllocations;
ResourceReleaseQueue<DynamicStaleResourceWrapper> m_ReleaseQueue;
diff --git a/Graphics/GraphicsEngineVulkan/include/FenceVkImpl.h b/Graphics/GraphicsEngineVulkan/include/FenceVkImpl.h
index 6d1a9267..fcb5f979 100644
--- a/Graphics/GraphicsEngineVulkan/include/FenceVkImpl.h
+++ b/Graphics/GraphicsEngineVulkan/include/FenceVkImpl.h
@@ -26,14 +26,16 @@
/// \file
/// Declaration of Diligent::FenceVkImpl class
+#include <deque>
#include "FenceVk.h"
-#include "RenderDeviceVk.h"
#include "FenceBase.h"
+#include "VulkanUtilities/VulkanFencePool.h"
namespace Diligent
{
class FixedBlockMemoryAllocator;
+class RenderDeviceVkImpl;
/// Implementation of the Diligent::IFenceVk interface
class FenceVkImpl : public FenceBase<IFenceVk>
@@ -42,17 +44,28 @@ public:
using TFenceBase = FenceBase<IFenceVk>;
FenceVkImpl(IReferenceCounters* pRefCounters,
- IRenderDevice* pDevice,
- const FenceDesc& Desc);
+ RenderDeviceVkImpl* pRendeDeviceVkImpl,
+ const FenceDesc& Desc,
+ bool IsDeviceInternal = false);
~FenceVkImpl();
virtual Uint64 GetCompletedValue()override final;
/// Resets the fence to the specified value.
virtual void Reset(Uint64 Value)override final;
+
+ VulkanUtilities::FenceWrapper GetVkFence() { return m_FencePool.GetFence(); }
+ void AddPendingFence(VulkanUtilities::FenceWrapper&& vkFence, Uint64 FenceValue)
+ {
+ m_PendingFences.emplace_back(FenceValue, std::move(vkFence));
+ }
-private:
+ void Wait();
+private:
+ VulkanUtilities::VulkanFencePool m_FencePool;
+ std::deque<std::pair<Uint64, VulkanUtilities::FenceWrapper>> m_PendingFences;
+ volatile Uint64 m_LastCompletedFenceValue = 0;
};
}
diff --git a/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.h b/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.h
index e2edd52b..612854f7 100644
--- a/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.h
+++ b/Graphics/GraphicsEngineVulkan/include/RenderDeviceVkImpl.h
@@ -103,7 +103,7 @@ public:
Uint64 IdleGPU(bool ReleaseStaleObjects);
// pImmediateCtx parameter is only used to make sure the command buffer is submitted from the immediate context
// The method returns fence value associated with the submitted command buffer
- Uint64 ExecuteCommandBuffer(const VkSubmitInfo &SubmitInfo, class DeviceContextVkImpl* pImmediateCtx);
+ Uint64 ExecuteCommandBuffer(const VkSubmitInfo &SubmitInfo, class DeviceContextVkImpl* pImmediateCtx, std::vector<std::pair<Uint64, RefCntAutoPtr<IFence> > >* pSignalFences);
void AllocateTransientCmdPool(VulkanUtilities::CommandPoolWrapper& CmdPool, VkCommandBuffer& vkCmdBuff, const Char* DebugPoolName = nullptr);
void ExecuteAndDisposeTransientCmdBuff(VkCommandBuffer vkCmdBuff, VulkanUtilities::CommandPoolWrapper&& CmdPool);
@@ -144,7 +144,7 @@ private:
// Parameters:
// * SubmittedCmdBuffNumber - submitted command buffer number
// * SubmittedFenceValue - fence value associated with the submitted command buffer
- void SubmitCommandBuffer(const VkSubmitInfo& SubmitInfo, Uint64& SubmittedCmdBuffNumber, Uint64& SubmittedFenceValue);
+ void SubmitCommandBuffer(const VkSubmitInfo& SubmitInfo, Uint64& SubmittedCmdBuffNumber, Uint64& SubmittedFenceValue, std::vector<std::pair<Uint64, RefCntAutoPtr<IFence> > >* pFences);
std::shared_ptr<VulkanUtilities::VulkanInstance> m_VulkanInstance;
std::unique_ptr<VulkanUtilities::VulkanPhysicalDevice> m_PhysicalDevice;
diff --git a/Graphics/GraphicsEngineVulkan/interface/CommandQueueVk.h b/Graphics/GraphicsEngineVulkan/interface/CommandQueueVk.h
index ca1a4acc..a7c58096 100644
--- a/Graphics/GraphicsEngineVulkan/interface/CommandQueueVk.h
+++ b/Graphics/GraphicsEngineVulkan/interface/CommandQueueVk.h
@@ -64,6 +64,9 @@ public:
/// Blocks execution until all pending GPU commands are complete
virtual void IdleGPU() = 0;
+
+ /// Signals the given fence
+ virtual void SignalFence(VkFence vkFence) = 0;
};
}
diff --git a/Graphics/GraphicsEngineVulkan/interface/FenceVk.h b/Graphics/GraphicsEngineVulkan/interface/FenceVk.h
index 4fa22e51..25bf1475 100644
--- a/Graphics/GraphicsEngineVulkan/interface/FenceVk.h
+++ b/Graphics/GraphicsEngineVulkan/interface/FenceVk.h
@@ -40,8 +40,7 @@ static constexpr INTERFACE_ID IID_FenceVk =
class IFenceVk : public IFence
{
public:
- /// Returns OpenGL sync object
- //virtual IGLFence* GetGLFence() = 0;
+
};
}
diff --git a/Graphics/GraphicsEngineVulkan/src/CommandQueueVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/CommandQueueVkImpl.cpp
index 92fd5f85..e75d4aaf 100644
--- a/Graphics/GraphicsEngineVulkan/src/CommandQueueVkImpl.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/CommandQueueVkImpl.cpp
@@ -35,8 +35,7 @@ CommandQueueVkImpl::CommandQueueVkImpl(IReferenceCounters*
m_LogicalDevice (LogicalDevice),
m_VkQueue (LogicalDevice->GetQueue(QueueFamilyIndex, 0)),
m_QueueFamilyIndex (QueueFamilyIndex),
- m_NextFenceValue (1),
- m_FencePool (LogicalDevice)
+ m_NextFenceValue (1)
{
}
@@ -46,11 +45,6 @@ CommandQueueVkImpl::~CommandQueueVkImpl()
// All queues associated with a logical device are destroyed when vkDestroyDevice
// is called on that device.
- while (!m_PendingFences.empty())
- {
- m_FencePool.DisposeFence(std::move(m_PendingFences.front().second));
- m_PendingFences.pop_front();
- }
}
IMPLEMENT_QUERY_INTERFACE( CommandQueueVkImpl, IID_CommandQueueVk, TBase )
@@ -59,18 +53,18 @@ IMPLEMENT_QUERY_INTERFACE( CommandQueueVkImpl, IID_CommandQueueVk, TBase )
Uint64 CommandQueueVkImpl::ExecuteCommandBuffer(const VkSubmitInfo& SubmitInfo)
{
std::lock_guard<std::mutex> Lock(m_QueueMutex);
- auto Fence = m_FencePool.GetFence();
+ auto vkFence = m_pFence->GetVkFence();
bool SubmitCount =
(SubmitInfo.waitSemaphoreCount != 0 ||
SubmitInfo.commandBufferCount != 0 ||
SubmitInfo.signalSemaphoreCount != 0) ?
1 : 0;
- auto err = vkQueueSubmit(m_VkQueue, SubmitCount, &SubmitInfo, Fence);
+ auto err = vkQueueSubmit(m_VkQueue, SubmitCount, &SubmitInfo, vkFence);
VERIFY(err == VK_SUCCESS, "Failed to submit command buffer to the command queue");
// We must atomically place the (value, fence) pair into the deque
auto FenceValue = m_NextFenceValue;
- m_PendingFences.emplace_back(FenceValue, std::move(Fence));
+ m_pFence->AddPendingFence(std::move(vkFence), FenceValue);
// Increment the value
Atomics::AtomicIncrement(m_NextFenceValue);
@@ -105,47 +99,21 @@ void CommandQueueVkImpl::IdleGPU()
// Increment fence before idling the queue
Atomics::AtomicIncrement(m_NextFenceValue);
vkQueueWaitIdle(m_VkQueue);
- if (LastCompletedFenceValue > m_LastCompletedFenceValue)
- m_LastCompletedFenceValue = LastCompletedFenceValue;
- for (auto& val_fence : m_PendingFences)
- {
- // For some reason after idling the queue not all fences are signaled
- while (m_LogicalDevice->GetFenceStatus(val_fence.second) != VK_SUCCESS)
- {
- VkFence FenceToWait = val_fence.second;
- auto res = vkWaitForFences(m_LogicalDevice->GetVkDevice(), 1, &FenceToWait, VK_TRUE, UINT64_MAX);
- VERIFY_EXPR(res == VK_SUCCESS);
- }
-
- auto status = m_LogicalDevice->GetFenceStatus(val_fence.second);
- VERIFY(status == VK_SUCCESS, "All pending fences must now be complete!");
- m_FencePool.DisposeFence(std::move(val_fence.second));
- }
- m_PendingFences.clear();
+ // For some reason after idling the queue not all fences are signaled
+ m_pFence->Wait();
+ m_pFence->Reset(LastCompletedFenceValue);
}
Uint64 CommandQueueVkImpl::GetCompletedFenceValue()
{
std::lock_guard<std::mutex> Lock(m_QueueMutex);
+ return m_pFence->GetCompletedValue();
+}
- while (!m_PendingFences.empty())
- {
- auto &Value_Fence = m_PendingFences.front();
- auto status = m_LogicalDevice->GetFenceStatus(Value_Fence.second);
- if(status == VK_SUCCESS)
- {
- if (Value_Fence.first > m_LastCompletedFenceValue)
- m_LastCompletedFenceValue = Value_Fence.first;
- m_FencePool.DisposeFence(std::move(Value_Fence.second));
- m_PendingFences.pop_front();
- }
- else
- {
- break;
- }
- }
-
- return m_LastCompletedFenceValue;
+void CommandQueueVkImpl::SignalFence(VkFence vkFence)
+{
+ auto err = vkQueueSubmit(m_VkQueue, 0, nullptr, vkFence);
+ VERIFY(err == VK_SUCCESS, "Failed to submit command buffer to the command queue");
}
}
diff --git a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp
index febcc1d7..bb7acaf7 100644
--- a/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/DeviceContextVkImpl.cpp
@@ -811,11 +811,12 @@ namespace Diligent
// Submit command buffer even if there are no commands to release stale resources.
//if (SubmitInfo.commandBufferCount != 0 || SubmitInfo.waitSemaphoreCount !=0 || SubmitInfo.signalSemaphoreCount != 0)
- auto SubmittedFenceValue = pDeviceVkImpl->ExecuteCommandBuffer(SubmitInfo, this);
+ auto SubmittedFenceValue = pDeviceVkImpl->ExecuteCommandBuffer(SubmitInfo, this, &m_PendingFences);
m_WaitSemaphores.clear();
m_WaitDstStageMasks.clear();
m_SignalSemaphores.clear();
+ m_PendingFences.clear();
if (vkCmdBuff != VK_NULL_HANDLE)
{
@@ -1269,8 +1270,9 @@ namespace Diligent
SubmitInfo.commandBufferCount = 1;
SubmitInfo.pCommandBuffers = &vkCmdBuff;
auto pDeviceVkImpl = m_pDevice.RawPtr<RenderDeviceVkImpl>();
- auto SubmittedFenceValue = pDeviceVkImpl->ExecuteCommandBuffer(SubmitInfo, this);
-
+ VERIFY_EXPR(m_PendingFences.empty());
+ auto SubmittedFenceValue = pDeviceVkImpl->ExecuteCommandBuffer(SubmitInfo, this, nullptr);
+
auto pDeferredCtxVkImpl = pDeferredCtx.RawPtr<DeviceContextVkImpl>();
// It is OK to dispose command buffer from another thread. We are not going to
// record any commands and only need to add the buffer to the queue
@@ -1282,6 +1284,12 @@ namespace Diligent
m_ReleaseQueue.Purge(CompletedFenceValue);
}
+ void DeviceContextVkImpl::SignalFence(IFence* pFence, Uint64 Value)
+ {
+ VERIFY(!m_bIsDeferred, "Fence can only be signalled from immediate context");
+ m_PendingFences.emplace_back( std::make_pair(Value, pFence) );
+ };
+
void DeviceContextVkImpl::TransitionImageLayout(ITexture *pTexture, VkImageLayout NewLayout)
{
VERIFY_EXPR(pTexture != nullptr);
diff --git a/Graphics/GraphicsEngineVulkan/src/FenceVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/FenceVkImpl.cpp
index bde0fe89..bbd872fc 100644
--- a/Graphics/GraphicsEngineVulkan/src/FenceVkImpl.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/FenceVkImpl.cpp
@@ -25,30 +25,79 @@
#include "FenceVkImpl.h"
#include "EngineMemory.h"
+#include "RenderDeviceVkImpl.h"
namespace Diligent
{
FenceVkImpl :: FenceVkImpl(IReferenceCounters* pRefCounters,
- IRenderDevice* pDevice,
- const FenceDesc& Desc) :
- TFenceBase(pRefCounters, pDevice, Desc)
+ RenderDeviceVkImpl* pRendeDeviceVkImpl,
+ const FenceDesc& Desc,
+ bool IsDeviceInternal) :
+ TFenceBase(pRefCounters, pRendeDeviceVkImpl, Desc, IsDeviceInternal),
+ m_FencePool(pRendeDeviceVkImpl->GetLogicalDevice().GetSharedPtr())
{
}
FenceVkImpl :: ~FenceVkImpl()
{
+ while (!m_PendingFences.empty())
+ {
+ m_FencePool.DisposeFence(std::move(m_PendingFences.front().second));
+ m_PendingFences.pop_front();
+ }
}
Uint64 FenceVkImpl :: GetCompletedValue()
{
- UNSUPPORTED("Not yet implemented");
- return 0;
+ const auto& LogicalDevice = GetDevice<RenderDeviceVkImpl>()->GetLogicalDevice();
+ while (!m_PendingFences.empty())
+ {
+ auto& Value_Fence = m_PendingFences.front();
+ auto status = LogicalDevice.GetFenceStatus(Value_Fence.second);
+ if(status == VK_SUCCESS)
+ {
+ if (Value_Fence.first > m_LastCompletedFenceValue)
+ m_LastCompletedFenceValue = Value_Fence.first;
+ m_FencePool.DisposeFence(std::move(Value_Fence.second));
+ m_PendingFences.pop_front();
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ return m_LastCompletedFenceValue;
}
void FenceVkImpl :: Reset(Uint64 Value)
{
- UNSUPPORTED("Not yet implemented");
+ DEV_CHECK_ERR(Value >= m_LastCompletedFenceValue, "Resetting fence '", m_Desc.Name, "' to the value (", Value, ") that is smaller than the last completed value (", m_LastCompletedFenceValue, ")");
+ if (Value > m_LastCompletedFenceValue)
+ m_LastCompletedFenceValue = Value;
+}
+
+
+void FenceVkImpl :: Wait()
+{
+ const auto& LogicalDevice = GetDevice<RenderDeviceVkImpl>()->GetLogicalDevice();
+ for (auto& val_fence : m_PendingFences)
+ {
+ while (LogicalDevice.GetFenceStatus(val_fence.second) != VK_SUCCESS)
+ {
+ VkFence FenceToWait = val_fence.second;
+ auto res = vkWaitForFences(LogicalDevice.GetVkDevice(), 1, &FenceToWait, VK_TRUE, UINT64_MAX);
+ VERIFY_EXPR(res == VK_SUCCESS);
+ }
+
+ auto status = LogicalDevice.GetFenceStatus(val_fence.second);
+ VERIFY(status == VK_SUCCESS, "All pending fences must now be complete!");
+ if (val_fence.first > m_LastCompletedFenceValue)
+ m_LastCompletedFenceValue = val_fence.first;
+ m_FencePool.DisposeFence(std::move(val_fence.second));
+ }
+ m_PendingFences.clear();
}
}
diff --git a/Graphics/GraphicsEngineVulkan/src/RenderDeviceFactoryVk.cpp b/Graphics/GraphicsEngineVulkan/src/RenderDeviceFactoryVk.cpp
index 4508a9ce..08ddd8bf 100644
--- a/Graphics/GraphicsEngineVulkan/src/RenderDeviceFactoryVk.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/RenderDeviceFactoryVk.cpp
@@ -195,6 +195,14 @@ void EngineFactoryVkImpl::CreateDeviceAndContextsVk( const EngineVkAttribs& Crea
pCmdQueueVk = NEW_RC_OBJ(RawMemAllocator, "CommandQueueVk instance", CommandQueueVkImpl)(LogicalDevice, QueueInfo.queueFamilyIndex);
AttachToVulkanDevice(Instance, std::move(PhysicalDevice), LogicalDevice, pCmdQueueVk, CreationAttribs, ppDevice, ppContexts, NumDeferredContexts);
+
+ FenceDesc Desc;
+ Desc.Name = "Command queue fence";
+ // Render device owns command queue that in turn owns the fence, so it is an internal device object
+ bool IsDeviceInternal = true;
+ auto* pRenderDeviceVk = ValidatedCast<RenderDeviceVkImpl>(*ppDevice);
+ RefCntAutoPtr<FenceVkImpl> pFenceVk( NEW_RC_OBJ(RawMemAllocator, "FenceVkImpl instance", FenceVkImpl)(pRenderDeviceVk, Desc, IsDeviceInternal) );
+ pCmdQueueVk->SetFence(std::move(pFenceVk));
}
catch(std::runtime_error& )
{
diff --git a/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp b/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp
index 762acebd..6095b2e8 100644
--- a/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp
+++ b/Graphics/GraphicsEngineVulkan/src/RenderDeviceVkImpl.cpp
@@ -172,7 +172,7 @@ void RenderDeviceVkImpl::ExecuteAndDisposeTransientCmdBuff(VkCommandBuffer vkCmd
Uint64 SubmittedFenceValue = 0;
Uint64 SubmittedCmdBuffNumber = 0;
- SubmitCommandBuffer(SubmitInfo, SubmittedCmdBuffNumber, SubmittedFenceValue);
+ SubmitCommandBuffer(SubmitInfo, SubmittedCmdBuffNumber, SubmittedFenceValue, nullptr);
// We MUST NOT discard stale objects when executing transient command buffer,
@@ -204,8 +204,9 @@ void RenderDeviceVkImpl::ExecuteAndDisposeTransientCmdBuff(VkCommandBuffer vkCmd
}
void RenderDeviceVkImpl::SubmitCommandBuffer(const VkSubmitInfo& SubmitInfo,
- Uint64& SubmittedCmdBuffNumber, // Number of the submitted command buffer
- Uint64& SubmittedFenceValue // Fence value associated with the submitted command buffer
+ Uint64& SubmittedCmdBuffNumber, // Number of the submitted command buffer
+ Uint64& SubmittedFenceValue, // Fence value associated with the submitted command buffer
+ std::vector<std::pair<Uint64, RefCntAutoPtr<IFence> > >* pFences // List of fences to signal
)
{
std::lock_guard<std::mutex> LockGuard(m_CmdQueueMutex);
@@ -216,9 +217,19 @@ void RenderDeviceVkImpl::SubmitCommandBuffer(const VkSubmitInfo& SubmitInfo,
SubmittedFenceValue = std::max(SubmittedFenceValue, NextFenceValue);
SubmittedCmdBuffNumber = m_NextCmdBuffNumber;
Atomics::AtomicIncrement(m_NextCmdBuffNumber);
+ if (pFences != nullptr)
+ {
+ for (auto& val_fence : *pFences)
+ {
+ auto* pFenceVkImpl = val_fence.second.RawPtr<FenceVkImpl>();
+ auto vkFence = pFenceVkImpl->GetVkFence();
+ m_pCommandQueue->SignalFence(vkFence);
+ pFenceVkImpl->AddPendingFence(std::move(vkFence), val_fence.first);
+ }
+ }
}
-Uint64 RenderDeviceVkImpl::ExecuteCommandBuffer(const VkSubmitInfo& SubmitInfo, DeviceContextVkImpl* pImmediateCtx)
+Uint64 RenderDeviceVkImpl::ExecuteCommandBuffer(const VkSubmitInfo& SubmitInfo, DeviceContextVkImpl* pImmediateCtx, std::vector<std::pair<Uint64, RefCntAutoPtr<IFence> > >* pSignalFences)
{
// pImmediateCtx parameter is only used to make sure the command buffer is submitted from the immediate context
// Stale objects MUST only be discarded when submitting cmd list from the immediate context
@@ -226,7 +237,7 @@ Uint64 RenderDeviceVkImpl::ExecuteCommandBuffer(const VkSubmitInfo& SubmitInfo,
Uint64 SubmittedFenceValue = 0;
Uint64 SubmittedCmdBuffNumber = 0;
- SubmitCommandBuffer(SubmitInfo, SubmittedCmdBuffNumber, SubmittedFenceValue);
+ SubmitCommandBuffer(SubmitInfo, SubmittedCmdBuffNumber, SubmittedFenceValue, pSignalFences);
// The following basic requirement guarantees correctness of resource deallocation:
//
@@ -325,7 +336,7 @@ void RenderDeviceVkImpl::FinishFrame(bool ReleaseAllResources)
Uint64 SubmittedCmdBuffNumber = 0;
VkSubmitInfo DummySubmitInfo = {};
// Submit empty command buffer to set a fence on the GPU
- SubmitCommandBuffer(DummySubmitInfo, SubmittedCmdBuffNumber, SubmittedFenceValue);
+ SubmitCommandBuffer(DummySubmitInfo, SubmittedCmdBuffNumber, SubmittedFenceValue, nullptr);
// Discard all remaining objects. This is important to do if there were
// no command lists submitted during the frame. All stale resources will