Use additional semaphore to synchronize compute and graphics (Refs #257)
This commit is contained in:
parent
a376f2d695
commit
f5d774d5cf
1 changed files with 33 additions and 10 deletions
|
|
@ -108,6 +108,7 @@ public:
|
|||
VkCommandPool commandPool; // Use a separate command pool (queue family may differ from the one used for graphics)
|
||||
VkCommandBuffer commandBuffer; // Command buffer storing the dispatch commands and barriers
|
||||
VkFence fence; // Synchronization fence to avoid rewriting compute CB if still in use
|
||||
VkSemaphore semaphore; // Used as a wait semaphore for graphics submission
|
||||
VkDescriptorSetLayout descriptorSetLayout; // Compute shader binding layout
|
||||
VkDescriptorSet descriptorSet; // Compute shader bindings
|
||||
VkPipelineLayout pipelineLayout; // Layout of the compute pipeline
|
||||
|
|
@ -751,6 +752,9 @@ public:
|
|||
VkFenceCreateInfo fenceCreateInfo = vkTools::initializers::fenceCreateInfo(VK_FENCE_CREATE_SIGNALED_BIT);
|
||||
VK_CHECK_RESULT(vkCreateFence(device, &fenceCreateInfo, nullptr, &compute.fence));
|
||||
|
||||
VkSemaphoreCreateInfo semaphoreCreateInfo = vkTools::initializers::semaphoreCreateInfo();
|
||||
VK_CHECK_RESULT(vkCreateSemaphore(device, &semaphoreCreateInfo, nullptr, &compute.semaphore));
|
||||
|
||||
// Build a single command buffer containing the compute dispatch commands
|
||||
buildComputeCommandBuffer();
|
||||
}
|
||||
|
|
@ -776,24 +780,43 @@ public:
|
|||
{
|
||||
VulkanExampleBase::prepareFrame();
|
||||
|
||||
// Command buffer to be sumitted to the queue
|
||||
submitInfo.commandBufferCount = 1;
|
||||
submitInfo.pCommandBuffers = &drawCmdBuffers[currentBuffer];
|
||||
// Submit compute shader for frustum culling
|
||||
|
||||
// Submit to queue
|
||||
VK_CHECK_RESULT(vkQueueSubmit(queue, 1, &submitInfo, VK_NULL_HANDLE));
|
||||
|
||||
VulkanExampleBase::submitFrame();
|
||||
|
||||
// Submit compute commands
|
||||
// Wait for fence to ensure that compute buffer writes have finished
|
||||
vkWaitForFences(device, 1, &compute.fence, VK_TRUE, UINT64_MAX);
|
||||
vkResetFences(device, 1, &compute.fence);
|
||||
|
||||
VkSubmitInfo computeSubmitInfo = vkTools::initializers::submitInfo();
|
||||
computeSubmitInfo.commandBufferCount = 1;
|
||||
computeSubmitInfo.pCommandBuffers = &compute.commandBuffer;
|
||||
computeSubmitInfo.signalSemaphoreCount = 1;
|
||||
computeSubmitInfo.pSignalSemaphores = &compute.semaphore;
|
||||
|
||||
VK_CHECK_RESULT(vkQueueSubmit(compute.queue, 1, &computeSubmitInfo, compute.fence));
|
||||
VK_CHECK_RESULT(vkQueueSubmit(compute.queue, 1, &computeSubmitInfo, VK_NULL_HANDLE));
|
||||
|
||||
// Submit graphics command buffer
|
||||
|
||||
submitInfo.commandBufferCount = 1;
|
||||
submitInfo.pCommandBuffers = &drawCmdBuffers[currentBuffer];
|
||||
|
||||
// Wait on present and compute semaphores
|
||||
std::vector<VkPipelineStageFlags> stageFlags = {
|
||||
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
|
||||
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
||||
};
|
||||
std::vector<VkSemaphore> waitSemaphores = {
|
||||
semaphores.presentComplete, // Wait for presentation to finished
|
||||
compute.semaphore // Wait for compute to finish
|
||||
};
|
||||
|
||||
submitInfo.pWaitSemaphores = waitSemaphores.data();
|
||||
submitInfo.waitSemaphoreCount = static_cast<uint32_t>(waitSemaphores.size());
|
||||
submitInfo.pWaitDstStageMask = stageFlags.data();
|
||||
|
||||
// Submit to queue
|
||||
VK_CHECK_RESULT(vkQueueSubmit(queue, 1, &submitInfo, compute.fence));
|
||||
|
||||
VulkanExampleBase::submitFrame();
|
||||
|
||||
// Get draw count from compute
|
||||
memcpy(&indirectStats, indirectDrawCountBuffer.mapped, sizeof(indirectStats));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue