From dae58772e2d89760a009ffb80cbbec04d214a29b Mon Sep 17 00:00:00 2001 From: InkSoul Date: Sun, 10 Mar 2024 16:21:28 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90=E5=B8=A7=E5=90=8C=E6=AD=A5?= =?UTF-8?q?=E5=92=8C=E7=BB=98=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- VulkanTutorial.cpp | 80 ++++++++++++++++++++++++++++++++++++++++++++++ VulkanTutorial.h | 6 ++++ 2 files changed, 86 insertions(+) diff --git a/VulkanTutorial.cpp b/VulkanTutorial.cpp index 3154aff..d0fd263 100644 --- a/VulkanTutorial.cpp +++ b/VulkanTutorial.cpp @@ -121,6 +121,8 @@ void HelloTriangleApplication::initVulkan() { createCommandBuffer(); + createSyncObjects(); + } @@ -133,6 +135,8 @@ void HelloTriangleApplication::mainLoop(GLFWwindow* window){ drawFrame(); } + vkDeviceWaitIdle(device); + } @@ -141,6 +145,10 @@ void HelloTriangleApplication::cleanup(GLFWwindow* window) { std::cout << "\nstart to destroy resource\n" << std::endl; + vkDestroySemaphore(device, imageAvailableSemaphore, nullptr); + vkDestroySemaphore(device, renderFinishedSemaphore, nullptr); + vkDestroyFence(device, inFlightFence, nullptr); + vkDestroyCommandPool(device, commandPool, nullptr); for (auto framebuffer : swapChainFramebuffers) @@ -729,6 +737,67 @@ void HelloTriangleApplication::recordCommandBuffer(VkCommandBuffer commandBuffer void HelloTriangleApplication::drawFrame() { + //等待所有fence收到信号后返回,uint64_max禁用超时 + vkWaitForFences(device, 1, &inFlightFence, VK_TRUE, UINT64_MAX); + + vkResetFences(device, 1, &inFlightFence); + + uint32_t imageIndex; + vkAcquireNextImageKHR(device, swapChain, UINT64_MAX, imageAvailableSemaphore, VK_NULL_HANDLE, &imageIndex); + + vkResetCommandBuffer(commandBuffer, 0); + recordCommandBuffer(commandBuffer, imageIndex); + + VkSubmitInfo submitInfo{}; + submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; + + VkSemaphore waitSemaphores[] = { imageAvailableSemaphore }; + VkPipelineStageFlags waitStages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT }; + submitInfo.waitSemaphoreCount = 1; + submitInfo.pWaitSemaphores = waitSemaphores; + submitInfo.pWaitDstStageMask = waitStages; + submitInfo.commandBufferCount = 1; + submitInfo.pCommandBuffers = &commandBuffer; + + VkSemaphore signalSemaphores[] = { renderFinishedSemaphore }; + submitInfo.signalSemaphoreCount = 1; + submitInfo.pSignalSemaphores = signalSemaphores; + + if (vkQueueSubmit(graphicQueue,1,&submitInfo,inFlightFence) != VK_SUCCESS) + { + throw std::runtime_error("failed to submit draw command buffer in drawFrame"); + } + + VkPresentInfoKHR presentInfo{}; + presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; + + presentInfo.waitSemaphoreCount = 1; + presentInfo.pWaitSemaphores = signalSemaphores; + + VkSwapchainKHR swapChains[] = { swapChain }; + presentInfo.swapchainCount = 1; + presentInfo.pSwapchains = swapChains; + presentInfo.pImageIndices = &imageIndex; + presentInfo.pResults = nullptr; + vkQueuePresentKHR(presentQueue, &presentInfo); + +} + +void HelloTriangleApplication::createSyncObjects() +{ + VkSemaphoreCreateInfo semaphoreInfo{}; + semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; + + VkFenceCreateInfo fenceInfo{}; + fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; + fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;//防止vkWaitForFences在第一帧无限期阻塞 + + if (vkCreateSemaphore(device,&semaphoreInfo,nullptr,&imageAvailableSemaphore) != VK_SUCCESS || + vkCreateSemaphore(device, &semaphoreInfo, nullptr, &renderFinishedSemaphore) != VK_SUCCESS || + vkCreateFence(device,&fenceInfo,nullptr,&inFlightFence) != VK_SUCCESS) + { + throw std::runtime_error("failed to create semaphores in creatSyncObjects"); + } } @@ -757,6 +826,14 @@ void HelloTriangleApplication::createRenderPass() subpass.colorAttachmentCount = 1; subpass.pColorAttachments = &colorAttachmentRef; + VkSubpassDependency dependency{}; + dependency.srcSubpass = VK_SUBPASS_EXTERNAL; + dependency.dstSubpass = 0; + dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + dependency.srcAccessMask = 0; + dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + VkRenderPassCreateInfo renderPassInfo{}; renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO; renderPassInfo.attachmentCount = 1; @@ -764,6 +841,9 @@ void HelloTriangleApplication::createRenderPass() renderPassInfo.subpassCount = 1; renderPassInfo.pSubpasses = &subpass; + renderPassInfo.dependencyCount = 1; + renderPassInfo.pDependencies = &dependency; + if (vkCreateRenderPass(device,&renderPassInfo,nullptr,&renderPass) != VK_SUCCESS) { throw std::runtime_error("failed to create render pass in createRenderPass"); diff --git a/VulkanTutorial.h b/VulkanTutorial.h index 3702013..90982e3 100644 --- a/VulkanTutorial.h +++ b/VulkanTutorial.h @@ -68,6 +68,10 @@ private: VkPipeline graphicsPipeline; + VkSemaphore imageAvailableSemaphore; + VkSemaphore renderFinishedSemaphore; + VkFence inFlightFence; + struct QueueFamilyIndices { std::optional graphicsFamily; @@ -153,6 +157,8 @@ private: void drawFrame(); + void createSyncObjects(); + }; HelloTriangleApplication::HelloTriangleApplication()