swap_chain.hpp

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
#pragma once


#include <planet/affine/extents2d.hpp>
#include <planet/vk/device.hpp>
#include <planet/vk/frame_buffer.hpp>
#include <planet/vk/image.hpp>
#include <planet/vk/render_pass.hpp>


namespace planet::vk {

A swap chain

15
16
17
18
    class swap_chain final {
        using handle_type =
                device_handle<VkSwapchainKHR, vkDestroySwapchainKHR>;
        handle_type handle;

(Re-)create the swap chain and its attendant items

21
22
23
24
25
        std::uint32_t create(VkExtent2D);
        std::uint32_t create(affine::extents2d);


      public:

Creation

27
28
29
30
        template<typename Ex>
        swap_chain(vk::device &d, Ex const ex) : device{d} {
            create(ex);
        }

Queries

34
35
        device_view device;
        VkSwapchainKHR get() const noexcept { return handle.get(); }

Recreation

Recreate the swap chain and everything dependant on it, for example if the window has changed dimensions. Returns the number of images to use

44
45
46
47
48
        template<typename Ex>
        std::uint32_t recreate(Ex const ex) {
            device().wait_idle();
            return create(ex);
        }

Extents

Calculation

Calculate suitable extents to use for the swap chain given the current window size

57
58
        static VkExtent2D
                calculate_extents(vk::device const &, affine::extents2d);

The extents the current swap chain has been created for

60
        VkExtent2D extents;

The swap chain images, and their views

64
65
66
        VkFormat image_format;
        std::vector<VkImage> images;
        std::vector<image_view> image_views;

Frame buffers

70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
        std::vector<frame_buffer> frame_buffers;
        template<typename... Attachments>
        void create_frame_buffers(render_pass const &rp, Attachments... extra) {
            frame_buffers.clear();
            for (auto const &view : image_views) {
                std::array attachments{VkImageView{extra}..., view.get()};
                VkFramebufferCreateInfo info = {};
                info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
                info.renderPass = rp.get();
                info.attachmentCount = attachments.size();
                info.pAttachments = attachments.data();
                info.width = extents.width;
                info.height = extents.height;
                info.layers = 1;
                frame_buffers.emplace_back(device, info);
            }
        }

Resolve attachment

90
91
92
93
94
        VkAttachmentDescription attachment_description() const;
    };


}