evan 2026.1.4
Evan
Loading...
Searching...
No Matches
DesktopSwapchainContext.cpp
1/*
2** ETIB PROJECT, 2026
3** evan
4** File description:
5** DesktopSwapchainContext
6*/
7
8#include "evan/glfw/DesktopSwapchainContext.hpp"
9
10#include "evan/CheckedCast.hpp"
11#include "evan/DeviceContext.hpp"
12
13std::unordered_map<GLFWwindow *, evan::DesktopSwapchainContext *>
14 evan::DesktopSwapchainContext::_contexts {};
15
17 const DeviceContext &deviceContext, GLFWwindow *window)
18 : _referenceWindow(window)
19 , _msaaSamples(deviceContext.getMsaaSamples())
20{
21 this->getLogger().info() << "Initializing DesktopSwapchainContext...";
22
23 this->createRenderPass(deviceContext.getDeviceBackend(), _msaaSamples,
24 desktopColorAttachmentMode(_msaaSamples));
25
26 this->getLogger().info()
27 << "Creating swapchain images for DesktopSwapchainContext...";
28 _swapchainImages.push_back(std::make_shared<DesktopSwapchainImage>(
29 deviceContext, window, _renderPass));
30
31 _viewSet.resize(1);
32
33 this->getLogger().info()
34 << "Registering GLFW framebuffer size callback for proactive swapchain "
35 "recreation...";
36 _contexts[window] = this;
38 window, &DesktopSwapchainContext::framebufferSizeCallback);
39}
40
41evan::DesktopSwapchainContext::~DesktopSwapchainContext()
42{
43 this->getLogger().info() << "Destroying DesktopSwapchainContext...";
44 if (_referenceWindow) {
45 glfwSetFramebufferSizeCallback(_referenceWindow, nullptr);
46 _contexts.erase(_referenceWindow);
47 }
48}
49
51// Public Methods //
53
55{
56 this->getLogger().info() << "Destroying swapchain and associated resources "
57 "for DesktopSwapchainContext...";
58
59 this->getLogger().info()
60 << "Destroying render pass for DesktopSwapchainContext...";
61 vkDestroyRenderPass(device, _renderPass, nullptr);
62
63 this->getLogger().info()
64 << "Destroying swapchain images for DesktopSwapchainContext...";
65 for (const auto &swapchainImage: _swapchainImages) {
66 this->getLogger().info() << "Destroying swapchain image and releasing "
67 "associated resources...";
68 swapchainImage->destroy(device);
69 }
70}
71
73 const DeviceContext &deviceContext, VkRenderPass renderpass)
74{
75 this->getLogger().info() << "Recreating swapchain and associated resources "
76 "for DesktopSwapchainContext...";
77
78 auto device = deviceContext.getDeviceBackend()->getDevice();
79
80 this->getLogger().info()
81 << "Waiting for the device to be idle before recreating the "
82 "swapchain...";
84
86 if (!_swapchainImages.empty()) {
88 dynamic_cast<DesktopSwapchainImage *>(_swapchainImages[0].get())
89 ->_swapchain;
90 }
91
92 this->getLogger().info()
93 << "Creating new swapchain image with the previous swapchain as "
94 "oldSwapchain...";
95 auto newSwapchainImage = std::make_shared<DesktopSwapchainImage>(
96 deviceContext, _referenceWindow, renderpass, oldSwapchain);
97
98 this->getLogger().info() << "Destroying existing swapchain images for "
99 "DesktopSwapchainContext...";
100 for (const auto &swapchainImage: _swapchainImages) {
101 this->getLogger().info() << "Destroying swapchain image and releasing "
102 "associated resources...";
103 swapchainImage->destroy(deviceContext.getDeviceBackend()->getDevice());
104 }
105 _swapchainImages.clear();
106 _swapchainImages.push_back(newSwapchainImage);
107
108 this->getLogger().info()
109 << "Updating view for the new swapchain extent while preserving the "
110 "camera transform...";
111 auto view = this->getViewSet()[0].view;
113 newSwapchainImage->getExtent());
114 this->getViewSet().setView(0, view);
115
116 _framebufferResized = false;
117}
118
122{
123 this->getLogger().info() << "Acquiring next available image from swapchain "
124 "for DesktopSwapchainContext...";
125 VkSwapchainKHR swapchain =
126 evan::checkedCast<DesktopSwapchainImage>(*_swapchainImages[index])
127 ._swapchain;
128
129 this->getLogger().info()
130 << "Calling vkAcquireNextImageKHR to acquire image from swapchain...";
131 return vkAcquireNextImageKHR(device, swapchain, UINT64_MAX,
133 &imageIndex);
134}
135
140
142{
143 return _viewSet;
144}
145
150
155
157{
158 return _framebufferResized;
159}
160
161void evan::DesktopSwapchainContext::framebufferSizeCallback(GLFWwindow *window,
162 int width,
163 int height)
164{
165 (void)width;
166 (void)height;
167 auto it = _contexts.find(window);
168 if (it != _contexts.end()) {
169 it->second->_framebufferResized = true;
170 }
171}
static void updateViewForExtent(utility::graphic::ViewF &view, VkExtent2D extent)
Updates a view's viewport size and perspective for a new swapchain extent.
std::vector< std::shared_ptr< ASwapchainImage > > _swapchainImages
void createRenderPass(const std::shared_ptr< ADeviceBackend > &deviceBackend, VkSampleCountFlagBits msaaSamples, ColorAttachmentMode mode, uint32_t viewMask=0)
Creates the Vulkan render pass for the swapchain context.
void recreateSwapchain(const DeviceContext &deviceContext, VkRenderPass renderpass) override
Recreates the swapchain and associated resources.
void destroy(VkDevice device) override
Destroys the swapchain and releases associated resources.
ViewSet & getViewSet() override
Retrieves the set of views to render (mutable).
DesktopSwapchainContext(const DeviceContext &deviceContext, GLFWwindow *window)
Constructs a DesktopSwapchainContext instance with the provided device context and GLFW window.
VkSampleCountFlagBits getMsaaSamples() const override
Retrieves the MSAA sample count used by this swapchain context.
VkResult aquireImage(uint32_t index, VkDevice device, VkSemaphore imageAvailableSemaphore, VkFence inFlightFence, uint32_t &imageIndex) override
Acquires the next available image from the swapchain for rendering.
bool needsSwapchainRecreation() const override
Desktop swapchains must be recreated when the GLFW window is resized.
bool usesImageAvailableSemaphore() const override
Desktop swapchains signal the image-available semaphore through vkAcquireNextImageKHR.
A swapchain image implementation for desktop platforms using GLFW.
Represents the device context for the engine, managing Vulkan-related resources and operations.
std::shared_ptr< ADeviceBackend > getDeviceBackend() const
Retrieves a shared pointer to the ADeviceBackend instance associated with this device context.
Describes a set of views to render, independent of the swapchain image sets.
Definition ViewSet.hpp:37
void resize(std::size_t count)
Resizes the view set to contain exactly count views.
Small result wrapper used by helpers that must return both a status and a value (e....
Definition Error.hpp:89