diff --git a/graphics/src/rse_vulkan_image.c b/graphics/src/rse_vulkan_image.c index 35558e0f..e4b2f1ed 100644 --- a/graphics/src/rse_vulkan_image.c +++ b/graphics/src/rse_vulkan_image.c @@ -213,7 +213,7 @@ static rse_err_t create_color_resource() } -static rse_err_t create_depth_resources() +rse_err_t rse_create_depth_resources() { rse_err_t status = RSE_ERROR_NO_ERROR; VkFormat depth_format = {0}; @@ -262,6 +262,62 @@ static rse_err_t format_to_pixel_size(VkFormat format, return RSE_ERROR_NO_ERROR; } +static rse_err_t transition_image_layout(struct rse_vulkan_image_t* image, VkImageLayout old_layout, VkImageLayout new_layout) +{ + VkImageSubresourceRange range = {0}; + VkImageMemoryBarrier image_barrier = {0}; + VkCommandBuffer command_buffer = {0}; + VkPipelineStageFlags source_stage = {0}; + VkPipelineStageFlags destination_stage = {0}; + + /* Put image into correct layout to copy pixels from buffer to image memory */ + range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + range.baseMipLevel = 0; + range.levelCount = 1; + range.baseArrayLayer = 0; + range.layerCount = 1; + + image_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; + image_barrier.pNext = NULL; + image_barrier.oldLayout = old_layout; + image_barrier.newLayout = new_layout; + image_barrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + image_barrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; + image_barrier.image = image->image; + image_barrier.subresourceRange = range; + + if (old_layout == VK_IMAGE_LAYOUT_UNDEFINED && new_layout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) { + image_barrier.srcAccessMask = 0; + image_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + + source_stage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; + destination_stage = VK_PIPELINE_STAGE_TRANSFER_BIT; + } else if (old_layout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL && new_layout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) { + image_barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + image_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; + + source_stage = VK_PIPELINE_STAGE_TRANSFER_BIT; + destination_stage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; + } else { + return VULKAN_ERROR_TRANSITION_IMAGE_LAYOUT_FAILED; + } + + command_buffer = rse_begin_single_time_command(); + vkCmdPipelineBarrier(command_buffer, + source_stage, + destination_stage, + 0, + 0, + NULL, + 0, + NULL, + 1, + &image_barrier); + rse_end_single_time_comands(command_buffer); + + return RSE_ERROR_NO_ERROR; +} + static rse_err_t create_textured_image(uint32_t width, uint32_t height, @@ -272,8 +328,6 @@ static rse_err_t create_textured_image(uint32_t width, rse_err_t status = RSE_ERROR_NO_ERROR; struct rse_vulkan_buffer_t staging_buffer = {0}; VkDeviceSize staging_buffer_size = 0U; - VkImageSubresourceRange range = {0}; - VkImageMemoryBarrier image_barrier = {0}; VkCommandBuffer command_buffer = {0}; VkBufferImageCopy copy_region = {0}; VkExtent3D image_extent = {0}; @@ -312,37 +366,38 @@ static rse_err_t create_textured_image(uint32_t width, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT)); - /* Put image into correct layout to copy pixels from buffer to image memory */ - range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - range.baseMipLevel = 0; - range.levelCount = 1; - range.baseArrayLayer = 0; - range.layerCount = 1; - - image_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; - image_barrier.pNext = NULL; - image_barrier.srcAccessMask = 0U; - image_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - image_barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; - image_barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; - image_barrier.srcQueueFamilyIndex = 0U; - image_barrier.dstQueueFamilyIndex = 0U; - image_barrier.image = free_texture_image->image; - image_barrier.subresourceRange = range; - - command_buffer = rse_begin_single_time_command(); - vkCmdPipelineBarrier(command_buffer, - VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, - VK_PIPELINE_STAGE_TRANSFER_BIT, - 0, - 0, - NULL, - 0, - NULL, - 1, - &image_barrier); - rse_end_single_time_comands(command_buffer); + // /* Put image into correct layout to copy pixels from buffer to image memory */ + // range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + // range.baseMipLevel = 0; + // range.levelCount = 1; + // range.baseArrayLayer = 0; + // range.layerCount = 1; + // + // image_barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; + // image_barrier.pNext = NULL; + // image_barrier.srcAccessMask = 0U; + // image_barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + // image_barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; + // image_barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + // image_barrier.srcQueueFamilyIndex = 0U; + // image_barrier.dstQueueFamilyIndex = 0U; + // image_barrier.image = free_texture_image->image; + // image_barrier.subresourceRange = range; + // + // command_buffer = rse_begin_single_time_command(); + // vkCmdPipelineBarrier(command_buffer, + // VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, + // VK_PIPELINE_STAGE_TRANSFER_BIT, + // 0, + // 0, + // NULL, + // 0, + // NULL, + // 1, + // &image_barrier); + // rse_end_single_time_comands(command_buffer); + transition_image_layout(free_texture_image, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); /* Copy pixel data to GPU memory */ STATUS_CHECK(create_buffer(staging_buffer_size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, @@ -375,24 +430,27 @@ static rse_err_t create_textured_image(uint32_t width, rse_end_single_time_comands(command_buffer); destroy_buffer(&staging_buffer); - /* Change image layout for shaders to be able to read it */ - image_barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; - image_barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; - image_barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; - image_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; - command_buffer = rse_begin_single_time_command(); - vkCmdPipelineBarrier(command_buffer, - VK_PIPELINE_STAGE_TRANSFER_BIT, - VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, - 0, - 0, - NULL, - 0, - NULL, - 1, - &image_barrier); - rse_end_single_time_comands(command_buffer); + transition_image_layout(free_texture_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); + + // /* Change image layout for shaders to be able to read it */ + // image_barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + // image_barrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + // image_barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + // image_barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; + // + // command_buffer = rse_begin_single_time_command(); + // vkCmdPipelineBarrier(command_buffer, + // VK_PIPELINE_STAGE_TRANSFER_BIT, + // VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, + // 0, + // 0, + // NULL, + // 0, + // NULL, + // 1, + // &image_barrier); + // rse_end_single_time_comands(command_buffer); STATUS_CHECK(create_image_view(free_texture_image, format, VK_IMAGE_ASPECT_COLOR_BIT)); @@ -405,8 +463,8 @@ rse_err_t init_vulkan_images() rse_err_t status = RSE_ERROR_NO_ERROR; STATUS_CHECK(create_sampler()); - STATUS_CHECK(create_depth_resources()); - STATUS_CHECK(create_color_resource()); + STATUS_CHECK(rse_create_depth_resources()); + // STATUS_CHECK(create_color_resource()); return status; } @@ -465,6 +523,13 @@ void rse_destroy_textures() vmaDestroyImage(g_vulkan_state.allocator, g_color_image.image, g_color_image.allocation); } +void rse_destroy_depth_resource() +{ + + vkDestroyImageView(g_vulkan_state.device, g_depth_image.image_view, NULL); + vmaDestroyImage(g_vulkan_state.allocator, g_depth_image.image, g_depth_image.allocation); +} + uint8_t image_exists(uint8_t image_id) { return g_texture_images[image_id].id_taken == IMAGE_TAKEN; } diff --git a/graphics/src/rse_vulkan_image.h b/graphics/src/rse_vulkan_image.h index 5d551073..2fdac902 100644 --- a/graphics/src/rse_vulkan_image.h +++ b/graphics/src/rse_vulkan_image.h @@ -93,4 +93,7 @@ VkImageView rse_get_depth_image_view(void); VkImageView rse_get_color_image_view(void); +rse_err_t rse_create_depth_resources(void); +void rse_destroy_depth_resource(void); + #endif /* RSE_TEXTURE_H */ diff --git a/graphics/src/vulkan_errors.h b/graphics/src/vulkan_errors.h index bb5e8418..90f68fb0 100644 --- a/graphics/src/vulkan_errors.h +++ b/graphics/src/vulkan_errors.h @@ -40,7 +40,8 @@ enum rse_vulkan_error_t VULKAN_ERROR_IMAGE_NOT_CREATED, VULKAN_ERROR_IMAGE_VIEW_NOT_CREATED, VULKAN_ERROR_MAX_TEXTURE_COUNT_REACHED, + VULKAN_ERROR_TRANSITION_IMAGE_LAYOUT_FAILED, VULKAN_ERROR_DRAW_FAILED, }; -#endif \ No newline at end of file +#endif diff --git a/graphics/src/vulkan_pipeline.c b/graphics/src/vulkan_pipeline.c index 2db1b8ca..c2650c8f 100644 --- a/graphics/src/vulkan_pipeline.c +++ b/graphics/src/vulkan_pipeline.c @@ -1,6 +1,8 @@ #include "vulkan_pipeline.h" +#include "GLFW/glfw3.h" #include "locale_vulkan.h" +#include "src/window.h" #include "utilities/file_utils.h" #include "utilities/logger.h" #include "utilities/rse_errors_common.h" @@ -776,9 +778,19 @@ static rse_err_t create_framebuffers() */ void recreate_swapchain() { + int width = 0; + int height = 0; + + while (width == 0 || height == 0) { + glfwGetFramebufferSize(get_window_handle(), &width, &height); + glfwWaitEvents(); + } + cleanup_swapchain(); + create_swapchain(); create_swapchain_image_views(); + rse_create_depth_resources(); create_framebuffers(); } @@ -789,7 +801,10 @@ void recreate_swapchain() void cleanup_swapchain() { size_t i; + vkDeviceWaitIdle(g_vulkan_state.device); + + rse_destroy_depth_resource(); for (i = 0; i < g_swapchain_images_count; i++) { vkDestroyFramebuffer(g_vulkan_state.device, g_vulkan_state.swapchain_framebuffers[i], NULL); }