From a4cc0e029d2a5a22fb69e3248db7794f6dcacff7 Mon Sep 17 00:00:00 2001 From: Alexander Gauggel <agauggel@uni-koblenz.de> Date: Sun, 16 May 2021 19:20:47 +0200 Subject: [PATCH] [#18]Add swapchain present --- config/Sources.cmake | 3 +++ include/vkcv/Core.hpp | 1 + include/vkcv/SwapChain.hpp | 9 +++++++- include/vkcv/SyncResources.hpp | 1 + src/vkcv/Core.cpp | 35 ++++++++++++++++++++++++++--- src/vkcv/ImageLayoutTransitions.cpp | 24 ++++++++++++++++++++ src/vkcv/ImageLayoutTransitions.hpp | 7 ++++++ src/vkcv/Queues.cpp | 1 - src/vkcv/SwapChain.cpp | 9 +++++--- src/vkcv/SyncResources.cpp | 2 ++ 10 files changed, 84 insertions(+), 8 deletions(-) create mode 100644 src/vkcv/ImageLayoutTransitions.cpp create mode 100644 src/vkcv/ImageLayoutTransitions.hpp diff --git a/config/Sources.cmake b/config/Sources.cmake index 784562de..ee7da418 100644 --- a/config/Sources.cmake +++ b/config/Sources.cmake @@ -42,4 +42,7 @@ set(vkcv_sources ${vkcv_source}/vkcv/Surface.hpp ${vkcv_source}/vkcv/Surface.cpp + + ${vkcv_source}/vkcv/ImageLayoutTransitions.hpp + ${vkcv_source}/vkcv/ImageLayoutTransitions.cpp ) diff --git a/include/vkcv/Core.hpp b/include/vkcv/Core.hpp index addce8e5..60514181 100644 --- a/include/vkcv/Core.hpp +++ b/include/vkcv/Core.hpp @@ -51,6 +51,7 @@ namespace vkcv CommandResources m_CommandResources; SyncResources m_SyncResources; VulkanQueues m_Queues; + uint32_t m_FrameIndex; public: /** * Destructor of #Core destroys the Vulkan objects contained in the core's context. diff --git a/include/vkcv/SwapChain.hpp b/include/vkcv/SwapChain.hpp index 91d2ccbb..d5d985ec 100644 --- a/include/vkcv/SwapChain.hpp +++ b/include/vkcv/SwapChain.hpp @@ -12,6 +12,8 @@ namespace vkcv { vk::SwapchainKHR m_swapchain; vk::SurfaceFormatKHR m_format; + uint32_t m_ImageCount; + /** * Constructor of a SwapChain object * glfw is not initialized in this class because ist must be sure that there exists a context first @@ -20,7 +22,7 @@ namespace vkcv { * @param swapchain to show images in the window * @param format */ - SwapChain(vk::SurfaceKHR surface, vk::SwapchainKHR swapchain, vk::SurfaceFormatKHR format); + SwapChain(vk::SurfaceKHR surface, vk::SwapchainKHR swapchain, vk::SurfaceFormatKHR format, uint32_t imageCount); public: SwapChain(const SwapChain &other) = default; @@ -58,6 +60,11 @@ namespace vkcv { * Destructor of SwapChain */ virtual ~SwapChain(); + + /** + * @return number of images in swapchain + */ + uint32_t getImageCount(); }; } diff --git a/include/vkcv/SyncResources.hpp b/include/vkcv/SyncResources.hpp index 35e8c774..44565947 100644 --- a/include/vkcv/SyncResources.hpp +++ b/include/vkcv/SyncResources.hpp @@ -4,6 +4,7 @@ namespace vkcv { struct SyncResources { vk::Semaphore renderFinished; + vk::Fence swapchainImageAcquired; vk::Fence presentFinished; }; diff --git a/src/vkcv/Core.cpp b/src/vkcv/Core.cpp index da17d6ec..7321f780 100644 --- a/src/vkcv/Core.cpp +++ b/src/vkcv/Core.cpp @@ -8,6 +8,7 @@ #include "PassManager.hpp" #include "PipelineManager.hpp" #include "Surface.hpp" +#include "ImageLayoutTransitions.hpp" namespace vkcv { @@ -278,10 +279,12 @@ namespace vkcv m_PipelineManager{std::make_unique<PipelineManager>(m_Context.m_Device)}, m_CommandResources(commandResources), m_SyncResources(syncResources), - m_Queues(queues) + m_Queues(queues), + m_FrameIndex(0) {} Core::~Core() noexcept { + m_Context.getDevice().waitIdle(); for (auto image : m_swapchainImageViews) { m_Context.m_Device.destroyImageView(image); } @@ -306,6 +309,7 @@ namespace vkcv } void Core::beginFrame() { + m_Context.getDevice().waitIdle(); // FIMXE: this is a sin against graphics programming, but its getting late - Alex const vk::CommandBufferUsageFlags beginFlags = vk::CommandBufferUsageFlagBits::eOneTimeSubmit; const vk::CommandBufferBeginInfo beginInfos(beginFlags); m_CommandResources.commandBuffer.begin(beginInfos); @@ -316,8 +320,33 @@ namespace vkcv } void Core::endFrame() { + + uint32_t swapchainImageIndex; + m_Context.getDevice().acquireNextImageKHR(m_swapchain.getSwapchain(), 0, nullptr, + m_SyncResources.swapchainImageAcquired, &swapchainImageIndex, {}); + const uint64_t timeoutPeriodNs = 1000; // TODO: think if is adequate + m_Context.getDevice().waitForFences(m_SyncResources.swapchainImageAcquired, true, timeoutPeriodNs); + m_Context.getDevice().resetFences(m_SyncResources.swapchainImageAcquired); + + const auto swapchainImages = m_Context.getDevice().getSwapchainImagesKHR(m_swapchain.getSwapchain()); + const vk::Image presentImage = swapchainImages[swapchainImageIndex]; + + transitionImageLayoutImmediate( + m_CommandResources.commandBuffer, + presentImage, + vk::ImageLayout::eUndefined, + vk::ImageLayout::ePresentSrcKHR); + m_CommandResources.commandBuffer.end(); - //m_Context. + + const vk::SubmitInfo submitInfo(0, nullptr, 0, 1, &(m_CommandResources.commandBuffer), 1, &m_SyncResources.renderFinished); + m_Queues.graphicsQueue.submit(submitInfo); + + vk::Result presentResult; + vk::PresentInfoKHR presentInfo(1, &m_SyncResources.renderFinished, 1, &m_swapchain.getSwapchain(), &swapchainImageIndex, &presentResult); + m_Queues.presentQueue.presentKHR(presentInfo); + if (presentResult != vk::Result::eSuccess) { + std::cout << "Error: swapchain present failed" << std::endl; + } } - } diff --git a/src/vkcv/ImageLayoutTransitions.cpp b/src/vkcv/ImageLayoutTransitions.cpp new file mode 100644 index 00000000..a64e0662 --- /dev/null +++ b/src/vkcv/ImageLayoutTransitions.cpp @@ -0,0 +1,24 @@ +#include "ImageLayoutTransitions.hpp" + +namespace vkcv { + void transitionImageLayoutImmediate(const vk::CommandBuffer cmdBuffer, const VkImage image, + const vk::ImageLayout oldLayout, const vk::ImageLayout newLayout) { + + // TODO: proper src and dst masks + const vk::PipelineStageFlags srcStageMask = vk::PipelineStageFlagBits::eAllCommands; + const vk::PipelineStageFlags dstStageMask = vk::PipelineStageFlagBits::eAllCommands; + const vk::DependencyFlags dependecyFlags = {}; + + // TODO: proper src and dst masks + const vk::AccessFlags srcAccessMask = vk::AccessFlagBits::eColorAttachmentWrite; + const vk::AccessFlags dstAccessMask = vk::AccessFlagBits::eColorAttachmentWrite; + + // TODO: proper aspect flags + const vk::ImageAspectFlags aspectFlags = vk::ImageAspectFlagBits::eColor; + + const vk::ImageSubresourceRange subresourceRange(aspectFlags, 0, 1, 0, 1); + vk::ImageMemoryBarrier imageBarrier(srcAccessMask, dstAccessMask, oldLayout, newLayout, 0, 0, image, subresourceRange); + + cmdBuffer.pipelineBarrier(srcStageMask, dstStageMask, dependecyFlags, 0, nullptr, 0, nullptr, 1, &imageBarrier, {}); + } +} \ No newline at end of file diff --git a/src/vkcv/ImageLayoutTransitions.hpp b/src/vkcv/ImageLayoutTransitions.hpp new file mode 100644 index 00000000..284fb64c --- /dev/null +++ b/src/vkcv/ImageLayoutTransitions.hpp @@ -0,0 +1,7 @@ +#pragma once +#include <vulkan/vulkan.hpp> + +namespace vkcv { + void transitionImageLayoutImmediate(const vk::CommandBuffer cmdBuffer, const VkImage image, + const vk::ImageLayout oldLayout, const vk::ImageLayout newLayout); +} \ No newline at end of file diff --git a/src/vkcv/Queues.cpp b/src/vkcv/Queues.cpp index 36b3a0a0..49e992ff 100644 --- a/src/vkcv/Queues.cpp +++ b/src/vkcv/Queues.cpp @@ -62,7 +62,6 @@ namespace vkcv { int priorityIndex = 0; for (const auto index : familyIndexSet) { - outQueuePriorities->push_back(1.f); const vk::DeviceQueueCreateInfo graphicsCreateInfo(flags, index, 1, &outQueuePriorities->at(priorityIndex)); createInfos.push_back(graphicsCreateInfo); priorityIndex++; diff --git a/src/vkcv/SwapChain.cpp b/src/vkcv/SwapChain.cpp index a9aeccea..1a8cfb79 100644 --- a/src/vkcv/SwapChain.cpp +++ b/src/vkcv/SwapChain.cpp @@ -2,8 +2,8 @@ namespace vkcv { - SwapChain::SwapChain(vk::SurfaceKHR surface, vk::SwapchainKHR swapchain, vk::SurfaceFormatKHR format ) - : m_surface(surface), m_swapchain(swapchain), m_format( format) + SwapChain::SwapChain(vk::SurfaceKHR surface, vk::SwapchainKHR swapchain, vk::SurfaceFormatKHR format, uint32_t imageCount) + : m_surface(surface), m_swapchain(swapchain), m_format( format), m_ImageCount(imageCount) {} vk::SwapchainKHR SwapChain::getSwapchain() { @@ -157,7 +157,7 @@ namespace vkcv { vk::SwapchainKHR swapchain = device.createSwapchainKHR(swapchainCreateInfo); - return SwapChain(surface, swapchain, surfaceFormat); + return SwapChain(surface, swapchain, surfaceFormat, imageCount); } @@ -165,4 +165,7 @@ namespace vkcv { // needs to be destroyed by creator } + uint32_t SwapChain::getImageCount() { + return m_ImageCount; + } } diff --git a/src/vkcv/SyncResources.cpp b/src/vkcv/SyncResources.cpp index 71516da8..10d582a2 100644 --- a/src/vkcv/SyncResources.cpp +++ b/src/vkcv/SyncResources.cpp @@ -11,6 +11,7 @@ namespace vkcv { const vk::FenceCreateFlags fenceFlags = vk::FenceCreateFlagBits(); vk::FenceCreateInfo fenceInfo(fenceFlags); resources.presentFinished = device.createFence(fenceInfo, nullptr, {}); + resources.swapchainImageAcquired = device.createFence(fenceInfo, nullptr, {}); return resources; } @@ -18,5 +19,6 @@ namespace vkcv { void destroySyncResources(const vk::Device& device, const SyncResources& resources) { device.destroySemaphore(resources.renderFinished); device.destroyFence(resources.presentFinished); + device.destroyFence(resources.swapchainImageAcquired); } } \ No newline at end of file -- GitLab