diff --git a/computecullandlod/computecullandlod.cpp b/computecullandlod/computecullandlod.cpp index eba0348e..9bd42744 100644 --- a/computecullandlod/computecullandlod.cpp +++ b/computecullandlod/computecullandlod.cpp @@ -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 stageFlags = { + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, + VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, + }; + std::vector waitSemaphores = { + semaphores.presentComplete, // Wait for presentation to finished + compute.semaphore // Wait for compute to finish + }; + + submitInfo.pWaitSemaphores = waitSemaphores.data(); + submitInfo.waitSemaphoreCount = static_cast(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));