diff options
| -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; | 
