diff --git a/src/main.c b/src/main.c index 9b6311a..9aa019b 100644 --- a/src/main.c +++ b/src/main.c @@ -316,6 +316,26 @@ void object_update_mappings(Material material, Object object, uint32_t frame_num map_iterator_free(mapping_iterator); } +VkSemaphore* create_semaphores(VkDevice device, VkSemaphoreCreateFlags flags, uint32_t count) { + VkSemaphore* semaphores = malloc(sizeof(VkSemaphore)*count); + if(semaphores == 0) { + return 0; + } + + VkSemaphoreCreateInfo semaphore_info = {}; + semaphore_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; + semaphore_info.flags = flags; + + for(uint32_t i = 0; i < count; i++) { + VkResult result = vkCreateSemaphore(device, &semaphore_info, 0, &semaphores[i]); + if(result != VK_SUCCESS) { + free(semaphores); + return 0; + } + } + return semaphores; +} + VkFormat find_depth_format(VkPhysicalDevice physical_device, uint32_t num_requested, VkFormat* requested, VkImageTiling tiling, VkFormatFeatureFlags features) { for(uint32_t i = 0; i < num_requested; i++) { VkFormatProperties properties; @@ -763,7 +783,6 @@ VkSwapchainKHR create_swapchain(VkDevice device, VkSurfaceFormatKHR format, VkPr swapchain_info.compositeAlpha = VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR; swapchain_info.presentMode = present_mode; swapchain_info.clipped = VK_TRUE; - swapchain_info.oldSwapchain = old_swapchain; VkSwapchainKHR swapchain; @@ -1167,7 +1186,7 @@ VkResult command_copy_buffers(VkDevice device, VkCommandPool transfer_pool, VkQu return command_end_single(device, command_buffer, transfer_pool, transfer_queue); } -VkResult command_transition_image_layout(VkDevice device, VkCommandPool transfer_pool, VkQueue transfer_queue, VkImageLayout old_layout, VkImageLayout new_layout, VkImage image, VkAccessFlags src_mask, VkAccessFlags dst_mask, VkPipelineStageFlags source, VkPipelineStageFlags dest, uint32_t source_family, uint32_t dest_family) { +VkResult command_transition_image_layout(VkDevice device, VkCommandPool transfer_pool, VkQueue transfer_queue, VkImageLayout old_layout, VkImageLayout new_layout, VkImage image, VkAccessFlags src_mask, VkAccessFlags dst_mask, VkPipelineStageFlags source, VkPipelineStageFlags dest, uint32_t source_family, uint32_t dest_family, VkImageAspectFlags aspect_flags) { VkCommandBuffer command_buffer = command_begin_single(device, transfer_pool); VkImageMemoryBarrier barrier = { @@ -1178,7 +1197,7 @@ VkResult command_transition_image_layout(VkDevice device, VkCommandPool transfer .dstQueueFamilyIndex = dest_family, .image = image, .subresourceRange = { - .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, + .aspectMask = aspect_flags, .levelCount = 1, .layerCount = 1, .baseMipLevel = 0, @@ -1292,7 +1311,7 @@ Texture load_texture(VkPhysicalDeviceMemoryProperties memories, VkDevice device, return ret; } - result = command_transition_image_layout(device, transfer_pool, transfer_queue, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, image.image, 0, VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, transfer_family, transfer_family); + result = command_transition_image_layout(device, transfer_pool, transfer_queue, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, image.image, 0, VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, transfer_family, transfer_family, VK_IMAGE_ASPECT_COLOR_BIT); if(result != VK_SUCCESS) { deallocate_buffer(device, staging); deallocate_image(device, image); @@ -1306,14 +1325,14 @@ Texture load_texture(VkPhysicalDeviceMemoryProperties memories, VkDevice device, return ret; } - result = command_transition_image_layout(device, transfer_pool, transfer_queue, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, image.image, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, transfer_family, graphics_family); + result = command_transition_image_layout(device, transfer_pool, transfer_queue, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, image.image, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, transfer_family, graphics_family, VK_IMAGE_ASPECT_COLOR_BIT); if(result != VK_SUCCESS) { deallocate_buffer(device, staging); deallocate_image(device, image); return ret; } - result = command_transition_image_layout(device, graphics_pool, graphics_queue, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, image.image, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, transfer_family, graphics_family); + result = command_transition_image_layout(device, graphics_pool, graphics_queue, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, image.image, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_READ_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, transfer_family, graphics_family, VK_IMAGE_ASPECT_COLOR_BIT); if(result != VK_SUCCESS) { deallocate_buffer(device, staging); deallocate_image(device, image); @@ -1602,17 +1621,27 @@ int create_depth_image(VulkanContext* context) { context->depth_image_view = depth_image_view; } + result = command_transition_image_layout(context->device, context->extra_graphics_pool, context->queues.graphics, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL, context->depth_image, 0, 0, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED, VK_IMAGE_ASPECT_DEPTH_BIT); + if(result != VK_SUCCESS) { + fprintf(stderr, "failed to transition depth image\n"); + return 5; + } + return 0; } -VkResult recreate_swap_chain(VulkanContext* context) { +VkResult recreate_swapchain(VulkanContext* context) { for(uint32_t i = 0; i < context->swapchain_image_count; i++) { vkDestroyFramebuffer(context->device, context->swapchain_framebuffers[i], 0); vkDestroyImageView(context->device, context->swapchain_image_views[i], 0); } - vkDestroySwapchainKHR(context->device, context->swapchain, 0); - free(context->swapchain_images); + for(uint32_t i = 0; i < context->max_frames_in_flight; i++) { + vkDestroySemaphore(context->device, context->image_available_semaphores[i], 0); + } + + //vkDestroySwapchainKHR(context->device, context->swapchain, 0); + //free(context->swapchain_images); free(context->swapchain_image_views); free(context->swapchain_framebuffers); free(context->swapchain_details.formats); @@ -1665,6 +1694,14 @@ VkResult recreate_swap_chain(VulkanContext* context) { context->swapchain_framebuffers = framebuffers; } + VkSemaphore* ia_semaphores = create_semaphores(context->device, 0, context->max_frames_in_flight); + if(ia_semaphores == 0) { + fprintf(stderr, "failed to create vulkan image available semaphores\n"); + return 0; + } else { + context->image_available_semaphores = ia_semaphores; + } + return VK_SUCCESS; } @@ -1787,26 +1824,6 @@ VkCommandBuffer* create_command_buffers(VkDevice device, VkCommandPool command_p return command_buffers; } -VkSemaphore* create_semaphores(VkDevice device, VkSemaphoreCreateFlags flags, uint32_t count) { - VkSemaphore* semaphores = malloc(sizeof(VkSemaphore)*count); - if(semaphores == 0) { - return 0; - } - - VkSemaphoreCreateInfo semaphore_info = {}; - semaphore_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; - semaphore_info.flags = flags; - - for(uint32_t i = 0; i < count; i++) { - VkResult result = vkCreateSemaphore(device, &semaphore_info, 0, &semaphores[i]); - if(result != VK_SUCCESS) { - free(semaphores); - return 0; - } - } - return semaphores; -} - VkFence* create_fences(VkDevice device, VkFenceCreateFlags flags, uint32_t count) { VkFence* fences = malloc(sizeof(VkFence)*count); if(fences == 0) { @@ -2406,6 +2423,18 @@ VulkanContext* init_vulkan(GLFWwindow* window, uint32_t max_frames_in_flight) { context->depth_format = depth_format; } + VkCommandPoolCreateInfo extra_pool_info = { + .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, + .queueFamilyIndex = context->queue_indices.graphics_family, + .flags = VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, + }; + + result = vkCreateCommandPool(context->device, &extra_pool_info, 0, &context->extra_graphics_pool); + if(result != VK_SUCCESS) { + fprintf(stderr, "failed to create extra graphics command pool\n"); + return 0; + } + if(create_depth_image(context) != 0) { fprintf(stderr, "failed to create depth image\n"); return 0; @@ -2465,14 +2494,6 @@ VulkanContext* init_vulkan(GLFWwindow* window, uint32_t max_frames_in_flight) { context->swapchain_command_buffers = swapchain_command_buffers; } - VkCommandPoolCreateInfo extra_pool_info = { - .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, - .queueFamilyIndex = context->queue_indices.graphics_family, - .flags = VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, - }; - - result = vkCreateCommandPool(context->device, &extra_pool_info, 0, &context->extra_graphics_pool); - VkSemaphore* ia_semaphores = create_semaphores(context->device, 0, max_frames_in_flight); if(ia_semaphores == 0) { fprintf(stderr, "failed to create vulkan image available semaphores\n"); @@ -3261,7 +3282,8 @@ void main_loop(GLFWwindow* window, VulkanContext* context) { VkResult result = draw_frame(context, &scene, sizeof(materials)/sizeof(Material), materials, objects_counts, objects); if(result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR) { - recreate_swap_chain(context); + vkDeviceWaitIdle(context->device); + recreate_swapchain(context); } else if(result != VK_SUCCESS) { fprintf(stderr, "draw_frame error %d\n", result); return;