Files
OpenVulkano/openVulkanoCpp/Vulkan/SwapChain.hpp
2024-07-02 21:29:15 +02:00

139 lines
3.1 KiB
C++

/*
* 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/Logger.hpp"
#include <vulkan/vulkan.hpp>
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<SwapChainImage> images;
Device* device = nullptr;
IVulkanWindow* window = nullptr;
vk::SurfaceFormatKHR surfaceFormat;
vk::PresentModeKHR presentMode;
vk::Viewport fullscreenViewport;
vk::Rect2D fullscreenScissor;
std::vector<vk::Semaphore> imageAvailableSemaphores;
uint32_t currentSemaphoreId = 0;
bool useVsync = false;
#ifdef __APPLE__
uint32_t preferredImageCount = 3; //TODO add option
#else
uint32_t preferredImageCount = 2; //TODO add option
#endif
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;
}
[[nodiscard]] const vk::Viewport& GetFullscreenViewport() const
{
return fullscreenViewport;
}
[[nodiscard]] const vk::Rect2D& GetFullscreenScissor() const
{
return fullscreenScissor;
}
uint32_t AcquireNextImage(const vk::Fence& fence = vk::Fence());
vk::Fence& GetCurrentSubmitFence()
{
return images[currentFrameBufferId].fence;
}
void Present(vk::Queue& queue ,std::vector<vk::Semaphore>& semaphores) const
{
const vk::Result result = queue.presentKHR(vk::PresentInfoKHR(semaphores.size(), semaphores.data(),
1, &swapChain, &currentFrameBufferId));
if (result != vk::Result::eSuccess) [[unlikely]]
{
Logger::RENDER->error("Failed to preset swap chain image: {}", to_string(result));
}
}
[[nodiscard]] bool UseVsync() const { return useVsync; }
void SetVsync(bool vsync)
{ //TODO change swap chain
this->useVsync = vsync;
}
[[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:
vk::Format FindColorFormat() override
{
return surfaceFormat.format;
}
virtual vk::PresentModeKHR ChosePresentMode();
virtual vk::SurfaceFormatKHR ChoseSurfaceFormat();
public:
std::vector<IImage*> GetImages() override;
};
}
}