summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkartofen <mladenovnasko0@gmail.com>2023-10-22 20:03:33 +0300
committerkartofen <mladenovnasko0@gmail.com>2023-10-22 20:03:33 +0300
commit7e555eeadd1f295db7700b8bde884fcb92bb2b8d (patch)
tree14ca519023f8e2e208d95d0250ee37a7b1b75fa8
parent560f07e306da1906720ffc8a7de32069b8b7353e (diff)
swap chain recreation and minor stuff
-rw-r--r--src/device.c93
-rw-r--r--src/device.h16
-rw-r--r--src/main.c1
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 {
diff --git a/src/main.c b/src/main.c
index 678db3a..8fd7345 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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;