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)
|
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
|
VkCommandBuffer commandBuffer; // Command buffer storing the dispatch commands and barriers
|
||||||
VkFence fence; // Synchronization fence to avoid rewriting compute CB if still in use
|
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
|
VkDescriptorSetLayout descriptorSetLayout; // Compute shader binding layout
|
||||||
VkDescriptorSet descriptorSet; // Compute shader bindings
|
VkDescriptorSet descriptorSet; // Compute shader bindings
|
||||||
VkPipelineLayout pipelineLayout; // Layout of the compute pipeline
|
VkPipelineLayout pipelineLayout; // Layout of the compute pipeline
|
||||||
|
|
@ -751,6 +752,9 @@ public:
|
||||||
VkFenceCreateInfo fenceCreateInfo = vkTools::initializers::fenceCreateInfo(VK_FENCE_CREATE_SIGNALED_BIT);
|
VkFenceCreateInfo fenceCreateInfo = vkTools::initializers::fenceCreateInfo(VK_FENCE_CREATE_SIGNALED_BIT);
|
||||||
VK_CHECK_RESULT(vkCreateFence(device, &fenceCreateInfo, nullptr, &compute.fence));
|
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
|
// Build a single command buffer containing the compute dispatch commands
|
||||||
buildComputeCommandBuffer();
|
buildComputeCommandBuffer();
|
||||||
}
|
}
|
||||||
|
|
@ -776,24 +780,43 @@ public:
|
||||||
{
|
{
|
||||||
VulkanExampleBase::prepareFrame();
|
VulkanExampleBase::prepareFrame();
|
||||||
|
|
||||||
// Command buffer to be sumitted to the queue
|
// Submit compute shader for frustum culling
|
||||||
submitInfo.commandBufferCount = 1;
|
|
||||||
submitInfo.pCommandBuffers = &drawCmdBuffers[currentBuffer];
|
|
||||||
|
|
||||||
// Submit to queue
|
// Wait for fence to ensure that compute buffer writes have finished
|
||||||
VK_CHECK_RESULT(vkQueueSubmit(queue, 1, &submitInfo, VK_NULL_HANDLE));
|
|
||||||
|
|
||||||
VulkanExampleBase::submitFrame();
|
|
||||||
|
|
||||||
// Submit compute commands
|
|
||||||
vkWaitForFences(device, 1, &compute.fence, VK_TRUE, UINT64_MAX);
|
vkWaitForFences(device, 1, &compute.fence, VK_TRUE, UINT64_MAX);
|
||||||
vkResetFences(device, 1, &compute.fence);
|
vkResetFences(device, 1, &compute.fence);
|
||||||
|
|
||||||
VkSubmitInfo computeSubmitInfo = vkTools::initializers::submitInfo();
|
VkSubmitInfo computeSubmitInfo = vkTools::initializers::submitInfo();
|
||||||
computeSubmitInfo.commandBufferCount = 1;
|
computeSubmitInfo.commandBufferCount = 1;
|
||||||
computeSubmitInfo.pCommandBuffers = &compute.commandBuffer;
|
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
|
// Get draw count from compute
|
||||||
memcpy(&indirectStats, indirectDrawCountBuffer.mapped, sizeof(indirectStats));
|
memcpy(&indirectStats, indirectDrawCountBuffer.mapped, sizeof(indirectStats));
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue