From 734db410d118a4c7a6b741a511e76b31fdb98c8b Mon Sep 17 00:00:00 2001 From: Jiga228 Date: Wed, 29 Oct 2025 13:20:04 +0700 Subject: [PATCH] Add RenderEngineSDK --- .../DeviceFunctions/DeviceFunctions.cpp | 125 ++++++++ .../DeviceFunctions/DeviceFunctions.hpp | 22 ++ UwURenderEngine/CMakeLists.txt | 2 +- UwURenderEngine/RenderEngine/ModelManager.cpp | 52 +++- UwURenderEngine/RenderEngine/ModelManager.hpp | 28 +- .../RenderEngine/UwURenderEngine.cpp | 266 +++++------------- .../RenderEngine/UwURenderEngine.hpp | 24 +- 7 files changed, 289 insertions(+), 230 deletions(-) create mode 100644 RenderEngineSDK/DeviceFunctions/DeviceFunctions.cpp create mode 100644 RenderEngineSDK/DeviceFunctions/DeviceFunctions.hpp diff --git a/RenderEngineSDK/DeviceFunctions/DeviceFunctions.cpp b/RenderEngineSDK/DeviceFunctions/DeviceFunctions.cpp new file mode 100644 index 0000000..44b6d87 --- /dev/null +++ b/RenderEngineSDK/DeviceFunctions/DeviceFunctions.cpp @@ -0,0 +1,125 @@ +#include "DeviceFunctions.hpp" + +#include +#include + +VkExtent2D DeviceFunctions::choose_extent(const VkSurfaceCapabilitiesKHR& capabilities, GLFWwindow* window) +{ + // The acceptable rendering sparsity is calculated here + if (capabilities.currentExtent.width != std::numeric_limits::max()) + return capabilities.currentExtent; + else + { + int width, height; + glfwGetFramebufferSize(window, &width, &height); + VkExtent2D actualExtent = { + static_cast(width), + static_cast(height) + }; + actualExtent.width = std::max(capabilities.minImageExtent.width, std::min(capabilities.maxImageExtent.width, actualExtent.width)); + return actualExtent; + } +} + +uint32_t DeviceFunctions::find_memory_type(VkPhysicalDevice physical_device, uint32_t typeFilter, + VkMemoryPropertyFlags properties) +{ + VkPhysicalDeviceMemoryProperties memory_properties{}; + vkGetPhysicalDeviceMemoryProperties(physical_device, &memory_properties); + + for (uint32_t i = 0; i < memory_properties.memoryTypeCount; ++i) + { + if (typeFilter & (1 << i) && (memory_properties.memoryTypes[i].propertyFlags & properties) == properties) + return i; + } + + throw std::runtime_error("failed to find suitable memory type!"); +} + +void DeviceFunctions::device_memcpy(VkDevice device, uint32_t transfer_queue_family, VkBuffer src, VkBuffer dst, size_t size) +{ + VkCommandPool copy_pool; + VkCommandPoolCreateInfo copy_pool_info{}; + copy_pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; + copy_pool_info.queueFamilyIndex = transfer_queue_family; + copy_pool_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; + VK_CHECK(vkCreateCommandPool(device, ©_pool_info, nullptr, ©_pool)); + + VkCommandBufferAllocateInfo command_buffer_allocate_info{}; + command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; + command_buffer_allocate_info.commandPool = copy_pool; + command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; + command_buffer_allocate_info.commandBufferCount = 1; + + VkCommandBuffer copy_buffer; + VK_CHECK(vkAllocateCommandBuffers(device, &command_buffer_allocate_info, ©_buffer)); + + VkCommandBufferBeginInfo command_buffer_begin_info{}; + command_buffer_begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; + command_buffer_begin_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; + + VK_CHECK(vkBeginCommandBuffer(copy_buffer, &command_buffer_begin_info)); + + VkBufferCopy buffer_copy{}; + buffer_copy.srcOffset = 0; + buffer_copy.dstOffset = 0; + buffer_copy.size = size; + vkCmdCopyBuffer(copy_buffer, src, dst, 1, &buffer_copy); + + vkEndCommandBuffer(copy_buffer); + + VkSubmitInfo submit_info{}; + submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; + submit_info.commandBufferCount = 1; + submit_info.pCommandBuffers = ©_buffer; + + VkQueue transfer_queue; + vkGetDeviceQueue(device, transfer_queue_family, 0, &transfer_queue); + + vkQueueSubmit(transfer_queue, 1, &submit_info, VK_NULL_HANDLE); + vkQueueWaitIdle(transfer_queue); + + vkFreeCommandBuffers(device, copy_pool, 1, ©_buffer); + vkDestroyCommandPool(device, copy_pool, nullptr); +} + +VkBuffer DeviceFunctions::create_buffer(VkDevice device, VkDeviceSize size, VkBufferUsageFlags usage, + const std::vector& queue_families) +{ + VkBufferCreateInfo buffer_info{}; + buffer_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; + buffer_info.size = size; + buffer_info.usage = usage; + + if (queue_families.size() > 1) + { + buffer_info.sharingMode = VK_SHARING_MODE_CONCURRENT; + buffer_info.queueFamilyIndexCount = static_cast(queue_families.size()); + buffer_info.pQueueFamilyIndices = queue_families.data(); + } + else + { + buffer_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + buffer_info.queueFamilyIndexCount = 0; + buffer_info.pQueueFamilyIndices = nullptr; + } + + VkBuffer buffer; + VK_CHECK(vkCreateBuffer(device, &buffer_info, nullptr, &buffer)); + return buffer; +} + +VkDeviceMemory DeviceFunctions::allocate_device_memory(VkPhysicalDevice physical_device, VkDevice device, VkBuffer buffer, VkMemoryPropertyFlags property) +{ + VkMemoryRequirements requirements{}; + vkGetBufferMemoryRequirements(device, buffer, &requirements); + + VkMemoryAllocateInfo allocate_info{}; + allocate_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; + allocate_info.allocationSize = requirements.size; + allocate_info.memoryTypeIndex = find_memory_type(physical_device, requirements.memoryTypeBits, property); + + VkDeviceMemory device_memory; + VK_CHECK(vkAllocateMemory(device, &allocate_info, nullptr, &device_memory)); + return device_memory; +} diff --git a/RenderEngineSDK/DeviceFunctions/DeviceFunctions.hpp b/RenderEngineSDK/DeviceFunctions/DeviceFunctions.hpp new file mode 100644 index 0000000..be009fd --- /dev/null +++ b/RenderEngineSDK/DeviceFunctions/DeviceFunctions.hpp @@ -0,0 +1,22 @@ +#pragma once + +#define GLFW_INCLUDE_VULKAN +#include + +#include + +#ifdef _DEBUG +#include +#define VK_CHECK(res) assert(res == VK_SUCCESS); +#else +#define VK_CHECK(val) {int res = (val); if ((res) != VK_SUCCESS) throw std::runtime_error("Vulkan error: " + std::to_string(static_cast(res)));} +#endif + +namespace DeviceFunctions +{ + VkExtent2D choose_extent(const VkSurfaceCapabilitiesKHR& capabilities, GLFWwindow* window); + uint32_t find_memory_type(VkPhysicalDevice physical_device, uint32_t typeFilter, VkMemoryPropertyFlags properties); + void device_memcpy(VkDevice device, uint32_t transfer_queue_family, VkBuffer src, VkBuffer dst, size_t size); + VkBuffer create_buffer(VkDevice device, VkDeviceSize size, VkBufferUsageFlags usage, const std::vector& queue_families); + VkDeviceMemory allocate_device_memory(VkPhysicalDevice physical_device, VkDevice device, VkBuffer buffer, VkMemoryPropertyFlags property); +} diff --git a/UwURenderEngine/CMakeLists.txt b/UwURenderEngine/CMakeLists.txt index 2b066f3..653b0c0 100644 --- a/UwURenderEngine/CMakeLists.txt +++ b/UwURenderEngine/CMakeLists.txt @@ -2,6 +2,6 @@ file(GLOB_RECURSE SRC "*.cpp" "*.c" "*.hpp" "*.h") add_library(UwURenderEngine ${SRC}) target_include_directories(UwURenderEngine PUBLIC ${PROJECT_SOURCE_DIR}/RenderEngineSDK) -target_link_libraries(UwURenderEngine PRIVATE RenderEngineSDK) +target_link_libraries(UwURenderEngine PUBLIC RenderEngineSDK) target_compile_features(UwURenderEngine PRIVATE cxx_std_17) \ No newline at end of file diff --git a/UwURenderEngine/RenderEngine/ModelManager.cpp b/UwURenderEngine/RenderEngine/ModelManager.cpp index acaa73a..587132d 100644 --- a/UwURenderEngine/RenderEngine/ModelManager.cpp +++ b/UwURenderEngine/RenderEngine/ModelManager.cpp @@ -1,7 +1,47 @@ #include "ModelManager.hpp" +#include + #include "Log/Log.hpp" +ModelManager::StaticModel::StaticModel(const std::vector& vertices, const std::vector& indices, + VkPhysicalDevice physical_device, VkDevice device): +physical_device_(physical_device), +device_(device) +{ +} + +ModelManager::StaticModel::~StaticModel() +{ +} + +VkVertexInputBindingDescription ModelManager::Vertex::get_binding_description() +{ + VkVertexInputBindingDescription description; + description.binding = 0; + description.stride = sizeof(Vertex); + description.inputRate = VK_VERTEX_INPUT_RATE_VERTEX; + return description; +} + +std::array ModelManager::Vertex::get_vertex_attribute_descriptions() +{ + std::array descriptions; + // Bind vertex loc + descriptions[0].binding = 0; + descriptions[0].location = 0; + descriptions[0].format = VK_FORMAT_R32G32B32_SFLOAT; + descriptions[0].offset = offsetof(Vertex, pos); + + // Bind color + descriptions[1].binding = 0; + descriptions[1].location = 1; + descriptions[1].format = VK_FORMAT_R32G32B32_SFLOAT; + descriptions[1].offset = offsetof(Vertex, color); + + return descriptions; +} + ModelManager::owner_counter::owner_counter(const owner_counter& other) : counter(other.counter.load()), model(other.model) { } @@ -19,6 +59,11 @@ unsigned int ModelManager::FNV1aHash(const char* buf) return h_val; } +ModelManager::ModelManager(VkPhysicalDevice physical_device, VkDevice device): +physical_device_(physical_device), +device_(device) +{} + ModelManager::~ModelManager() { models.clear(); @@ -37,11 +82,14 @@ ModelManager::StaticModel* ModelManager::LoadModel(const std::string& name) } Loging::Log("Load new model: " + name); - + + std::vector vertices; + std::vector indices; // Load model_data + owner_counter new_counter; new_counter.counter.store(1); - new_counter.model = new StaticModel(); + new_counter.model = new StaticModel(vertices, indices, physical_device_, device_); models.try_emplace(hash, new_counter); return new_counter.model; } diff --git a/UwURenderEngine/RenderEngine/ModelManager.hpp b/UwURenderEngine/RenderEngine/ModelManager.hpp index fba7e57..61133b3 100644 --- a/UwURenderEngine/RenderEngine/ModelManager.hpp +++ b/UwURenderEngine/RenderEngine/ModelManager.hpp @@ -3,14 +3,34 @@ #include #include #include +#include + +#include class ModelManager { public: + struct Vertex + { + glm::vec3 pos, color; + static VkVertexInputBindingDescription get_binding_description(); + static std::array get_vertex_attribute_descriptions(); + + }; class StaticModel { - //DATA - }; + VkPhysicalDevice physical_device_; + VkDevice device_; + VkBuffer vertex_buffer_; + VkBuffer index_buffer_; + + + public: + StaticModel(const std::vector& vertices, const std::vector& indices, + VkPhysicalDevice physical_device, VkDevice device); + ~StaticModel(); + + }; struct owner_counter { @@ -22,12 +42,14 @@ public: }; private: - + VkPhysicalDevice physical_device_; + VkDevice device_; std::unordered_map models; static unsigned int FNV1aHash (const char *buf); public: + ModelManager(VkPhysicalDevice physical_device, VkDevice device); ~ModelManager(); StaticModel* LoadModel(const std::string& name); diff --git a/UwURenderEngine/RenderEngine/UwURenderEngine.cpp b/UwURenderEngine/RenderEngine/UwURenderEngine.cpp index f5d49fb..abe3c0a 100644 --- a/UwURenderEngine/RenderEngine/UwURenderEngine.cpp +++ b/UwURenderEngine/RenderEngine/UwURenderEngine.cpp @@ -12,6 +12,7 @@ #include "Game/GameInstance.hpp" #include "Game/World/World.hpp" #include "../Game/Actors/Mesh/Mesh.hpp" +#include "DeviceFunctions/DeviceFunctions.hpp" const std::vector UwURenderEngine::deviceExtensions = { VK_KHR_SWAPCHAIN_EXTENSION_NAME @@ -47,14 +48,14 @@ UwURenderEngine::SwapchainSupportDetails UwURenderEngine::query_swapchain_detail vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physical_device_, surface_, &details.capabilities); uint32_t surface_format_cnt = 0; - VK_CHECK(vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device_, surface_, &surface_format_cnt, nullptr)); + VK_CHECK(vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device_, surface_, &surface_format_cnt, nullptr)) details.formats.resize(surface_format_cnt); - VK_CHECK(vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device_, surface_, &surface_format_cnt, details.formats.data())); + VK_CHECK(vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device_, surface_, &surface_format_cnt, details.formats.data())) uint32_t present_modes_cnt = 0; - VK_CHECK(vkGetPhysicalDeviceSurfacePresentModesKHR(physical_device_, surface_, &present_modes_cnt, nullptr)); + VK_CHECK(vkGetPhysicalDeviceSurfacePresentModesKHR(physical_device_, surface_, &present_modes_cnt, nullptr)) details.present_modes.resize(surface_format_cnt); - VK_CHECK(vkGetPhysicalDeviceSurfacePresentModesKHR(physical_device_, surface_, &present_modes_cnt, details.present_modes.data())); + VK_CHECK(vkGetPhysicalDeviceSurfacePresentModesKHR(physical_device_, surface_, &present_modes_cnt, details.present_modes.data())) return details; } @@ -71,33 +72,6 @@ std::vector UwURenderEngine::get_required_extensions() return extensions; } -VkVertexInputBindingDescription UwURenderEngine::Vertex::get_binding_description() -{ - VkVertexInputBindingDescription description; - description.binding = 0; - description.stride = sizeof(Vertex); - description.inputRate = VK_VERTEX_INPUT_RATE_VERTEX; - return description; -} - -std::array UwURenderEngine::Vertex::get_vertex_attribute_descriptions() -{ - std::array descriptions; - // Bind vertex loc - descriptions[0].binding = 0; - descriptions[0].location = 0; - descriptions[0].format = VK_FORMAT_R32G32B32_SFLOAT; - descriptions[0].offset = offsetof(Vertex, pos); - - // Bind color - descriptions[1].binding = 0; - descriptions[1].location = 1; - descriptions[1].format = VK_FORMAT_R32G32B32_SFLOAT; - descriptions[1].offset = offsetof(Vertex, color); - - return descriptions; -} - bool UwURenderEngine::is_device_suitable(VkPhysicalDevice device, VkSurfaceKHR surface) { VkPhysicalDeviceProperties device_properties; @@ -107,7 +81,7 @@ bool UwURenderEngine::is_device_suitable(VkPhysicalDevice device, VkSurfaceKHR s try { // Ловить исключения имеет смысыл только здесь - QueueFamilyIndices indices = find_queue_family_indices(device, surface); + find_queue_family_indices(device, surface); } catch (...) { return false; } @@ -118,9 +92,9 @@ bool UwURenderEngine::is_device_suitable(VkPhysicalDevice device, VkSurfaceKHR s bool UwURenderEngine::check_device_extensions_support(VkPhysicalDevice device) { uint32_t extension_count; - VK_CHECK(vkEnumerateDeviceExtensionProperties(device, nullptr, &extension_count, nullptr)); + VK_CHECK(vkEnumerateDeviceExtensionProperties(device, nullptr, &extension_count, nullptr)) std::vector available_extensions(extension_count); - VK_CHECK(vkEnumerateDeviceExtensionProperties(device, nullptr, &extension_count, available_extensions.data())); + VK_CHECK(vkEnumerateDeviceExtensionProperties(device, nullptr, &extension_count, available_extensions.data())) for (const auto& extension : deviceExtensions) { @@ -163,7 +137,7 @@ UwURenderEngine::QueueFamilyIndices UwURenderEngine::find_queue_family_indices(V // Find present VkBool32 present_support = false; - VK_CHECK(vkGetPhysicalDeviceSurfaceSupportKHR(physical_device, queue_family_indices.graphics_family.value(), surface, &present_support)); + VK_CHECK(vkGetPhysicalDeviceSurfaceSupportKHR(physical_device, queue_family_indices.graphics_family.value(), surface, &present_support)) // Если графическая очередь поддерживет презентацию кадров, то используем её if (present_support == VK_TRUE) queue_family_indices.present_family = queue_family_indices.graphics_family; @@ -173,7 +147,7 @@ UwURenderEngine::QueueFamilyIndices UwURenderEngine::find_queue_family_indices(V for(uint32_t i = 0; i < family_properties.size(); ++i) { present_support = false; - VK_CHECK(vkGetPhysicalDeviceSurfaceSupportKHR(physical_device, i, surface, &present_support)); + VK_CHECK(vkGetPhysicalDeviceSurfaceSupportKHR(physical_device, i, surface, &present_support)) if (present_support == VK_TRUE) { queue_family_indices.present_family = i; @@ -220,24 +194,6 @@ VkPresentModeKHR UwURenderEngine::choose_present_mode(const std::vector::max()) - return capabilities.currentExtent; - else - { - int width, height; - glfwGetFramebufferSize(window, &width, &height); - VkExtent2D actualExtent = { - static_cast(width), - static_cast(height) - }; - actualExtent.width = std::max(capabilities.minImageExtent.width, std::min(capabilities.maxImageExtent.width, actualExtent.width)); - return actualExtent; - } -} - VkShaderModule UwURenderEngine::create_shader_module(const std::string& code) const { VkShaderModuleCreateInfo shader_module_info{}; @@ -246,47 +202,10 @@ VkShaderModule UwURenderEngine::create_shader_module(const std::string& code) co shader_module_info.pCode = reinterpret_cast(code.c_str()); VkShaderModule shader_module; - VK_CHECK(vkCreateShaderModule(device_, &shader_module_info, nullptr, &shader_module)); + VK_CHECK(vkCreateShaderModule(device_, &shader_module_info, nullptr, &shader_module)) return shader_module; } -void UwURenderEngine::create_buffer(VkDeviceSize size, VkBufferUsageFlags usage, - VkBuffer* buffer, const std::vector& queue_families) -{ - VkBufferCreateInfo buffer_info{}; - buffer_info.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; - buffer_info.size = size; - buffer_info.usage = usage; - - if (queue_families.size() > 1) - { - buffer_info.sharingMode = VK_SHARING_MODE_CONCURRENT; - buffer_info.queueFamilyIndexCount = static_cast(queue_families.size()); - buffer_info.pQueueFamilyIndices = queue_families.data(); - } - else - { - buffer_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; - buffer_info.queueFamilyIndexCount = 0; - buffer_info.pQueueFamilyIndices = nullptr; - } - - VK_CHECK(vkCreateBuffer(device_, &buffer_info, nullptr, buffer)); -} - -void UwURenderEngine::allocate_memory(VkBuffer buffer, VkMemoryPropertyFlags property, VkDeviceMemory* device_memory) -{ - VkMemoryRequirements requirements{}; - vkGetBufferMemoryRequirements(device_, buffer, &requirements); - - VkMemoryAllocateInfo allocate_info{}; - allocate_info.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; - allocate_info.allocationSize = requirements.size; - allocate_info.memoryTypeIndex = find_memory_type(requirements.memoryTypeBits, property); - - VK_CHECK(vkAllocateMemory(device_, &allocate_info, nullptr, device_memory)); -} - void UwURenderEngine::create_instance() { std::vector extensions = get_required_extensions(); @@ -318,9 +237,9 @@ void UwURenderEngine::create_instance() debug_messenger_create_info.pfnUserCallback = &debugCallback; instance_create_info.pNext = &debug_messenger_create_info; #endif - VK_CHECK(vkCreateInstance(&instance_create_info, nullptr, &instance_)); + VK_CHECK(vkCreateInstance(&instance_create_info, nullptr, &instance_)) #ifdef _DEBUG - VK_CHECK(enable_layer_validation(&debug_messenger_create_info)); + VK_CHECK(enable_layer_validation(&debug_messenger_create_info)) #endif } @@ -328,9 +247,9 @@ void UwURenderEngine::pick_physical_device() { uint32_t device_count = 0; std::vector devices; - VK_CHECK(vkEnumeratePhysicalDevices(instance_, &device_count, nullptr)); + VK_CHECK(vkEnumeratePhysicalDevices(instance_, &device_count, nullptr)) devices.resize(device_count); - VK_CHECK(vkEnumeratePhysicalDevices(instance_, &device_count, devices.data())); + VK_CHECK(vkEnumeratePhysicalDevices(instance_, &device_count, devices.data())) for (const auto& device : devices) { @@ -389,7 +308,7 @@ void UwURenderEngine::create_logical_device() device_create_info.ppEnabledLayerNames = nullptr; #endif - VK_CHECK(vkCreateDevice(physical_device_, &device_create_info, nullptr, &device_)); + VK_CHECK(vkCreateDevice(physical_device_, &device_create_info, nullptr, &device_)) vkGetDeviceQueue(device_, indices.graphics_family.value(), 0, &graphics_queue_); vkGetDeviceQueue(device_, indices.present_family.value(), 0, &present_queue_); vkGetDeviceQueue(device_, indices.transfer_family.value(), 0, &transfer_queue_); @@ -400,7 +319,7 @@ void UwURenderEngine::create_swapchain() SwapchainSupportDetails swapchain_support = query_swapchain_details(); VkSurfaceFormatKHR surface_format = choose_surface_format(swapchain_support.formats); VkPresentModeKHR present_mode = choose_present_mode(swapchain_support.present_modes, VK_PRESENT_MODE_MAILBOX_KHR); - VkExtent2D extent = choose_extent(swapchain_support.capabilities, get_window()); + VkExtent2D extent = DeviceFunctions::choose_extent(swapchain_support.capabilities, get_window()); uint32_t image_count = swapchain_support.capabilities.minImageCount + 1; if (swapchain_support.capabilities.maxImageCount > 0 && image_count > swapchain_support.capabilities.maxImageCount) @@ -444,7 +363,7 @@ void UwURenderEngine::create_swapchain() swapchain_create_info.pQueueFamilyIndices = nullptr; } - VK_CHECK(vkCreateSwapchainKHR(device_, &swapchain_create_info, nullptr, &swapchain_)); + VK_CHECK(vkCreateSwapchainKHR(device_, &swapchain_create_info, nullptr, &swapchain_)) vkGetSwapchainImagesKHR(device_, swapchain_, &image_count, nullptr); swapchain_images_.resize(image_count); @@ -474,7 +393,7 @@ void UwURenderEngine::create_image_views() for (uint32_t i = 0; i < swapchain_images_.size(); ++i) { image_view_info.image = swapchain_images_[i]; - VK_CHECK(vkCreateImageView(device_, &image_view_info, nullptr, &swapchain_image_views_[i])); + VK_CHECK(vkCreateImageView(device_, &image_view_info, nullptr, &swapchain_image_views_[i])) } } @@ -516,7 +435,7 @@ void UwURenderEngine::create_render_pass() render_pass_info.dependencyCount = 1; render_pass_info.pDependencies = &dependency; - VK_CHECK(vkCreateRenderPass(device_, &render_pass_info, nullptr, &render_pass_)); + VK_CHECK(vkCreateRenderPass(device_, &render_pass_info, nullptr, &render_pass_)) } void UwURenderEngine::create_description_set_layout() @@ -533,7 +452,7 @@ void UwURenderEngine::create_description_set_layout() ubo_layout_info.bindingCount = 1; ubo_layout_info.pBindings = &ubo_layout_binding; - VK_CHECK(vkCreateDescriptorSetLayout(device_, &ubo_layout_info, nullptr, &ubo_layout_binding_)); + VK_CHECK(vkCreateDescriptorSetLayout(device_, &ubo_layout_info, nullptr, &ubo_layout_binding_)) } void UwURenderEngine::create_uniform_buffers() @@ -546,8 +465,8 @@ void UwURenderEngine::create_uniform_buffers() for (size_t i = 0; i < swapchain_images_.size(); ++i) { const VkDeviceSize size = sizeof(UniformBufferObject); - create_buffer(size, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, &uniform_buffers_[i], arr_indices); - allocate_memory(uniform_buffers_[i], VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, &uniform_buffers_memory_[i]); + uniform_buffers_[i] = DeviceFunctions::create_buffer(device_, size, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, arr_indices); + uniform_buffers_memory_[i] = DeviceFunctions::allocate_device_memory(physical_device_, device_, uniform_buffers_[i], VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); vkBindBufferMemory(device_, uniform_buffers_[i], uniform_buffers_memory_[i], 0); vkMapMemory(device_, uniform_buffers_memory_[i], 0, size, 0, &uniform_buffers_mapped_[i]); @@ -566,7 +485,7 @@ void UwURenderEngine::create_descriptor_pool() descriptor_pool_info.pPoolSizes = &pool_size; descriptor_pool_info.maxSets = static_cast(swapchain_images_.size()); - VK_CHECK(vkCreateDescriptorPool(device_, &descriptor_pool_info, nullptr, &descriptor_pool_)); + VK_CHECK(vkCreateDescriptorPool(device_, &descriptor_pool_info, nullptr, &descriptor_pool_)) } void UwURenderEngine::create_descriptor_sets() @@ -579,7 +498,7 @@ void UwURenderEngine::create_descriptor_sets() descriptor_set_allocate_info.pSetLayouts = layouts.data(); descriptor_sets_.resize(swapchain_images_.size()); - VK_CHECK(vkAllocateDescriptorSets(device_, &descriptor_set_allocate_info, descriptor_sets_.data())); + VK_CHECK(vkAllocateDescriptorSets(device_, &descriptor_set_allocate_info, descriptor_sets_.data())) for (size_t i = 0; i < swapchain_images_.size(); ++i) { @@ -645,8 +564,8 @@ void UwURenderEngine::create_graphics_pipeline() dynamic_state_info.dynamicStateCount = static_cast(dynamic_states.size()); dynamic_state_info.pDynamicStates = dynamic_states.data(); - VkVertexInputBindingDescription binding_description = Vertex::get_binding_description(); - std::array attribute_descriptions = Vertex::get_vertex_attribute_descriptions(); + VkVertexInputBindingDescription binding_description = ModelManager::Vertex::get_binding_description(); + std::array attribute_descriptions = ModelManager::Vertex::get_vertex_attribute_descriptions(); VkPipelineVertexInputStateCreateInfo vertex_input_info{}; vertex_input_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO; @@ -719,7 +638,7 @@ void UwURenderEngine::create_graphics_pipeline() pipeline_layout_info.setLayoutCount = 1; pipeline_layout_info.pSetLayouts = &ubo_layout_binding_; - VK_CHECK(vkCreatePipelineLayout(device_, &pipeline_layout_info, nullptr, &pipeline_layout_)); + VK_CHECK(vkCreatePipelineLayout(device_, &pipeline_layout_info, nullptr, &pipeline_layout_)) VkGraphicsPipelineCreateInfo graphics_pipeline_info{}; graphics_pipeline_info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; @@ -739,7 +658,7 @@ void UwURenderEngine::create_graphics_pipeline() graphics_pipeline_info.basePipelineHandle = nullptr; graphics_pipeline_info.basePipelineIndex = -1; - VK_CHECK(vkCreateGraphicsPipelines(device_, nullptr, 1, &graphics_pipeline_info, nullptr, &graphics_pipeline_)); + VK_CHECK(vkCreateGraphicsPipelines(device_, nullptr, 1, &graphics_pipeline_info, nullptr, &graphics_pipeline_)) vkDestroyShaderModule(device_, vertex_shader, nullptr); vkDestroyShaderModule(device_, fragment_shader, nullptr); @@ -760,7 +679,7 @@ void UwURenderEngine::create_framebuffers() for (size_t i = 0; i < framebuffers_.size(); ++i) { framebuffer_info.pAttachments = &swapchain_image_views_[i]; - VK_CHECK(vkCreateFramebuffer(device_, &framebuffer_info, nullptr, &framebuffers_[i])); + VK_CHECK(vkCreateFramebuffer(device_, &framebuffer_info, nullptr, &framebuffers_[i])) } } @@ -773,21 +692,7 @@ void UwURenderEngine::create_command_pool() command_pool_info.queueFamilyIndex = queue_family_indices.graphics_family.value(); command_pool_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; - VK_CHECK(vkCreateCommandPool(device_, &command_pool_info, nullptr, &command_pool_)); -} - -uint32_t UwURenderEngine::find_memory_type(uint32_t typeFilter, VkMemoryPropertyFlags properties) const -{ - VkPhysicalDeviceMemoryProperties memory_properties{}; - vkGetPhysicalDeviceMemoryProperties(physical_device_, &memory_properties); - - for (uint32_t i = 0; i < memory_properties.memoryTypeCount; ++i) - { - if (typeFilter & (1 << i) && (memory_properties.memoryTypes[i].propertyFlags & properties) == properties) - return i; - } - - throw std::runtime_error("failed to find suitable memory type!"); + VK_CHECK(vkCreateCommandPool(device_, &command_pool_info, nullptr, &command_pool_)) } std::vector UwURenderEngine::get_unique_family_indices(const QueueFamilyIndices& indices) @@ -810,26 +715,26 @@ void UwURenderEngine::allocate_vertex_buffer() std::vector arr_indices = get_unique_family_indices(indices); std::vector transfer_index = {indices.transfer_family.value()}; - - VkBuffer staging_buffer = VK_NULL_HANDLE; - VkDeviceMemory staging_buffer_memory = VK_NULL_HANDLE; - + VkDeviceSize size_buffer = sizeof(vertices_[0]) * vertices_.size(); - create_buffer(size_buffer, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, &staging_buffer, transfer_index); - allocate_memory(staging_buffer, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, &staging_buffer_memory); + VkBuffer staging_buffer = DeviceFunctions::create_buffer(device_, size_buffer, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, + transfer_index); + VkDeviceMemory staging_buffer_memory = DeviceFunctions::allocate_device_memory( + physical_device_, device_, staging_buffer, + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); - create_buffer(size_buffer, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, &vertex_buffer_, arr_indices); - allocate_memory(vertex_buffer_, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &vertex_buffer_memory_); + vertex_buffer_ = DeviceFunctions::create_buffer(device_, size_buffer, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, arr_indices); + vertex_buffer_memory_ = DeviceFunctions::allocate_device_memory(physical_device_, device_, vertex_buffer_, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); - VK_CHECK(vkBindBufferMemory(device_, staging_buffer, staging_buffer_memory, 0)); - VK_CHECK(vkBindBufferMemory(device_, vertex_buffer_, vertex_buffer_memory_, 0)); + VK_CHECK(vkBindBufferMemory(device_, staging_buffer, staging_buffer_memory, 0)) + VK_CHECK(vkBindBufferMemory(device_, vertex_buffer_, vertex_buffer_memory_, 0)) void* data; - VK_CHECK(vkMapMemory(device_, staging_buffer_memory, 0, size_buffer, 0, &data)); + VK_CHECK(vkMapMemory(device_, staging_buffer_memory, 0, size_buffer, 0, &data)) memcpy(data, vertices_.data(), size_buffer); vkUnmapMemory(device_, staging_buffer_memory); - copy_memory(staging_buffer, vertex_buffer_, size_buffer); + DeviceFunctions::device_memcpy(device_, indices.transfer_family.value(), staging_buffer, vertex_buffer_, size_buffer); vkFreeMemory(device_, staging_buffer_memory, nullptr); vkDestroyBuffer(device_, staging_buffer, nullptr); @@ -845,11 +750,12 @@ void UwURenderEngine::allocate_index_buffer() std::vector arr_indices = get_unique_family_indices(indices); std::vector transfer_index = {indices.transfer_family.value()}; - VkBuffer staging_buffer = VK_NULL_HANDLE; - VkDeviceMemory staging_buffer_memory = VK_NULL_HANDLE; VkDeviceSize size_buffer = sizeof(indices_[0]) * indices_.size(); - create_buffer(size_buffer, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, &staging_buffer, transfer_index); - allocate_memory(staging_buffer, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, &staging_buffer_memory); + VkBuffer staging_buffer = DeviceFunctions::create_buffer(device_, size_buffer, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, + transfer_index); + VkDeviceMemory staging_buffer_memory = DeviceFunctions::allocate_device_memory( + physical_device_, device_, staging_buffer, + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); vkBindBufferMemory(device_, staging_buffer, staging_buffer_memory, 0); void* data; @@ -857,61 +763,16 @@ void UwURenderEngine::allocate_index_buffer() memcpy(data, indices_.data(), size_buffer); vkUnmapMemory(device_, staging_buffer_memory); - create_buffer(size_buffer, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT, &index_buffer_, arr_indices); - allocate_memory(index_buffer_, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &index_buffer_memory_); + index_buffer_ = DeviceFunctions::create_buffer(device_, size_buffer, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT, arr_indices); + index_buffer_memory_ = DeviceFunctions::allocate_device_memory(physical_device_, device_, index_buffer_, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT); vkBindBufferMemory(device_, index_buffer_, index_buffer_memory_, 0); - - copy_memory(staging_buffer, index_buffer_, size_buffer); + + DeviceFunctions::device_memcpy(device_, indices.transfer_family.value(),staging_buffer, index_buffer_, size_buffer); vkDestroyBuffer(device_, staging_buffer, nullptr); vkFreeMemory(device_, staging_buffer_memory, nullptr); } -void UwURenderEngine::copy_memory(VkBuffer src, VkBuffer dst, VkDeviceSize size) -{ - QueueFamilyIndices indices = find_queue_family_indices(physical_device_, surface_); - VkCommandPool copy_pool; - VkCommandPoolCreateInfo copy_pool_info{}; - copy_pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; - copy_pool_info.queueFamilyIndex = indices.transfer_family.value(); - copy_pool_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; - VK_CHECK(vkCreateCommandPool(device_, ©_pool_info, nullptr, ©_pool)); - - VkCommandBufferAllocateInfo command_buffer_allocate_info{}; - command_buffer_allocate_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; - command_buffer_allocate_info.commandPool = copy_pool; - command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; - command_buffer_allocate_info.commandBufferCount = 1; - - VkCommandBuffer copy_buffer; - VK_CHECK(vkAllocateCommandBuffers(device_, &command_buffer_allocate_info, ©_buffer)); - - VkCommandBufferBeginInfo command_buffer_begin_info{}; - command_buffer_begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; - command_buffer_begin_info.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; - - VK_CHECK(vkBeginCommandBuffer(copy_buffer, &command_buffer_begin_info)); - - VkBufferCopy buffer_copy{}; - buffer_copy.srcOffset = 0; - buffer_copy.dstOffset = 0; - buffer_copy.size = size; - vkCmdCopyBuffer(copy_buffer, src, dst, 1, &buffer_copy); - - vkEndCommandBuffer(copy_buffer); - - VkSubmitInfo submit_info{}; - submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; - submit_info.commandBufferCount = 1; - submit_info.pCommandBuffers = ©_buffer; - - vkQueueSubmit(transfer_queue_, 1, &submit_info, VK_NULL_HANDLE); - vkQueueWaitIdle(transfer_queue_); - - vkFreeCommandBuffers(device_, copy_pool, 1, ©_buffer); - vkDestroyCommandPool(device_, copy_pool, nullptr); -} - void UwURenderEngine::allocate_command_buffers() { command_buffers_.resize(swapchain_images_.size()); @@ -922,7 +783,7 @@ void UwURenderEngine::allocate_command_buffers() command_buffer_allocate_info.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; command_buffer_allocate_info.commandBufferCount = static_cast(command_buffers_.size()); - VK_CHECK(vkAllocateCommandBuffers(device_, &command_buffer_allocate_info, command_buffers_.data())); + VK_CHECK(vkAllocateCommandBuffers(device_, &command_buffer_allocate_info, command_buffers_.data())) } void UwURenderEngine::create_sync_objects() @@ -940,9 +801,9 @@ void UwURenderEngine::create_sync_objects() for (size_t i = 0; i < swapchain_images_.size(); ++i) { - VK_CHECK(vkCreateSemaphore(device_, &semaphore_info, nullptr, &image_available_semaphores_[i])); - VK_CHECK(vkCreateSemaphore(device_, &semaphore_info, nullptr, &render_finished_semaphores_[i])); - VK_CHECK(vkCreateFence(device_, &fence_info, nullptr, &in_flight_fences_[i])); + VK_CHECK(vkCreateSemaphore(device_, &semaphore_info, nullptr, &image_available_semaphores_[i])) + VK_CHECK(vkCreateSemaphore(device_, &semaphore_info, nullptr, &render_finished_semaphores_[i])) + VK_CHECK(vkCreateFence(device_, &fence_info, nullptr, &in_flight_fences_[i])) } } @@ -950,7 +811,7 @@ void UwURenderEngine::record_command_buffer(VkCommandBuffer command_buffer, uint { VkCommandBufferBeginInfo command_buffer_begin_info{}; command_buffer_begin_info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; - VK_CHECK(vkBeginCommandBuffer(command_buffer, &command_buffer_begin_info)); + VK_CHECK(vkBeginCommandBuffer(command_buffer, &command_buffer_begin_info)) constexpr VkClearValue clear_color = {{{0.0f, 0.0f, 0.0f, 1.0f}}}; VkRenderPassBeginInfo render_pass_begin_info{}; @@ -990,7 +851,7 @@ void UwURenderEngine::record_command_buffer(VkCommandBuffer command_buffer, uint vkCmdDrawIndexed(command_buffer, static_cast(indices_.size()), 1, 0, 0, 0); vkCmdEndRenderPass(command_buffer); - VK_CHECK(vkEndCommandBuffer(command_buffer)); + VK_CHECK(vkEndCommandBuffer(command_buffer)) } void UwURenderEngine::update_uniform_buffer(uint32_t current_frame) @@ -998,7 +859,7 @@ void UwURenderEngine::update_uniform_buffer(uint32_t current_frame) static auto start_time = std::chrono::high_resolution_clock::now(); auto current_time = std::chrono::high_resolution_clock::now(); float time = std::chrono::duration_cast>(current_time - start_time).count(); - UniformBufferObject ubo{}; + UniformBufferObject ubo; ubo.model = glm::rotate(glm::mat4(1.0f), time * glm::radians(45.0f), glm::vec3(0.0f, 0.0f, 1.0f)); ubo.view = glm::lookAt(glm::vec3(2.0f, 2.0f, 2.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f)); ubo.proj = glm::perspective(glm::radians(45.0f), static_cast(swapchain_extent_.width) / static_cast(swapchain_extent_.height), 0.1f, 256.0f); @@ -1030,7 +891,7 @@ void UwURenderEngine::draw_frame() submit_info.signalSemaphoreCount = 1; submit_info.pSignalSemaphores = &render_finished_semaphores_[current_frame_]; - VK_CHECK(vkQueueSubmit(graphics_queue_, 1, &submit_info, in_flight_fences_[current_frame_])); + VK_CHECK(vkQueueSubmit(graphics_queue_, 1, &submit_info, in_flight_fences_[current_frame_])) VkPresentInfoKHR present_info{}; present_info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; @@ -1048,12 +909,11 @@ void UwURenderEngine::draw_frame() void UwURenderEngine::create_surface() { - VK_CHECK(glfwCreateWindowSurface(instance_, get_window(), nullptr, &surface_)); + VK_CHECK(glfwCreateWindowSurface(instance_, get_window(), nullptr, &surface_)) } UwURenderEngine::UwURenderEngine(CoreInstance& core): -core_(core), -model_manager_(new ModelManager) +core_(core) #ifdef _DEBUG ,debug_messenger_(nullptr) #endif @@ -1076,6 +936,8 @@ model_manager_(new ModelManager) allocate_command_buffers(); allocate_index_buffer(); create_sync_objects(); + + model_manager_.reset(new ModelManager(physical_device_, device_)); } UwURenderEngine::~UwURenderEngine() diff --git a/UwURenderEngine/RenderEngine/UwURenderEngine.hpp b/UwURenderEngine/RenderEngine/UwURenderEngine.hpp index 7393ed7..8f108ad 100644 --- a/UwURenderEngine/RenderEngine/UwURenderEngine.hpp +++ b/UwURenderEngine/RenderEngine/UwURenderEngine.hpp @@ -12,13 +12,6 @@ #include #include -#ifdef _DEBUG -#include -#define VK_CHECK(res) assert(res == VK_SUCCESS) -#else -#define VK_CHECK(res) if ((res) != VK_SUCCESS) throw std::runtime_error("Vulkan error: " + std::to_string(res)) -#endif - class UwURenderEngine : public RenderEngineBase { struct QueueFamilyIndices @@ -33,20 +26,13 @@ class UwURenderEngine : public RenderEngineBase std::vector formats; std::vector present_modes; }; - struct Vertex - { - glm::vec3 pos; - glm::vec3 color; - static VkVertexInputBindingDescription get_binding_description(); - static std::array get_vertex_attribute_descriptions(); - }; struct UniformBufferObject { glm::mat4 model; glm::mat4 view; glm::mat4 proj; }; - const std::vector vertices_ = { + const std::vector vertices_ = { {{-0.5f, -0.5f, 0.5f}, {1.0f, 0.0f, 0.0f}}, {{0.5f, -0.5f, 0.5f}, {0.0f, 1.0f, 0.0f}}, {{0.5f, 0.5f, 0.5f}, {0.0f, 0.0f, 1.0f}}, @@ -117,13 +103,8 @@ class UwURenderEngine : public RenderEngineBase static QueueFamilyIndices find_queue_family_indices(VkPhysicalDevice physical_device, VkSurfaceKHR surface); static VkSurfaceFormatKHR choose_surface_format(const std::vector& surface_formats); static VkPresentModeKHR choose_present_mode(const std::vector& present_modes, VkPresentModeKHR desired_present_mode); - static VkExtent2D choose_extent(const VkSurfaceCapabilitiesKHR& capabilities, GLFWwindow* window); VkShaderModule create_shader_module(const std::string& code) const; - void create_buffer(VkDeviceSize size, VkBufferUsageFlags usage, - VkBuffer* buffer, const std::vector& queue_families); - void allocate_memory(VkBuffer buffer, VkMemoryPropertyFlags property, VkDeviceMemory* device_memory); - uint32_t find_memory_type(uint32_t typeFilter, VkMemoryPropertyFlags properties) const; - std::vector get_unique_family_indices(const QueueFamilyIndices& indices); + static std::vector get_unique_family_indices(const QueueFamilyIndices& indices); void create_instance(); void create_surface(); @@ -144,7 +125,6 @@ class UwURenderEngine : public RenderEngineBase void allocate_vertex_buffer(); void allocate_index_buffer(); - void copy_memory(VkBuffer src, VkBuffer dst, VkDeviceSize size); void record_command_buffer(VkCommandBuffer command_buffer, uint32_t image_index) const; void update_uniform_buffer(uint32_t current_frame); void draw_frame();