diff --git a/graphics/src/rse_vulkan_image.c b/graphics/src/rse_vulkan_image.c index 10903817..1e313a8e 100644 --- a/graphics/src/rse_vulkan_image.c +++ b/graphics/src/rse_vulkan_image.c @@ -1,9 +1,13 @@ #include "rse_vulkan_image.h" +#include #include "utilities/file_utils.h" #include "utilities/logger.h" +#include "utilities/rse_commons.h" #include "utilities/rse_errors_common.h" #include "locale_vulkan.h" +#include "vk_mem_alloc.h" +#include "vulkan/vulkan_core.h" #include "vulkan_errors.h" #include "rse_vulkan_commands.h" #include "vulkan_buffers.h" @@ -101,45 +105,33 @@ static rse_err_t find_supported_format(const VkFormat* candidates, return VULKAN_ERROR_FORMAT_NOT_FOUND; } -static rse_err_t create_depth_resources() +static rse_err_t create_image(struct rse_vulkan_image_t* image, uint32_t width, uint32_t height, VkFormat format, VkImageUsageFlags usage, VmaAllocationCreateFlags allocationFlags) { - rse_err_t status = RSE_ERROR_NO_ERROR; - VkFormat depth_format = {0}; VkExtent3D image_extent = {0}; VkImageCreateInfo image_info = {0}; VmaAllocationCreateInfo alloc_create_info = {0}; - VkImageViewCreateInfo image_view_create_info = {0}; - VkSurfaceCapabilitiesKHR physical_device_surface_capabilities; - - STATUS_CHECK(find_depth_format(&depth_format)); - vkGetPhysicalDeviceSurfaceCapabilitiesKHR(g_vulkan_state.physical_device, - g_vulkan_state.surface, - &physical_device_surface_capabilities); - - /*TODO: Remove boilerplate code */ - - image_extent.width = physical_device_surface_capabilities.currentExtent.width; - image_extent.height = physical_device_surface_capabilities.currentExtent.height; + image_extent.width = width; + image_extent.height = height; image_extent.depth = 1U; image_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; image_info.pNext = NULL; image_info.flags = 0U; image_info.imageType = VK_IMAGE_TYPE_2D; - image_info.format = depth_format; + image_info.format = format; image_info.extent = image_extent; image_info.mipLevels = 1U; image_info.arrayLayers = 1U; image_info.samples = VK_SAMPLE_COUNT_1_BIT; //TODO: Enable multisampling image_info.tiling = VK_IMAGE_TILING_OPTIMAL; - image_info.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; + image_info.usage = usage; image_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; //TODO: Change if used by more than one queue family image_info.queueFamilyIndexCount = 0U; image_info.pQueueFamilyIndices = NULL; image_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - alloc_create_info.flags = 0U; + alloc_create_info.flags = allocationFlags; alloc_create_info.usage = VMA_MEMORY_USAGE_AUTO; alloc_create_info.requiredFlags = 0U; alloc_create_info.preferredFlags = 0U; @@ -151,24 +143,31 @@ static rse_err_t create_depth_resources() if (VK_SUCCESS != vmaCreateImage(g_vulkan_state.allocator, &image_info, &alloc_create_info, - &g_depth_image.image, - &g_depth_image.allocation, - &g_depth_image.allocation_info)) { + &image->image, + &image->allocation, + &image->allocation_info)) { LOGF(vulkan_messages[VULKAN_IMAGE_NOT_CREATED]); return VULKAN_ERROR_IMAGE_NOT_CREATED; } + return RSE_ERROR_NO_ERROR; +} + +static rse_err_t create_image_view(struct rse_vulkan_image_t* image, VkFormat format, VkImageAspectFlags aspectFlags) +{ + VkImageViewCreateInfo image_view_create_info = {0}; + image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; image_view_create_info.pNext = NULL; image_view_create_info.flags = 0U; - image_view_create_info.image = g_depth_image.image; + image_view_create_info.image = image->image; image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D; /* 2D Texture */ - image_view_create_info.format = depth_format; + image_view_create_info.format = format; image_view_create_info.components.a = VK_COMPONENT_SWIZZLE_IDENTITY; image_view_create_info.components.r = VK_COMPONENT_SWIZZLE_IDENTITY; image_view_create_info.components.g = VK_COMPONENT_SWIZZLE_IDENTITY; image_view_create_info.components.b = VK_COMPONENT_SWIZZLE_IDENTITY; - image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; + image_view_create_info.subresourceRange.aspectMask = aspectFlags; image_view_create_info.subresourceRange.baseMipLevel = 0U; image_view_create_info.subresourceRange.levelCount = 1U; image_view_create_info.subresourceRange.baseArrayLayer = 0U; @@ -177,14 +176,40 @@ static rse_err_t create_depth_resources() if (VK_SUCCESS != vkCreateImageView(g_vulkan_state.device, &image_view_create_info, NULL, - &g_depth_image.image_view)) { + &image->image_view)) { LOGF(vulkan_messages[VULKAN_SWAPCHAIN_IMVIEW_CREATION_FAILED]); return VULKAN_ERROR_SWAPCHAIN_IMVIEW_CREATION_FAILED; } - return RSE_ERROR_NO_ERROR; } +// static rse_err_t create_color_resource() +// { +// return RSE_ERROR_NO_ERROR; +// } + + +static rse_err_t create_depth_resources() +{ + rse_err_t status = RSE_ERROR_NO_ERROR; + VkFormat depth_format = {0}; + VkSurfaceCapabilitiesKHR physical_device_surface_capabilities; + + + STATUS_CHECK(find_depth_format(&depth_format)); + vkGetPhysicalDeviceSurfaceCapabilitiesKHR(g_vulkan_state.physical_device, + g_vulkan_state.surface, + &physical_device_surface_capabilities); + + STATUS_CHECK(create_image(&g_depth_image, + physical_device_surface_capabilities.currentExtent.width, + physical_device_surface_capabilities.currentExtent.height, + depth_format, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, 0U)); + STATUS_CHECK(create_image_view(&g_depth_image, depth_format, VK_IMAGE_ASPECT_DEPTH_BIT)); + + return status; +} + static rse_err_t format_to_pixel_size(VkFormat format, VkDeviceSize* format_size) { @@ -203,7 +228,7 @@ static rse_err_t format_to_pixel_size(VkFormat format, } -static rse_err_t create_vulkan_image(uint32_t width, +static rse_err_t create_textured_image(uint32_t width, uint32_t height, VkFormat format, unsigned char* pixels, @@ -212,16 +237,17 @@ static rse_err_t create_vulkan_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; - VkImageCreateInfo image_info = {0}; - VmaAllocationCreateInfo alloc_create_info = {0}; VkImageSubresourceRange range = {0}; VkImageMemoryBarrier image_barrier = {0}; VkCommandBuffer command_buffer = {0}; VkBufferImageCopy copy_region = {0}; VkExtent3D image_extent = {0}; - VkImageViewCreateInfo image_view_create_info = {0}; struct rse_vulkan_image_t* free_texture_image = NULL; + image_extent.width = width; + image_extent.height = height; + image_extent.depth = 1U; + *texture_id = 0U; while(free_texture_image == NULL && *texture_id < RSE_MAX_IMAGE_COUNT) { @@ -243,44 +269,12 @@ static rse_err_t create_vulkan_image(uint32_t width, staging_buffer_size = staging_buffer_size * width * height; - image_extent.width = width; - image_extent.height = height; - image_extent.depth = 1U; - - image_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; - image_info.pNext = NULL; - image_info.flags = 0U; - image_info.imageType = VK_IMAGE_TYPE_2D; - image_info.format = format; - image_info.extent = image_extent; - image_info.mipLevels = 1U; - image_info.arrayLayers = 1U; - image_info.samples = VK_SAMPLE_COUNT_1_BIT; //TODO: Enable multisampling - image_info.tiling = VK_IMAGE_TILING_OPTIMAL; - image_info.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; - image_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; //TODO: Change if used by more than one queue family - image_info.queueFamilyIndexCount = 0U; - image_info.pQueueFamilyIndices = NULL; - image_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED; - - alloc_create_info.flags = VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT; - alloc_create_info.usage = VMA_MEMORY_USAGE_AUTO; - alloc_create_info.requiredFlags = 0U; - alloc_create_info.preferredFlags = 0U; - alloc_create_info.memoryTypeBits = 0U; - alloc_create_info.pool = NULL; - alloc_create_info.pUserData = NULL; - alloc_create_info.priority = 1.0f; - - if (VK_SUCCESS != vmaCreateImage(g_vulkan_state.allocator, - &image_info, - &alloc_create_info, - &free_texture_image->image, - &free_texture_image->allocation, - &free_texture_image->allocation_info)) { - LOGF(vulkan_messages[VULKAN_IMAGE_NOT_CREATED]); - return VULKAN_ERROR_IMAGE_NOT_CREATED; - } + STATUS_CHECK(create_image(free_texture_image, + width, + height, + format, + 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; @@ -364,26 +358,7 @@ static rse_err_t create_vulkan_image(uint32_t width, &image_barrier); rse_end_single_time_comands(command_buffer); - /* Fill image view */ - image_view_create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; - image_view_create_info.pNext = NULL; - image_view_create_info.flags = 0U; - image_view_create_info.image = free_texture_image->image; - image_view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D; - image_view_create_info.format = format; - image_view_create_info.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - image_view_create_info.subresourceRange.baseMipLevel = 0; - image_view_create_info.subresourceRange.levelCount = 1; - image_view_create_info.subresourceRange.baseArrayLayer = 0; - image_view_create_info.subresourceRange.layerCount = 1; - - if (VK_SUCCESS != vkCreateImageView(g_vulkan_state.device, - &image_view_create_info, - NULL, - &free_texture_image->image_view)) { - LOGF(vulkan_messages[VULKAN_IMAGE_VIEW_NOT_CREATED]); - return VULKAN_ERROR_IMAGE_VIEW_NOT_CREATED; - } + STATUS_CHECK(create_image_view(free_texture_image, format, VK_IMAGE_ASPECT_COLOR_BIT)); free_texture_image->id_taken = IMAGE_TAKEN; return RSE_ERROR_NO_ERROR; @@ -415,7 +390,7 @@ rse_err_t rse_load_texture(const char* file_path, uint16_t* texture_id) } /* Create actual Vulkan Image */ - status = create_vulkan_image(width, + status = create_textured_image(width, height, VK_FORMAT_R8G8B8A8_SRGB, pixel_buffer, texture_id);