yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
f65d756bf
master
1// vk-command-queue.cpp 2#include "vk-command-queue.h" 3 4#include "vk-command-buffer.h" 5#include "vk-fence.h" 6#include "vk-transient-heap.h" 7 8namespace gfx 9{ 10 11using namespace Slang ; 12 13namespace vk 14{ 15 16ICommandQueue * CommandQueueImpl ::getInterface (const Guid & guid ) 17{ 18if (guid == GfxGUID ::IID_ISlangUnknown || guid == GfxGUID ::IID_ICommandQueue ) 19return static_cast < ICommandQueue *> (this ); 20return nullptr ; 21} 22 23CommandQueueImpl ::~CommandQueueImpl () 24{ 25m_renderer -> m_api .vkQueueWaitIdle (m_queue ); 26 27m_renderer -> m_queueAllocCount -- ; 28m_renderer -> m_api .vkDestroySemaphore (m_renderer -> m_api .m_device ,m_semaphore ,nullptr ); 29} 30 31void CommandQueueImpl ::init (DeviceImpl * renderer ,VkQueue queue ,uint32_t queueFamilyIndex ) 32{ 33m_renderer = renderer ; 34m_queue = queue ; 35m_queueFamilyIndex = queueFamilyIndex ; 36VkSemaphoreCreateInfo semaphoreCreateInfo = {}; 37semaphoreCreateInfo .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO ; 38semaphoreCreateInfo .flags = 0 ; 39m_renderer -> m_api 40 .vkCreateSemaphore (m_renderer -> m_api .m_device ,& semaphoreCreateInfo ,nullptr ,& m_semaphore ); 41} 42 43void CommandQueueImpl ::waitOnHost () 44{ 45auto & vkAPI = m_renderer -> m_api ; 46vkAPI .vkQueueWaitIdle (m_queue ); 47} 48 49Result CommandQueueImpl ::getNativeHandle (InteropHandle * outHandle ) 50{ 51outHandle -> api = InteropHandleAPI ::D3D12 ; 52outHandle -> handleValue = (uint64_t )m_queue ; 53return SLANG_OK ; 54} 55 56const CommandQueueImpl ::Desc & CommandQueueImpl ::getDesc () 57{ 58return m_desc ; 59} 60 61Result CommandQueueImpl ::waitForFenceValuesOnDevice ( 62GfxCount fenceCount , 63IFence ** fences , 64uint64_t * waitValues ) 65{ 66for (GfxIndex i = 0 ;i < fenceCount ;++ i ) 67 { 68FenceWaitInfo waitInfo ; 69waitInfo .fence = static_cast < FenceImpl *> (fences [i ]); 70waitInfo .waitValue = waitValues [i ]; 71m_pendingWaitFences .add (waitInfo ); 72 } 73return SLANG_OK ; 74} 75 76void CommandQueueImpl ::queueSubmitImpl ( 77uint32_t count , 78ICommandBuffer * const * commandBuffers , 79IFence * fence , 80uint64_t valueToSignal ) 81{ 82auto & vkAPI = m_renderer -> m_api ; 83m_submitCommandBuffers .clear (); 84for (uint32_t i = 0 ;i < count ;i ++ ) 85 { 86auto cmdBufImpl = static_cast < CommandBufferImpl *> (commandBuffers [i ]); 87if (!cmdBufImpl -> m_isPreCommandBufferEmpty ) 88m_submitCommandBuffers .add (cmdBufImpl -> m_preCommandBuffer ); 89auto vkCmdBuf = cmdBufImpl -> m_commandBuffer ; 90m_submitCommandBuffers .add (vkCmdBuf ); 91 } 92Array < VkSemaphore ,2 > signalSemaphores ; 93Array < uint64_t ,2 > signalValues ; 94signalSemaphores .add (m_semaphore ); 95signalValues .add (0 ); 96 97VkSubmitInfo submitInfo = {}; 98submitInfo .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO ; 99VkPipelineStageFlags stageFlag []= { 100VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT , 101VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT }; 102submitInfo .pWaitDstStageMask = stageFlag ; 103submitInfo .commandBufferCount = (uint32_t )m_submitCommandBuffers .getCount (); 104submitInfo .pCommandBuffers = m_submitCommandBuffers .getBuffer (); 105Array < VkSemaphore ,3 > waitSemaphores ; 106Array < uint64_t ,3 > waitValues ; 107for (auto s :m_pendingWaitSemaphores ) 108 { 109if (s != VK_NULL_HANDLE ) 110 { 111waitSemaphores .add (s ); 112waitValues .add (0 ); 113 } 114 } 115for (auto & fenceWait :m_pendingWaitFences ) 116 { 117waitSemaphores .add (fenceWait .fence -> m_semaphore ); 118waitValues .add (fenceWait .waitValue ); 119 } 120m_pendingWaitFences .clear (); 121VkTimelineSemaphoreSubmitInfo timelineSubmitInfo = { 122VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO }; 123if (fence ) 124 { 125auto fenceImpl = static_cast < FenceImpl *> (fence ); 126signalSemaphores .add (fenceImpl -> m_semaphore ); 127signalValues .add (valueToSignal ); 128submitInfo .pNext = & timelineSubmitInfo ; 129timelineSubmitInfo .signalSemaphoreValueCount = (uint32_t )signalValues .getCount (); 130timelineSubmitInfo .pSignalSemaphoreValues = signalValues .getBuffer (); 131timelineSubmitInfo .waitSemaphoreValueCount = (uint32_t )waitValues .getCount (); 132timelineSubmitInfo .pWaitSemaphoreValues = waitValues .getBuffer (); 133 } 134submitInfo .waitSemaphoreCount = (uint32_t )waitSemaphores .getCount (); 135if (submitInfo .waitSemaphoreCount ) 136 { 137submitInfo .pWaitSemaphores = waitSemaphores .getBuffer (); 138 } 139submitInfo .signalSemaphoreCount = (uint32_t )signalSemaphores .getCount (); 140submitInfo .pSignalSemaphores = signalSemaphores .getBuffer (); 141 142VkFence vkFence = VK_NULL_HANDLE ; 143if (count ) 144 { 145auto commandBufferImpl = static_cast < CommandBufferImpl *> (commandBuffers [0 ]); 146vkFence = commandBufferImpl -> m_transientHeap -> getCurrentFence (); 147vkAPI .vkResetFences (vkAPI .m_device ,1 ,& vkFence ); 148commandBufferImpl -> m_transientHeap -> advanceFence (); 149 } 150vkAPI .vkQueueSubmit (m_queue ,1 ,& submitInfo ,vkFence ); 151m_pendingWaitSemaphores [0 ]= m_semaphore ; 152m_pendingWaitSemaphores [1 ]= VK_NULL_HANDLE ; 153} 154 155void CommandQueueImpl ::executeCommandBuffers ( 156GfxCount count , 157ICommandBuffer * const * commandBuffers , 158IFence * fence , 159uint64_t valueToSignal ) 160{ 161if (count == 0 && fence == nullptr ) 162return ; 163queueSubmitImpl (count ,commandBuffers ,fence ,valueToSignal ); 164} 165 166}// namespace vk 167}// namespace gfx