Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 55b4803

Browse files
committed
Change swap chain chapter to no longer use oldSwapChain approach
1 parent 4682b42 commit 55b4803

2 files changed

Lines changed: 22 additions & 56 deletions

File tree

03_Drawing_a_triangle/04_Swap_chain_recreation.md

Lines changed: 17 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -39,17 +39,17 @@ chain images.
3939
To make sure that the old versions of these objects are cleaned up before
4040
recreating them, we should move some of the cleanup code to a separate function
4141
that we can call from the `recreateSwapChain` function. Let's call it
42-
`cleanupSwapChainDependents`:
42+
`cleanupSwapChain`:
4343

4444
```c++
45-
void cleanupSwapChainDependents() {
45+
void cleanupSwapChain() {
4646

4747
}
4848

4949
void recreateSwapChain() {
5050
vkDeviceWaitIdle(device);
5151

52-
cleanupSwapChainDependents();
52+
cleanupSwapChain();
5353

5454
createSwapChain();
5555
createImageViews();
@@ -60,11 +60,11 @@ void recreateSwapChain() {
6060
}
6161
```
6262

63-
we'll move the cleanup code of all objects that are recreated after a swap chain
64-
renewal from `cleanup` to `cleanupSwapChainDependents`:
63+
we'll move the cleanup code of all objects that are recreated as part of a swap
64+
chain refresh from `cleanup` to `cleanupSwapChain`:
6565

