Add RenderEngineSDK

This commit is contained in:
Jiga228
2025-10-29 13:20:04 +07:00
parent 1ab74b8128
commit 734db410d1
7 changed files with 289 additions and 230 deletions
@@ -0,0 +1,125 @@
#include "DeviceFunctions.hpp"
#include <stdexcept>
#include <string>
VkExtent2D DeviceFunctions::choose_extent(const VkSurfaceCapabilitiesKHR& capabilities, GLFWwindow* window)
{
// The acceptable rendering sparsity is calculated here
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;
}
}
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, &copy_pool_info, nullptr, &copy_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, &copy_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 = &copy_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, &copy_buffer);
vkDestroyCommandPool(device, copy_pool, nullptr);
}
VkBuffer DeviceFunctions::create_buffer(VkDevice device, VkDeviceSize size, VkBufferUsageFlags usage,
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;
}
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;
}
@@ -0,0 +1,22 @@
#pragma once
#define GLFW_INCLUDE_VULKAN
#include <GLFW/glfw3.h>
#include <vector>
#ifdef _DEBUG
#include <assert.h>
#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<int>(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<uint32_t>& queue_families);
VkDeviceMemory allocate_device_memory(VkPhysicalDevice physical_device, VkDevice device, VkBuffer buffer, VkMemoryPropertyFlags property);
}
+1 -1
View File
@@ -2,6 +2,6 @@ file(GLOB_RECURSE SRC "*.cpp" "*.c" "*.hpp" "*.h")
add_library(UwURenderEngine ${SRC}) add_library(UwURenderEngine ${SRC})
target_include_directories(UwURenderEngine PUBLIC ${PROJECT_SOURCE_DIR}/RenderEngineSDK) 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) target_compile_features(UwURenderEngine PRIVATE cxx_std_17)
+50 -2
View File
@@ -1,7 +1,47 @@
#include "ModelManager.hpp" #include "ModelManager.hpp"
#include <array>
#include "Log/Log.hpp" #include "Log/Log.hpp"
ModelManager::StaticModel::StaticModel(const std::vector<Vertex>& vertices, const std::vector<uint32_t>& 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<VkVertexInputAttributeDescription, 2> ModelManager::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;
}
ModelManager::owner_counter::owner_counter(const owner_counter& other) : counter(other.counter.load()), model(other.model) 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; return h_val;
} }
ModelManager::ModelManager(VkPhysicalDevice physical_device, VkDevice device):
physical_device_(physical_device),
device_(device)
{}
ModelManager::~ModelManager() ModelManager::~ModelManager()
{ {
models.clear(); models.clear();
@@ -37,11 +82,14 @@ ModelManager::StaticModel* ModelManager::LoadModel(const std::string& name)
} }
Loging::Log("Load new model: " + name); Loging::Log("Load new model: " + name);
std::vector<Vertex> vertices;
std::vector<uint32_t> indices;
// Load model_data // Load model_data
owner_counter new_counter; owner_counter new_counter;
new_counter.counter.store(1); 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); models.try_emplace(hash, new_counter);
return new_counter.model; return new_counter.model;
} }
+25 -3
View File
@@ -3,14 +3,34 @@
#include <unordered_map> #include <unordered_map>
#include <string> #include <string>
#include <atomic> #include <atomic>
#include <glm/vec3.hpp>
#include <vulkan/vulkan.h>
class ModelManager class ModelManager
{ {
public: public:
struct Vertex
{
glm::vec3 pos, color;
static VkVertexInputBindingDescription get_binding_description();
static std::array<VkVertexInputAttributeDescription, 2> get_vertex_attribute_descriptions();
};
class StaticModel class StaticModel
{ {
//DATA VkPhysicalDevice physical_device_;
}; VkDevice device_;
VkBuffer vertex_buffer_;
VkBuffer index_buffer_;
public:
StaticModel(const std::vector<Vertex>& vertices, const std::vector<uint32_t>& indices,
VkPhysicalDevice physical_device, VkDevice device);
~StaticModel();
};
struct owner_counter struct owner_counter
{ {
@@ -22,12 +42,14 @@ public:
}; };
private: private:
VkPhysicalDevice physical_device_;
VkDevice device_;
std::unordered_map<unsigned int, owner_counter> models; std::unordered_map<unsigned int, owner_counter> models;
static unsigned int FNV1aHash (const char *buf); static unsigned int FNV1aHash (const char *buf);
public: public:
ModelManager(VkPhysicalDevice physical_device, VkDevice device);
~ModelManager(); ~ModelManager();
StaticModel* LoadModel(const std::string& name); StaticModel* LoadModel(const std::string& name);
+64 -202
View File
@@ -12,6 +12,7 @@
#include "Game/GameInstance.hpp" #include "Game/GameInstance.hpp"
#include "Game/World/World.hpp" #include "Game/World/World.hpp"
#include "../Game/Actors/Mesh/Mesh.hpp" #include "../Game/Actors/Mesh/Mesh.hpp"
#include "DeviceFunctions/DeviceFunctions.hpp"
const std::vector<const char*> UwURenderEngine::deviceExtensions = { const std::vector<const char*> UwURenderEngine::deviceExtensions = {
VK_KHR_SWAPCHAIN_EXTENSION_NAME VK_KHR_SWAPCHAIN_EXTENSION_NAME
@@ -47,14 +48,14 @@ UwURenderEngine::SwapchainSupportDetails UwURenderEngine::query_swapchain_detail
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physical_device_, surface_, &details.capabilities); vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physical_device_, surface_, &details.capabilities);
uint32_t surface_format_cnt = 0; 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); 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; 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); 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; return details;
} }
@@ -71,33 +72,6 @@ std::vector<const char*> UwURenderEngine::get_required_extensions()
return 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) bool UwURenderEngine::is_device_suitable(VkPhysicalDevice device, VkSurfaceKHR surface)
{ {
VkPhysicalDeviceProperties device_properties; VkPhysicalDeviceProperties device_properties;
@@ -107,7 +81,7 @@ bool UwURenderEngine::is_device_suitable(VkPhysicalDevice device, VkSurfaceKHR s
try { try {
// Ловить исключения имеет смысыл только здесь // Ловить исключения имеет смысыл только здесь
QueueFamilyIndices indices = find_queue_family_indices(device, surface); find_queue_family_indices(device, surface);
} catch (...) { } catch (...) {
return false; return false;
} }
@@ -118,9 +92,9 @@ bool UwURenderEngine::is_device_suitable(VkPhysicalDevice device, VkSurfaceKHR s
bool UwURenderEngine::check_device_extensions_support(VkPhysicalDevice device) bool UwURenderEngine::check_device_extensions_support(VkPhysicalDevice device)
{ {
uint32_t extension_count; 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); 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) for (const auto& extension : deviceExtensions)
{ {
@@ -163,7 +137,7 @@ UwURenderEngine::QueueFamilyIndices UwURenderEngine::find_queue_family_indices(V
// Find present // Find present
VkBool32 present_support = false; 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) if (present_support == VK_TRUE)
queue_family_indices.present_family = queue_family_indices.graphics_family; 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) for(uint32_t i = 0; i < family_properties.size(); ++i)
{ {
present_support = false; 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) if (present_support == VK_TRUE)
{ {
queue_family_indices.present_family = i; 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; 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 VkShaderModule UwURenderEngine::create_shader_module(const std::string& code) const
{ {
VkShaderModuleCreateInfo shader_module_info{}; 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()); shader_module_info.pCode = reinterpret_cast<const uint32_t*>(code.c_str());
VkShaderModule shader_module; 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; 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() void UwURenderEngine::create_instance()
{ {
std::vector<const char*> extensions = get_required_extensions(); std::vector<const char*> extensions = get_required_extensions();
@@ -318,9 +237,9 @@ void UwURenderEngine::create_instance()
debug_messenger_create_info.pfnUserCallback = &debugCallback; debug_messenger_create_info.pfnUserCallback = &debugCallback;
instance_create_info.pNext = &debug_messenger_create_info; instance_create_info.pNext = &debug_messenger_create_info;
#endif #endif
VK_CHECK(vkCreateInstance(&instance_create_info, nullptr, &instance_)); VK_CHECK(vkCreateInstance(&instance_create_info, nullptr, &instance_))
#ifdef _DEBUG #ifdef _DEBUG
VK_CHECK(enable_layer_validation(&debug_messenger_create_info)); VK_CHECK(enable_layer_validation(&debug_messenger_create_info))
#endif #endif
} }
@@ -328,9 +247,9 @@ void UwURenderEngine::pick_physical_device()
{ {
uint32_t device_count = 0; uint32_t device_count = 0;
std::vector<VkPhysicalDevice> devices; std::vector<VkPhysicalDevice> devices;
VK_CHECK(vkEnumeratePhysicalDevices(instance_, &device_count, nullptr)); VK_CHECK(vkEnumeratePhysicalDevices(instance_, &device_count, nullptr))
devices.resize(device_count); 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) for (const auto& device : devices)
{ {
@@ -389,7 +308,7 @@ void UwURenderEngine::create_logical_device()
device_create_info.ppEnabledLayerNames = nullptr; device_create_info.ppEnabledLayerNames = nullptr;
#endif #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.graphics_family.value(), 0, &graphics_queue_);
vkGetDeviceQueue(device_, indices.present_family.value(), 0, &present_queue_); vkGetDeviceQueue(device_, indices.present_family.value(), 0, &present_queue_);
vkGetDeviceQueue(device_, indices.transfer_family.value(), 0, &transfer_queue_); vkGetDeviceQueue(device_, indices.transfer_family.value(), 0, &transfer_queue_);
@@ -400,7 +319,7 @@ void UwURenderEngine::create_swapchain()
SwapchainSupportDetails swapchain_support = query_swapchain_details(); SwapchainSupportDetails swapchain_support = query_swapchain_details();
VkSurfaceFormatKHR surface_format = choose_surface_format(swapchain_support.formats); VkSurfaceFormatKHR surface_format = choose_surface_format(swapchain_support.formats);
VkPresentModeKHR present_mode = choose_present_mode(swapchain_support.present_modes, VK_PRESENT_MODE_MAILBOX_KHR); 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; uint32_t image_count = swapchain_support.capabilities.minImageCount + 1;
if (swapchain_support.capabilities.maxImageCount > 0 && image_count > swapchain_support.capabilities.maxImageCount) 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; 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); vkGetSwapchainImagesKHR(device_, swapchain_, &image_count, nullptr);
swapchain_images_.resize(image_count); swapchain_images_.resize(image_count);
@@ -474,7 +393,7 @@ void UwURenderEngine::create_image_views()
for (uint32_t i = 0; i < swapchain_images_.size(); ++i) for (uint32_t i = 0; i < swapchain_images_.size(); ++i)
{ {
image_view_info.image = swapchain_images_[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.dependencyCount = 1;
render_pass_info.pDependencies = &dependency; 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() void UwURenderEngine::create_description_set_layout()
@@ -533,7 +452,7 @@ void UwURenderEngine::create_description_set_layout()
ubo_layout_info.bindingCount = 1; ubo_layout_info.bindingCount = 1;
ubo_layout_info.pBindings = &ubo_layout_binding; 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() void UwURenderEngine::create_uniform_buffers()
@@ -546,8 +465,8 @@ void UwURenderEngine::create_uniform_buffers()
for (size_t i = 0; i < swapchain_images_.size(); ++i) for (size_t i = 0; i < swapchain_images_.size(); ++i)
{ {
const VkDeviceSize size = sizeof(UniformBufferObject); const VkDeviceSize size = sizeof(UniformBufferObject);
create_buffer(size, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, &uniform_buffers_[i], arr_indices); uniform_buffers_[i] = DeviceFunctions::create_buffer(device_, size, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, 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_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); vkBindBufferMemory(device_, uniform_buffers_[i], uniform_buffers_memory_[i], 0);
vkMapMemory(device_, uniform_buffers_memory_[i], 0, size, 0, &uniform_buffers_mapped_[i]); 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.pPoolSizes = &pool_size;
descriptor_pool_info.maxSets = static_cast<uint32_t>(swapchain_images_.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() void UwURenderEngine::create_descriptor_sets()
@@ -579,7 +498,7 @@ void UwURenderEngine::create_descriptor_sets()
descriptor_set_allocate_info.pSetLayouts = layouts.data(); descriptor_set_allocate_info.pSetLayouts = layouts.data();
descriptor_sets_.resize(swapchain_images_.size()); 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) 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.dynamicStateCount = static_cast<uint32_t>(dynamic_states.size());
dynamic_state_info.pDynamicStates = dynamic_states.data(); dynamic_state_info.pDynamicStates = dynamic_states.data();
VkVertexInputBindingDescription binding_description = Vertex::get_binding_description(); VkVertexInputBindingDescription binding_description = ModelManager::Vertex::get_binding_description();
std::array<VkVertexInputAttributeDescription, 2> attribute_descriptions = Vertex::get_vertex_attribute_descriptions(); std::array<VkVertexInputAttributeDescription, 2> attribute_descriptions = ModelManager::Vertex::get_vertex_attribute_descriptions();
VkPipelineVertexInputStateCreateInfo vertex_input_info{}; VkPipelineVertexInputStateCreateInfo vertex_input_info{};
vertex_input_info.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_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.setLayoutCount = 1;
pipeline_layout_info.pSetLayouts = &ubo_layout_binding_; 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{}; VkGraphicsPipelineCreateInfo graphics_pipeline_info{};
graphics_pipeline_info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_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.basePipelineHandle = nullptr;
graphics_pipeline_info.basePipelineIndex = -1; 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_, vertex_shader, nullptr);
vkDestroyShaderModule(device_, fragment_shader, nullptr); vkDestroyShaderModule(device_, fragment_shader, nullptr);
@@ -760,7 +679,7 @@ void UwURenderEngine::create_framebuffers()
for (size_t i = 0; i < framebuffers_.size(); ++i) for (size_t i = 0; i < framebuffers_.size(); ++i)
{ {
framebuffer_info.pAttachments = &swapchain_image_views_[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.queueFamilyIndex = queue_family_indices.graphics_family.value();
command_pool_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; command_pool_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
VK_CHECK(vkCreateCommandPool(device_, &command_pool_info, nullptr, &command_pool_)); 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!");
} }
std::vector<uint32_t> UwURenderEngine::get_unique_family_indices(const QueueFamilyIndices& indices) std::vector<uint32_t> UwURenderEngine::get_unique_family_indices(const QueueFamilyIndices& indices)
@@ -810,26 +715,26 @@ void UwURenderEngine::allocate_vertex_buffer()
std::vector<uint32_t> arr_indices = get_unique_family_indices(indices); std::vector<uint32_t> arr_indices = get_unique_family_indices(indices);
std::vector<uint32_t> transfer_index = {indices.transfer_family.value()}; 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(); VkDeviceSize size_buffer = sizeof(vertices_[0]) * vertices_.size();
create_buffer(size_buffer, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, &staging_buffer, transfer_index); VkBuffer staging_buffer = DeviceFunctions::create_buffer(device_, size_buffer, VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
allocate_memory(staging_buffer, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, &staging_buffer_memory); 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); vertex_buffer_ = DeviceFunctions::create_buffer(device_, size_buffer, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, arr_indices);
allocate_memory(vertex_buffer_, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &vertex_buffer_memory_); 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_, staging_buffer, staging_buffer_memory, 0))
VK_CHECK(vkBindBufferMemory(device_, vertex_buffer_, vertex_buffer_memory_, 0)); VK_CHECK(vkBindBufferMemory(device_, vertex_buffer_, vertex_buffer_memory_, 0))
void* data; 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); memcpy(data, vertices_.data(), size_buffer);
vkUnmapMemory(device_, staging_buffer_memory); 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); vkFreeMemory(device_, staging_buffer_memory, nullptr);
vkDestroyBuffer(device_, staging_buffer, 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> arr_indices = get_unique_family_indices(indices);
std::vector<uint32_t> transfer_index = {indices.transfer_family.value()}; 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(); VkDeviceSize size_buffer = sizeof(indices_[0]) * indices_.size();
create_buffer(size_buffer, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, &staging_buffer, transfer_index); VkBuffer staging_buffer = DeviceFunctions::create_buffer(device_, size_buffer, VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
allocate_memory(staging_buffer, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, &staging_buffer_memory); 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); vkBindBufferMemory(device_, staging_buffer, staging_buffer_memory, 0);
void* data; void* data;
@@ -857,61 +763,16 @@ void UwURenderEngine::allocate_index_buffer()
memcpy(data, indices_.data(), size_buffer); memcpy(data, indices_.data(), size_buffer);
vkUnmapMemory(device_, staging_buffer_memory); 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); index_buffer_ = DeviceFunctions::create_buffer(device_, size_buffer, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT, arr_indices);
allocate_memory(index_buffer_, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &index_buffer_memory_); 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); 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); vkDestroyBuffer(device_, staging_buffer, nullptr);
vkFreeMemory(device_, staging_buffer_memory, 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_, &copy_pool_info, nullptr, &copy_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, &copy_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 = &copy_buffer;
vkQueueSubmit(transfer_queue_, 1, &submit_info, VK_NULL_HANDLE);
vkQueueWaitIdle(transfer_queue_);
vkFreeCommandBuffers(device_, copy_pool, 1, &copy_buffer);
vkDestroyCommandPool(device_, copy_pool, nullptr);
}
void UwURenderEngine::allocate_command_buffers() void UwURenderEngine::allocate_command_buffers()
{ {
command_buffers_.resize(swapchain_images_.size()); 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.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
command_buffer_allocate_info.commandBufferCount = static_cast<uint32_t>(command_buffers_.size()); 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() void UwURenderEngine::create_sync_objects()
@@ -940,9 +801,9 @@ void UwURenderEngine::create_sync_objects()
for (size_t i = 0; i < swapchain_images_.size(); ++i) 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, &image_available_semaphores_[i]))
VK_CHECK(vkCreateSemaphore(device_, &semaphore_info, nullptr, &render_finished_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(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{}; VkCommandBufferBeginInfo command_buffer_begin_info{};
command_buffer_begin_info.sType = VK_STRUCTURE_TYPE_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}}}; constexpr VkClearValue clear_color = {{{0.0f, 0.0f, 0.0f, 1.0f}}};
VkRenderPassBeginInfo render_pass_begin_info{}; 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); vkCmdDrawIndexed(command_buffer, static_cast<uint32_t>(indices_.size()), 1, 0, 0, 0);
vkCmdEndRenderPass(command_buffer); vkCmdEndRenderPass(command_buffer);
VK_CHECK(vkEndCommandBuffer(command_buffer)); VK_CHECK(vkEndCommandBuffer(command_buffer))
} }
void UwURenderEngine::update_uniform_buffer(uint32_t current_frame) 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(); static auto start_time = std::chrono::high_resolution_clock::now();
auto current_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(); 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.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.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); 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.signalSemaphoreCount = 1;
submit_info.pSignalSemaphores = &render_finished_semaphores_[current_frame_]; 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{}; VkPresentInfoKHR present_info{};
present_info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; present_info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
@@ -1048,12 +909,11 @@ void UwURenderEngine::draw_frame()
void UwURenderEngine::create_surface() void UwURenderEngine::create_surface()
{ {
VK_CHECK(glfwCreateWindowSurface(instance_, get_window(), nullptr, &surface_)); VK_CHECK(glfwCreateWindowSurface(instance_, get_window(), nullptr, &surface_))
} }
UwURenderEngine::UwURenderEngine(CoreInstance& core): UwURenderEngine::UwURenderEngine(CoreInstance& core):
core_(core), core_(core)
model_manager_(new ModelManager)
#ifdef _DEBUG #ifdef _DEBUG
,debug_messenger_(nullptr) ,debug_messenger_(nullptr)
#endif #endif
@@ -1076,6 +936,8 @@ model_manager_(new ModelManager)
allocate_command_buffers(); allocate_command_buffers();
allocate_index_buffer(); allocate_index_buffer();
create_sync_objects(); create_sync_objects();
model_manager_.reset(new ModelManager(physical_device_, device_));
} }
UwURenderEngine::~UwURenderEngine() UwURenderEngine::~UwURenderEngine()
@@ -12,13 +12,6 @@
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp> #include <glm/gtc/matrix_transform.hpp>
#ifdef _DEBUG
#include <assert.h>
#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 class UwURenderEngine : public RenderEngineBase
{ {
struct QueueFamilyIndices struct QueueFamilyIndices
@@ -33,20 +26,13 @@ class UwURenderEngine : public RenderEngineBase
std::vector<VkSurfaceFormatKHR> formats; std::vector<VkSurfaceFormatKHR> formats;
std::vector<VkPresentModeKHR> present_modes; std::vector<VkPresentModeKHR> present_modes;
}; };
struct Vertex
{
glm::vec3 pos;
glm::vec3 color;
static VkVertexInputBindingDescription get_binding_description();
static std::array<VkVertexInputAttributeDescription, 2> get_vertex_attribute_descriptions();
};
struct UniformBufferObject { struct UniformBufferObject {
glm::mat4 model; glm::mat4 model;
glm::mat4 view; glm::mat4 view;
glm::mat4 proj; glm::mat4 proj;
}; };
const std::vector<Vertex> vertices_ = { const std::vector<ModelManager::Vertex> vertices_ = {
{{-0.5f, -0.5f, 0.5f}, {1.0f, 0.0f, 0.0f}}, {{-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, 1.0f, 0.0f}},
{{0.5f, 0.5f, 0.5f}, {0.0f, 0.0f, 1.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 QueueFamilyIndices find_queue_family_indices(VkPhysicalDevice physical_device, VkSurfaceKHR surface);
static VkSurfaceFormatKHR choose_surface_format(const std::vector<VkSurfaceFormatKHR>& surface_formats); static VkSurfaceFormatKHR choose_surface_format(const std::vector<VkSurfaceFormatKHR>& surface_formats);
static VkPresentModeKHR choose_present_mode(const std::vector<VkPresentModeKHR>& present_modes, VkPresentModeKHR desired_present_mode); static VkPresentModeKHR choose_present_mode(const std::vector<VkPresentModeKHR>& present_modes, VkPresentModeKHR desired_present_mode);
static VkExtent2D choose_extent(const VkSurfaceCapabilitiesKHR& capabilities, GLFWwindow* window);
VkShaderModule create_shader_module(const std::string& code) const; VkShaderModule create_shader_module(const std::string& code) const;
void create_buffer(VkDeviceSize size, VkBufferUsageFlags usage, static std::vector<uint32_t> get_unique_family_indices(const QueueFamilyIndices& indices);
VkBuffer* buffer, const std::vector<uint32_t>& 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<uint32_t> get_unique_family_indices(const QueueFamilyIndices& indices);
void create_instance(); void create_instance();
void create_surface(); void create_surface();
@@ -144,7 +125,6 @@ class UwURenderEngine : public RenderEngineBase
void allocate_vertex_buffer(); void allocate_vertex_buffer();
void allocate_index_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 record_command_buffer(VkCommandBuffer command_buffer, uint32_t image_index) const;
void update_uniform_buffer(uint32_t current_frame); void update_uniform_buffer(uint32_t current_frame);
void draw_frame(); void draw_frame();