Skip to content

Commit

Permalink
Merged pull request "Fixed swapchain sync with present": #15
Browse files Browse the repository at this point in the history
  • Loading branch information
apanteleev committed Feb 17, 2024
2 parents 7b21635 + 184f2ca commit 7946491
Showing 1 changed file with 46 additions and 41 deletions.
87 changes: 46 additions & 41 deletions src/app/vulkan/DeviceManager_VK.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,8 @@ class DeviceManager_VK : public DeviceManager
nvrhi::DeviceHandle m_ValidationLayer;

nvrhi::CommandListHandle m_BarrierCommandList;
vk::Semaphore m_PresentSemaphore;
std::vector<vk::Semaphore> m_PresentSemaphores;
uint32_t m_PresentSemaphoreIndex = 0;

std::queue<nvrhi::EventQueryHandle> m_FramesInFlight;
std::vector<nvrhi::EventQueryHandle> m_QueryPool;
Expand Down Expand Up @@ -1133,8 +1134,12 @@ bool DeviceManager_VK::CreateSwapChain()

m_BarrierCommandList = m_NvrhiDevice->createCommandList();

m_PresentSemaphore = m_VulkanDevice.createSemaphore(vk::SemaphoreCreateInfo());

m_PresentSemaphores.reserve(m_DeviceParams.maxFramesInFlight + 1);
for (uint32_t i = 0; i < m_DeviceParams.maxFramesInFlight + 1; ++i)
{
m_PresentSemaphores.push_back(m_VulkanDevice.createSemaphore(vk::SemaphoreCreateInfo()));
}

return true;
}
#undef CHECK
Expand All @@ -1143,10 +1148,13 @@ void DeviceManager_VK::DestroyDeviceAndSwapChain()
{
destroySwapChain();

if (m_PresentSemaphore)
for (auto& semaphore : m_PresentSemaphores)
{
m_VulkanDevice.destroySemaphore(m_PresentSemaphore);
m_PresentSemaphore = vk::Semaphore();
if (semaphore)
{
m_VulkanDevice.destroySemaphore(semaphore);
semaphore = vk::Semaphore();
}
}

m_BarrierCommandList = nullptr;
Expand Down Expand Up @@ -1182,75 +1190,72 @@ void DeviceManager_VK::DestroyDeviceAndSwapChain()

void DeviceManager_VK::BeginFrame()
{
const auto& semaphore = m_PresentSemaphores[m_PresentSemaphoreIndex];

const vk::Result res = m_VulkanDevice.acquireNextImageKHR(m_SwapChain,
std::numeric_limits<uint64_t>::max(), // timeout
m_PresentSemaphore,
semaphore,
vk::Fence(),
&m_SwapChainIndex);

assert(res == vk::Result::eSuccess);

m_NvrhiDevice->queueWaitForSemaphore(nvrhi::CommandQueue::Graphics, m_PresentSemaphore, 0);
m_NvrhiDevice->queueWaitForSemaphore(nvrhi::CommandQueue::Graphics, semaphore, 0);
}

void DeviceManager_VK::Present()
{
m_NvrhiDevice->queueSignalSemaphore(nvrhi::CommandQueue::Graphics, m_PresentSemaphore, 0);
const auto& semaphore = m_PresentSemaphores[m_PresentSemaphoreIndex];

m_NvrhiDevice->queueSignalSemaphore(nvrhi::CommandQueue::Graphics, semaphore, 0);

m_BarrierCommandList->open(); // umm...
m_BarrierCommandList->close();
m_NvrhiDevice->executeCommandList(m_BarrierCommandList);

vk::PresentInfoKHR info = vk::PresentInfoKHR()
.setWaitSemaphoreCount(1)
.setPWaitSemaphores(&m_PresentSemaphore)
.setPWaitSemaphores(&semaphore)
.setSwapchainCount(1)
.setPSwapchains(&m_SwapChain)
.setPImageIndices(&m_SwapChainIndex);

const vk::Result res = m_PresentQueue.presentKHR(&info);
assert(res == vk::Result::eSuccess || res == vk::Result::eErrorOutOfDateKHR);

if (m_DeviceParams.enableDebugRuntime)
m_PresentSemaphoreIndex = (m_PresentSemaphoreIndex + 1) % m_PresentSemaphores.size();

#ifndef _WIN32
if (m_DeviceParams.vsyncEnabled)
{
// according to vulkan-tutorial.com, "the validation layer implementation expects
// the application to explicitly synchronize with the GPU"
m_PresentQueue.waitIdle();
}
else
{
#ifndef _WIN32
if (m_DeviceParams.vsyncEnabled)
{
m_PresentQueue.waitIdle();
}
#endif

while (m_FramesInFlight.size() > m_DeviceParams.maxFramesInFlight)
{
auto query = m_FramesInFlight.front();
m_FramesInFlight.pop();

m_NvrhiDevice->waitEventQuery(query);
while (m_FramesInFlight.size() >= m_DeviceParams.maxFramesInFlight)
{
auto query = m_FramesInFlight.front();
m_FramesInFlight.pop();

m_QueryPool.push_back(query);
}
m_NvrhiDevice->waitEventQuery(query);

nvrhi::EventQueryHandle query;
if (!m_QueryPool.empty())
{
query = m_QueryPool.back();
m_QueryPool.pop_back();
}
else
{
query = m_NvrhiDevice->createEventQuery();
}
m_QueryPool.push_back(query);
}

m_NvrhiDevice->resetEventQuery(query);
m_NvrhiDevice->setEventQuery(query, nvrhi::CommandQueue::Graphics);
m_FramesInFlight.push(query);
nvrhi::EventQueryHandle query;
if (!m_QueryPool.empty())
{
query = m_QueryPool.back();
m_QueryPool.pop_back();
}
else
{
query = m_NvrhiDevice->createEventQuery();
}

m_NvrhiDevice->resetEventQuery(query);
m_NvrhiDevice->setEventQuery(query, nvrhi::CommandQueue::Graphics);
m_FramesInFlight.push(query);
}

DeviceManager *DeviceManager::CreateVK()
Expand Down

0 comments on commit 7946491

Please sign in to comment.