#pragma once #include "Gpu.hpp" #include "props.hpp" #include "resources/Image.hpp" #include #include struct ImageResourceLayout; class Swapchain { private: const Gpu* m_gpu; VkSurfaceKHR m_surface; VkSwapchainKHR m_swapchain; VkSurfaceFormatKHR m_format; VkExtent2D m_extent; unsigned m_numImages; unsigned m_numFrames; VkImage *m_pImages; VkImageView *m_pImageViews; VkSurfaceFormatKHR choose_format(); VkPresentModeKHR choose_present_mode(); VkExtent2D choose_extent(VkExtent2D actualExtent = {0, 0}); ResultCode create_swapchain(); ResultCode get_images(unsigned *pOutCount, VkImage *pOut); ResultCode create_views(); std::vector m_images; std::vector m_views; public: GET(m_format, format); GET(m_swapchain, swapchain); GET(m_extent, extent); GET(m_numImages, num_images); REF(m_images, images); REF(m_views, views); GET(m_surface, surface); const Image* get_image(uint32_t idx) const { if(idx >= m_numImages) { return nullptr; } return &m_images[idx]; } VkResult get_next_image_idx(VkSemaphore signalSemaphore, VkFence signalFence, uint32_t *pOutImageIdx) const { return vkAcquireNextImageKHR(m_gpu->dev(), m_swapchain, UINT64_MAX, signalSemaphore, signalFence, pOutImageIdx); } void present(std::vector waitSemaphores, uint32_t imageIdx) const { VkPresentInfoKHR presentInfo = {}; presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; presentInfo.waitSemaphoreCount = (uint32_t)waitSemaphores.size(); presentInfo.pWaitSemaphores = waitSemaphores.data(); presentInfo.swapchainCount = 1; presentInfo.pSwapchains = &m_swapchain; presentInfo.pImageIndices = &imageIdx; m_gpu->enqueue_present(&presentInfo); } void cleanup(); void resize(VkExtent2D size); Swapchain(const Gpu* gpu, VkExtent2D extent, Surface* surface); };