Program Listing for File swapchain.hpp

Return to documentation for file (inexor/vulkan-renderer/wrapper/swapchain.hpp)

#pragma once

#include "inexor/vulkan-renderer/wrapper/semaphore.hpp"

#include <cstdint>
#include <limits>
#include <memory>
#include <optional>
#include <vector>

namespace inexor::vulkan_renderer::wrapper {

// Forward declarations
class Device;
class Semaphore;

class Swapchain {
private:
    Device &m_device;
    VkSwapchainKHR m_swapchain{VK_NULL_HANDLE};
    VkSurfaceKHR m_surface{VK_NULL_HANDLE};
    std::optional<VkSurfaceFormatKHR> m_surface_format{};
    std::vector<VkImage> m_imgs;
    std::vector<VkImageView> m_img_views;
    VkExtent2D m_extent{};
    std::unique_ptr<Semaphore> m_img_available;
    bool m_vsync_enabled{false};

    [[nodiscard]] std::vector<VkImage> get_swapchain_images();

public:
    Swapchain(Device &device, VkSurfaceKHR surface, std::uint32_t width, std::uint32_t height, bool vsync_enabled);

    Swapchain(const Swapchain &) = delete;
    Swapchain(Swapchain &&) noexcept;

    ~Swapchain();

    Swapchain &operator=(const Swapchain &) = delete;
    Swapchain &operator=(Swapchain &&) = delete;

    [[nodiscard]] std::uint32_t
    acquire_next_image_index(std::uint64_t timeout = std::numeric_limits<std::uint64_t>::max());

    [[nodiscard]] static std::optional<VkCompositeAlphaFlagBitsKHR>
    choose_composite_alpha(VkCompositeAlphaFlagBitsKHR request_composite_alpha,
                           VkCompositeAlphaFlagsKHR supported_composite_alpha);

    [[nodiscard]] static VkExtent2D choose_image_extent(const VkExtent2D &requested_extent,
                                                        const VkExtent2D &min_extent, const VkExtent2D &max_extent,
                                                        const VkExtent2D &current_extent);

    [[nodiscard]] static VkPresentModeKHR
    choose_present_mode(const std::vector<VkPresentModeKHR> &available_present_modes,
                        const std::vector<VkPresentModeKHR> &present_mode_priority_list, bool vsync_enabled);

    [[nodiscard]] static std::optional<VkSurfaceFormatKHR>
    choose_surface_format(const std::vector<VkSurfaceFormatKHR> &available_formats,
                          const std::vector<VkSurfaceFormatKHR> &format_prioriy_list = {});

    [[nodiscard]] VkExtent2D extent() const {
        return m_extent;
    }

    [[nodiscard]] const VkSemaphore *image_available_semaphore() const {
        return m_img_available->semaphore();
    }

    [[nodiscard]] std::uint32_t image_count() const {
        return static_cast<std::uint32_t>(m_imgs.size());
    }

    [[nodiscard]] VkFormat image_format() const {
        return m_surface_format.value().format;
    }

    [[nodiscard]] const std::vector<VkImageView> &image_views() const {
        return m_img_views;
    }

    void present(std::uint32_t img_index);

    void setup_swapchain(std::uint32_t width, std::uint32_t height, bool vsync_enabled);

    [[nodiscard]] const VkSwapchainKHR *swapchain() const {
        return &m_swapchain;
    }
};

} // namespace inexor::vulkan_renderer::wrapper