6666
```c++
67-
void cleanupSwapChainDependents() {
67+
void cleanupSwapChain() {
6868
for (size_t i = 0; i < swapChainFramebuffers.size(); i++) {
6969
vkDestroyFramebuffer(device, swapChainFramebuffers[i], nullptr);
7070
}
@@ -78,17 +78,18 @@ void cleanupSwapChainDependents() {
7878
for (size_t i = 0; i < swapChainImageViews.size(); i++) {
7979
vkDestroyImageView(device, swapChainImageViews[i], nullptr);
8080
}
81+
82+
vkDestroySwapchainKHR(device, swapChain, nullptr);
8183
}
8284

8385
void cleanup() {
84-
cleanupSwapChainDependents();
86+
cleanupSwapChain();
8587

8688
vkDestroySemaphore(device, renderFinishedSemaphore, nullptr);
8789
vkDestroySemaphore(device, imageAvailableSemaphore, nullptr);
8890

8991
vkDestroyCommandPool(device, commandPool, nullptr);
9092

91-
vkDestroySwapchainKHR(device, swapChain, nullptr);
9293
vkDestroyDevice(device, nullptr);
9394
DestroyDebugReportCallbackEXT(instance, callback, nullptr);
9495
vkDestroySurfaceKHR(instance, surface, nullptr);
@@ -103,44 +104,14 @@ void cleanup() {
103104
We could recreate the command pool from scratch, but that is rather wasteful.
104105
Instead I've opted to clean up the existing command buffers with the
105106
`vkFreeCommandBuffers` function. This way we can reuse the existing pool to
106-
allocate the new command buffers.
107-
108-
So why aren't we also destroying the swap chain itself in this function? Vulkan
109-
requires us to keep the old swap chain around until after the new one has been
110-
created. We're now going to use a new field in the `VkSwapchainCreateInfoKHR`
111-
struct called `oldSwapChain`:
112-
113-
```c++
114-
createInfo.oldSwapchain = swapChain;
115-
116-
if (vkCreateSwapchainKHR(device, &createInfo, nullptr, &swapChain) != VK_SUCCESS) {
117-
throw std::runtime_error("failed to create swap chain!");
118-
}
119-
```
120-
121-
We need to pass the previous swap chain object in the `oldSwapchain` parameter
122-
of `VkSwapchainCreateInfoKHR` to indicate that we intend to replace it. After
123-
the new swap chain has been successfully created, we can destroy the old one:
124-
125-
```c++
126-
if (vkCreateSwapchainKHR(device, &createInfo, nullptr, &swapChain) != VK_SUCCESS) {
127-
throw std::runtime_error("failed to create swap chain!");
128-
}
129-
130-
if (createInfo.oldSwapchain != VK_NULL_HANDLE) {
131-
vkDestroySwapchainKHR(device, createInfo.oldSwapchain, nullptr);
132-
}
133-
```
134-
135-
To make sure that the old swap chain is set to `VK_NULL_HANDLE` when the program
136-
has just started, make sure that the class member variable is properly
137-
initialized:
138-
139-
```c++
140-
VkSwapchainKHR swapChain = VK_NULL_HANDLE;
141-
```
142-
143-
That's all it takes to recreate the swap chain!
107+
allocate the new command buffers.
108+
109+
That's all it takes to recreate the swap chain! However, the disadvantage of
110+
this approach is that we need to stop all rendering before creating the new swap
111+
chain. It is possible to create a new swap chain while drawing commands on an
112+
image from the old swap chain are still in-flight. You need to pass the previous
113+
swap chain to the `oldSwapChain` field in the `VkSwapchainCreateInfoKHR` struct
114+
and destroy the old swap chain as soon as you've finished using it.
144115

145116
## Window resizing
146117

code/swap_chain_recreation.cpp

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ class HelloTriangleApplication {
132132
vkDeviceWaitIdle(device);
133133
}
134134

135-
void cleanupSwapChainDependents() {
135+
void cleanupSwapChain() {
136136
for (size_t i = 0; i < swapChainFramebuffers.size(); i++) {
137137
vkDestroyFramebuffer(device, swapChainFramebuffers[i], nullptr);
138138
}
@@ -146,17 +146,18 @@ class HelloTriangleApplication {
146146
for (size_t i = 0; i < swapChainImageViews.size(); i++) {
147147
vkDestroyImageView(device, swapChainImageViews[i], nullptr);
148148
}
149+
150+
vkDestroySwapchainKHR(device, swapChain, nullptr);
149151
}
150152

151153
void cleanup() {
152-
cleanupSwapChainDependents();
154+
cleanupSwapChain();
153155

154156
vkDestroySemaphore(device, renderFinishedSemaphore, nullptr);
155157
vkDestroySemaphore(device, imageAvailableSemaphore, nullptr);
156158

157159
vkDestroyCommandPool(device, commandPool, nullptr);
158160

159-
vkDestroySwapchainKHR(device, swapChain, nullptr);
160161
vkDestroyDevice(device, nullptr);
161162
DestroyDebugReportCallbackEXT(instance, callback, nullptr);
162163
vkDestroySurfaceKHR(instance, surface, nullptr);
@@ -177,7 +178,7 @@ class HelloTriangleApplication {
177178
void recreateSwapChain() {
178179
vkDeviceWaitIdle(device);
179180

180-
cleanupSwapChainDependents();
181+
cleanupSwapChain();
181182

182183
createSwapChain();
183184
createImageViews();
@@ -345,16 +346,10 @@ class HelloTriangleApplication {
345346
createInfo.presentMode = presentMode;
346347
createInfo.clipped = VK_TRUE;
347348

348-
createInfo.oldSwapchain = swapChain;
349-
350349
if (vkCreateSwapchainKHR(device, &createInfo, nullptr, &swapChain) != VK_SUCCESS) {
351350
throw std::runtime_error("failed to create swap chain!");
352351
}
353352

354-
if (createInfo.oldSwapchain != VK_NULL_HANDLE) {
355-
vkDestroySwapchainKHR(device, createInfo.oldSwapchain, nullptr);
356-
}
357-
358353
vkGetSwapchainImagesKHR(device, swapChain, &imageCount, nullptr);
359354
swapChainImages.resize(imageCount);
360355
vkGetSwapchainImagesKHR(device, swapChain, &imageCount, swapChainImages.data());

0 commit comments

Comments
 (0)