diff options
| author | Anna (navi) Figueiredo Gomes <navi@vlhl.dev> | 2023-12-27 13:09:22 +0100 | 
|---|---|---|
| committer | Anna (navi) Figueiredo Gomes <navi@vlhl.dev> | 2023-12-27 13:09:22 +0100 | 
| commit | 7dbb36c6f46012f8234f1449270b28edbe148b1d (patch) | |
| tree | 3f18f9b328f880efa77e5edf82d1e6890f52f0a0 | |
| parent | 15b6cbff60d8d577a591f32e0ee3879635cb085d (diff) | |
| download | vlkn-7dbb36c6f46012f8234f1449270b28edbe148b1d.tar.xz | |
resiiize by recreating the swapchain
Signed-off-by: Anna (navi) Figueiredo Gomes <navi@vlhl.dev>
| -rw-r--r-- | main.c | 72 | 
1 files changed, 55 insertions, 17 deletions
| @@ -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; | 
