// Copyright 2022 Simon Boyé #pragma once #include #include #include #include #include #include #include #include #include #include namespace vk { class Swapchain; class SwapchainSettings { public: SwapchainSettings(Context* context); ~SwapchainSettings(); Context* context() const; std::vector queue_families() const; SwapchainSettings& with_queue(uint32_t queue_family); private: Context* m_context; std::vector m_queue_families; }; class Swapchain { public: static constexpr uint32_t CURRENT_IMAGE_INDEX = UINT32_MAX; static constexpr uint32_t MAX_FRAMES_IN_FLIGHT = 2; using CreationCallback = std::function; using DestructionCallback = std::function; public: Swapchain(); Swapchain(const Swapchain&) = delete; ~Swapchain(); Swapchain& operator=(const Swapchain&) = delete; VkSwapchainKHR swapchain(); VkExtent2D extent() const; size_t image_count() const; uint32_t current_image_index() const; VkImage image(); VkImage image(size_t image_index); VkImageView image_view(); VkImageView image_view(size_t image_index); Semaphore& ready_to_render(); Fence& render_done(); void initialize(const SwapchainSettings& settings); void shutdown(); void begin_frame(); void swap_buffers(Array wait_semaphores); void invalidate(); void register_creation_callback(CreationCallback callback); void register_destruction_callback(DestructionCallback callback); private: struct ImageResources { VkImage image = VK_NULL_HANDLE; ImageView view; Fence render_done; }; struct FrameResources { Semaphore ready_to_render; Fence* render_done = nullptr; }; private: void create(const SwapchainSettings& settings); void create(); void destroy(); void recreate(); private: Context* m_context = nullptr; VkSwapchainKHR m_swapchain = VK_NULL_HANDLE; VkExtent2D m_extent; std::vector m_queue_families; std::vector m_image_resources; std::vector m_frame_resources; bool m_invalid = false; std::vector m_creation_callbacks; std::vector m_destruction_callbacks; uint32_t m_current_image_index = CURRENT_IMAGE_INDEX; size_t m_frame_index = 0; size_t m_frame_resources_index = 0; }; }