yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
f65d756bf
master
1// vk-device-queue.cpp 2#include "vk-device-queue.h" 3 4#include <assert.h> 5#include <stdio.h> 6#include <stdlib.h> 7 8namespace gfx 9{ 10using namespace Slang ; 11 12VulkanDeviceQueue ::~VulkanDeviceQueue () 13{ 14destroy (); 15} 16 17void VulkanDeviceQueue ::destroy () 18{ 19if (m_api ) 20 { 21for (int i = 0 ;i < int (EventType ::CountOf );++ i ) 22 { 23m_api -> vkDestroySemaphore (m_api -> m_device ,m_semaphores [i ],nullptr ); 24 } 25 26for (int i = 0 ;i < m_numCommandBuffers ;i ++ ) 27 { 28m_api 29-> vkFreeCommandBuffers (m_api -> m_device ,m_commandPools [i ],1 ,& m_commandBuffers [i ]); 30m_api -> vkDestroyFence (m_api -> m_device ,m_fences [i ].fence ,nullptr ); 31m_api -> vkDestroyCommandPool (m_api -> m_device ,m_commandPools [i ],nullptr ); 32 } 33m_api = nullptr ; 34 } 35} 36 37SlangResult VulkanDeviceQueue ::init (const VulkanApi & api ,VkQueue queue ,int queueIndex ) 38{ 39assert (m_api == nullptr ); 40 41for (int i = 0 ;i < int (EventType ::CountOf );++ i ) 42 { 43m_semaphores [i ]= VK_NULL_HANDLE ; 44m_currentSemaphores [i ]= VK_NULL_HANDLE ; 45 } 46 47m_numCommandBuffers = kMaxCommandBuffers ; 48m_queueIndex = queueIndex ; 49 50m_queue = queue ; 51 52for (int i = 0 ;i < m_numCommandBuffers ;i ++ ) 53 { 54VkCommandPoolCreateInfo poolCreateInfo = {}; 55poolCreateInfo .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO ; 56poolCreateInfo .flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT ; 57 58poolCreateInfo .queueFamilyIndex = queueIndex ; 59 60api .vkCreateCommandPool (api .m_device ,& poolCreateInfo ,nullptr ,& m_commandPools [i ]); 61 62VkCommandBufferAllocateInfo commandInfo = {}; 63commandInfo .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO ; 64commandInfo .commandPool = m_commandPools [i ]; 65commandInfo .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY ; 66commandInfo .commandBufferCount = 1 ; 67 68VkFenceCreateInfo fenceCreateInfo = {}; 69fenceCreateInfo .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO ; 70fenceCreateInfo .flags = 0 ;// VK_FENCE_CREATE_SIGNALED_BIT; 71Fence & fence = m_fences [i ]; 72 73api .vkAllocateCommandBuffers (api .m_device ,& commandInfo ,& m_commandBuffers [i ]); 74 75api .vkCreateFence (api .m_device ,& fenceCreateInfo ,nullptr ,& fence .fence ); 76fence .active = false; 77fence .value = 0 ; 78 } 79 80VkSemaphoreCreateInfo semaphoreCreateInfo = {}; 81semaphoreCreateInfo .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO ; 82 83for (int i = 0 ;i < int (EventType ::CountOf );++ i ) 84 { 85api .vkCreateSemaphore (api .m_device ,& semaphoreCreateInfo ,nullptr ,& m_semaphores [i ]); 86 } 87 88// Set the api - also marks that the queue appears to be valid 89m_api = & api ; 90 91// Second step of flush to prime command buffer 92flushStepB (); 93 94return SLANG_OK ; 95} 96 97void VulkanDeviceQueue ::flushStepA () 98{ 99m_api -> vkEndCommandBuffer (m_commandBuffer ); 100 101VkPipelineStageFlags stageFlags = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT ; 102 103VkSubmitInfo submitInfo = {}; 104submitInfo .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO ; 105 106// Wait semaphores 107if (isCurrent (EventType ::BeginFrame )) 108 { 109submitInfo .waitSemaphoreCount = 1 ; 110submitInfo .pWaitSemaphores = & m_currentSemaphores [int (EventType ::BeginFrame )]; 111 } 112 113submitInfo .pWaitDstStageMask = & stageFlags ; 114submitInfo .commandBufferCount = 1 ; 115submitInfo .pCommandBuffers = & m_commandBuffer ; 116 117// Signal semaphores 118if (isCurrent (EventType ::EndFrame )) 119 { 120submitInfo .signalSemaphoreCount = 1 ; 121submitInfo .pSignalSemaphores = & m_currentSemaphores [int (EventType ::EndFrame )]; 122 } 123 124Fence & fence = m_fences [m_commandBufferIndex ]; 125 126m_api -> vkQueueSubmit (m_queue ,1 ,& submitInfo ,fence .fence ); 127 128// mark signaled fence value 129fence .value = m_nextFenceValue ; 130fence .active = true; 131 132// increment fence value 133m_nextFenceValue ++ ; 134 135// No longer waiting on this semaphore 136makeCompleted (EventType ::BeginFrame ); 137makeCompleted (EventType ::EndFrame ); 138} 139 140void VulkanDeviceQueue ::_updateFenceAtIndex (int fenceIndex ,bool blocking ) 141{ 142Fence & fence = m_fences [fenceIndex ]; 143 144if (fence .active ) 145 { 146uint64_t timeout = blocking ? ~uint64_t (0 ) :0 ; 147 148if (VK_SUCCESS == 149m_api -> vkWaitForFences (m_api -> m_device ,1 ,& fence .fence ,VK_TRUE ,timeout )) 150 { 151m_api -> vkResetFences (m_api -> m_device ,1 ,& fence .fence ); 152 153fence .active = false; 154 155if (fence .value > m_lastFenceCompleted ) 156 { 157m_lastFenceCompleted = fence .value ; 158 } 159 } 160 } 161} 162 163void VulkanDeviceQueue ::flushStepB () 164{ 165m_commandBufferIndex = (m_commandBufferIndex + 1 ) %m_numCommandBuffers ; 166m_commandBuffer = m_commandBuffers [m_commandBufferIndex ]; 167m_commandPool = m_commandPools [m_commandBufferIndex ]; 168 169// non-blocking update of fence values 170for (int i = 0 ;i < m_numCommandBuffers ;++ i ) 171 { 172_updateFenceAtIndex (i , false); 173 } 174 175// blocking update of fence values 176_updateFenceAtIndex (m_commandBufferIndex , true); 177 178m_api -> vkResetCommandPool (m_api -> m_device ,m_commandPool ,0 ); 179 180VkCommandBufferBeginInfo beginInfo = {}; 181beginInfo .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO ; 182beginInfo .flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT ; 183 184m_api -> vkBeginCommandBuffer (m_commandBuffer ,& beginInfo ); 185} 186 187void VulkanDeviceQueue ::flush () 188{ 189flushStepA (); 190flushStepB (); 191} 192 193void VulkanDeviceQueue ::flushAndWait () 194{ 195flush (); 196waitForIdle (); 197} 198 199VkSemaphore VulkanDeviceQueue ::getSemaphore (EventType eventType ) 200{ 201return m_semaphores [int (eventType )]; 202} 203 204VkSemaphore VulkanDeviceQueue ::makeCurrent (EventType eventType ) 205{ 206assert (!isCurrent (eventType )); 207VkSemaphore semaphore = m_semaphores [int (eventType )]; 208m_currentSemaphores [int (eventType )]= semaphore ; 209return semaphore ; 210} 211 212void VulkanDeviceQueue ::makeCompleted (EventType eventType ) 213{ 214m_currentSemaphores [int (eventType )]= VK_NULL_HANDLE ; 215} 216 217}// namespace gfx