| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158 |
- //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
- //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
- #include "BsVulkanQueue.h"
- #include "BsVulkanCommandBuffer.h"
- #include "BsVulkanSwapChain.h"
- namespace bs
- {
- VulkanQueue::VulkanQueue(VulkanDevice& device, VkQueue queue, GpuQueueType type, UINT32 index)
- :mDevice(device), mQueue(queue), mType(type), mIndex(index), mLastCommandBuffer(nullptr), mNextSubmitIdx(1)
- {
- for (UINT32 i = 0; i < BS_MAX_UNIQUE_QUEUES; i++)
- mSubmitDstWaitMask[i] = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
- }
- bool VulkanQueue::isExecuting() const
- {
- if (mLastCommandBuffer == nullptr)
- return false;
- return mLastCommandBuffer->isSubmitted();
- }
- void VulkanQueue::submit(VulkanCmdBuffer* cmdBuffer, VulkanSemaphore** waitSemaphores, UINT32 semaphoresCount)
- {
- VkCommandBuffer vkCmdBuffer = cmdBuffer->getHandle();
- VulkanSemaphore* semaphore = cmdBuffer->allocateSemaphore();
- VkSemaphore vkSemaphore = semaphore->getHandle();
- VkSubmitInfo submitInfo;
- submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
- submitInfo.pNext = nullptr;
- submitInfo.commandBufferCount = 1;
- submitInfo.pCommandBuffers = &vkCmdBuffer;
- submitInfo.signalSemaphoreCount = 1;
- submitInfo.pSignalSemaphores = &vkSemaphore;
- submitInfo.waitSemaphoreCount = semaphoresCount;
- if (semaphoresCount > 0)
- {
- for (UINT32 i = 0; i < semaphoresCount; i++)
- mSemaphoresTemp[i] = waitSemaphores[i]->getHandle();
- submitInfo.pWaitSemaphores = mSemaphoresTemp;
- submitInfo.pWaitDstStageMask = mSubmitDstWaitMask;
- }
- else
- {
- submitInfo.pWaitSemaphores = nullptr;
- submitInfo.pWaitDstStageMask = nullptr;
- }
- VkResult result = vkQueueSubmit(mQueue, 1, &submitInfo, cmdBuffer->getFence());
- assert(result == VK_SUCCESS);
- cmdBuffer->setIsSubmitted();
- mLastCommandBuffer = cmdBuffer;
- for (UINT32 i = 0; i < semaphoresCount; i++)
- {
- waitSemaphores[i]->notifyBound();
- waitSemaphores[i]->notifyUsed(0, 0, VulkanUseFlag::Read | VulkanUseFlag::Write);
- mActiveSemaphores.push(waitSemaphores[i]);
- }
- mActiveBuffers.push_back(SubmitInfo(cmdBuffer, mNextSubmitIdx++, semaphoresCount));
- }
- void VulkanQueue::present(VulkanSwapChain* swapChain, VulkanSemaphore** waitSemaphores, UINT32 semaphoresCount)
- {
- UINT32 backBufferIdx = swapChain->prepareForPresent();
- VkSwapchainKHR vkSwapChain = swapChain->getHandle();
- VkPresentInfoKHR presentInfo;
- presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
- presentInfo.pNext = nullptr;
- presentInfo.swapchainCount = 1;
- presentInfo.pSwapchains = &vkSwapChain;
- presentInfo.pImageIndices = &backBufferIdx;
- presentInfo.pResults = nullptr;
- // Wait before presenting, if required
- if (semaphoresCount > 0)
- {
- for (UINT32 i = 0; i < semaphoresCount; i++)
- mSemaphoresTemp[i] = waitSemaphores[i]->getHandle();
- presentInfo.pWaitSemaphores = mSemaphoresTemp;
- presentInfo.waitSemaphoreCount = semaphoresCount;
- }
- else
- {
- presentInfo.pWaitSemaphores = nullptr;
- presentInfo.waitSemaphoreCount = 0;
- }
- VkResult result = vkQueuePresentKHR(mQueue, &presentInfo);
- assert(result == VK_SUCCESS || result == VK_SUBOPTIMAL_KHR);
- for (UINT32 i = 0; i < semaphoresCount; i++)
- {
- waitSemaphores[i]->notifyBound();
- waitSemaphores[i]->notifyUsed(0, 0, VulkanUseFlag::Read | VulkanUseFlag::Write);
- mActiveSemaphores.push(waitSemaphores[i]);
- }
- mActiveBuffers.push_back(SubmitInfo(nullptr, mNextSubmitIdx++, semaphoresCount));
- }
- void VulkanQueue::waitIdle() const
- {
- VkResult result = vkQueueWaitIdle(mQueue);
- assert(result == VK_SUCCESS);
- }
- void VulkanQueue::refreshStates()
- {
- UINT32 lastFinishedSubmission = 0;
- auto iter = mActiveBuffers.begin();
- while (iter != mActiveBuffers.end())
- {
- VulkanCmdBuffer* cmdBuffer = iter->cmdBuffer;
- if (cmdBuffer == nullptr)
- {
- ++iter;
- continue;
- }
- cmdBuffer->refreshFenceStatus();
- if (cmdBuffer->isSubmitted())
- break; // No chance of any later CBs of being done either
-
- lastFinishedSubmission = iter->submitIdx;
- ++iter;
- }
- iter = mActiveBuffers.begin();
- while (iter != mActiveBuffers.end())
- {
- if (iter->submitIdx > lastFinishedSubmission)
- break;
- for (UINT32 i = 0; i < iter->numSemaphores; i++)
- {
- VulkanSemaphore* semaphore = mActiveSemaphores.front();
- mActiveSemaphores.pop();
- semaphore->notifyDone(0, VulkanUseFlag::Read | VulkanUseFlag::Write);
- }
- iter = mActiveBuffers.erase(iter);
- }
- }
- }
|