/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ #pragma once #include "Device.hpp" #include "Image.hpp" #include "FrameBuffer.hpp" #include "Base/UI/IWindow.hpp" #include "Base/EngineConfiguration.hpp" #include "Base/Logger.hpp" #include namespace OpenVulkano { namespace Vulkan { struct SwapChainImage : public IImage { vk::Image image; vk::ImageView view; vk::Fence fence; vk::Image GetImage() override { return image; } vk::ImageView GetView() override { return view; } }; class SwapChain final : public FrameBuffer { vk::SurfaceKHR surface; std::vector images; Device* device = nullptr; IVulkanWindow* window = nullptr; vk::SurfaceFormatKHR surfaceFormat; vk::PresentModeKHR presentMode; std::vector imageAvailableSemaphores; uint32_t currentSemaphoreId = 0; vk::Extent2D size{ 0, 0 }; public: vk::SwapchainKHR swapChain; SwapChain() = default; ~SwapChain() override { if (device) SwapChain::Close(); } void Init(Device* device, vk::SurfaceKHR surface, IVulkanWindow* window); void Close() override; void Resize(uint32_t newWidth, uint32_t newHeight); [[nodiscard]] vk::Extent2D GetSize() const { return size; } uint32_t AcquireNextImage(const vk::Fence& fence = vk::Fence()); vk::Fence& GetCurrentSubmitFence() { return images[currentFrameBufferId].fence; } void Present(vk::Queue& queue ,std::vector& semaphores) const { const vk::Result result = queue.presentKHR(vk::PresentInfoKHR(semaphores.size(), semaphores.data(), 1, &swapChain, ¤tFrameBufferId)); if (result != vk::Result::eSuccess) [[unlikely]] { Logger::RENDER->error("Failed to preset swap chain image: {}", to_string(result)); } } [[nodiscard]] uint32_t GetImageCount() const { return images.size(); } vk::Semaphore& GetCurrentSemaphore() { return imageAvailableSemaphores[currentSemaphoreId]; } private: void CreateSwapChain(vk::Extent2D size); void CreateSwapChainImages(); void DestroySwapChain(); protected: [[nodiscard]] vk::Format FindColorFormat() override { return surfaceFormat.format; } virtual vk::PresentModeKHR ChosePresentMode(); virtual vk::SurfaceFormatKHR ChoseSurfaceFormat(); public: std::vector GetImages() override; }; } }