diff options
author | kartofen <mladenovnasko0@gmail.com> | 2023-10-22 20:03:33 +0300 |
---|---|---|
committer | kartofen <mladenovnasko0@gmail.com> | 2023-10-22 20:03:33 +0300 |
commit | 7e555eeadd1f295db7700b8bde884fcb92bb2b8d (patch) | |
tree | 14ca519023f8e2e208d95d0250ee37a7b1b75fa8 | |
parent | 560f07e306da1906720ffc8a7de32069b8b7353e (diff) |
swap chain recreation and minor stuff
-rw-r--r-- | src/device.c | 93 | ||||
-rw-r--r-- | src/device.h | 16 | ||||
-rw-r--r-- | src/main.c | 1 |
3 files changed, 64 insertions, 46 deletions
diff --git a/src/device.c b/src/device.c index 23cece2..5934270 100644 --- a/src/device.c +++ b/src/device.c @@ -61,8 +61,8 @@ static int create_instance(device_t device, struct device_info *info); static int create_surface(device_t device, struct device_info *info); static int create_physical_device(device_t device, struct device_info *info); static int create_logical_device(device_t device, struct device_info *info); -static int create_swap_chain(device_t device, struct device_info *info); static int create_pipeline(device_t device, struct device_info *info); +static int create_swap_chain(device_t device, struct device_info *info); static int create_command_pool(device_t device, struct device_info *info); static int create_sync_objects(device_t device, struct device_info *info); @@ -71,13 +71,16 @@ static void destroy_pipeline(device_t device); // static void destroy_command_pool(device_t device); static void destroy_sync_objects(device_t device); -// --- Helper Function --- +// --- Helper Functions --- static char *str_VkResult(VkResult result); static bool device_is_suitable(VkPhysicalDevice phy_device, VkSurfaceKHR surface); static bool device_has_extension_support(VkPhysicalDevice phy_device); static int device_queue_families(VkPhysicalDevice phy_device, VkSurfaceKHR surface, struct queue_family_idx *queue_family); +#define PPLN device->pipeline +static int pipeline_load_shader_module(VkDevice device, char *path, VkShaderModule *module); + #define SWCH device->swap_chain static int swap_chain_support(VkPhysicalDevice phy_device, VkSurfaceKHR surface, struct swap_chain_support_details *details); static void swap_chain_free_support_details(struct swap_chain_support_details *details); @@ -85,9 +88,6 @@ static int swap_chain_choose_format(VkSurfaceFormatKHR* formats, u32 nformats, V static int swap_chain_choose_present_mode(VkPresentModeKHR *modes, u32 nmodes, VkPresentModeKHR *mode); static int swap_chain_get_extent(VkSurfaceCapabilitiesKHR capabilities, VkExtent2D *extent); -#define PPLN device->pipeline -static int pipeline_load_shader_module(VkDevice device, char *path, VkShaderModule *module); - #define CMND device->command static int command_buffer_record(device_t device, u32 image_index); @@ -128,13 +128,14 @@ device_t device_create(struct device_info *info) device->instance = VK_NULL_HANDLE; device->logical_device = VK_NULL_HANDLE; - SWCH.swap_chain = VK_NULL_HANDLE; - SWCH.nimages = 0; PPLN.pipeline = VK_NULL_HANDLE; PPLN.layout = VK_NULL_HANDLE; PPLN.render_pass = VK_NULL_HANDLE; + SWCH.swap_chain = VK_NULL_HANDLE; + SWCH.nimages = 0; + CMND.pool = VK_NULL_HANDLE; SYNC.semph_image_available = VK_NULL_HANDLE; @@ -148,8 +149,8 @@ device_t device_create(struct device_info *info) #endif CCHECK(create_physical_device); CCHECK(create_logical_device); - CCHECK(create_swap_chain); CCHECK(create_pipeline); + CCHECK(create_swap_chain); CCHECK(create_command_pool); CCHECK(create_sync_objects); @@ -169,8 +170,8 @@ void device_destroy(device_t device) vkDestroyCommandPool(device->logical_device, CMND.pool, NULL); - destroy_pipeline(device); destroy_swap_chain(device); + destroy_pipeline(device); vkDestroyDevice(device->logical_device, NULL); @@ -190,12 +191,21 @@ int device_draw_frame(device_t device) // wait for the previous frame to finish vkWaitForFences(device->logical_device, 1, &SYNC.fence_inflight, VK_TRUE, UINT64_MAX); - vkResetFences(device->logical_device, 1, &SYNC.fence_inflight); // aquire the next image the form the swap chain u32 image_index; - vkAcquireNextImageKHR(device->logical_device, SWCH.swap_chain, UINT64_MAX, SYNC.semph_image_available, VK_NULL_HANDLE, &image_index); + VkResult res = vkAcquireNextImageKHR(device->logical_device, SWCH.swap_chain, UINT64_MAX, SYNC.semph_image_available, VK_NULL_HANDLE, &image_index); + // recreate the swap chain on resize + if(res == VK_ERROR_OUT_OF_DATE_KHR) { + destroy_swap_chain(device); + create_swap_chain(device, NULL); + + ret = 0; goto exit; + } + + vkResetFences(device->logical_device, 1, &SYNC.fence_inflight); + // reset the command buffer vkResetCommandBuffer(CMND.buffer, 0); command_buffer_record(device, image_index); @@ -233,7 +243,9 @@ int device_draw_frame(device_t device) present_info.pImageIndices = &image_index; present_info.pResults = NULL; // Optional + vkQueuePresentKHR(device->present_queue, &present_info); + ret = 0; exit: @@ -425,7 +437,7 @@ static int create_swap_chain(device_t device, struct device_info *info) (void)info; int ret = 1; - struct swap_chain_support_details details = {0}; + struct swap_chain_support_details details; swap_chain_support(device->physical_device, device->surface, &details); VkSurfaceFormatKHR surface_format; @@ -487,6 +499,7 @@ static int create_swap_chain(device_t device, struct device_info *info) SWCH.images = xcalloc(SWCH.nimages, sizeof(*SWCH.images)); SWCH.image_views = xcalloc(SWCH.nimages, sizeof(SWCH.image_views)); + SWCH.framebuffers = xcalloc(SWCH.nimages, sizeof(*SWCH.framebuffers)); vkGetSwapchainImagesKHR(device->logical_device, SWCH.swap_chain, &SWCH.nimages, SWCH.images); @@ -513,6 +526,24 @@ static int create_swap_chain(device_t device, struct device_info *info) VCHECK(vkCreateImageView, device->logical_device, &create_info, NULL, &SWCH.image_views[i]); } + for(u32 i = 0; i < SWCH.nimages; i++) + { + VkImageView attachments[] = { + SWCH.image_views[i] + }; + + VkFramebufferCreateInfo framebuffer_info = {0}; + framebuffer_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; + framebuffer_info.renderPass = PPLN.render_pass; + framebuffer_info.attachmentCount = 1; + framebuffer_info.pAttachments = attachments; + framebuffer_info.width = SWCH.extent.width; + framebuffer_info.height = SWCH.extent.height; + framebuffer_info.layers = 1; + + VCHECK(vkCreateFramebuffer, device->logical_device, &framebuffer_info, NULL, &SWCH.framebuffers[i]); + } + ret = 0; exit: swap_chain_free_support_details(&details); @@ -523,11 +554,13 @@ static void destroy_swap_chain(device_t device) { for(u32 i = 0; i < SWCH.nimages; i++) { vkDestroyImageView(device->logical_device, SWCH.image_views[i], NULL); + vkDestroyFramebuffer(device->logical_device, SWCH.framebuffers[i], NULL); } if(SWCH.nimages != 0) { free(SWCH.images); free(SWCH.image_views); + free(SWCH.framebuffers); } vkDestroySwapchainKHR(device->logical_device, SWCH.swap_chain, NULL); @@ -639,9 +672,18 @@ static int create_pipeline(device_t device, struct device_info *info) VCHECK(vkCreatePipelineLayout, device->logical_device, &pipeline_layout_info, NULL, &PPLN.layout); + // get the required format + // currently the only to do that + // TOOD: fix this + VkSurfaceFormatKHR surface_format; + struct swap_chain_support_details details; + swap_chain_support(device->physical_device, device->surface, &details); + swap_chain_choose_format(details.formats, details.nformats, &surface_format); + swap_chain_free_support_details(&details); + // Create Render Pass VkAttachmentDescription color_attachment = {0}; - color_attachment.format = SWCH.image_format; + color_attachment.format = surface_format.format; color_attachment.samples = VK_SAMPLE_COUNT_1_BIT; color_attachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; color_attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; @@ -702,24 +744,6 @@ static int create_pipeline(device_t device, struct device_info *info) VCHECK(vkCreateGraphicsPipelines, device->logical_device, VK_NULL_HANDLE, 1, &pipeline_info, NULL, &PPLN.pipeline); - PPLN.framebuffers = xcalloc(SWCH.nimages, sizeof(*PPLN.framebuffers)); - for(u32 i = 0; i < SWCH.nimages; i++) { - VkImageView attachments[] = { - SWCH.image_views[i] - }; - - VkFramebufferCreateInfo framebuffer_info = {0}; - framebuffer_info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; - framebuffer_info.renderPass = PPLN.render_pass; - framebuffer_info.attachmentCount = 1; - framebuffer_info.pAttachments = attachments; - framebuffer_info.width = SWCH.extent.width; - framebuffer_info.height = SWCH.extent.height; - framebuffer_info.layers = 1; - - VCHECK(vkCreateFramebuffer, device->logical_device, &framebuffer_info, NULL, &PPLN.framebuffers[i]); - } - ret = 0; exit: vkDestroyShaderModule(device->logical_device, frag_shader, NULL); @@ -729,11 +753,6 @@ exit: static void destroy_pipeline(device_t device) { - for(u32 i = 0; i < SWCH.nimages; i++) { - vkDestroyFramebuffer(device->logical_device, PPLN.framebuffers[i], NULL); - } - if(SWCH.nimages > 0) free(PPLN.framebuffers); - vkDestroyPipeline(device->logical_device, PPLN.pipeline, NULL); vkDestroyPipelineLayout(device->logical_device, PPLN.layout, NULL); vkDestroyRenderPass(device->logical_device, PPLN.render_pass, NULL); @@ -971,7 +990,7 @@ static int command_buffer_record(device_t device, u32 image_index) VkRenderPassBeginInfo render_pass_info = {0}; render_pass_info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; render_pass_info.renderPass = PPLN.render_pass; - render_pass_info.framebuffer = PPLN.framebuffers[image_index]; + render_pass_info.framebuffer = SWCH.framebuffers[image_index]; render_pass_info.renderArea.offset = (VkOffset2D){0, 0}; render_pass_info.renderArea.extent = SWCH.extent; diff --git a/src/device.h b/src/device.h index fac15b9..b28c806 100644 --- a/src/device.h +++ b/src/device.h @@ -24,30 +24,28 @@ typedef struct device { VkQueue present_queue; VkSurfaceKHR surface; + + struct pipeline { + VkRenderPass render_pass; + VkPipelineLayout layout; + VkPipeline pipeline; + } pipeline; struct swap_chain { VkSwapchainKHR swap_chain; VkImage *images; VkImageView *image_views; + VkFramebuffer *framebuffers; u32 nimages; VkFormat image_format; VkExtent2D extent; } swap_chain; - struct pipeline { - VkRenderPass render_pass; - VkFramebuffer *framebuffers; - - VkPipelineLayout layout; - VkPipeline pipeline; - } pipeline; - struct command { VkCommandPool pool; VkCommandBuffer buffer; - // VkCommandBuffer *buffers; } command; struct sync { @@ -25,6 +25,7 @@ int main(void) // populate window info struct window_info win_info = {0}; win_info.title = "Test App"; + win_info.flags = SDL_WINDOW_RESIZABLE; win_info.w = 640; win_info.h = 480; |