summaryrefslogtreecommitdiff
path: root/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'main.c')
-rw-r--r--main.c72
1 files changed, 55 insertions, 17 deletions
diff --git a/main.c b/main.c
index 2dddbd0..7063979 100644
--- a/main.c
+++ b/main.c
@@ -38,7 +38,7 @@ static struct {
static struct {
size_t len;
VkFramebuffer data[];
-} *swapchain_buffers;
+} *framebuffers;
struct code {
size_t len;
@@ -130,6 +130,16 @@ bool found_queue_indx(struct queue_indices inds) {
return inds.found_queues == (GRAPHICS | PRESENT);
}
+void cleanup_swapchain() {
+ for (size_t i = 0; i < framebuffers->len; i++) {
+ vkDestroyFramebuffer(gpu, framebuffers->data[i], NULL);
+ }
+ for (size_t i = 0; i < swapchain_image_views->len; i++) {
+ vkDestroyImageView(gpu, swapchain_image_views->data[i], NULL);
+ }
+ vkDestroySwapchainKHR(gpu, swapchain, NULL);
+}
+
void cleanup() {
vkDeviceWaitIdle(gpu);
for (size_t i = 0; i < MAX_FRAMES_INFLIGHT; i++) {
@@ -137,17 +147,11 @@ void cleanup() {
vkDestroySemaphore(gpu, render_finished[i], NULL);
vkDestroyFence(gpu, in_flight_fence[i], NULL);
}
+ cleanup_swapchain();
vkDestroyCommandPool(gpu, command_pool, NULL);
- for (size_t i = 0; i < swapchain_buffers->len; i++) {
- vkDestroyFramebuffer(gpu, swapchain_buffers->data[i], NULL);
- }
vkDestroyPipeline(gpu, graphics_pipeline, NULL);
vkDestroyPipelineLayout(gpu, pipeline_layout, NULL);
vkDestroyRenderPass(gpu, render_pass, NULL);
- for (size_t i = 0; i < swapchain_image_views->len; i++) {
- vkDestroyImageView(gpu, swapchain_image_views->data[i], NULL);
- }
- vkDestroySwapchainKHR(gpu, swapchain, NULL);
vkDestroySurfaceKHR(instance, surface, NULL);
vkDestroyDevice(gpu, NULL);
vkDestroyInstance(instance, NULL);
@@ -648,8 +652,8 @@ void create_render_pass() {
}
void create_framebuffers() {
- swapchain_buffers = malloc(sizeof(*swapchain_buffers) + sizeof(*swapchain_buffers->data) * swapchain_image_views->len);
- swapchain_buffers->len = swapchain_image_views->len;
+ framebuffers = malloc(sizeof(*framebuffers) + sizeof(*framebuffers->data) * swapchain_image_views->len);
+ framebuffers->len = swapchain_image_views->len;
for (size_t i = 0; i < swapchain_image_views->len; i++) {
VkImageView attachs[] = {
@@ -666,7 +670,7 @@ void create_framebuffers() {
.layers = 1
};
- VkResult res = vkCreateFramebuffer(gpu, &framebuffer_info, NULL, &swapchain_buffers->data[i]);
+ VkResult res = vkCreateFramebuffer(gpu, &framebuffer_info, NULL, &framebuffers->data[i]);
if (res != VK_SUCCESS) {
fputs("failed to create framebuffer", stderr);
exit(-1);
@@ -720,7 +724,7 @@ void record_command_buffer(VkCommandBuffer buffer, uint32_t image_index) {
VkRenderPassBeginInfo render_pass_info = {
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
.renderPass = render_pass,
- .framebuffer = swapchain_buffers->data[image_index],
+ .framebuffer = framebuffers->data[image_index],
.renderArea = {
.extent = swapchain_extent,
.offset = {0, 0}
@@ -776,9 +780,27 @@ void create_sync_objects() {
}
}
+void recreate_swapchain() {
+ int32_t width = 0, height = 0;
+ SDL_GetWindowSize(window, &width, &height);
+ while (width == 0 || height == 0) {
+ SDL_Event e;
+ SDL_PollEvent(&e);
+ SDL_GetWindowSize(window, &width, &height);
+ }
+
+ vkDeviceWaitIdle(gpu);
+
+ cleanup_swapchain();
+
+ create_swapchain();
+ create_image_views();
+ create_framebuffers();
+}
+
void init() {
SDL_Init(SDL_INIT_VIDEO);
- window = SDL_CreateWindow("vk", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 800, 800, SDL_WINDOW_VULKAN);
+ window = SDL_CreateWindow("vk", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 800, 800, SDL_WINDOW_VULKAN | SDL_WINDOW_RESIZABLE);
if (!window) {
fputs("failed to create sdl window", stderr);
exit(-1);
@@ -818,10 +840,22 @@ void init() {
void draw() {
vkWaitForFences(gpu, 1, &in_flight_fence[current_frame], VK_TRUE, UINT64_MAX);
- vkResetFences(gpu, 1, &in_flight_fence[current_frame]);
uint32_t image_index;
- vkAcquireNextImageKHR(gpu, swapchain, UINT64_MAX, image_avail[current_frame], VK_NULL_HANDLE, &image_index);
+ VkResult res = vkAcquireNextImageKHR(gpu, swapchain, UINT64_MAX, image_avail[current_frame], VK_NULL_HANDLE, &image_index);
+ switch (res) {
+ case VK_SUCCESS:
+ break;
+ case VK_ERROR_OUT_OF_DATE_KHR:
+ case VK_SUBOPTIMAL_KHR:
+ recreate_swapchain();
+ return;
+ default:
+ fputs("failed to acquire swapchain images", stderr);
+ exit(-1);
+ }
+
+ vkResetFences(gpu, 1, &in_flight_fence[current_frame]);
vkResetCommandBuffer(command_buffers[current_frame], 0);
record_command_buffer(command_buffers[current_frame], image_index);
@@ -839,7 +873,7 @@ void draw() {
.pCommandBuffers = &command_buffers[current_frame]
};
- VkResult res = vkQueueSubmit(gfx_queue, 1, &submit_info, in_flight_fence[current_frame]);
+ res = vkQueueSubmit(gfx_queue, 1, &submit_info, in_flight_fence[current_frame]);
if (res != VK_SUCCESS) {
fputs("failed to submit draw command buffer", stderr);
exit(-1);
@@ -864,8 +898,12 @@ int main() {
init();
SDL_Event e;
- while (SDL_PollEvent(&e), e.type != SDL_QUIT)
+ while (SDL_PollEvent(&e), e.type != SDL_QUIT) {
+ if (e.type == SDL_WINDOWEVENT && e.window.event == SDL_WINDOWEVENT_RESIZED) {
+ recreate_swapchain();
+ }
draw();
+ }
cleanup();
return 0;