From 9af8d5149df8723482dd1a2fec0ea5ed97e58e72 Mon Sep 17 00:00:00 2001 From: Draklaw Date: Tue, 11 Jan 2022 01:01:08 +0100 Subject: [PATCH] Use index buffer. --- src/Vulkan/Context.cpp | 106 +++++++++++++++++++++++++++++++---------- src/Vulkan/Context.h | 10 +++- src/VulkanTutorial.cpp | 93 ++++++++++++++++-------------------- src/VulkanTutorial.h | 3 ++ 4 files changed, 135 insertions(+), 77 deletions(-) diff --git a/src/Vulkan/Context.cpp b/src/Vulkan/Context.cpp index 8e45eac..921475f 100644 --- a/src/Vulkan/Context.cpp +++ b/src/Vulkan/Context.cpp @@ -338,6 +338,60 @@ std::tuple Context::create_buffer(VkDeviceSize size, V return { buffer, memory }; } +std::tuple Context::create_buffer( + VkDeviceSize size, char* data, + VkBufferUsageFlags usage, + VkMemoryPropertyFlags memory_properties, + uint32_t dst_queue_family +) { + VkBuffer tmp_buffer = VK_NULL_HANDLE; + VkDeviceMemory tmp_buffer_memory = VK_NULL_HANDLE; + std::tie(tmp_buffer, tmp_buffer_memory) = create_buffer( + size, + VK_BUFFER_USAGE_TRANSFER_SRC_BIT, + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT + | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT + ); + auto const tmp_buffer_guard = make_guard([&] { + free_memory(tmp_buffer_memory); + destroy_buffer(tmp_buffer); + }); + + VkBuffer buffer = VK_NULL_HANDLE; + VkDeviceMemory buffer_memory = VK_NULL_HANDLE; + std::tie(buffer, buffer_memory) = create_buffer( + size, + usage | VK_BUFFER_USAGE_TRANSFER_DST_BIT, + memory_properties + ); + + void* device_buffer = nullptr; + vkMapMemory( + m_device, + tmp_buffer_memory, + 0, + size, + 0, + &device_buffer + ); + + memcpy(device_buffer, data, size_t(size)); + + vkUnmapMemory( + m_device, + tmp_buffer_memory + ); + + copy_buffer( + buffer, + tmp_buffer, + dst_queue_family, + size + ); + + return std::make_tuple(buffer, buffer_memory); +} + void Context::copy_buffer(VkBuffer dst, VkBuffer src, uint32_t dst_queue_family, VkDeviceSize size) { VkCommandBufferAllocateInfo alloc_info { .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, @@ -387,6 +441,8 @@ void Context::copy_buffer(VkBuffer dst, VkBuffer src, uint32_t dst_queue_family, vkEndCommandBuffer(command_buffer); + vkResetFences(m_device, 1, &m_transfer_fence); + VkSubmitInfo submit_info { .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, .commandBufferCount = 1, @@ -853,33 +909,35 @@ VKAPI_ATTR VkBool32 VKAPI_CALL Context::log_debug_message( const VkDebugUtilsMessengerCallbackDataEXT* data, void* user_data ) { - auto stream = [severity]() { - switch(severity) { - case VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT: + { + auto stream = [severity]() { + switch(severity) { + case VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT: + return logger.debug(); + case VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT: + return logger.info(); + case VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT: + return logger.warning(); + case VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT: + return logger.error(); + } return logger.debug(); - case VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT: - return logger.info(); - case VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT: - return logger.warning(); - case VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT: - return logger.error(); + }(); + + switch(type) { + case VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT: + stream << "[vk:general] "; + break; + case VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT: + stream << "[vk:validation] "; + break; + case VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT: + stream << "[vk:performance] "; + break; } - return logger.debug(); - }(); - - switch(type) { - case VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT: - stream << "[vk:general] "; - break; - case VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT: - stream << "[vk:validation] "; - break; - case VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT: - stream << "[vk:performance] "; - break; - } - stream << data->pMessage; + stream << data->pMessage; + } if(severity == VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) abort(); diff --git a/src/Vulkan/Context.h b/src/Vulkan/Context.h index 564d6c2..69fb317 100644 --- a/src/Vulkan/Context.h +++ b/src/Vulkan/Context.h @@ -103,7 +103,15 @@ public: int32_t find_memory_type(uint32_t type_filter, VkMemoryPropertyFlags properties); VkDeviceMemory allocate_memory(VkDeviceSize size, uint32_t type_filter, VkMemoryPropertyFlags properties); - std::tuple create_buffer(VkDeviceSize size, VkBufferUsageFlags usage, VkMemoryPropertyFlags memory_properties); + std::tuple create_buffer( + VkDeviceSize size, + VkBufferUsageFlags usage, + VkMemoryPropertyFlags memory_properties); + std::tuple create_buffer( + VkDeviceSize size, char* buffer, + VkBufferUsageFlags usage, + VkMemoryPropertyFlags memory_properties, + uint32_t dst_queue_family); void copy_buffer(VkBuffer dst, VkBuffer src, uint32_t dst_queue_family, VkDeviceSize size); diff --git a/src/VulkanTutorial.cpp b/src/VulkanTutorial.cpp index 2f08392..5a29d98 100644 --- a/src/VulkanTutorial.cpp +++ b/src/VulkanTutorial.cpp @@ -40,9 +40,15 @@ std::array Vertex::attributes_description( const std::vector vertices = { - {{0.0f, -0.5f}, {1.0f, 0.0f, 0.0f}}, - {{0.5f, 0.5f}, {0.0f, 1.0f, 0.0f}}, - {{-0.5f, 0.5f}, {0.0f, 0.0f, 1.0f}} + {{-0.5f, -0.5f}, {1.0f, 0.0f, 0.0f}}, + {{0.5f, -0.5f}, {0.0f, 1.0f, 0.0f}}, + {{-0.5f, 0.5f}, {0.0f, 0.0f, 1.0f}}, + {{0.5f, 0.5f}, {1.0f, 1.0f, 1.0f}}, +}; + +const std::vector indices = { + 0, 1, 2, + 2, 1, 3, }; @@ -66,12 +72,13 @@ void VulkanTutorial::initialize(SDL_Window* window) { .with_window(window); m_context.initialize(context_settings); + create_command_pool(); + create_vertex_buffer(); + create_index_buffer(); + auto const swapchain_settings = Vulkan::SwapchainSettings(&m_context) .with_queue(m_context.queue_family(GRAPHIC_QUEUE)); m_swapchain.initialize(swapchain_settings); - - create_command_pool(); - create_vertex_buffer(); } void VulkanTutorial::shutdown() { @@ -84,8 +91,10 @@ void VulkanTutorial::shutdown() { m_context.free_memory(m_vertex_buffer_memory); m_context.destroy_command_pool(m_command_pool); - m_context.destroy_buffer(m_vertex_buffer); + m_context.free_memory(m_index_buffer_memory); + m_context.destroy_buffer(m_index_buffer); m_context.free_memory(m_vertex_buffer_memory); + m_context.destroy_buffer(m_vertex_buffer); for(VkSemaphore semaphore: m_render_done) m_context.destroy_semaphore(semaphore); @@ -436,57 +445,29 @@ void VulkanTutorial::create_vertex_buffer() { if(m_vertex_buffer != VK_NULL_HANDLE) return; - VkDeviceSize buffer_size = sizeof(vertices[0]) * vertices.size(); - - VkBuffer tmp_buffer = VK_NULL_HANDLE; - VkDeviceMemory tmp_buffer_memory = VK_NULL_HANDLE; - std::tie(tmp_buffer, tmp_buffer_memory) = m_context.create_buffer( - buffer_size, - VK_BUFFER_USAGE_TRANSFER_SRC_BIT, - VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT - | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT - ); - auto const tmp_buffer_guard = make_guard([&] { - m_context.free_memory(tmp_buffer_memory); - m_context.destroy_buffer(tmp_buffer); - }); - + VkDeviceSize size = sizeof(vertices[0]) * vertices.size(); std::tie(m_vertex_buffer, m_vertex_buffer_memory) = m_context.create_buffer( - buffer_size, - VK_BUFFER_USAGE_VERTEX_BUFFER_BIT - | VK_BUFFER_USAGE_TRANSFER_DST_BIT, - VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT - ); - - void* buffer = nullptr; - vkMapMemory( - m_context.device(), - tmp_buffer_memory, - 0, - buffer_size, - 0, - &buffer + size, (char*)vertices.data(), + VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, + m_context.queue_family(GRAPHIC_QUEUE) ); +} - memcpy(buffer, vertices.data(), size_t(buffer_size)); - - vkUnmapMemory( - m_context.device(), - tmp_buffer_memory - ); +void VulkanTutorial::create_index_buffer() { + if(m_index_buffer != VK_NULL_HANDLE) + return; - m_context.copy_buffer( - m_vertex_buffer, - tmp_buffer, - m_context.queue_family(GRAPHIC_QUEUE), - buffer_size + VkDeviceSize size = sizeof(indices[0]) * indices.size(); + std::tie(m_index_buffer, m_index_buffer_memory) = m_context.create_buffer( + size, (char*)indices.data(), + VK_BUFFER_USAGE_INDEX_BUFFER_BIT, + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, + m_context.queue_family(GRAPHIC_QUEUE) ); } void VulkanTutorial::create_command_buffers() { - create_command_pool(); - create_vertex_buffer(); - m_command_buffers.resize(m_framebuffers.size()); VkCommandBufferAllocateInfo allocate_info { @@ -564,11 +545,19 @@ void VulkanTutorial::create_command_buffers() { offsets ); - vkCmdDraw( + vkCmdBindIndexBuffer( command_buffer, - uint32_t(vertices.size()), + m_index_buffer, + 0, + VK_INDEX_TYPE_UINT16 + ); + + vkCmdDrawIndexed( + command_buffer, + uint32_t(indices.size()), 1, 0, + 0, 0 ); diff --git a/src/VulkanTutorial.h b/src/VulkanTutorial.h index 887ce92..9225496 100644 --- a/src/VulkanTutorial.h +++ b/src/VulkanTutorial.h @@ -46,6 +46,7 @@ private: void create_framebuffers(); void create_command_pool(); void create_vertex_buffer(); + void create_index_buffer(); void create_command_buffers(); private: @@ -61,6 +62,8 @@ private: VkCommandPool m_command_pool = VK_NULL_HANDLE; VkBuffer m_vertex_buffer = VK_NULL_HANDLE; VkDeviceMemory m_vertex_buffer_memory = VK_NULL_HANDLE; + VkBuffer m_index_buffer = VK_NULL_HANDLE; + VkDeviceMemory m_index_buffer_memory = VK_NULL_HANDLE; std::vector m_command_buffers; std::vector m_render_done; };