diff --git a/include/gpu_mem.h b/include/gpu_mem.h index 44f92b5..aa05f2c 100644 --- a/include/gpu_mem.h +++ b/include/gpu_mem.h @@ -46,6 +46,7 @@ void gpu_page_free(VkDevice device, GPUPage* page); VkResult gpu_buffer_malloc(VkDevice device, GPUPage* page, VkDeviceSize size, VkBufferUsageFlags usage, GPUBuffer* buffer); VkResult gpu_image_malloc(VkDevice device, GPUPage* page, VkImageCreateInfo* info, GPUImage* image); void gpu_buffer_free(VkDevice device, GPUBuffer buffer); +void gpu_image_free(VkDevice device, GPUImage image); void gpu_free(GPUPage* page, GPUMemoryChunk* memory); diff --git a/src/gpu_mem.c b/src/gpu_mem.c index 2d83405..b7d2653 100644 --- a/src/gpu_mem.c +++ b/src/gpu_mem.c @@ -239,6 +239,11 @@ VkResult gpu_buffer_malloc(VkDevice device, GPUPage* page, VkDeviceSize size, Vk return VK_SUCCESS; } +void gpu_image_free(VkDevice device, GPUImage image) { + vkDestroyImage(device, image.handle, 0); + gpu_free(image.page, image.memory); +} + void gpu_buffer_free(VkDevice device, GPUBuffer buffer) { vkDestroyBuffer(device, buffer.handle, 0); gpu_free(buffer.page, buffer.memory); diff --git a/src/main.c b/src/main.c index 2abbe78..a223382 100644 --- a/src/main.c +++ b/src/main.c @@ -1,6 +1,5 @@ #define VK_USE_PLATFORM_MACOS_MVK #include "vulkan/vulkan_core.h" -#include "vulkan/vk_enum_string_helper.h" #define GLFW_INCLUDE_VULKAN #include @@ -66,7 +65,7 @@ typedef struct SwapchainImagesStruct { } SwapchainImages; typedef struct TextureStruct { - AllocatedImage image; + GPUImage image; VkImageView view; VkSampler sampler; } Texture; @@ -1284,74 +1283,71 @@ AllocatedBuffer create_populated_buffer(VkPhysicalDeviceMemoryProperties memorie return vertex_buffer; } -Texture load_texture(VkPhysicalDeviceMemoryProperties memories, VkDevice device, VkCommandPool transfer_pool, VkQueue transfer_queue, VkCommandPool graphics_pool, VkQueue graphics_queue, VkExtent2D size, uint32_t stride, VkFormat format, void* image_data, uint32_t transfer_family, uint32_t graphics_family){ +Texture load_texture(VkDevice device, GPUPage* page, GPUBuffer staging, VkCommandPool transfer_pool, VkQueue transfer_queue, VkCommandPool graphics_pool, VkQueue graphics_queue, VkExtent2D size, VkFormat format, void* image_data, uint32_t transfer_family, uint32_t graphics_family){ Texture ret = { - .image.image = VK_NULL_HANDLE, - .image.memory = VK_NULL_HANDLE, + .image.page = NULL, + .image.memory = NULL, + .image.handle = VK_NULL_HANDLE, .view = VK_NULL_HANDLE, }; - uint32_t image_size = size.width * size.height * stride; - AllocatedBuffer staging = allocate_buffer(memories, device, image_size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); - if(staging.memory == VK_NULL_HANDLE) { - return ret; - } - - void* staging_ptr; - VkResult result = vkMapMemory(device, staging.memory, 0, image_size, 0, &staging_ptr); - if(result != VK_SUCCESS) { - deallocate_buffer(device, staging); - return ret; - } - - memcpy(staging_ptr, image_data, image_size); - - vkUnmapMemory(device, staging.memory); - VkExtent3D full_extent = { .width = size.width, .height = size.height, .depth = 1, }; - AllocatedImage image = allocate_image(memories, device, VK_IMAGE_TYPE_2D, format, full_extent, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, 0); - if(image.memory == VK_NULL_HANDLE) { - deallocate_buffer(device, staging); - deallocate_image(device, image); + + VkImageCreateInfo info = { + .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, + .imageType = VK_IMAGE_TYPE_2D, + .extent = full_extent, + .mipLevels = 1, + .arrayLayers = 1, + .format = format, + .tiling = VK_IMAGE_TILING_OPTIMAL, + .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED, + .usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, + .sharingMode = VK_SHARING_MODE_EXCLUSIVE, + .samples = VK_SAMPLE_COUNT_1_BIT, + .flags = 0, + }; + + GPUImage image = {0}; + VkResult result = gpu_image_malloc(device, page, &info, &image); + if(result != VK_SUCCESS) { 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, VK_IMAGE_ASPECT_COLOR_BIT); + memcpy(staging.page->ptr + staging.memory->offset, image_data, image.memory->size); + + result = command_transition_image_layout(device, transfer_pool, transfer_queue, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, image.handle, 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); + gpu_image_free(device, image); return ret; } - result = command_copy_buffer_to_image(device, transfer_pool, transfer_queue, full_extent, staging.buffer, image.image); + result = command_copy_buffer_to_image(device, transfer_pool, transfer_queue, full_extent, staging.handle, image.handle); if(result != VK_SUCCESS) { - deallocate_buffer(device, staging); - deallocate_image(device, image); + gpu_image_free(device, image); 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, VK_IMAGE_ASPECT_COLOR_BIT); + result = command_transition_image_layout(device, transfer_pool, transfer_queue, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, image.handle, 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); + gpu_image_free(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, VK_IMAGE_ASPECT_COLOR_BIT); + result = command_transition_image_layout(device, graphics_pool, graphics_queue, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, image.handle, 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); + gpu_image_free(device, image); return ret; } VkImageView view; VkImageViewCreateInfo view_info = { .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, - .image = image.image, + .image = image.handle, .viewType = VK_IMAGE_VIEW_TYPE_2D, .components = { .a = VK_COMPONENT_SWIZZLE_IDENTITY, @@ -1371,8 +1367,7 @@ Texture load_texture(VkPhysicalDeviceMemoryProperties memories, VkDevice device, result = vkCreateImageView(device, &view_info, 0, &view); if(result != VK_SUCCESS) { - deallocate_buffer(device, staging); - deallocate_image(device, image); + gpu_image_free(device, image); return ret; } @@ -1397,9 +1392,9 @@ Texture load_texture(VkPhysicalDeviceMemoryProperties memories, VkDevice device, }; result = vkCreateSampler(device, &sampler_info, 0, &sampler); - deallocate_buffer(device, staging); if(result != VK_SUCCESS) { - deallocate_image(device, image); + gpu_image_free(device, image); + vkDestroyImageView(device, view, 0); return ret; } @@ -3438,7 +3433,7 @@ Object create_texture_mesh_object(Material* texture_mesh_material, VkPhysicalDev RED, WHT, GRN, WHT, BLU, WHT, RED, WHT, GRN, BLK, }; - Texture test_texture = load_texture(memories, device, transfer_pool, transfer_queue, graphics_pool, graphics_queue, texture_size, 4, VK_FORMAT_R8G8B8A8_SRGB, texture_data, transfer_family, graphics_family); + Texture test_texture = load_texture(device, mesh_memory, transfer_buffer, transfer_pool, transfer_queue, graphics_pool, graphics_queue, texture_size, VK_FORMAT_R8G8B8A8_SRGB, texture_data, transfer_family, graphics_family); for(uint32_t i = 0; i < max_frames_in_flight; i++) { VkDescriptorImageInfo image_info = {