From 7890faf3685b7fdcb41038e49bce9d503e383c55 Mon Sep 17 00:00:00 2001 From: Alexander Gauggel <agauggel@uni-koblenz.de> Date: Sun, 16 May 2021 20:48:39 +0200 Subject: [PATCH] [#18]Do yellow nice (now executing renderpass) --- config/Sources.cmake | 3 ++ include/vkcv/Core.hpp | 11 ++++- include/vkcv/PassConfig.hpp | 15 ++++--- include/vkcv/SwapChain.hpp | 3 ++ projects/first_triangle/src/main.cpp | 5 ++- src/vkcv/Core.cpp | 62 +++++++++++++++++++--------- src/vkcv/Framebuffer.cpp | 11 +++++ src/vkcv/Framebuffer.hpp | 7 ++++ src/vkcv/PassConfig.cpp | 23 ++++++----- src/vkcv/PassManager.cpp | 7 +--- src/vkcv/SwapChain.cpp | 6 ++- 11 files changed, 108 insertions(+), 45 deletions(-) create mode 100644 src/vkcv/Framebuffer.cpp create mode 100644 src/vkcv/Framebuffer.hpp diff --git a/config/Sources.cmake b/config/Sources.cmake index ee7da418..dce76b39 100644 --- a/config/Sources.cmake +++ b/config/Sources.cmake @@ -45,4 +45,7 @@ set(vkcv_sources ${vkcv_source}/vkcv/ImageLayoutTransitions.hpp ${vkcv_source}/vkcv/ImageLayoutTransitions.cpp + + ${vkcv_source}/vkcv/Framebuffer.hpp + ${vkcv_source}/vkcv/Framebuffer.cpp ) diff --git a/include/vkcv/Core.hpp b/include/vkcv/Core.hpp index 60514181..b7b553d7 100644 --- a/include/vkcv/Core.hpp +++ b/include/vkcv/Core.hpp @@ -40,6 +40,9 @@ namespace vkcv // explicit destruction of default constructor Core() = delete; + uint32_t acquireSwapchainImage(); + void destroyTemporaryFramebuffers(); + Context m_Context; SwapChain m_swapchain; @@ -51,7 +54,8 @@ namespace vkcv CommandResources m_CommandResources; SyncResources m_SyncResources; VulkanQueues m_Queues; - uint32_t m_FrameIndex; + uint32_t m_currentSwapchainImageIndex; + std::vector<vk::Framebuffer> m_TemporaryFramebuffers; public: /** * Destructor of #Core destroys the Vulkan objects contained in the core's context. @@ -146,11 +150,14 @@ namespace vkcv /** * @brief render a beautiful triangle */ - void renderTriangle(); + void renderTriangle(const PassHandle renderpassHandle, const PipelineHandle pipelineHandle, + const int width, const int height); /** * @brief end recording and present image */ void endFrame(); + + vk::Format getSwapchainImageFormat(); }; } diff --git a/include/vkcv/PassConfig.hpp b/include/vkcv/PassConfig.hpp index b0ded8f5..b8e80c67 100644 --- a/include/vkcv/PassConfig.hpp +++ b/include/vkcv/PassConfig.hpp @@ -1,6 +1,7 @@ #pragma once #include <vector> +#include <vulkan/vulkan.hpp> namespace vkcv { @@ -32,11 +33,13 @@ namespace vkcv struct AttachmentDescription { AttachmentDescription() = delete; - AttachmentDescription(AttachmentLayout initial, - AttachmentLayout in_pass, - AttachmentLayout final, - AttachmentOperation store_op, - AttachmentOperation load_op) noexcept; + AttachmentDescription( + AttachmentLayout initial, + AttachmentLayout in_pass, + AttachmentLayout final, + AttachmentOperation store_op, + AttachmentOperation load_op, + vk::Format format) noexcept; AttachmentLayout layout_initial; AttachmentLayout layout_in_pass; @@ -44,6 +47,8 @@ namespace vkcv AttachmentOperation store_operation; AttachmentOperation load_operation; + + vk::Format format; }; struct PassConfig diff --git a/include/vkcv/SwapChain.hpp b/include/vkcv/SwapChain.hpp index 1d2f4710..351905fa 100644 --- a/include/vkcv/SwapChain.hpp +++ b/include/vkcv/SwapChain.hpp @@ -13,6 +13,7 @@ namespace vkcv { vk::SurfaceFormatKHR m_format; uint32_t m_ImageCount; + vk::Format m_ImageFormat; /** * Constructor of a SwapChain object @@ -65,6 +66,8 @@ namespace vkcv { * @return number of images in swapchain */ uint32_t getImageCount(); + + vk::Format getImageFormat(); }; } diff --git a/projects/first_triangle/src/main.cpp b/projects/first_triangle/src/main.cpp index 0e567db7..fb9d764c 100644 --- a/projects/first_triangle/src/main.cpp +++ b/projects/first_triangle/src/main.cpp @@ -46,7 +46,8 @@ int main(int argc, const char** argv) { vkcv::AttachmentLayout::COLOR_ATTACHMENT, vkcv::AttachmentLayout::PRESENTATION, vkcv::AttachmentOperation::STORE, - vkcv::AttachmentOperation::CLEAR); + vkcv::AttachmentOperation::CLEAR, + core.getSwapchainImageFormat()); vkcv::PassConfig trianglePassDefinition({present_color_attachment}); vkcv::PassHandle trianglePass = core.createPass(trianglePassDefinition); @@ -88,7 +89,7 @@ int main(int argc, const char** argv) { while (window.isWindowOpen()) { core.beginFrame(); - // core.execute(trianglePass, trianglePipeline, triangleModel); + core.renderTriangle(trianglePass, trianglePipeline, windowWidth, windowHeight); core.endFrame(); window.pollEvents(); diff --git a/src/vkcv/Core.cpp b/src/vkcv/Core.cpp index 70f0425f..3c113a7a 100644 --- a/src/vkcv/Core.cpp +++ b/src/vkcv/Core.cpp @@ -9,6 +9,7 @@ #include "PipelineManager.hpp" #include "Surface.hpp" #include "ImageLayoutTransitions.hpp" +#include "Framebuffer.hpp" namespace vkcv { @@ -279,8 +280,7 @@ namespace vkcv m_PipelineManager{std::make_unique<PipelineManager>(m_Context.m_Device)}, m_CommandResources(commandResources), m_SyncResources(syncResources), - m_Queues(queues), - m_FrameIndex(0) + m_Queues(queues) {} Core::~Core() noexcept { @@ -291,6 +291,7 @@ namespace vkcv destroyCommandResources(m_Context.getDevice(), m_CommandResources); destroySyncResources(m_Context.getDevice(), m_SyncResources); + destroyTemporaryFramebuffers(); m_Context.m_Device.destroySwapchainKHR(m_swapchain.getSwapchain()); m_Context.m_Instance.destroySurfaceKHR(m_swapchain.getSurface()); @@ -308,34 +309,50 @@ namespace vkcv return m_PassManager->createPass(config); } + uint32_t Core::acquireSwapchainImage() { + uint32_t index; + m_Context.getDevice().acquireNextImageKHR(m_swapchain.getSwapchain(), 0, nullptr, + m_SyncResources.swapchainImageAcquired, &index, {}); + 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); + return index; + } + + void Core::destroyTemporaryFramebuffers() { + for (const vk::Framebuffer f : m_TemporaryFramebuffers) { + m_Context.getDevice().destroyFramebuffer(f); + } + m_TemporaryFramebuffers.clear(); + } + void Core::beginFrame() { + m_currentSwapchainImageIndex = acquireSwapchainImage(); m_Context.getDevice().waitIdle(); // FIMXE: this is a sin against graphics programming, but its getting late - Alex + destroyTemporaryFramebuffers(); const vk::CommandBufferUsageFlags beginFlags = vk::CommandBufferUsageFlagBits::eOneTimeSubmit; const vk::CommandBufferBeginInfo beginInfos(beginFlags); m_CommandResources.commandBuffer.begin(beginInfos); } - void Core::renderTriangle() { - + void Core::renderTriangle(const PassHandle renderpassHandle, const PipelineHandle pipelineHandle, + const int width, const int height) { + const vk::RenderPass renderpass = m_PassManager->getVkPass(renderpassHandle); + const std::array<float, 4> clearColor = { 1.f, 1.f, 0.f, 1.f }; + const vk::ClearValue clearValues(clearColor); + const vk::Rect2D renderArea(vk::Offset2D(0, 0), vk::Extent2D(width, height)); + const vk::ImageView imageView = m_swapchainImageViews[m_currentSwapchainImageIndex]; + const vk::Framebuffer framebuffer = createFramebuffer(m_Context.getDevice(), renderpass, width, height, imageView); + m_TemporaryFramebuffers.push_back(framebuffer); + const vk::RenderPassBeginInfo beginInfo(renderpass, framebuffer, renderArea, 1, &clearValues); + const vk::SubpassContents subpassContents = {}; + m_CommandResources.commandBuffer.beginRenderPass(beginInfo, subpassContents, {}); + m_CommandResources.commandBuffer.endRenderPass(); } 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); + const vk::Image presentImage = swapchainImages[m_currentSwapchainImageIndex]; m_CommandResources.commandBuffer.end(); @@ -344,10 +361,15 @@ namespace vkcv vk::Result presentResult; const vk::SwapchainKHR& swapchain = m_swapchain.getSwapchain(); - const vk::PresentInfoKHR presentInfo(1, &m_SyncResources.renderFinished, 1, &swapchain, &swapchainImageIndex, &presentResult); + const vk::PresentInfoKHR presentInfo(1, &m_SyncResources.renderFinished, 1, &swapchain, + &m_currentSwapchainImageIndex, &presentResult); m_Queues.presentQueue.presentKHR(presentInfo); if (presentResult != vk::Result::eSuccess) { std::cout << "Error: swapchain present failed" << std::endl; } } + + vk::Format Core::getSwapchainImageFormat() { + return m_swapchain.getImageFormat(); + } } diff --git a/src/vkcv/Framebuffer.cpp b/src/vkcv/Framebuffer.cpp new file mode 100644 index 00000000..3b3e8000 --- /dev/null +++ b/src/vkcv/Framebuffer.cpp @@ -0,0 +1,11 @@ +#include "Framebuffer.hpp" + +namespace vkcv { + vk::Framebuffer createFramebuffer(const vk::Device device, const vk::RenderPass renderpass, + const int width, const int height, const vk::ImageView imageView) { + const vk::FramebufferCreateFlags flags = {}; + const uint32_t attachmentCount = 1; // TODO: proper value + const vk::FramebufferCreateInfo createInfo(flags, renderpass, attachmentCount, &imageView, width, height, 1); + return device.createFramebuffer(createInfo, nullptr, {}); + } +} \ No newline at end of file diff --git a/src/vkcv/Framebuffer.hpp b/src/vkcv/Framebuffer.hpp new file mode 100644 index 00000000..7d5d718a --- /dev/null +++ b/src/vkcv/Framebuffer.hpp @@ -0,0 +1,7 @@ +#pragma once +#include <vulkan/vulkan.hpp> + +namespace vkcv{ + vk::Framebuffer createFramebuffer(const vk::Device device, const vk::RenderPass renderpass, + const int width, const int height, const vk::ImageView imageView); +} \ No newline at end of file diff --git a/src/vkcv/PassConfig.cpp b/src/vkcv/PassConfig.cpp index a0c22896..ef07d3ee 100644 --- a/src/vkcv/PassConfig.cpp +++ b/src/vkcv/PassConfig.cpp @@ -4,16 +4,19 @@ namespace vkcv { - AttachmentDescription::AttachmentDescription(AttachmentLayout initial, - AttachmentLayout in_pass, - AttachmentLayout final, - AttachmentOperation store_op, - AttachmentOperation load_op) noexcept : - layout_initial{initial}, - layout_in_pass{in_pass}, - layout_final{final}, - store_operation{store_op}, - load_operation{load_op} + AttachmentDescription::AttachmentDescription( + AttachmentLayout initial, + AttachmentLayout in_pass, + AttachmentLayout final, + AttachmentOperation store_op, + AttachmentOperation load_op, + vk::Format format) noexcept : + layout_initial{initial}, + layout_in_pass{in_pass}, + layout_final{final}, + store_operation{store_op}, + load_operation{load_op}, + format(format) {}; PassConfig::PassConfig(std::vector<AttachmentDescription> attachments) noexcept : diff --git a/src/vkcv/PassManager.cpp b/src/vkcv/PassManager.cpp index 3184cfa2..820bf3ff 100644 --- a/src/vkcv/PassManager.cpp +++ b/src/vkcv/PassManager.cpp @@ -76,19 +76,16 @@ namespace vkcv for (uint32_t i = 0; i < config.attachments.size(); i++) { // TODO: Renderpass struct should hold proper format information - vk::Format format; + vk::Format format = config.attachments[i].format; if (config.attachments[i].layout_in_pass == AttachmentLayout::DEPTH_STENCIL_ATTACHMENT) { - format = vk::Format::eD16Unorm; // depth attachments; - depthAttachmentReference.attachment = i; depthAttachmentReference.layout = getVkLayoutFromAttachLayout(config.attachments[i].layout_in_pass); pDepthAttachment = &depthAttachmentReference; } else { - format = vk::Format::eB8G8R8A8Srgb; // color attachments, compatible with swapchain vk::AttachmentReference attachmentRef(i, getVkLayoutFromAttachLayout(config.attachments[i].layout_in_pass)); colorAttachmentReferences.push_back(attachmentRef); } @@ -97,7 +94,7 @@ namespace vkcv format, vk::SampleCountFlagBits::e1, getVKLoadOpFromAttachOp(config.attachments[i].load_operation), - getVkStoreOpFromAttachOp(config.attachments[i].load_operation), + getVkStoreOpFromAttachOp(config.attachments[i].store_operation), vk::AttachmentLoadOp::eDontCare, vk::AttachmentStoreOp::eDontCare, getVkLayoutFromAttachLayout(config.attachments[i].layout_initial), diff --git a/src/vkcv/SwapChain.cpp b/src/vkcv/SwapChain.cpp index 3483ae37..ef182bcd 100644 --- a/src/vkcv/SwapChain.cpp +++ b/src/vkcv/SwapChain.cpp @@ -3,7 +3,7 @@ namespace vkcv { 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) + : m_surface(surface), m_swapchain(swapchain), m_format( format), m_ImageCount(imageCount), m_ImageFormat(format.format) {} const vk::SwapchainKHR& SwapChain::getSwapchain() const { @@ -168,4 +168,8 @@ namespace vkcv { uint32_t SwapChain::getImageCount() { return m_ImageCount; } + + vk::Format SwapChain::getImageFormat() { + return m_ImageFormat; + } } -- GitLab