Skip to content

Commit 5d0c080

Browse files
committed
Window resizing
1 parent e7473b1 commit 5d0c080

4 files changed

Lines changed: 75 additions & 20 deletions

File tree

src/main.cpp

Lines changed: 62 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -30,17 +30,14 @@ bool handleMessage() {
3030
return true;
3131
}
3232

33-
void initApplication(SDL_Window* window) {
34-
uint32_t instanceExtensionCount;
35-
SDL_Vulkan_GetInstanceExtensions(window, &instanceExtensionCount, 0);
36-
const char** enabledInstanceExtensions = new const char* [instanceExtensionCount];
37-
SDL_Vulkan_GetInstanceExtensions(window, &instanceExtensionCount, enabledInstanceExtensions);
38-
39-
const char* enabledDeviceExtensions[]{ VK_KHR_SWAPCHAIN_EXTENSION_NAME };
40-
context = initVulkan(instanceExtensionCount, enabledInstanceExtensions, ARRAY_COUNT(enabledDeviceExtensions), enabledDeviceExtensions);
41-
42-
SDL_Vulkan_CreateSurface(window, context->instance, &surface);
43-
swapchain = createSwapchain(context, surface, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
33+
void recreateRenderPass() {
34+
if(renderPass) {
35+
for (uint32_t i = 0; i < framebuffers.size(); ++i) {
36+
VK(vkDestroyFramebuffer(context->device, framebuffers[i], 0));
37+
}
38+
destroyRenderpass(context, renderPass);
39+
}
40+
framebuffers.clear();
4441

4542
renderPass = createRenderPass(context, swapchain.format);
4643
framebuffers.resize(swapchain.images.size());
@@ -54,6 +51,21 @@ void initApplication(SDL_Window* window) {
5451
createInfo.layers = 1;
5552
VKA(vkCreateFramebuffer(context->device, &createInfo, 0, &framebuffers[i]));
5653
}
54+
}
55+
56+
void initApplication(SDL_Window* window) {
57+
uint32_t instanceExtensionCount;
58+
SDL_Vulkan_GetInstanceExtensions(window, &instanceExtensionCount, 0);
59+
const char** enabledInstanceExtensions = new const char* [instanceExtensionCount];
60+
SDL_Vulkan_GetInstanceExtensions(window, &instanceExtensionCount, enabledInstanceExtensions);
61+
62+
const char* enabledDeviceExtensions[]{ VK_KHR_SWAPCHAIN_EXTENSION_NAME };
63+
context = initVulkan(instanceExtensionCount, enabledInstanceExtensions, ARRAY_COUNT(enabledDeviceExtensions), enabledDeviceExtensions);
64+
65+
SDL_Vulkan_CreateSurface(window, context->instance, &surface);
66+
swapchain = createSwapchain(context, surface, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
67+
68+
recreateRenderPass();
5769

5870
pipeline = createPipeline(context, "../shaders/triangle_vert.spv", "../shaders/triangle_frag.spv", renderPass, swapchain.width, swapchain.height);
5971

@@ -83,6 +95,23 @@ void initApplication(SDL_Window* window) {
8395
}
8496
}
8597

98+
void recreateSwapchain() {
99+
VulkanSwapchain oldSwapchain = swapchain;
100+
101+
VkSurfaceCapabilitiesKHR surfaceCapabilities;
102+
VKA(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(context->physicalDevice, surface, &surfaceCapabilities));
103+
if(surfaceCapabilities.currentExtent.width == 0 || surfaceCapabilities.currentExtent.height == 0) {
104+
return;
105+
}
106+
107+
108+
VKA(vkDeviceWaitIdle(context->device));
109+
swapchain = createSwapchain(context, surface, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, &oldSwapchain);
110+
111+
destroySwapchain(context, &oldSwapchain);
112+
recreateRenderPass();
113+
}
114+
86115
void renderApplication() {
87116
static float greenChannel = 0.0f;
88117
greenChannel += 0.01f;
@@ -94,7 +123,14 @@ void renderApplication() {
94123
VKA(vkWaitForFences(context->device, 1, &fences[frameIndex], VK_TRUE, UINT64_MAX));
95124
VKA(vkResetFences(context->device, 1, &fences[frameIndex]));
96125

97-
VK(vkAcquireNextImageKHR(context->device, swapchain.swapchain, UINT64_MAX, acquireSemaphores[frameIndex], 0, &imageIndex));
126+
VkResult result = VK(vkAcquireNextImageKHR(context->device, swapchain.swapchain, UINT64_MAX, acquireSemaphores[frameIndex], 0, &imageIndex));
127+
if(result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR) {
128+
// Swapchain is out of date
129+
recreateSwapchain();
130+
return;
131+
} else {
132+
ASSERT_VULKAN(result);
133+
}
98134

99135
VKA(vkResetCommandPool(context->device, commandPools[frameIndex], 0));
100136

@@ -104,6 +140,11 @@ void renderApplication() {
104140
VkCommandBuffer commandBuffer = commandBuffers[frameIndex];
105141
VKA(vkBeginCommandBuffer(commandBuffer, &beginInfo));
106142

143+
VkViewport viewport = { 0.0f, 0.0f, (float)swapchain.width, (float)swapchain.height };
144+
VkRect2D scissor = { {0, 0}, {swapchain.width, swapchain.height} };
145+
vkCmdSetViewport(commandBuffer, 0, 1, &viewport);
146+
vkCmdSetScissor(commandBuffer, 0, 1, &scissor);
147+
107148
VkClearValue clearValue = {0.0f, greenChannel, 1.0f, 1.0f};
108149
VkRenderPassBeginInfo beginInfo = { VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO };
109150
beginInfo.renderPass = renderPass;
@@ -114,6 +155,7 @@ void renderApplication() {
114155
vkCmdBeginRenderPass(commandBuffer, &beginInfo, VK_SUBPASS_CONTENTS_INLINE);
115156

116157
vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline.pipeline);
158+
117159
vkCmdDraw(commandBuffer, 3, 1, 0, 0);
118160

119161
vkCmdEndRenderPass(commandBuffer);
@@ -138,7 +180,13 @@ void renderApplication() {
138180
presentInfo.pImageIndices = &imageIndex;
139181
presentInfo.waitSemaphoreCount = 1;
140182
presentInfo.pWaitSemaphores = &releaseSemaphores[frameIndex];
141-
VK(vkQueuePresentKHR(context->graphicsQueue.queue, &presentInfo));
183+
result = VK(vkQueuePresentKHR(context->graphicsQueue.queue, &presentInfo));
184+
if(result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR) {
185+
// Swapchain is out of date
186+
recreateSwapchain();
187+
} else {
188+
ASSERT_VULKAN(result);
189+
}
142190

143191
frameIndex = (frameIndex + 1) % FRAMES_IN_FLIGHT;
144192
}
@@ -173,7 +221,7 @@ int main() {
173221
return 1;
174222
}
175223

176-
SDL_Window* window = SDL_CreateWindow("Vulkan Tutorial", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1240, 720, SDL_WINDOW_VULKAN);
224+
SDL_Window* window = SDL_CreateWindow("Vulkan Tutorial", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1240, 720, SDL_WINDOW_VULKAN | SDL_WINDOW_RESIZABLE);
177225
if (!window) {
178226
LOG_ERROR("Error creating SDL window");
179227
return 1;

src/vulkan_base/vulkan_base.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ struct VulkanContext {
4444
VulkanContext* initVulkan(uint32_t instanceExtensionCount, const char** instanceExtensions, uint32_t deviceExtensionCount, const char** deviceExtensions);
4545
void exitVulkan(VulkanContext* context);
4646

47-
VulkanSwapchain createSwapchain(VulkanContext* context, VkSurfaceKHR surface, VkImageUsageFlags usage);
47+
VulkanSwapchain createSwapchain(VulkanContext* context, VkSurfaceKHR surface, VkImageUsageFlags usage, VulkanSwapchain* oldSwapchain = 0);
4848
void destroySwapchain(VulkanContext* context, VulkanSwapchain* swapchain);
4949

5050
VkRenderPass createRenderPass(VulkanContext* context, VkFormat format);

src/vulkan_base/vulkan_pipeline.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,11 @@ VulkanPipeline createPipeline(VulkanContext* context, const char* vertexShaderFi
4848

4949
VkPipelineViewportStateCreateInfo viewportState = { VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO };
5050
viewportState.viewportCount = 1;
51-
VkViewport viewport = { 0.0f, 0.0f, (float)width, (float)height };
52-
viewportState.pViewports = &viewport;
51+
//VkViewport viewport = { 0.0f, 0.0f, (float)width, (float)height };
52+
//viewportState.pViewports = &viewport;
5353
viewportState.scissorCount = 1;
54-
VkRect2D scissor = { {0, 0}, {width, height} };
55-
viewportState.pScissors = &scissor;
54+
//VkRect2D scissor = { {0, 0}, {width, height} };
55+
//viewportState.pScissors = &scissor;
5656

5757
VkPipelineRasterizationStateCreateInfo rasterizationState = { VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO };
5858
rasterizationState.lineWidth = 1.0f;
@@ -67,6 +67,11 @@ VulkanPipeline createPipeline(VulkanContext* context, const char* vertexShaderFi
6767
colorBlendState.attachmentCount = 1;
6868
colorBlendState.pAttachments = &colorBlendAttachment;
6969

70+
VkPipelineDynamicStateCreateInfo dynamicState = {VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO};
71+
VkDynamicState dynamicStates[] = {VK_DYNAMIC_STATE_VIEWPORT, VK_DYNAMIC_STATE_SCISSOR};
72+
dynamicState.dynamicStateCount = ARRAY_COUNT(dynamicStates);
73+
dynamicState.pDynamicStates = dynamicStates;
74+
7075
VkPipelineLayout pipelineLayout;
7176
{
7277
VkPipelineLayoutCreateInfo createInfo = { VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO };
@@ -84,6 +89,7 @@ VulkanPipeline createPipeline(VulkanContext* context, const char* vertexShaderFi
8489
createInfo.pRasterizationState = &rasterizationState;
8590
createInfo.pMultisampleState = &multisampleState;
8691
createInfo.pColorBlendState = &colorBlendState;
92+
createInfo.pDynamicState = &dynamicState;
8793
createInfo.layout = pipelineLayout;
8894
createInfo.renderPass = renderPass;
8995
createInfo.subpass = 0;

src/vulkan_base/vulkan_swapchain.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#include "vulkan_base.h"
22

3-
VulkanSwapchain createSwapchain(VulkanContext* context, VkSurfaceKHR surface, VkImageUsageFlags usage) {
3+
VulkanSwapchain createSwapchain(VulkanContext* context, VkSurfaceKHR surface, VkImageUsageFlags usage, VulkanSwapchain* oldSwapchain) {
44
VulkanSwapchain result = {};
55

66
VkBool32 supportsPresent = 0;
@@ -48,6 +48,7 @@ VulkanSwapchain createSwapchain(VulkanContext* context, VkSurfaceKHR surface, Vk
4848
createInfo.preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
4949
createInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
5050
createInfo.presentMode = VK_PRESENT_MODE_FIFO_KHR;
51+
createInfo.oldSwapchain = oldSwapchain ? oldSwapchain->swapchain : 0;
5152
VKA(vkCreateSwapchainKHR(context->device, &createInfo, 0, &result.swapchain));
5253

5354
result.format = format;

0 commit comments

Comments
 (0)