|
|
|
@@ -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<const char*> 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<const char*> 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<VkVertexInputAttributeDescription, 2> UwURenderEngine::Vertex::get_vertex_attribute_descriptions()
|
|
|
|
|
{
|
|
|
|
|
std::array<VkVertexInputAttributeDescription, 2> 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<VkExtensionProperties> 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<VkPresen
|
|
|
|
|
return VK_PRESENT_MODE_FIFO_KHR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VkExtent2D UwURenderEngine::choose_extent(const VkSurfaceCapabilitiesKHR& capabilities, GLFWwindow* window)
|
|
|
|
|
{
|
|
|
|
|
// Здесь вычисляется допустимое разрешение рендера
|
|
|
|
|
if (capabilities.currentExtent.width != std::numeric_limits<uint32_t>::max())
|
|
|
|
|
return capabilities.currentExtent;
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
int width, height;
|
|
|
|
|
glfwGetFramebufferSize(window, &width, &height);
|
|
|
|
|
VkExtent2D actualExtent = {
|
|
|
|
|
static_cast<uint32_t>(width),
|
|
|
|
|
static_cast<uint32_t>(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<const uint32_t*>(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<uint32_t>& 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<uint32_t>(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<const char*> 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<VkPhysicalDevice> 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<uint32_t>(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<uint32_t>(dynamic_states.size());
|
|
|
|
|
dynamic_state_info.pDynamicStates = dynamic_states.data();
|
|
|
|
|
|
|
|
|
|
VkVertexInputBindingDescription binding_description = Vertex::get_binding_description();
|
|
|
|
|
std::array<VkVertexInputAttributeDescription, 2> attribute_descriptions = Vertex::get_vertex_attribute_descriptions();
|
|
|
|
|
VkVertexInputBindingDescription binding_description = ModelManager::Vertex::get_binding_description();
|
|
|
|
|
std::array<VkVertexInputAttributeDescription, 2> 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<uint32_t> UwURenderEngine::get_unique_family_indices(const QueueFamilyIndices& indices)
|
|
|
|
@@ -811,25 +716,25 @@ void UwURenderEngine::allocate_vertex_buffer()
|
|
|
|
|
std::vector<uint32_t> arr_indices = get_unique_family_indices(indices);
|
|
|
|
|
std::vector<uint32_t> 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<uint32_t> arr_indices = get_unique_family_indices(indices);
|
|
|
|
|
std::vector<uint32_t> 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<uint32_t>(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<uint32_t>(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<std::chrono::duration<float>>(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<float>(swapchain_extent_.width) / static_cast<float>(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()
|
|
|
|
|