From f9215657056786f4879ffbd65bf2a89c1d86a7de Mon Sep 17 00:00:00 2001 From: Tobias Frisch <tfrisch@uni-koblenz.de> Date: Fri, 8 Jul 2022 11:29:05 +0200 Subject: [PATCH] Adjusted swapchain manager (still WIP) Signed-off-by: Tobias Frisch <tfrisch@uni-koblenz.de> --- config/Sources.cmake | 6 - include/vkcv/Core.hpp | 43 +-- include/vkcv/Surface.hpp | 107 ------- include/vkcv/Swapchain.hpp | 136 --------- include/vkcv/Window.hpp | 3 +- modules/gui/src/vkcv/gui/GUI.cpp | 19 +- projects/bindless_textures/src/main.cpp | 9 +- projects/first_mesh/src/main.cpp | 7 +- projects/first_scene/src/main.cpp | 2 +- projects/first_triangle/src/main.cpp | 2 +- projects/head_demo/src/main.cpp | 2 +- projects/indirect_draw/src/main.cpp | 7 +- projects/mesh_shader/src/main.cpp | 2 +- projects/particle_simulation/src/main.cpp | 7 +- projects/saf_r/src/main.cpp | 5 +- projects/sph/src/main.cpp | 7 +- projects/voxelization/src/main.cpp | 2 +- projects/wobble_bobble/src/main.cpp | 8 +- src/vkcv/Core.cpp | 155 ++++++----- src/vkcv/QueueManager.cpp | 1 - src/vkcv/Surface.cpp | 258 ----------------- src/vkcv/Swapchain.cpp | 96 ------- src/vkcv/SwapchainManager.cpp | 322 +++++++++++++++++++--- src/vkcv/SwapchainManager.hpp | 141 ++++++++-- src/vkcv/Window.cpp | 2 +- 25 files changed, 549 insertions(+), 800 deletions(-) delete mode 100644 include/vkcv/Surface.hpp delete mode 100644 include/vkcv/Swapchain.hpp delete mode 100644 src/vkcv/Surface.cpp delete mode 100644 src/vkcv/Swapchain.cpp diff --git a/config/Sources.cmake b/config/Sources.cmake index f2c69d35..c3231e7a 100644 --- a/config/Sources.cmake +++ b/config/Sources.cmake @@ -49,12 +49,6 @@ set(vkcv_sources ${vkcv_include}/vkcv/Logger.hpp - ${vkcv_include}/vkcv/Surface.hpp - ${vkcv_source}/vkcv/Surface.cpp - - ${vkcv_include}/vkcv/Swapchain.hpp - ${vkcv_source}/vkcv/Swapchain.cpp - ${vkcv_include}/vkcv/ShaderStage.hpp ${vkcv_include}/vkcv/ShaderProgram.hpp diff --git a/include/vkcv/Core.hpp b/include/vkcv/Core.hpp index bf5cf40f..aaac77de 100644 --- a/include/vkcv/Core.hpp +++ b/include/vkcv/Core.hpp @@ -11,7 +11,6 @@ #include "BufferTypes.hpp" #include "Context.hpp" -#include "Swapchain.hpp" #include "Window.hpp" #include "PassConfig.hpp" #include "Handles.hpp" @@ -380,30 +379,36 @@ namespace vkcv * @return the window */ [[nodiscard]] - Window& getWindow(const WindowHandle& handle ); - + Window& getWindow(const WindowHandle& handle); + /** - * Gets the swapchain of the current focused window - * @return swapchain - */ + * @brief Returns the image format for the current surface + * of the swapchain. + * + * @param[in] handle Swapchain handle + * @return Swapchain image format + */ [[nodiscard]] - Swapchain& getSwapchainOfCurrentWindow(); - + vk::Format getSwapchainFormat(const SwapchainHandle& swapchain) const; + /** - * Returns the swapchain reference - * @param handle of the swapchain - * @return swapchain - */ + * @brief Returns the amount of images for the swapchain. + * + * @param[in] handle Swapchain handle + * @return Number of images + */ [[nodiscard]] - Swapchain& getSwapchain(const SwapchainHandle &handle); - + uint32_t getSwapchainImageCount(const SwapchainHandle& swapchain) const; + /** - * Gets the swapchain handle from the window - * @param handle of the window - * @return the swapchain from getSwapchain( SwapchainHandle ) - */ + * @brief Returns the extent from the current surface of + * the swapchain. + * + * @param[in] handle Swapchain handle + * @return Extent of the swapchains surface + */ [[nodiscard]] - Swapchain& getSwapchain(const WindowHandle &handle); + vk::Extent2D getSwapchainExtent(const SwapchainHandle& swapchain) const; /** * @brief Returns the image width. diff --git a/include/vkcv/Surface.hpp b/include/vkcv/Surface.hpp deleted file mode 100644 index 47862b9c..00000000 --- a/include/vkcv/Surface.hpp +++ /dev/null @@ -1,107 +0,0 @@ -#pragma once -/** - * @authors Tobias Frisch - * @file vkcv/Surface.hpp - * @brief Class to manage the surface used by a swapchain. - */ - -#include <vulkan/vulkan.hpp> - -#include "Context.hpp" -#include "Window.hpp" - -namespace vkcv { - - const uint32_t MIN_SURFACE_SIZE = 2; - - /** - * @brief Class to handle surfaces to use with a swapchain. - */ - class Surface final { - private: - friend class Swapchain; - friend class SwapchainManager; - - const Context *m_Context; - vk::SurfaceKHR m_Handle; - uint32_t m_PresentQueueIndex; - vk::Extent2D m_Extent; - vk::Format m_Format; - vk::ColorSpaceKHR m_ColorSpace; - - Surface(const Context &context, - const vk::SurfaceKHR &handle, - uint32_t presentQueueIndex, - const vk::Extent2D &extent, - vk::Format format, - vk::ColorSpaceKHR colorSpace); - - vk::SwapchainKHR createVulkanSwapchain(const Window &window, - const vk::SwapchainKHR &oldSwapchain); - - public: - Surface(const Surface& other) = default; - - Surface(Surface&& other) noexcept; - - Surface& operator=(const Surface& other) = default; - - Surface& operator=(Surface&& other) noexcept; - - ~Surface(); - - /** - * @brief Creates a surface via a window and a current context. - * - * @param[in] window Window - * @param[in] context Context - * @return Created surface - */ - static Surface create(const Window &window, - const Context &context); - - /** - * @brief Returns the Vulkan-Surface of the object. - * - * @return Current Vulkan-Surface - */ - [[nodiscard]] - vk::SurfaceKHR getSurface() const; - - /** - * @brief Returns the queue index of the present queue - * for the surface. - * - * @return Present queue index - */ - [[nodiscard]] - uint32_t getPresentQueueIndex() const; - - /** - * @brief Returns the extent of the surfaces resolution. - * - * @return Extent of surface - */ - [[nodiscard]] - const vk::Extent2D& getExtent() const; - - /** - * @brief Returns the image format of the surface to - * present an image. - * - * @return Vulkan image format - */ - [[nodiscard]] - vk::Format getFormat() const; - - /** - * @brief Returns the color space of the surface. - * - * @return Color space - */ - [[nodiscard]] - vk::ColorSpaceKHR getColorSpace() const; - - }; - -} diff --git a/include/vkcv/Swapchain.hpp b/include/vkcv/Swapchain.hpp deleted file mode 100644 index 9380b97c..00000000 --- a/include/vkcv/Swapchain.hpp +++ /dev/null @@ -1,136 +0,0 @@ -#pragma once -/** - * @authors Sebastian Gaida, Tobias Frisch - * @file vkcv/Swapchain.hpp - * @brief Class to manage the state of a swapchain and its transitions. - */ - -#include <atomic> -#include <vulkan/vulkan.hpp> - -#include "Context.hpp" -#include "Surface.hpp" -#include "Window.hpp" - -namespace vkcv -{ - - /** - * @brief Class to handle swapchains using a context. - */ - class Swapchain final { - private: - friend class Core; - friend class Window; - friend class SwapchainManager; - - const Context *m_Context; - Surface m_Surface; - vk::SwapchainKHR m_Swapchain; - std::atomic<bool> m_RecreationRequired; - - /** - * @brief Constructor of the swapchain with the current context, - * a surface and a given vulkan swapchain object. - * - * @param[in,out] context Current context - * @param[in] surface used by the swapchain - * @param[in,out] swapchain to show images in the window - */ - Swapchain(const Context &context, - const Surface &surface, - vk::SwapchainKHR swapchain) noexcept; - - /** - * @brief Checks whether the swapchain needs to be recreated. - * - * @return True, if the swapchain should be updated, - * otherwise false. - */ - bool shouldUpdateSwapchain() const; - - /** - * @brief Updates and recreates the swapchain. - * - * @param[in,out] context that holds the device to recreate the swapchain - * @param[in] window that the new swapchain gets bound to - */ - void updateSwapchain(const Context &context, const Window &window); - - /** - * @brief Signals the swapchain to be recreated. - */ - void signalSwapchainRecreation(); - - public: - Swapchain(const Swapchain& other); - - /** - * @brief Returns the vulkan swapchain object of the swapchain. - * - * @return The swapchain linked with the #SwapChain class - * @note The reference to our Swapchain variable is needed for the recreation step - */ - [[nodiscard]] - const vk::SwapchainKHR& getSwapchain() const; - - /** - * @brief Returns the current surface of the swapchain. - * - * @return Current surface - */ - [[nodiscard]] - const Surface& getSurface() const; - - /** - * @brief Returns the image format for the current surface - * of the swapchain. - * - * @return Swapchain image format - */ - [[nodiscard]] - vk::Format getFormat() const; - - /** - * @brief Creates a swapchain for a specific window and - * a given context. - * - * @param[in,out] window Window - * @param[in,out] context Context - * @return New created swapchain - */ - static Swapchain create(const Window &window, const Context &context); - - /** - * Destructor of thw swapchain. - */ - virtual ~Swapchain(); - - /** - * @brief Returns the amount of images for the swapchain. - * - * @return Number of images - */ - uint32_t getImageCount() const; - - /** - * @brief Returns the extent from the current surface of - * the swapchain. - * - * @return Extent of the swapchains surface - */ - [[nodiscard]] - const vk::Extent2D& getExtent() const; - - /** - * @brief Returns the present queue index to be used with - * the swapchain and its current surface. - * - * @return Present queue family index - */ - [[nodiscard]] - uint32_t getPresentQueueIndex() const; - - }; - -} diff --git a/include/vkcv/Window.hpp b/include/vkcv/Window.hpp index d1db4bf4..e7a27730 100644 --- a/include/vkcv/Window.hpp +++ b/include/vkcv/Window.hpp @@ -169,7 +169,8 @@ namespace vkcv { * * @return Swapchain handle */ - SwapchainHandle getSwapchainHandle() const; + SwapchainHandle getSwapchain() const; + }; } diff --git a/modules/gui/src/vkcv/gui/GUI.cpp b/modules/gui/src/vkcv/gui/GUI.cpp index 7ee33537..5ac03ce5 100644 --- a/modules/gui/src/vkcv/gui/GUI.cpp +++ b/modules/gui/src/vkcv/gui/GUI.cpp @@ -71,7 +71,8 @@ namespace vkcv::gui { m_descriptor_pool = m_context.getDevice().createDescriptorPool(descriptorPoolCreateInfo); const vk::PhysicalDevice& physicalDevice = m_context.getPhysicalDevice(); - const Swapchain& swapchain = m_core.getSwapchain(m_windowHandle); + const SwapchainHandle& swapchainHandle = m_core.getWindow(m_windowHandle).getSwapchain(); + const uint32_t swapchainImageCount = m_core.getSwapchainImageCount(swapchainHandle); const uint32_t graphicsQueueFamilyIndex = ( m_context.getQueueManager().getGraphicsQueues()[0].familyIndex @@ -86,13 +87,13 @@ namespace vkcv::gui { init_info.PipelineCache = 0; init_info.DescriptorPool = static_cast<VkDescriptorPool>(m_descriptor_pool); init_info.Allocator = nullptr; - init_info.MinImageCount = swapchain.getImageCount(); - init_info.ImageCount = swapchain.getImageCount(); + init_info.MinImageCount = swapchainImageCount; + init_info.ImageCount = swapchainImageCount; init_info.CheckVkResultFn = checkVulkanResult; const vk::AttachmentDescription attachment ( vk::AttachmentDescriptionFlags(), - swapchain.getFormat(), + m_core.getSwapchainFormat(swapchainHandle), vk::SampleCountFlagBits::e1, vk::AttachmentLoadOp::eLoad, vk::AttachmentStoreOp::eStore, @@ -177,11 +178,11 @@ namespace vkcv::gui { } void GUI::beginGUI() { - const Swapchain& swapchain = m_core.getSwapchain(m_windowHandle); - const auto extent = swapchain.getExtent(); + const auto swapchainHandle = m_core.getWindow(m_windowHandle).getSwapchain(); + const auto& extent = m_core.getSwapchainExtent(swapchainHandle); if ((extent.width > 0) && (extent.height > 0)) { - ImGui_ImplVulkan_SetMinImageCount(swapchain.getImageCount()); + ImGui_ImplVulkan_SetMinImageCount(m_core.getSwapchainImageCount(swapchainHandle)); } ImGui_ImplVulkan_NewFrame(); @@ -200,8 +201,8 @@ namespace vkcv::gui { return; } - const Swapchain& swapchain = m_core.getSwapchain(m_windowHandle); - const auto extent = swapchain.getExtent(); + const auto swapchainHandle = m_core.getWindow(m_windowHandle).getSwapchain(); + const auto& extent = m_core.getSwapchainExtent(swapchainHandle); const vk::ImageView swapchainImageView = m_core.getSwapchainImageView(); diff --git a/projects/bindless_textures/src/main.cpp b/projects/bindless_textures/src/main.cpp index afc58330..e2f4c4ac 100644 --- a/projects/bindless_textures/src/main.cpp +++ b/projects/bindless_textures/src/main.cpp @@ -47,6 +47,7 @@ int main(int argc, const char** argv) { ); vkcv::WindowHandle windowHandle = core.createWindow(applicationName, 800, 600, true); + vkcv::Window& window = core.getWindow(windowHandle); vkcv::asset::Scene mesh; @@ -102,7 +103,7 @@ int main(int argc, const char** argv) { const vkcv::AttachmentDescription present_color_attachment( vkcv::AttachmentOperation::STORE, vkcv::AttachmentOperation::CLEAR, - core.getSwapchain(windowHandle).getFormat() + core.getSwapchainFormat(window.getSwapchain()) ); const vkcv::AttachmentDescription depth_attachment( @@ -221,7 +222,7 @@ int main(int argc, const char** argv) { vkcv::DescriptorSetUsage descriptorUsage(0, descriptorSet); vkcv::DrawcallInfo drawcall(renderMesh, { descriptorUsage },1); - vkcv::camera::CameraManager cameraManager(core.getWindow(windowHandle)); + vkcv::camera::CameraManager cameraManager(window); uint32_t camIndex0 = cameraManager.addCamera(vkcv::camera::ControllerType::PILOT); cameraManager.addCamera(vkcv::camera::ControllerType::TRACKBALL); @@ -232,11 +233,11 @@ int main(int argc, const char** argv) { while (vkcv::Window::hasOpenWindow()) { vkcv::Window::pollEvents(); - if(core.getWindow(windowHandle).getHeight() == 0 || core.getWindow(windowHandle).getWidth() == 0) + if (window.getHeight() == 0 || window.getWidth() == 0) continue; uint32_t swapchainWidth, swapchainHeight; - if (!core.beginFrame(swapchainWidth, swapchainHeight,windowHandle)) { + if (!core.beginFrame(swapchainWidth, swapchainHeight, windowHandle)) { continue; } diff --git a/projects/first_mesh/src/main.cpp b/projects/first_mesh/src/main.cpp index 40a16aed..1220b36e 100644 --- a/projects/first_mesh/src/main.cpp +++ b/projects/first_mesh/src/main.cpp @@ -17,6 +17,7 @@ int main(int argc, const char** argv) { ); vkcv::WindowHandle windowHandle = core.createWindow(applicationName, 800, 600, true); + vkcv::Window& window = core.getWindow(windowHandle); vkcv::asset::Scene mesh; @@ -53,7 +54,7 @@ int main(int argc, const char** argv) { const vkcv::AttachmentDescription present_color_attachment( vkcv::AttachmentOperation::STORE, vkcv::AttachmentOperation::CLEAR, - core.getSwapchain(windowHandle).getFormat() + core.getSwapchainFormat(window.getSwapchain()) ); const vkcv::AttachmentDescription depth_attachment( @@ -162,7 +163,7 @@ int main(int argc, const char** argv) { vkcv::DescriptorSetUsage descriptorUsage(0, descriptorSet); vkcv::DrawcallInfo drawcall(renderMesh, { descriptorUsage },1); - vkcv::camera::CameraManager cameraManager(core.getWindow(windowHandle)); + vkcv::camera::CameraManager cameraManager(window); uint32_t camIndex0 = cameraManager.addCamera(vkcv::camera::ControllerType::PILOT); cameraManager.getCamera(camIndex0).setPosition(glm::vec3(0, 0, -3)); @@ -172,7 +173,7 @@ int main(int argc, const char** argv) { while (vkcv::Window::hasOpenWindow()) { vkcv::Window::pollEvents(); - if(core.getWindow(windowHandle).getHeight() == 0 || core.getWindow(windowHandle).getWidth() == 0) + if (window.getHeight() == 0 || window.getWidth() == 0) continue; uint32_t swapchainWidth, swapchainHeight; diff --git a/projects/first_scene/src/main.cpp b/projects/first_scene/src/main.cpp index c09d0121..dfa58d88 100644 --- a/projects/first_scene/src/main.cpp +++ b/projects/first_scene/src/main.cpp @@ -51,7 +51,7 @@ int main(int argc, const char** argv) { const vkcv::AttachmentDescription present_color_attachment( vkcv::AttachmentOperation::STORE, vkcv::AttachmentOperation::CLEAR, - core.getSwapchain(windowHandle).getFormat() + core.getSwapchainFormat(window.getSwapchain()) ); const vkcv::AttachmentDescription depth_attachment( diff --git a/projects/first_triangle/src/main.cpp b/projects/first_triangle/src/main.cpp index d98ea8e7..c3824b49 100644 --- a/projects/first_triangle/src/main.cpp +++ b/projects/first_triangle/src/main.cpp @@ -32,7 +32,7 @@ int main(int argc, const char** argv) { const vkcv::AttachmentDescription present_color_attachment( vkcv::AttachmentOperation::STORE, vkcv::AttachmentOperation::CLEAR, - core.getSwapchain(windowHandle).getFormat()); + core.getSwapchainFormat(window.getSwapchain())); vkcv::PassConfig trianglePassDefinition({ present_color_attachment }, vkcv::Multisampling::None); vkcv::PassHandle trianglePass = core.createPass(trianglePassDefinition); diff --git a/projects/head_demo/src/main.cpp b/projects/head_demo/src/main.cpp index 5e3d0abc..fb3170d4 100644 --- a/projects/head_demo/src/main.cpp +++ b/projects/head_demo/src/main.cpp @@ -175,7 +175,7 @@ int main(int argc, const char** argv) { return EXIT_FAILURE; } - auto swapchainExtent = core.getSwapchain(windowHandle).getExtent(); + auto swapchainExtent = core.getSwapchainExtent(window.getSwapchain()); vkcv::ImageHandle depthBuffer = core.createImage( vk::Format::eD32Sfloat, diff --git a/projects/indirect_draw/src/main.cpp b/projects/indirect_draw/src/main.cpp index 6c3c19df..cba4be9a 100644 --- a/projects/indirect_draw/src/main.cpp +++ b/projects/indirect_draw/src/main.cpp @@ -307,6 +307,7 @@ int main(int argc, const char** argv) { ); vkcv::WindowHandle windowHandle = core.createWindow(applicationName,800,600,true); + vkcv::Window& window = core.getWindow(windowHandle); vkcv::gui::GUI gui (core, windowHandle); @@ -330,7 +331,7 @@ int main(int argc, const char** argv) { const vkcv::AttachmentDescription present_color_attachment( vkcv::AttachmentOperation::STORE, vkcv::AttachmentOperation::CLEAR, - core.getSwapchain(windowHandle).getFormat() + core.getSwapchainFormat(window.getSwapchain()) ); const vkcv::AttachmentDescription depth_attachment( vkcv::AttachmentOperation::STORE, @@ -507,7 +508,7 @@ int main(int argc, const char** argv) { return EXIT_FAILURE; } - vkcv::camera::CameraManager cameraManager(core.getWindow(windowHandle)); + vkcv::camera::CameraManager cameraManager (window); uint32_t camIndex0 = cameraManager.addCamera(vkcv::camera::ControllerType::PILOT); cameraManager.getCamera(camIndex0).setPosition(glm::vec3(0, 0, -3)); @@ -532,7 +533,7 @@ int main(int argc, const char** argv) { while (vkcv::Window::hasOpenWindow()) { vkcv::Window::pollEvents(); - if(core.getWindow(windowHandle).getHeight() == 0 || core.getWindow(windowHandle).getWidth() == 0) + if (window.getHeight() == 0 || window.getWidth() == 0) continue; uint32_t swapchainWidth, swapchainHeight; diff --git a/projects/mesh_shader/src/main.cpp b/projects/mesh_shader/src/main.cpp index 287a925f..f369e42d 100644 --- a/projects/mesh_shader/src/main.cpp +++ b/projects/mesh_shader/src/main.cpp @@ -166,7 +166,7 @@ int main(int argc, const char** argv) { const vkcv::AttachmentDescription present_color_attachment( vkcv::AttachmentOperation::STORE, vkcv::AttachmentOperation::CLEAR, - core.getSwapchain(windowHandle).getFormat()); + core.getSwapchainFormat(window.getSwapchain())); const vkcv::AttachmentDescription depth_attachment( vkcv::AttachmentOperation::STORE, diff --git a/projects/particle_simulation/src/main.cpp b/projects/particle_simulation/src/main.cpp index a281c393..764f3c06 100644 --- a/projects/particle_simulation/src/main.cpp +++ b/projects/particle_simulation/src/main.cpp @@ -43,10 +43,7 @@ int main(int argc, const char **argv) { vkcv::PassConfig particlePassDefinition({present_color_attachment}, vkcv::Multisampling::None); vkcv::PassHandle particlePass = core.createPass(particlePassDefinition); - vkcv::PassConfig computePassDefinition({}); - vkcv::PassHandle computePass = core.createPass(computePassDefinition); - - if (!particlePass || !computePass) + if (!particlePass) { std::cout << "Error. Could not create renderpass. Exiting." << std::endl; return EXIT_FAILURE; @@ -214,7 +211,7 @@ int main(int argc, const char **argv) { cameraManager.getCamera(camIndex1).setPosition(glm::vec3(0.0f, 0.0f, -2.0f)); cameraManager.getCamera(camIndex1).setCenter(glm::vec3(0.0f, 0.0f, 0.0f)); - const auto swapchainExtent = core.getSwapchain(windowHandle).getExtent(); + const auto swapchainExtent = core.getSwapchainExtent(window.getSwapchain()); vkcv::ImageHandle colorBuffer = core.createImage( colorFormat, diff --git a/projects/saf_r/src/main.cpp b/projects/saf_r/src/main.cpp index cc6dd0d4..dd20e132 100644 --- a/projects/saf_r/src/main.cpp +++ b/projects/saf_r/src/main.cpp @@ -40,6 +40,7 @@ int main(int argc, const char** argv) { ); vkcv::WindowHandle windowHandle = core.createWindow(applicationName, windowWidth, windowHeight, true); + vkcv::Window& window = core.getWindow(windowHandle); //configuring the compute Shader vkcv::PassConfig computePassDefinition({}); @@ -164,7 +165,7 @@ int main(int argc, const char** argv) { const vkcv::AttachmentDescription present_color_attachment( vkcv::AttachmentOperation::STORE, vkcv::AttachmentOperation::CLEAR, - core.getSwapchain(windowHandle).getFormat()); + core.getSwapchainFormat(window.getSwapchain())); vkcv::PassConfig safrPassDefinition({ present_color_attachment }, vkcv::Multisampling::None); vkcv::PassHandle safrPass = core.createPass(safrPassDefinition); @@ -205,7 +206,7 @@ int main(int argc, const char** argv) { vkcv::DrawcallInfo drawcall(renderMesh, { descriptorUsage }, 1); //create the camera - vkcv::camera::CameraManager cameraManager(core.getWindow(windowHandle)); + vkcv::camera::CameraManager cameraManager(window); uint32_t camIndex0 = cameraManager.addCamera(vkcv::camera::ControllerType::PILOT); uint32_t camIndex1 = cameraManager.addCamera(vkcv::camera::ControllerType::TRACKBALL); diff --git a/projects/sph/src/main.cpp b/projects/sph/src/main.cpp index 02d659eb..6955281c 100644 --- a/projects/sph/src/main.cpp +++ b/projects/sph/src/main.cpp @@ -41,9 +41,6 @@ int main(int argc, const char **argv) { vkcv::PassConfig particlePassDefinition({present_color_attachment}, vkcv::Multisampling::None); vkcv::PassHandle particlePass = core.createPass(particlePassDefinition); - vkcv::PassConfig computePassDefinition({}); - vkcv::PassHandle computePass = core.createPass(computePassDefinition); - //rotation float rotationx = 0; float rotationy = 0; @@ -58,7 +55,7 @@ int main(int argc, const char **argv) { float param_ABSORBTION = 0.5; float param_dt = 0.0005; - if (!particlePass || !computePass) + if (!particlePass) { std::cout << "Error. Could not create renderpass. Exiting." << std::endl; return EXIT_FAILURE; @@ -231,7 +228,7 @@ int main(int argc, const char **argv) { cameraManager.getCamera(camIndex1).setPosition(glm::vec3(0.0f, 0.0f, -2.5f)); cameraManager.getCamera(camIndex1).setCenter(glm::vec3(0.0f, 0.0f, 0.0f)); - const auto swapchainExtent = core.getSwapchain(window.getSwapchainHandle()).getExtent(); + const auto swapchainExtent = core.getSwapchainExtent(window.getSwapchain()); vkcv::ImageHandle colorBuffer = core.createImage( colorFormat, diff --git a/projects/voxelization/src/main.cpp b/projects/voxelization/src/main.cpp index 995045d2..821cc1c2 100644 --- a/projects/voxelization/src/main.cpp +++ b/projects/voxelization/src/main.cpp @@ -333,7 +333,7 @@ int main(int argc, const char** argv) { vkcv::DescriptorSetLayoutHandle prepassDescriptorSetLayout = core.createDescriptorSetLayout({}); vkcv::DescriptorSetHandle prepassDescriptorSet = core.createDescriptorSet(prepassDescriptorSetLayout); - auto swapchainExtent = core.getSwapchain(windowHandle).getExtent(); + auto swapchainExtent = core.getSwapchainExtent(window.getSwapchain()); vkcv::GraphicsPipelineConfig prepassPipelineConfig ( depthPrepassShader, diff --git a/projects/wobble_bobble/src/main.cpp b/projects/wobble_bobble/src/main.cpp index 7a567c40..24c203f7 100644 --- a/projects/wobble_bobble/src/main.cpp +++ b/projects/wobble_bobble/src/main.cpp @@ -303,7 +303,7 @@ int main(int argc, const char **argv) { cameraManager.getCamera(trackballIdx).setCenter(glm::vec3(0.5f, 0.5f, 0.5f)); // set camera to look at the center of the particle volume cameraManager.addCamera(vkcv::camera::ControllerType::PILOT); - auto swapchainExtent = core.getSwapchain(windowHandle).getExtent(); + auto swapchainExtent = core.getSwapchainExtent(window.getSwapchain()); vkcv::ImageHandle depthBuffer = core.createImage( vk::Format::eD32Sfloat, @@ -458,7 +458,7 @@ int main(int argc, const char **argv) { vkcv::AttachmentDescription( vkcv::AttachmentOperation::STORE, vkcv::AttachmentOperation::CLEAR, - core.getSwapchain(windowHandle).getFormat() + core.getSwapchainFormat(window.getSwapchain()) ), vkcv::AttachmentDescription( vkcv::AttachmentOperation::STORE, @@ -471,7 +471,7 @@ int main(int argc, const char **argv) { vkcv::AttachmentDescription( vkcv::AttachmentOperation::STORE, vkcv::AttachmentOperation::CLEAR, - core.getSwapchain(windowHandle).getFormat() + core.getSwapchainFormat(window.getSwapchain()) ), vkcv::AttachmentDescription( vkcv::AttachmentOperation::STORE, @@ -484,7 +484,7 @@ int main(int argc, const char **argv) { vkcv::AttachmentDescription( vkcv::AttachmentOperation::STORE, vkcv::AttachmentOperation::LOAD, - core.getSwapchain(windowHandle).getFormat() + core.getSwapchainFormat(window.getSwapchain()) ), vkcv::AttachmentDescription( vkcv::AttachmentOperation::STORE, diff --git a/src/vkcv/Core.cpp b/src/vkcv/Core.cpp index d54e5c85..edccae45 100644 --- a/src/vkcv/Core.cpp +++ b/src/vkcv/Core.cpp @@ -73,9 +73,9 @@ namespace vkcv m_DescriptorSetManager->init(*this, *m_DescriptorSetLayoutManager); m_BufferManager->init(*this); m_SamplerManager->init(*this); - m_CommandStreamManager->init(*this); - m_SwapchainManager->m_context = &m_Context; m_ImageManager->init(*this, *m_BufferManager); + m_CommandStreamManager->init(*this); + m_SwapchainManager->init(*this); m_downsampler = std::unique_ptr<Downsampler>(new BlitDownsampler(*this, *m_ImageManager)); } @@ -172,7 +172,7 @@ namespace vkcv try { result = m_Context.getDevice().acquireNextImageKHR( - m_SwapchainManager->getSwapchain(swapchainHandle).getSwapchain(), + m_SwapchainManager->getSwapchain(swapchainHandle).m_Swapchain, std::numeric_limits<uint64_t>::max(), m_SyncResources.swapchainImageAcquired, nullptr, @@ -191,7 +191,7 @@ namespace vkcv } else if (result == vk::Result::eSuboptimalKHR) { vkcv_log(LogLevel::WARNING, "Acquired image is suboptimal"); - m_SwapchainManager->getSwapchain(swapchainHandle).signalSwapchainRecreation(); + m_SwapchainManager->signalRecreation(swapchainHandle); } m_currentSwapchainImageIndex = imageIndex; @@ -199,21 +199,22 @@ namespace vkcv } bool Core::beginFrame(uint32_t& width, uint32_t& height, const WindowHandle &windowHandle) { - const SwapchainHandle swapchainHandle = m_WindowManager->getWindow(windowHandle).getSwapchainHandle(); + const Window& window = m_WindowManager->getWindow(windowHandle); + const SwapchainHandle swapchainHandle = window.getSwapchain(); - if (m_SwapchainManager->getSwapchain(swapchainHandle).shouldUpdateSwapchain()) { + if (m_SwapchainManager->shouldUpdateSwapchain(swapchainHandle)) { m_Context.getDevice().waitIdle(); - m_SwapchainManager->getSwapchain(swapchainHandle).updateSwapchain(m_Context, m_WindowManager->getWindow(windowHandle)); + m_SwapchainManager->updateSwapchain(swapchainHandle, window); - if (!m_SwapchainManager->getSwapchain(swapchainHandle).getSwapchain()) { + if (!m_SwapchainManager->getSwapchain(swapchainHandle).m_Swapchain) { return false; } setSwapchainImages(swapchainHandle); } - const auto& extent = m_SwapchainManager->getSwapchain(swapchainHandle).getExtent(); + const auto& extent = m_SwapchainManager->getExtent(swapchainHandle); width = extent.width; height = extent.height; @@ -235,21 +236,18 @@ namespace vkcv return (m_currentSwapchainImageIndex != std::numeric_limits<uint32_t>::max()); } - std::array<uint32_t, 2> getWidthHeightFromRenderTargets( - const std::vector<ImageHandle>& renderTargets, - const Swapchain& swapchain, - const ImageManager& imageManager) { + static std::array<uint32_t, 2> getWidthHeightFromRenderTargets(const std::vector<ImageHandle>& renderTargets, + const vk::Extent2D& swapchainExtent, + const ImageManager& imageManager) { std::array<uint32_t, 2> widthHeight; if (renderTargets.size() > 0) { const vkcv::ImageHandle firstImage = renderTargets[0]; if (firstImage.isSwapchainImage()) { - const auto& swapchainExtent = swapchain.getExtent(); widthHeight[0] = swapchainExtent.width; widthHeight[1] = swapchainExtent.height; - } - else { + } else { widthHeight[0] = imageManager.getImageWidth(firstImage); widthHeight[1] = imageManager.getImageHeight(firstImage); } @@ -262,27 +260,24 @@ namespace vkcv return widthHeight; } - vk::Framebuffer createFramebuffer( - const std::vector<ImageHandle>& renderTargets, - const ImageManager& imageManager, - const Swapchain& swapchain, - vk::RenderPass renderpass, - vk::Device device) { + static vk::Framebuffer createFramebuffer(const std::vector<ImageHandle>& renderTargets, + const ImageManager& imageManager, + const vk::Extent2D& renderExtent, + vk::RenderPass renderpass, + vk::Device device) { std::vector<vk::ImageView> attachmentsViews; for (const ImageHandle& handle : renderTargets) { attachmentsViews.push_back(imageManager.getVulkanImageView(handle)); } - const std::array<uint32_t, 2> widthHeight = getWidthHeightFromRenderTargets(renderTargets, swapchain, imageManager); - const vk::FramebufferCreateInfo createInfo( {}, renderpass, static_cast<uint32_t>(attachmentsViews.size()), attachmentsViews.data(), - widthHeight[0], - widthHeight[1], + renderExtent.width, + renderExtent.height, 1); return device.createFramebuffer(createInfo); @@ -397,13 +392,18 @@ namespace vkcv const std::vector<ImageHandle> &renderTargets, const WindowHandle &windowHandle) { - SwapchainHandle swapchainHandle = m_WindowManager->getWindow(windowHandle).getSwapchainHandle(); + SwapchainHandle swapchainHandle = m_WindowManager->getWindow(windowHandle).getSwapchain(); if (m_currentSwapchainImageIndex == std::numeric_limits<uint32_t>::max()) { return; } - const std::array<uint32_t, 2> widthHeight = getWidthHeightFromRenderTargets(renderTargets, m_SwapchainManager->getSwapchain(swapchainHandle), *m_ImageManager); + const std::array<uint32_t, 2> widthHeight = getWidthHeightFromRenderTargets( + renderTargets, + m_SwapchainManager->getExtent(swapchainHandle), + *m_ImageManager + ); + const auto width = widthHeight[0]; const auto height = widthHeight[1]; @@ -412,12 +412,18 @@ namespace vkcv const vk::Pipeline pipeline = m_GraphicsPipelineManager->getVkPipeline(pipelineHandle); const vk::PipelineLayout pipelineLayout = m_GraphicsPipelineManager->getVkPipelineLayout(pipelineHandle); - const vk::Rect2D renderArea(vk::Offset2D(0, 0), vk::Extent2D(width, height)); + const vk::Rect2D renderArea (vk::Offset2D(0, 0), vk::Extent2D(width, height)); vk::CommandBuffer cmdBuffer = m_CommandStreamManager->getStreamCommandBuffer(cmdStreamHandle); transitionRendertargetsToAttachmentLayout(renderTargets, *m_ImageManager, cmdBuffer); - const vk::Framebuffer framebuffer = createFramebuffer(renderTargets, *m_ImageManager, m_SwapchainManager->getSwapchain(swapchainHandle), renderpass, m_Context.m_Device); + const vk::Framebuffer framebuffer = createFramebuffer( + renderTargets, + *m_ImageManager, + renderArea.extent, + renderpass, + m_Context.m_Device + ); if (!framebuffer) { vkcv_log(LogLevel::ERROR, "Failed to create temporary framebuffer"); @@ -471,9 +477,11 @@ namespace vkcv if (m_currentSwapchainImageIndex == std::numeric_limits<uint32_t>::max()) { return; } - SwapchainHandle swapchainHandle = m_WindowManager->getWindow(windowHandle).getSwapchainHandle(); - const std::array<uint32_t, 2> widthHeight = getWidthHeightFromRenderTargets(renderTargets, m_SwapchainManager->getSwapchain(swapchainHandle), - *m_ImageManager); + SwapchainHandle swapchainHandle = m_WindowManager->getWindow(windowHandle).getSwapchain(); + const std::array<uint32_t, 2> widthHeight = getWidthHeightFromRenderTargets( + renderTargets, + m_SwapchainManager->getExtent(swapchainHandle), + *m_ImageManager); const auto width = widthHeight[0]; const auto height = widthHeight[1]; @@ -482,13 +490,18 @@ namespace vkcv const vk::Pipeline pipeline = m_GraphicsPipelineManager->getVkPipeline(pipelineHandle); const vk::PipelineLayout pipelineLayout = m_GraphicsPipelineManager->getVkPipelineLayout(pipelineHandle); - const vk::Rect2D renderArea(vk::Offset2D(0, 0), vk::Extent2D(width, height)); + const vk::Rect2D renderArea (vk::Offset2D(0, 0), vk::Extent2D(width, height)); vk::CommandBuffer cmdBuffer = m_CommandStreamManager->getStreamCommandBuffer(cmdStreamHandle); transitionRendertargetsToAttachmentLayout(renderTargets, *m_ImageManager, cmdBuffer); - const vk::Framebuffer framebuffer = createFramebuffer(renderTargets, *m_ImageManager, m_SwapchainManager->getSwapchain(swapchainHandle), renderpass, - m_Context.m_Device); + const vk::Framebuffer framebuffer = createFramebuffer( + renderTargets, + *m_ImageManager, + renderArea.extent, + renderpass, + m_Context.m_Device + ); if (!framebuffer) { vkcv_log(LogLevel::ERROR, "Failed to create temporary framebuffer"); @@ -603,13 +616,16 @@ namespace vkcv const std::vector<ImageHandle>& renderTargets, const WindowHandle& windowHandle) { - SwapchainHandle swapchainHandle = m_WindowManager->getWindow(windowHandle).getSwapchainHandle(); + SwapchainHandle swapchainHandle = m_WindowManager->getWindow(windowHandle).getSwapchain(); if (m_currentSwapchainImageIndex == std::numeric_limits<uint32_t>::max()) { return; } - const std::array<uint32_t, 2> widthHeight = getWidthHeightFromRenderTargets(renderTargets, m_SwapchainManager->getSwapchain(swapchainHandle), *m_ImageManager); + const std::array<uint32_t, 2> widthHeight = getWidthHeightFromRenderTargets( + renderTargets, + m_SwapchainManager->getExtent(swapchainHandle), + *m_ImageManager); const auto width = widthHeight[0]; const auto height = widthHeight[1]; @@ -618,12 +634,18 @@ namespace vkcv const vk::Pipeline pipeline = m_GraphicsPipelineManager->getVkPipeline(pipelineHandle); const vk::PipelineLayout pipelineLayout = m_GraphicsPipelineManager->getVkPipelineLayout(pipelineHandle); - const vk::Rect2D renderArea(vk::Offset2D(0, 0), vk::Extent2D(width, height)); + const vk::Rect2D renderArea (vk::Offset2D(0, 0), vk::Extent2D(width, height)); vk::CommandBuffer cmdBuffer = m_CommandStreamManager->getStreamCommandBuffer(cmdStreamHandle); transitionRendertargetsToAttachmentLayout(renderTargets, *m_ImageManager, cmdBuffer); - const vk::Framebuffer framebuffer = createFramebuffer(renderTargets, *m_ImageManager, m_SwapchainManager->getSwapchain(swapchainHandle), renderpass, m_Context.m_Device); + const vk::Framebuffer framebuffer = createFramebuffer( + renderTargets, + *m_ImageManager, + renderArea.extent, + renderpass, + m_Context.m_Device + ); if (!framebuffer) { vkcv_log(LogLevel::ERROR, "Failed to create temporary framebuffer"); @@ -830,8 +852,7 @@ namespace vkcv } void Core::endFrame(const WindowHandle& windowHandle) { - - SwapchainHandle swapchainHandle = m_WindowManager->getWindow(windowHandle).getSwapchainHandle(); + SwapchainHandle swapchainHandle = m_WindowManager->getWindow(windowHandle).getSwapchain(); if (m_currentSwapchainImageIndex == std::numeric_limits<uint32_t>::max()) { return; @@ -842,7 +863,7 @@ namespace vkcv m_SyncResources.swapchainImageAcquired }; - const vk::SwapchainKHR& swapchain = m_SwapchainManager->getSwapchain(swapchainHandle).getSwapchain(); + const vk::SwapchainKHR& swapchain = m_SwapchainManager->getSwapchain(swapchainHandle).m_Swapchain; const vk::PresentInfoKHR presentInfo( waitSemaphores, swapchain, @@ -852,7 +873,7 @@ namespace vkcv vk::Result result; try { - result = m_Context.getDevice().getQueue(m_SwapchainManager->getSwapchain(swapchainHandle).getPresentQueueIndex(),0).presentKHR(presentInfo); + result = m_Context.getDevice().getQueue(m_SwapchainManager->getPresentQueueIndex(swapchainHandle),0).presentKHR(presentInfo); } catch (const vk::OutOfDateKHRError& e) { result = vk::Result::eErrorOutOfDateKHR; } catch (const vk::DeviceLostError& e) { @@ -970,14 +991,13 @@ namespace vkcv return *m_downsampler; } - WindowHandle Core::createWindow( - const char *applicationName, - uint32_t windowWidth, - uint32_t windowHeight, - bool resizeable) { + WindowHandle Core::createWindow(const char *applicationName, + uint32_t windowWidth, + uint32_t windowHeight, + bool resizeable) { WindowHandle windowHandle = m_WindowManager->createWindow(*m_SwapchainManager ,applicationName, windowWidth, windowHeight, resizeable); - SwapchainHandle swapchainHandle = m_WindowManager->getWindow(windowHandle).getSwapchainHandle(); + SwapchainHandle swapchainHandle = m_WindowManager->getWindow(windowHandle).getSwapchain(); setSwapchainImages( swapchainHandle ); return windowHandle; } @@ -985,7 +1005,19 @@ namespace vkcv Window& Core::getWindow(const WindowHandle& handle) { return m_WindowManager->getWindow(handle); } - + + vk::Format Core::getSwapchainFormat(const SwapchainHandle &swapchain) const { + return m_SwapchainManager->getFormat(swapchain); + } + + uint32_t Core::getSwapchainImageCount(const SwapchainHandle &swapchain) const { + return m_SwapchainManager->getImageCount(swapchain); + } + + vk::Extent2D Core::getSwapchainExtent(const SwapchainHandle& swapchain) const { + return m_SwapchainManager->getExtent(swapchain); + } + uint32_t Core::getImageWidth(const ImageHandle& image) { return m_ImageManager->getImageWidth(image); @@ -1017,19 +1049,6 @@ namespace vkcv return m_ImageManager->getImageArrayLayers(image); } - Swapchain& Core::getSwapchainOfCurrentWindow() { - return m_SwapchainManager->getSwapchain(Window::getFocusedWindow().getSwapchainHandle()); - } - - Swapchain& Core::getSwapchain(const SwapchainHandle& handle) { - return m_SwapchainManager->getSwapchain(handle); - } - - Swapchain& Core::getSwapchain(const WindowHandle& handle) { - SwapchainHandle swapchainHandle = m_WindowManager->getWindow(handle).getSwapchainHandle(); - return getSwapchain(swapchainHandle); - } - DescriptorSetLayoutHandle Core::createDescriptorSetLayout(const DescriptorBindings &bindings) { return m_DescriptorSetLayoutManager->createDescriptorSetLayout(bindings); } @@ -1202,16 +1221,16 @@ namespace vkcv } void Core::setSwapchainImages( SwapchainHandle handle ) { - Swapchain swapchain = m_SwapchainManager->getSwapchain(handle); + const auto& swapchain = m_SwapchainManager->getSwapchain(handle); const auto swapchainImages = m_SwapchainManager->getSwapchainImages(handle); const auto swapchainImageViews = m_SwapchainManager->createSwapchainImageViews(handle); m_ImageManager->setSwapchainImages( swapchainImages, swapchainImageViews, - swapchain.getExtent().width, - swapchain.getExtent().height, - swapchain.getFormat() + swapchain.m_Extent.width, + swapchain.m_Extent.height, + swapchain.m_Format ); } diff --git a/src/vkcv/QueueManager.cpp b/src/vkcv/QueueManager.cpp index d2a4d593..c818769e 100644 --- a/src/vkcv/QueueManager.cpp +++ b/src/vkcv/QueueManager.cpp @@ -5,7 +5,6 @@ #include "vkcv/QueueManager.hpp" #include "vkcv/Logger.hpp" -#include "vkcv/Swapchain.hpp" namespace vkcv { diff --git a/src/vkcv/Surface.cpp b/src/vkcv/Surface.cpp deleted file mode 100644 index 3fa601b7..00000000 --- a/src/vkcv/Surface.cpp +++ /dev/null @@ -1,258 +0,0 @@ - -#include <vkcv/Surface.hpp> -#include <vkcv/Logger.hpp> - -#include <GLFW/glfw3.h> - -namespace vkcv { - - /** - * @brief Creates vulkan surface and checks availability. - * - * @param[in,out] window Current window for the surface - * @param[in,out] instance Vulkan-Instance - * @param[in,out] physicalDevice Vulkan-PhysicalDevice - * @param[out] surface Vulkan-Surface - * @return Created vulkan surface - */ - bool createVulkanSurface(GLFWwindow* window, - const vk::Instance& instance, - const vk::PhysicalDevice& physicalDevice, - vk::SurfaceKHR& surface) { - VkSurfaceKHR api_surface; - - if (glfwCreateWindowSurface(VkInstance(instance), window, nullptr, &api_surface) != VK_SUCCESS) { - vkcv_log(LogLevel::ERROR, "Failed to create a window surface"); - return false; - } - - vk::Bool32 surfaceSupport = false; - surface = vk::SurfaceKHR(api_surface); - - if ((physicalDevice.getSurfaceSupportKHR(0, surface, &surfaceSupport) != vk::Result::eSuccess) || - (!surfaceSupport)) { - vkcv_log(LogLevel::ERROR, "Surface is not supported by the device"); - instance.destroy(surface); - surface = nullptr; - return false; - } - - return true; - } - - /** - * @brief Chooses an Extent and clamps values to the available capabilities. - * - * @param physicalDevice Vulkan-PhysicalDevice - * @param surface Vulkan-Surface of the swapchain - * @param window Window of the current application - * @return Chosen Extent for the surface - */ - vk::Extent2D chooseExtent(vk::PhysicalDevice physicalDevice, vk::SurfaceKHR surface, const Window &window) { - int fb_width, fb_height; - window.getFramebufferSize(fb_width, fb_height); - - VkExtent2D extent2D = { - static_cast<uint32_t>(fb_width), - static_cast<uint32_t>(fb_height) - }; - - vk::SurfaceCapabilitiesKHR surfaceCapabilities; - if(physicalDevice.getSurfaceCapabilitiesKHR(surface, &surfaceCapabilities) != vk::Result::eSuccess) { - vkcv_log(LogLevel::WARNING, "The capabilities of the surface can not be retrieved"); - - extent2D.width = std::max(MIN_SURFACE_SIZE, extent2D.width); - extent2D.height = std::max(MIN_SURFACE_SIZE, extent2D.height); - } else { - extent2D.width = std::max(surfaceCapabilities.minImageExtent.width, std::min(surfaceCapabilities.maxImageExtent.width, extent2D.width)); - extent2D.height = std::max(surfaceCapabilities.minImageExtent.height, std::min(surfaceCapabilities.maxImageExtent.height, extent2D.height)); - } - - return extent2D; - } - - /** - * @brief Chooses Surface Format for the current surface - * - * @param physicalDevice Vulkan-PhysicalDevice - * @param surface Vulkan-Surface of the swapchain - * @return Available Format - */ - vk::SurfaceFormatKHR chooseSurfaceFormat(vk::PhysicalDevice physicalDevice, vk::SurfaceKHR surface) { - std::vector<vk::SurfaceFormatKHR> availableFormats = physicalDevice.getSurfaceFormatsKHR(surface); - - for (const auto& availableFormat : availableFormats) { - if (availableFormat.format == vk::Format::eB8G8R8A8Unorm && availableFormat.colorSpace == vk::ColorSpaceKHR::eSrgbNonlinear) { - return availableFormat; - } - } - - return availableFormats[0]; - } - - /** - * @brief Returns vk::PresentModeKHR::eMailbox if available or - * vk::PresentModeKHR::eFifo otherwise - * - * @param physicalDevice Vulkan-PhysicalDevice - * @param surface Vulkan-Surface of the swapchain - * @return Available PresentationMode - */ - vk::PresentModeKHR choosePresentMode(vk::PhysicalDevice physicalDevice, vk::SurfaceKHR surface) { - std::vector<vk::PresentModeKHR> availablePresentModes = physicalDevice.getSurfacePresentModesKHR(surface); - - for (const auto& availablePresentMode : availablePresentModes) { - if (availablePresentMode == vk::PresentModeKHR::eMailbox) { - return availablePresentMode; - } - } - // The FIFO present mode is guaranteed by the spec to be supported - return vk::PresentModeKHR::eFifo; - } - - /** - * @brief Returns the minImageCount +1 for at least double buffering, - * if it's greater than maxImageCount return maxImageCount - * - * @param physicalDevice Vulkan-PhysicalDevice - * @param surface Vulkan-Surface of the swapchain - * @return Available image count - */ - uint32_t chooseImageCount(vk::PhysicalDevice physicalDevice, vk::SurfaceKHR surface) { - vk::SurfaceCapabilitiesKHR surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR(surface); - - // minImageCount should always be at least 2; set to 3 for triple buffering - uint32_t imageCount = surfaceCapabilities.minImageCount + 1; - - // check if requested image count is supported - if (surfaceCapabilities.maxImageCount > 0 && imageCount > surfaceCapabilities.maxImageCount) { - imageCount = surfaceCapabilities.maxImageCount; - } - - return imageCount; - } - - Surface::Surface(const Context &context, - const vk::SurfaceKHR &handle, - uint32_t presentQueueIndex, - const vk::Extent2D &extent, - vk::Format format, - vk::ColorSpaceKHR colorSpace) - : m_Context(&context), - m_Handle(handle), - m_PresentQueueIndex(presentQueueIndex), - m_Extent(extent), - m_Format(format), - m_ColorSpace(colorSpace) { - } - - vk::SwapchainKHR Surface::createVulkanSwapchain(const Window &window, - const vk::SwapchainKHR &oldSwapchain) { - if ((!m_Context) || (!m_Handle)) - return nullptr; - - const vk::PhysicalDevice& physicalDevice = m_Context->getPhysicalDevice(); - const vk::Device& device = m_Context->getDevice(); - - m_Extent = chooseExtent(physicalDevice, m_Handle, window); - - if ((m_Extent.width < MIN_SURFACE_SIZE) || (m_Extent.height < MIN_SURFACE_SIZE)) { - return nullptr; - } - - vk::SurfaceFormatKHR chosenSurfaceFormat = chooseSurfaceFormat(physicalDevice, m_Handle); - vk::PresentModeKHR chosenPresentMode = choosePresentMode(physicalDevice, m_Handle); - uint32_t chosenImageCount = chooseImageCount(physicalDevice, m_Handle); - - m_Format = chosenSurfaceFormat.format; - m_ColorSpace = chosenSurfaceFormat.colorSpace; - - vk::SwapchainCreateInfoKHR swapchainCreateInfo ( - vk::SwapchainCreateFlagsKHR(), - m_Handle, - chosenImageCount, - m_Format, - m_ColorSpace, - m_Extent, - 1, - vk::ImageUsageFlagBits::eColorAttachment | vk::ImageUsageFlagBits::eStorage, - vk::SharingMode::eExclusive, - 0, - nullptr, - vk::SurfaceTransformFlagBitsKHR::eIdentity, - vk::CompositeAlphaFlagBitsKHR::eOpaque, - chosenPresentMode, - true, - oldSwapchain - ); - - return device.createSwapchainKHR(swapchainCreateInfo); - } - - Surface::Surface(Surface &&other) noexcept - : m_Context(other.m_Context), - m_Handle(other.m_Handle), - m_PresentQueueIndex(other.m_PresentQueueIndex), - m_Extent(other.m_Extent), - m_Format(other.m_Format), - m_ColorSpace(other.m_ColorSpace) { - other.m_Context = nullptr; - other.m_Handle = nullptr; - } - - Surface &Surface::operator=(Surface &&other) noexcept { - m_Context = other.m_Context; - m_Handle = other.m_Handle; - m_PresentQueueIndex = other.m_PresentQueueIndex; - m_Extent = other.m_Extent; - m_Format = other.m_Format; - m_ColorSpace = other.m_ColorSpace; - - other.m_Context = nullptr; - other.m_Handle = nullptr; - return *this; - } - - Surface::~Surface() { - // needs to be destroyed by creator - } - - Surface Surface::create(const Window &window, const Context &context) { - const vk::Instance& instance = context.getInstance(); - const vk::PhysicalDevice& physicalDevice = context.getPhysicalDevice(); - - uint32_t presentQueueIndex = 0; - - vk::SurfaceKHR surfaceHandle; - if (!createVulkanSurface(window.getWindow(), instance, physicalDevice, surfaceHandle)) - surfaceHandle = nullptr; - else - presentQueueIndex = QueueManager::checkSurfaceSupport(physicalDevice, surfaceHandle); - - const vk::Extent2D extent = chooseExtent(physicalDevice, surfaceHandle, window); - const vk::SurfaceFormatKHR format = chooseSurfaceFormat(physicalDevice, surfaceHandle); - - return { context, surfaceHandle, presentQueueIndex, extent, format.format, format.colorSpace }; - } - - vk::SurfaceKHR Surface::getSurface() const { - return m_Handle; - } - - uint32_t Surface::getPresentQueueIndex() const { - return m_PresentQueueIndex; - } - - const vk::Extent2D& Surface::getExtent() const { - return m_Extent; - } - - vk::Format Surface::getFormat() const { - return m_Format; - } - - vk::ColorSpaceKHR Surface::getColorSpace() const { - return m_ColorSpace; - } - -} diff --git a/src/vkcv/Swapchain.cpp b/src/vkcv/Swapchain.cpp deleted file mode 100644 index 2ca69e7d..00000000 --- a/src/vkcv/Swapchain.cpp +++ /dev/null @@ -1,96 +0,0 @@ -#include <vkcv/Swapchain.hpp> -#include <utility> - -#include <GLFW/glfw3.h> - -namespace vkcv -{ - - Swapchain::Swapchain(const Context &context, - const Surface &surface, - vk::SwapchainKHR swapchain) noexcept - : m_Context(&context), - m_Surface(surface), - m_Swapchain(swapchain), - m_RecreationRequired(false) { - } - - Swapchain::Swapchain(const Swapchain &other) : - m_Context(other.m_Context), - m_Surface(other.m_Surface), - m_Swapchain(other.m_Swapchain), - m_RecreationRequired(other.m_RecreationRequired.load()) { - } - - const vk::SwapchainKHR& Swapchain::getSwapchain() const { - return m_Swapchain; - } - - const Surface& Swapchain::getSurface() const { - return m_Surface; - } - - vk::Format Swapchain::getFormat() const{ - return m_Surface.getFormat(); - } - - Swapchain Swapchain::create(const Window &window, const Context &context) { - Surface surface = Surface::create(window, context); - - vk::SwapchainKHR swapchain = surface.createVulkanSwapchain( - window, nullptr - ); - - return { context, surface, swapchain }; - } - - bool Swapchain::shouldUpdateSwapchain() const { - return m_RecreationRequired; - } - - void Swapchain::updateSwapchain(const Context &context, const Window &window) { - if (!m_RecreationRequired.exchange(false)) { - return; - } - - vk::SwapchainKHR oldSwapchain = m_Swapchain; - - m_Swapchain = m_Surface.createVulkanSwapchain( - window, oldSwapchain - ); - - if (!m_Swapchain) { - signalSwapchainRecreation(); - } - - if (oldSwapchain) { - context.getDevice().destroySwapchainKHR(oldSwapchain); - } - } - - void Swapchain::signalSwapchainRecreation() { - m_RecreationRequired = true; - } - - const vk::Extent2D& Swapchain::getExtent() const { - return m_Surface.getExtent(); - } - - Swapchain::~Swapchain() { - // needs to be destroyed by creator - } - - uint32_t Swapchain::getImageCount() const { - uint32_t imageCount = 0; - - if (vk::Result::eSuccess != m_Context->getDevice().getSwapchainImagesKHR(m_Swapchain, &imageCount, nullptr)) - return 0; - else - return imageCount; - } - - uint32_t Swapchain::getPresentQueueIndex() const { - return m_Surface.getPresentQueueIndex(); - } - -} diff --git a/src/vkcv/SwapchainManager.cpp b/src/vkcv/SwapchainManager.cpp index 369e077a..f16a4c30 100644 --- a/src/vkcv/SwapchainManager.cpp +++ b/src/vkcv/SwapchainManager.cpp @@ -1,62 +1,309 @@ #include "SwapchainManager.hpp" -namespace vkcv { +#include <GLFW/glfw3.h> + +#include "vkcv/Core.hpp" - SwapchainManager::SwapchainManager() noexcept { +namespace vkcv { + + uint64_t SwapchainManager::getIdFrom(const SwapchainHandle &handle) const { + return handle.getId(); + } + + SwapchainHandle SwapchainManager::createById(uint64_t id, const HandleDestroyFunction &destroy) { + return SwapchainHandle(id, destroy); + } + + void SwapchainManager::destroyById(uint64_t id) { + auto& swapchain = getById(id); + + if (swapchain.m_Swapchain) { + getCore().getContext().getDevice().destroySwapchainKHR(swapchain.m_Swapchain); + swapchain.m_Swapchain = nullptr; + } + + if (swapchain.m_Surface) { + getCore().getContext().getInstance().destroySurfaceKHR(swapchain.m_Surface); + swapchain.m_Surface = nullptr; + } } + + SwapchainManager::SwapchainManager() noexcept : HandleManager<SwapchainEntry, SwapchainHandle>() {} SwapchainManager::~SwapchainManager() noexcept { - for (uint64_t id = 0; id < m_swapchains.size(); id++) { - destroySwapchainById(id); + clear(); + } + + /** + * @brief Creates vulkan surface and checks availability. + * + * @param[in,out] window Current window for the surface + * @param[in,out] instance Vulkan-Instance + * @param[in,out] physicalDevice Vulkan-PhysicalDevice + * @param[out] surface Vulkan-Surface + * @return Created vulkan surface + */ + static bool createVulkanSurface(GLFWwindow* window, + const vk::Instance& instance, + const vk::PhysicalDevice& physicalDevice, + vk::SurfaceKHR& surface) { + VkSurfaceKHR api_surface; + + if (glfwCreateWindowSurface(VkInstance(instance), window, nullptr, &api_surface) != VK_SUCCESS) { + vkcv_log(LogLevel::ERROR, "Failed to create a window surface"); + return false; + } + + vk::Bool32 surfaceSupport = false; + surface = vk::SurfaceKHR(api_surface); + + if ((physicalDevice.getSurfaceSupportKHR(0, surface, &surfaceSupport) != vk::Result::eSuccess) || + (!surfaceSupport)) { + vkcv_log(LogLevel::ERROR, "Surface is not supported by the device"); + instance.destroy(surface); + surface = nullptr; + return false; + } + + return true; + } + + /** + * @brief Chooses an Extent and clamps values to the available capabilities. + * + * @param physicalDevice Vulkan-PhysicalDevice + * @param surface Vulkan-Surface of the swapchain + * @param window Window of the current application + * @return Chosen Extent for the surface + */ + static vk::Extent2D chooseExtent(vk::PhysicalDevice physicalDevice, vk::SurfaceKHR surface, const Window &window) { + int fb_width, fb_height; + window.getFramebufferSize(fb_width, fb_height); + + VkExtent2D extent2D = { + static_cast<uint32_t>(fb_width), + static_cast<uint32_t>(fb_height) + }; + + vk::SurfaceCapabilitiesKHR surfaceCapabilities; + if(physicalDevice.getSurfaceCapabilitiesKHR(surface, &surfaceCapabilities) != vk::Result::eSuccess) { + vkcv_log(LogLevel::WARNING, "The capabilities of the surface can not be retrieved"); + + extent2D.width = std::max(MIN_SURFACE_SIZE, extent2D.width); + extent2D.height = std::max(MIN_SURFACE_SIZE, extent2D.height); + } else { + extent2D.width = std::max(surfaceCapabilities.minImageExtent.width, std::min(surfaceCapabilities.maxImageExtent.width, extent2D.width)); + extent2D.height = std::max(surfaceCapabilities.minImageExtent.height, std::min(surfaceCapabilities.maxImageExtent.height, extent2D.height)); + } + + return extent2D; + } + + /** + * @brief Chooses Surface Format for the current surface + * + * @param physicalDevice Vulkan-PhysicalDevice + * @param surface Vulkan-Surface of the swapchain + * @return Available Format + */ + static vk::SurfaceFormatKHR chooseSurfaceFormat(vk::PhysicalDevice physicalDevice, vk::SurfaceKHR surface) { + std::vector<vk::SurfaceFormatKHR> availableFormats = physicalDevice.getSurfaceFormatsKHR(surface); + + for (const auto& availableFormat : availableFormats) { + if (availableFormat.format == vk::Format::eB8G8R8A8Unorm && availableFormat.colorSpace == vk::ColorSpaceKHR::eSrgbNonlinear) { + return availableFormat; + } + } + + return availableFormats[0]; + } + + /** + * @brief Returns vk::PresentModeKHR::eMailbox if available or + * vk::PresentModeKHR::eFifo otherwise + * + * @param physicalDevice Vulkan-PhysicalDevice + * @param surface Vulkan-Surface of the swapchain + * @return Available PresentationMode + */ + static vk::PresentModeKHR choosePresentMode(vk::PhysicalDevice physicalDevice, vk::SurfaceKHR surface) { + std::vector<vk::PresentModeKHR> availablePresentModes = physicalDevice.getSurfacePresentModesKHR(surface); + + for (const auto& availablePresentMode : availablePresentModes) { + if (availablePresentMode == vk::PresentModeKHR::eMailbox) { + return availablePresentMode; + } } - m_swapchains.clear(); + // The FIFO present mode is guaranteed by the spec to be supported + return vk::PresentModeKHR::eFifo; + } + + /** + * @brief Returns the minImageCount +1 for at least double buffering, + * if it's greater than maxImageCount return maxImageCount + * + * @param physicalDevice Vulkan-PhysicalDevice + * @param surface Vulkan-Surface of the swapchain + * @return Available image count + */ + static uint32_t chooseImageCount(vk::PhysicalDevice physicalDevice, vk::SurfaceKHR surface) { + vk::SurfaceCapabilitiesKHR surfaceCapabilities = physicalDevice.getSurfaceCapabilitiesKHR(surface); + + // minImageCount should always be at least 2; set to 3 for triple buffering + uint32_t imageCount = surfaceCapabilities.minImageCount + 1; + + // check if requested image count is supported + if (surfaceCapabilities.maxImageCount > 0 && imageCount > surfaceCapabilities.maxImageCount) { + imageCount = surfaceCapabilities.maxImageCount; + } + + return imageCount; + } + + static bool createVulkanSwapchain(const Context& context, + const Window &window, + SwapchainEntry& entry) { + const vk::PhysicalDevice& physicalDevice = context.getPhysicalDevice(); + const vk::Device& device = context.getDevice(); + + entry.m_Extent = chooseExtent(physicalDevice, entry.m_Surface, window); + + if ((entry.m_Extent.width < MIN_SURFACE_SIZE) || (entry.m_Extent.height < MIN_SURFACE_SIZE)) { + return false; + } + + vk::SurfaceFormatKHR chosenSurfaceFormat = chooseSurfaceFormat(physicalDevice, entry.m_Surface); + vk::PresentModeKHR chosenPresentMode = choosePresentMode(physicalDevice, entry.m_Surface); + uint32_t chosenImageCount = chooseImageCount(physicalDevice, entry.m_Surface); + + entry.m_Format = chosenSurfaceFormat.format; + entry.m_ColorSpace = chosenSurfaceFormat.colorSpace; + + vk::SwapchainCreateInfoKHR swapchainCreateInfo ( + vk::SwapchainCreateFlagsKHR(), + entry.m_Surface, + chosenImageCount, + entry.m_Format, + entry.m_ColorSpace, + entry.m_Extent, + 1, + vk::ImageUsageFlagBits::eColorAttachment | vk::ImageUsageFlagBits::eStorage, + vk::SharingMode::eExclusive, + 0, + nullptr, + vk::SurfaceTransformFlagBitsKHR::eIdentity, + vk::CompositeAlphaFlagBitsKHR::eOpaque, + chosenPresentMode, + true, + entry.m_Swapchain + ); + + entry.m_Swapchain = device.createSwapchainKHR(swapchainCreateInfo); + return true; } SwapchainHandle SwapchainManager::createSwapchain(Window &window) { - const uint64_t id = m_swapchains.size(); - - Swapchain swapchain = Swapchain::create(window, *m_context); - - m_swapchains.push_back(swapchain); - SwapchainHandle swapchainHandle = SwapchainHandle(id, [&](uint64_t id) { destroySwapchainById(id); }); - window.m_swapchainHandle = swapchainHandle; - return swapchainHandle; + const vk::Instance& instance = getCore().getContext().getInstance(); + const vk::PhysicalDevice& physicalDevice = getCore().getContext().getPhysicalDevice(); + + vk::SurfaceKHR surfaceHandle; + if (!createVulkanSurface(window.getWindow(), instance, physicalDevice, surfaceHandle)) { + return {}; + } + + uint32_t presentQueueIndex = QueueManager::checkSurfaceSupport(physicalDevice, surfaceHandle); + + const vk::Extent2D extent = chooseExtent(physicalDevice, surfaceHandle, window); + const vk::SurfaceFormatKHR format = chooseSurfaceFormat(physicalDevice, surfaceHandle); + + SwapchainEntry entry { + nullptr, + false, + + surfaceHandle, + presentQueueIndex, + extent, + format.format, + format.colorSpace + }; + + if (!createVulkanSwapchain(getCore().getContext(), window, entry)) { + instance.destroySurfaceKHR(surfaceHandle); + return {}; + } + + window.m_swapchainHandle = add(entry); + return window.m_swapchainHandle; } - Swapchain& SwapchainManager::getSwapchain(const SwapchainHandle& handle) { - return m_swapchains[handle.getId()]; + SwapchainEntry& SwapchainManager::getSwapchain(const SwapchainHandle& handle) { + return (*this)[handle]; } - - void SwapchainManager::destroySwapchainById(uint64_t id) { - - if (id >= m_swapchains.size()) { - vkcv_log(LogLevel::ERROR, "Invalid id"); + + bool SwapchainManager::shouldUpdateSwapchain(const SwapchainHandle &handle) const { + return (*this)[handle].m_RecreationRequired; + } + + void SwapchainManager::updateSwapchain(const SwapchainHandle &handle, const Window &window) { + auto& swapchain = (*this)[handle]; + + if (!swapchain.m_RecreationRequired) { return; + } else { + swapchain.m_RecreationRequired = false; } - Swapchain &swapchain = m_swapchains[id]; - - if (swapchain.m_Swapchain) { - m_context->getDevice().destroySwapchainKHR(swapchain.m_Swapchain); - swapchain.m_Swapchain = nullptr; - } - if (swapchain.m_Surface.m_Handle) { - m_context->getInstance().destroySurfaceKHR(swapchain.m_Surface.m_Handle); - swapchain.m_Surface.m_Handle = nullptr; + vk::SwapchainKHR oldSwapchain = swapchain.m_Swapchain; + + if (createVulkanSwapchain(getCore().getContext(), window, swapchain)) { + if (oldSwapchain) { + getCore().getContext().getDevice().destroySwapchainKHR(oldSwapchain); + } + } else { + signalRecreation(handle); } } - + void SwapchainManager::signalRecreation(const SwapchainHandle& handle) { - m_swapchains[handle.getId()].signalSwapchainRecreation(); + (*this)[handle].m_RecreationRequired = true; } - - std::vector<vk::Image> SwapchainManager::getSwapchainImages(const SwapchainHandle& handle) { - return m_context->getDevice().getSwapchainImagesKHR(m_swapchains[handle.getId()].getSwapchain()); + + vk::Format SwapchainManager::getFormat(const SwapchainHandle &handle) const { + return (*this)[handle].m_Format; + } + + uint32_t SwapchainManager::getImageCount(const SwapchainHandle &handle) const { + auto& swapchain = (*this)[handle]; + + uint32_t imageCount; + if (vk::Result::eSuccess != getCore().getContext().getDevice().getSwapchainImagesKHR(swapchain.m_Swapchain, + &imageCount, + nullptr)) { + return 0; + } else { + return imageCount; + } + } + + const vk::Extent2D &SwapchainManager::getExtent(const SwapchainHandle &handle) const { + return (*this)[handle].m_Extent; + } + + uint32_t SwapchainManager::getPresentQueueIndex(const SwapchainHandle &handle) const { + return (*this)[handle].m_PresentQueueIndex; + } + + vk::ColorSpaceKHR SwapchainManager::getSurfaceColorSpace(const SwapchainHandle &handle) const { + return (*this)[handle].m_ColorSpace; + } + + std::vector<vk::Image> SwapchainManager::getSwapchainImages(const SwapchainHandle& handle) const { + return getCore().getContext().getDevice().getSwapchainImagesKHR((*this)[handle].m_Swapchain); } std::vector<vk::ImageView> SwapchainManager::createSwapchainImageViews(SwapchainHandle& handle) { std::vector<vk::Image> images = getSwapchainImages(handle); - Swapchain &swapchain = m_swapchains[handle.getId()]; + auto& swapchain = (*this)[handle]; std::vector<vk::ImageView> imageViews; imageViews.reserve(images.size()); @@ -74,12 +321,13 @@ namespace vkcv { vk::ImageViewCreateFlags(), image, vk::ImageViewType::e2D, - swapchain.getFormat(), + swapchain.m_Format, componentMapping, subResourceRange); - imageViews.push_back(m_context->getDevice().createImageView(imageViewCreateInfo)); + imageViews.push_back(getCore().getContext().getDevice().createImageView(imageViewCreateInfo)); } + return imageViews; } } \ No newline at end of file diff --git a/src/vkcv/SwapchainManager.hpp b/src/vkcv/SwapchainManager.hpp index 285641db..d9ba37aa 100644 --- a/src/vkcv/SwapchainManager.hpp +++ b/src/vkcv/SwapchainManager.hpp @@ -1,35 +1,55 @@ #pragma once +/** + * @authors Tobias Frisch + * @file vkcv/SwapchainManager.hpp + * @brief Class to manage the swapchains and their surfaces. + */ +#include <atomic> #include <vector> -#include <GLFW/glfw3.h> +#include <vulkan/vulkan.hpp> -#include "WindowManager.hpp" -#include "vkcv/Swapchain.hpp" -#include "vkcv/Handles.hpp" +#include "vkcv/Window.hpp" + +#include "HandleManager.hpp" namespace vkcv { - class Core; + const uint32_t MIN_SURFACE_SIZE = 2; + + /** + * @brief Structure to handle swapchains. + */ + struct SwapchainEntry { + vk::SwapchainKHR m_Swapchain; + bool m_RecreationRequired; + + vk::SurfaceKHR m_Surface; + uint32_t m_PresentQueueIndex; + vk::Extent2D m_Extent; + vk::Format m_Format; + vk::ColorSpaceKHR m_ColorSpace; + }; /** * @brief Class to manage the creation, destruction and * allocation of swapchains. */ - class SwapchainManager { + class SwapchainManager : public HandleManager<SwapchainEntry, SwapchainHandle> { friend class Core; - - friend class WindowManager; - private: - std::vector<Swapchain> m_swapchains; - - Context *m_context; - + [[nodiscard]] + uint64_t getIdFrom(const SwapchainHandle& handle) const override; + + [[nodiscard]] + SwapchainHandle createById(uint64_t id, const HandleDestroyFunction& destroy) override; + /** - * destroys a specific swapchain by a given id - * @param id of the swapchain to be destroyed + * @brief Destroys a specific swapchain by a given id + * + * @param[in] id ID of the swapchain to be destroyed */ - void destroySwapchainById(uint64_t id); + void destroyById(uint64_t id) override; public: SwapchainManager() noexcept; @@ -37,15 +57,7 @@ namespace vkcv { /** * destroys every swapchain */ - ~SwapchainManager() noexcept; - - SwapchainManager(SwapchainManager &&other) = delete; - - SwapchainManager(const SwapchainManager &other) = delete; - - SwapchainManager &operator=(SwapchainManager &&other) = delete; - - SwapchainManager &operator=(const SwapchainManager &other) = delete; + ~SwapchainManager() noexcept override; /** * creates a swapchain and returns the handle @@ -59,27 +71,96 @@ namespace vkcv { * @return the reference of the swapchain */ [[nodiscard]] - Swapchain &getSwapchain(const SwapchainHandle& handle); - + SwapchainEntry& getSwapchain(const SwapchainHandle& handle); + + /** + * @brief Checks whether the swapchain needs to be recreated. + * + * @param[in] handle Swapchain handle + * @return True, if the swapchain should be updated, + * otherwise false. + */ + bool shouldUpdateSwapchain(const SwapchainHandle& handle) const; + + /** + * @brief Updates and recreates the swapchain. + * + * @param[in] handle Swapchain handle + * @param[in] window that the new swapchain gets bound to + */ + void updateSwapchain(const SwapchainHandle& handle, const Window &window); + /** - * sets the recreation flag fot the swapchain - * @param handle of the swapchain that should be recreated + * @brief Signals the swapchain to be recreated. + * + * @param[in] handle Swapchain handle */ void signalRecreation(const SwapchainHandle& handle); + + /** + * @brief Returns the image format for the current surface + * of the swapchain. + * + * @param[in] handle Swapchain handle + * @return Swapchain image format + */ + [[nodiscard]] + vk::Format getFormat(const SwapchainHandle& handle) const; + + /** + * @brief Returns the amount of images for the swapchain. + * + * @param[in] handle Swapchain handle + * @return Number of images + */ + uint32_t getImageCount(const SwapchainHandle& handle) const; + + /** + * @brief Returns the extent from the current surface of + * the swapchain. + * + * @param[in] handle Swapchain handle + * @return Extent of the swapchains surface + */ + [[nodiscard]] + const vk::Extent2D& getExtent(const SwapchainHandle& handle) const; + + /** + * @brief Returns the present queue index to be used with + * the swapchain and its current surface. + * + * @param[in] handle Swapchain handle + * @return Present queue family index + */ + [[nodiscard]] + uint32_t getPresentQueueIndex(const SwapchainHandle& handle) const; + + /** + * @brief Returns the color space of the surface from + * a swapchain. + * + * @param[in] handle Swapchain handle + * @return Color space + */ + [[nodiscard]] + vk::ColorSpaceKHR getSurfaceColorSpace(const SwapchainHandle& handle) const; /** * gets the swapchain images * @param handle of the swapchain * @return a vector of the swapchain images */ - std::vector<vk::Image> getSwapchainImages(const SwapchainHandle& handle); + [[nodiscard]] + std::vector<vk::Image> getSwapchainImages(const SwapchainHandle& handle) const; /** * creates the swapchain imageViews for the swapchain * @param handle of the swapchain which ImageViews should be created * @return a ov ImageViews of the swapchain */ + [[nodiscard]] std::vector<vk::ImageView> createSwapchainImageViews(SwapchainHandle& handle); + }; } \ No newline at end of file diff --git a/src/vkcv/Window.cpp b/src/vkcv/Window.cpp index f6f9aa69..8787053d 100644 --- a/src/vkcv/Window.cpp +++ b/src/vkcv/Window.cpp @@ -284,7 +284,7 @@ namespace vkcv { return window; } - SwapchainHandle Window::getSwapchainHandle() const { + SwapchainHandle Window::getSwapchain() const { return m_swapchainHandle; } } -- GitLab