Вынес работу с VpPhysicalDevice в отдельный класс
This commit is contained in:
@@ -29,134 +29,21 @@ UwURenderEngine::SwapchainSupportDetails UwURenderEngine::query_swapchain_detail
|
|||||||
{
|
{
|
||||||
SwapchainSupportDetails details;
|
SwapchainSupportDetails details;
|
||||||
|
|
||||||
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physical_device_, surface_.get_native(), &details.capabilities);
|
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physical_device_.get_native(), surface_.get_native(), &details.capabilities);
|
||||||
|
|
||||||
uint32_t surface_format_cnt = 0;
|
uint32_t surface_format_cnt = 0;
|
||||||
VK_CHECK(vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device_, surface_.get_native(), &surface_format_cnt, nullptr))
|
VK_CHECK(vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device_.get_native(), surface_.get_native(), &surface_format_cnt, nullptr))
|
||||||
details.formats.resize(surface_format_cnt);
|
details.formats.resize(surface_format_cnt);
|
||||||
VK_CHECK(vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device_, surface_.get_native(), &surface_format_cnt, details.formats.data()))
|
VK_CHECK(vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device_.get_native(), surface_.get_native(), &surface_format_cnt, details.formats.data()))
|
||||||
|
|
||||||
uint32_t present_modes_cnt = 0;
|
uint32_t present_modes_cnt = 0;
|
||||||
VK_CHECK(vkGetPhysicalDeviceSurfacePresentModesKHR(physical_device_, surface_.get_native(), &present_modes_cnt, nullptr))
|
VK_CHECK(vkGetPhysicalDeviceSurfacePresentModesKHR(physical_device_.get_native(), surface_.get_native(), &present_modes_cnt, nullptr))
|
||||||
details.present_modes.resize(surface_format_cnt);
|
details.present_modes.resize(surface_format_cnt);
|
||||||
VK_CHECK(vkGetPhysicalDeviceSurfacePresentModesKHR(physical_device_, surface_.get_native(), &present_modes_cnt, details.present_modes.data()))
|
VK_CHECK(vkGetPhysicalDeviceSurfacePresentModesKHR(physical_device_.get_native(), surface_.get_native(), &present_modes_cnt, details.present_modes.data()))
|
||||||
|
|
||||||
return details;
|
return details;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool UwURenderEngine::is_device_suitable(VkPhysicalDevice device, VkSurfaceKHR surface)
|
|
||||||
{
|
|
||||||
VkPhysicalDeviceProperties device_properties;
|
|
||||||
VkPhysicalDeviceFeatures device_features;
|
|
||||||
vkGetPhysicalDeviceProperties(device, &device_properties);
|
|
||||||
vkGetPhysicalDeviceFeatures(device, &device_features);
|
|
||||||
|
|
||||||
try {
|
|
||||||
// Ловить исключения имеет смысыл только здесь
|
|
||||||
find_queue_family_indices(device, surface);
|
|
||||||
} catch (...) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return check_device_extensions_support(device);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool UwURenderEngine::check_device_extensions_support(VkPhysicalDevice device)
|
|
||||||
{
|
|
||||||
uint32_t extension_count;
|
|
||||||
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()))
|
|
||||||
|
|
||||||
for (const auto& extension : deviceExtensions)
|
|
||||||
{
|
|
||||||
bool isFind = false;
|
|
||||||
for (const auto& i : available_extensions)
|
|
||||||
{
|
|
||||||
if (std::strcmp(i.extensionName, extension) == 0)
|
|
||||||
{
|
|
||||||
isFind = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!isFind)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
UwURenderEngine::QueueFamilyIndices UwURenderEngine::find_queue_family_indices(VkPhysicalDevice physical_device, VkSurfaceKHR surface)
|
|
||||||
{
|
|
||||||
QueueFamilyIndices queue_family_indices;
|
|
||||||
|
|
||||||
uint32_t queueFamilyCount = 0;
|
|
||||||
vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &queueFamilyCount, nullptr);
|
|
||||||
std::vector<VkQueueFamilyProperties> family_properties(queueFamilyCount);
|
|
||||||
vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &queueFamilyCount, family_properties.data());
|
|
||||||
|
|
||||||
// Find graphics
|
|
||||||
for(uint32_t i = 0; i < family_properties.size(); ++i)
|
|
||||||
{
|
|
||||||
if (family_properties[i].queueFlags & VK_QUEUE_GRAPHICS_BIT)
|
|
||||||
{
|
|
||||||
queue_family_indices.graphics_family = i;
|
|
||||||
queue_family_indices.is_find_graphics_family = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (queue_family_indices.is_find_graphics_family == false)
|
|
||||||
throw std::runtime_error("Failed to find a graphics queue family");
|
|
||||||
|
|
||||||
// Find present
|
|
||||||
VkBool32 present_support = false;
|
|
||||||
VK_CHECK(vkGetPhysicalDeviceSurfaceSupportKHR(physical_device, queue_family_indices.graphics_family, surface, &present_support))
|
|
||||||
// Если графическая очередь поддерживет презентацию кадров, то используем её
|
|
||||||
if (present_support == VK_TRUE)
|
|
||||||
{
|
|
||||||
queue_family_indices.present_family = queue_family_indices.graphics_family;
|
|
||||||
queue_family_indices.is_find_present_family = true;
|
|
||||||
}
|
|
||||||
// иначе ищем другую подходящую очередь
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for(uint32_t i = 0; i < family_properties.size(); ++i)
|
|
||||||
{
|
|
||||||
present_support = false;
|
|
||||||
VK_CHECK(vkGetPhysicalDeviceSurfaceSupportKHR(physical_device, i, surface, &present_support))
|
|
||||||
if (present_support == VK_TRUE)
|
|
||||||
{
|
|
||||||
queue_family_indices.present_family = i;
|
|
||||||
queue_family_indices.is_find_present_family = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (queue_family_indices.is_find_present_family == false)
|
|
||||||
throw std::runtime_error("Failed to find a present queue family");
|
|
||||||
|
|
||||||
// С начала пытаемся найти очередь специалезированную
|
|
||||||
// для копирования отличную от графической
|
|
||||||
for(uint32_t i = 0; i < family_properties.size(); ++i)
|
|
||||||
{
|
|
||||||
if (i == queue_family_indices.graphics_family)
|
|
||||||
continue;
|
|
||||||
if (family_properties[i].queueFlags & VK_QUEUE_TRANSFER_BIT)
|
|
||||||
{
|
|
||||||
queue_family_indices.transfer_family = i;
|
|
||||||
queue_family_indices.is_find_transfer_family = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Если не находим, то используем графическую
|
|
||||||
if (queue_family_indices.is_find_transfer_family == false)
|
|
||||||
{
|
|
||||||
queue_family_indices.transfer_family = queue_family_indices.graphics_family;
|
|
||||||
queue_family_indices.is_find_transfer_family = true;
|
|
||||||
}
|
|
||||||
return queue_family_indices;
|
|
||||||
}
|
|
||||||
|
|
||||||
VkSurfaceFormatKHR UwURenderEngine::choose_surface_format(const std::vector<VkSurfaceFormatKHR>& surface_formats)
|
VkSurfaceFormatKHR UwURenderEngine::choose_surface_format(const std::vector<VkSurfaceFormatKHR>& surface_formats)
|
||||||
{
|
{
|
||||||
for (const auto& i : surface_formats)
|
for (const auto& i : surface_formats)
|
||||||
@@ -189,33 +76,9 @@ VkShaderModule UwURenderEngine::create_shader_module(const std::string& code) co
|
|||||||
return shader_module;
|
return shader_module;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UwURenderEngine::pick_physical_device()
|
|
||||||
{
|
|
||||||
uint32_t device_count = 0;
|
|
||||||
std::vector<VkPhysicalDevice> devices;
|
|
||||||
VK_CHECK(vkEnumeratePhysicalDevices(instance_.get_native(), &device_count, nullptr))
|
|
||||||
devices.resize(device_count);
|
|
||||||
VK_CHECK(vkEnumeratePhysicalDevices(instance_.get_native(), &device_count, devices.data()))
|
|
||||||
|
|
||||||
for (const auto& device : devices)
|
|
||||||
{
|
|
||||||
if (is_device_suitable(device, surface_.get_native()))
|
|
||||||
{
|
|
||||||
physical_device_ = device;
|
|
||||||
VkPhysicalDeviceProperties device_properties;
|
|
||||||
vkGetPhysicalDeviceProperties(physical_device_, &device_properties);
|
|
||||||
Loging::Log("Using device: " + std::string(device_properties.deviceName));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (VK_NULL_HANDLE == physical_device_)
|
|
||||||
throw std::runtime_error("No suitable device found");
|
|
||||||
}
|
|
||||||
|
|
||||||
void UwURenderEngine::create_logical_device()
|
void UwURenderEngine::create_logical_device()
|
||||||
{
|
{
|
||||||
QueueFamilyIndices indices = find_queue_family_indices(physical_device_, surface_.get_native());
|
VkObjects::PhysicalDevice::QueueFamilyIndices indices = physical_device_.get_queue_family_indices();
|
||||||
|
|
||||||
VkPhysicalDeviceFeatures device_features{};
|
VkPhysicalDeviceFeatures device_features{};
|
||||||
|
|
||||||
@@ -254,7 +117,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_.get_native(), &device_create_info, nullptr, &device_))
|
||||||
vkGetDeviceQueue(device_, indices.graphics_family, 0, &graphics_queue_);
|
vkGetDeviceQueue(device_, indices.graphics_family, 0, &graphics_queue_);
|
||||||
vkGetDeviceQueue(device_, indices.present_family, 0, &present_queue_);
|
vkGetDeviceQueue(device_, indices.present_family, 0, &present_queue_);
|
||||||
vkGetDeviceQueue(device_, indices.transfer_family, 0, &transfer_queue_);
|
vkGetDeviceQueue(device_, indices.transfer_family, 0, &transfer_queue_);
|
||||||
@@ -286,7 +149,7 @@ void UwURenderEngine::create_swapchain()
|
|||||||
swapchain_create_info.clipped = VK_TRUE;
|
swapchain_create_info.clipped = VK_TRUE;
|
||||||
swapchain_create_info.oldSwapchain = VK_NULL_HANDLE;
|
swapchain_create_info.oldSwapchain = VK_NULL_HANDLE;
|
||||||
|
|
||||||
QueueFamilyIndices family_indices = find_queue_family_indices(physical_device_, surface_.get_native());
|
VkObjects::PhysicalDevice::QueueFamilyIndices family_indices = physical_device_.get_queue_family_indices();
|
||||||
const std::set<uint32_t> queue_family_indices = { family_indices.graphics_family,
|
const std::set<uint32_t> queue_family_indices = { family_indices.graphics_family,
|
||||||
family_indices.present_family,
|
family_indices.present_family,
|
||||||
family_indices.transfer_family };
|
family_indices.transfer_family };
|
||||||
@@ -407,12 +270,12 @@ void UwURenderEngine::create_uniform_buffers()
|
|||||||
uniform_buffers_memory_.resize(swapchain_images_.size());
|
uniform_buffers_memory_.resize(swapchain_images_.size());
|
||||||
uniform_buffers_mapped_.resize(swapchain_images_.size());
|
uniform_buffers_mapped_.resize(swapchain_images_.size());
|
||||||
|
|
||||||
std::vector<uint32_t> arr_indices = get_unique_family_indices(find_queue_family_indices(physical_device_, surface_.get_native()));
|
std::vector<uint32_t> arr_indices = physical_device_.get_unique_family_indices();
|
||||||
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);
|
||||||
uniform_buffers_[i] = DeviceFunctions::create_buffer(device_, size, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, arr_indices);
|
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);
|
uniform_buffers_memory_[i] = DeviceFunctions::allocate_device_memory(physical_device_.get_native(), 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]);
|
||||||
@@ -631,7 +494,7 @@ void UwURenderEngine::create_framebuffers()
|
|||||||
|
|
||||||
void UwURenderEngine::create_command_pool()
|
void UwURenderEngine::create_command_pool()
|
||||||
{
|
{
|
||||||
QueueFamilyIndices queue_family_indices = find_queue_family_indices(physical_device_, surface_.get_native());
|
VkObjects::PhysicalDevice::QueueFamilyIndices queue_family_indices = physical_device_.get_queue_family_indices();
|
||||||
|
|
||||||
VkCommandPoolCreateInfo command_pool_info{};
|
VkCommandPoolCreateInfo command_pool_info{};
|
||||||
command_pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
|
command_pool_info.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
|
||||||
@@ -641,36 +504,23 @@ void UwURenderEngine::create_command_pool()
|
|||||||
VK_CHECK(vkCreateCommandPool(device_, &command_pool_info, nullptr, &command_pool_))
|
VK_CHECK(vkCreateCommandPool(device_, &command_pool_info, nullptr, &command_pool_))
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<uint32_t> UwURenderEngine::get_unique_family_indices(const QueueFamilyIndices& indices)
|
|
||||||
{
|
|
||||||
std::set<uint32_t> set_indices = {indices.graphics_family,
|
|
||||||
indices.present_family,
|
|
||||||
indices.transfer_family};
|
|
||||||
|
|
||||||
std::vector<uint32_t> arr_indices;
|
|
||||||
arr_indices.reserve(set_indices.size());
|
|
||||||
for (auto& i : set_indices)
|
|
||||||
arr_indices.push_back(i);
|
|
||||||
return arr_indices;
|
|
||||||
}
|
|
||||||
|
|
||||||
void UwURenderEngine::allocate_vertex_buffer()
|
void UwURenderEngine::allocate_vertex_buffer()
|
||||||
{
|
{
|
||||||
QueueFamilyIndices indices = find_queue_family_indices(physical_device_, surface_.get_native());
|
VkObjects::PhysicalDevice::QueueFamilyIndices indices = physical_device_.get_queue_family_indices();
|
||||||
|
|
||||||
|
|
||||||
std::vector<uint32_t> arr_indices = get_unique_family_indices(indices);
|
std::vector<uint32_t> arr_indices = physical_device_.get_unique_family_indices();
|
||||||
std::vector<uint32_t> transfer_index = {indices.transfer_family};
|
std::vector<uint32_t> transfer_index = {indices.transfer_family};
|
||||||
|
|
||||||
VkDeviceSize size_buffer = sizeof(vertices_[0]) * vertices_.size();
|
VkDeviceSize size_buffer = sizeof(vertices_[0]) * vertices_.size();
|
||||||
VkBuffer staging_buffer = DeviceFunctions::create_buffer(device_, size_buffer, VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
|
VkBuffer staging_buffer = DeviceFunctions::create_buffer(device_, size_buffer, VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
|
||||||
transfer_index);
|
transfer_index);
|
||||||
VkDeviceMemory staging_buffer_memory = DeviceFunctions::allocate_device_memory(
|
VkDeviceMemory staging_buffer_memory = DeviceFunctions::allocate_device_memory(
|
||||||
physical_device_, device_, staging_buffer,
|
physical_device_.get_native(), device_, staging_buffer,
|
||||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
|
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
|
||||||
|
|
||||||
vertex_buffer_ = DeviceFunctions::create_buffer(device_, size_buffer, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, arr_indices);
|
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);
|
vertex_buffer_memory_ = DeviceFunctions::allocate_device_memory(physical_device_.get_native(), 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))
|
||||||
@@ -688,19 +538,15 @@ void UwURenderEngine::allocate_vertex_buffer()
|
|||||||
|
|
||||||
void UwURenderEngine::allocate_index_buffer()
|
void UwURenderEngine::allocate_index_buffer()
|
||||||
{
|
{
|
||||||
QueueFamilyIndices indices = find_queue_family_indices(physical_device_, surface_.get_native());
|
std::vector<uint32_t> arr_indices = physical_device_.get_unique_family_indices();
|
||||||
std::set<uint32_t> set_indices = {indices.graphics_family,
|
VkObjects::PhysicalDevice::QueueFamilyIndices indices = physical_device_.get_queue_family_indices();
|
||||||
indices.present_family,
|
|
||||||
indices.transfer_family};
|
|
||||||
|
|
||||||
std::vector<uint32_t> arr_indices = get_unique_family_indices(indices);
|
|
||||||
std::vector<uint32_t> transfer_index = {indices.transfer_family};
|
std::vector<uint32_t> transfer_index = {indices.transfer_family};
|
||||||
|
|
||||||
VkDeviceSize size_buffer = sizeof(indices_[0]) * indices_.size();
|
VkDeviceSize size_buffer = sizeof(indices_[0]) * indices_.size();
|
||||||
VkBuffer staging_buffer = DeviceFunctions::create_buffer(device_, size_buffer, VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
|
VkBuffer staging_buffer = DeviceFunctions::create_buffer(device_, size_buffer, VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
|
||||||
transfer_index);
|
transfer_index);
|
||||||
VkDeviceMemory staging_buffer_memory = DeviceFunctions::allocate_device_memory(
|
VkDeviceMemory staging_buffer_memory = DeviceFunctions::allocate_device_memory(
|
||||||
physical_device_, device_, staging_buffer,
|
physical_device_.get_native(), device_, staging_buffer,
|
||||||
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
|
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);
|
||||||
|
|
||||||
@@ -710,7 +556,7 @@ void UwURenderEngine::allocate_index_buffer()
|
|||||||
vkUnmapMemory(device_, staging_buffer_memory);
|
vkUnmapMemory(device_, staging_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_ = 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);
|
index_buffer_memory_ = DeviceFunctions::allocate_device_memory(physical_device_.get_native(), 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);
|
||||||
|
|
||||||
DeviceFunctions::device_memcpy(device_, indices.transfer_family,staging_buffer, index_buffer_, size_buffer);
|
DeviceFunctions::device_memcpy(device_, indices.transfer_family,staging_buffer, index_buffer_, size_buffer);
|
||||||
@@ -875,9 +721,9 @@ void UwURenderEngine::draw_frame()
|
|||||||
UwURenderEngine::UwURenderEngine(CoreInstance& core):RenderEngineBase(core),
|
UwURenderEngine::UwURenderEngine(CoreInstance& core):RenderEngineBase(core),
|
||||||
instance_(core),
|
instance_(core),
|
||||||
surface_(instance_, get_window()),
|
surface_(instance_, get_window()),
|
||||||
|
physical_device_(instance_, surface_, deviceExtensions),
|
||||||
core_(core)
|
core_(core)
|
||||||
{
|
{
|
||||||
pick_physical_device();
|
|
||||||
create_logical_device();
|
create_logical_device();
|
||||||
create_swapchain();
|
create_swapchain();
|
||||||
create_image_views();
|
create_image_views();
|
||||||
@@ -895,7 +741,7 @@ core_(core)
|
|||||||
create_sync_objects();
|
create_sync_objects();
|
||||||
|
|
||||||
garbage_collector_.reset(new GPU_GarbageCollector(device_));
|
garbage_collector_.reset(new GPU_GarbageCollector(device_));
|
||||||
model_manager_.reset(new ModelManager(physical_device_, device_));
|
model_manager_.reset(new ModelManager(physical_device_.get_native(), device_));
|
||||||
}
|
}
|
||||||
|
|
||||||
UwURenderEngine::~UwURenderEngine()
|
UwURenderEngine::~UwURenderEngine()
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
#include "VkObjects/Instance.hpp"
|
#include "VkObjects/Instance.hpp"
|
||||||
|
#include "VkObjects/PhysicalDevice.hpp"
|
||||||
#include "VkObjects/Surface.hpp"
|
#include "VkObjects/Surface.hpp"
|
||||||
|
|
||||||
class Camera;
|
class Camera;
|
||||||
@@ -21,15 +22,6 @@ class GPU_GarbageCollector;
|
|||||||
|
|
||||||
class UwURenderEngine : public RenderEngineBase
|
class UwURenderEngine : public RenderEngineBase
|
||||||
{
|
{
|
||||||
struct QueueFamilyIndices
|
|
||||||
{
|
|
||||||
uint32_t graphics_family = 0;
|
|
||||||
uint32_t present_family = 0;
|
|
||||||
uint32_t transfer_family = 0;
|
|
||||||
bool is_find_graphics_family = false;
|
|
||||||
bool is_find_present_family = false;
|
|
||||||
bool is_find_transfer_family = false;
|
|
||||||
};
|
|
||||||
struct SwapchainSupportDetails
|
struct SwapchainSupportDetails
|
||||||
{
|
{
|
||||||
std::vector<VkSurfaceFormatKHR> formats;
|
std::vector<VkSurfaceFormatKHR> formats;
|
||||||
@@ -74,8 +66,8 @@ class UwURenderEngine : public RenderEngineBase
|
|||||||
|
|
||||||
VkObjects::Instance instance_;
|
VkObjects::Instance instance_;
|
||||||
VkObjects::Surface surface_;
|
VkObjects::Surface surface_;
|
||||||
//VkSurfaceKHR surface_ = VK_NULL_HANDLE;
|
VkObjects::PhysicalDevice physical_device_;
|
||||||
VkPhysicalDevice physical_device_ = VK_NULL_HANDLE;
|
//VkPhysicalDevice physical_device_ = VK_NULL_HANDLE;
|
||||||
VkDevice device_ = VK_NULL_HANDLE;
|
VkDevice device_ = VK_NULL_HANDLE;
|
||||||
VkQueue graphics_queue_ = VK_NULL_HANDLE;
|
VkQueue graphics_queue_ = VK_NULL_HANDLE;
|
||||||
VkQueue present_queue_ = VK_NULL_HANDLE;
|
VkQueue present_queue_ = VK_NULL_HANDLE;
|
||||||
@@ -108,15 +100,10 @@ class UwURenderEngine : public RenderEngineBase
|
|||||||
|
|
||||||
SwapchainSupportDetails query_swapchain_details() const;
|
SwapchainSupportDetails query_swapchain_details() const;
|
||||||
|
|
||||||
static bool is_device_suitable(VkPhysicalDevice device, VkSurfaceKHR surface);
|
|
||||||
static bool check_device_extensions_support(VkPhysicalDevice device);
|
|
||||||
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);
|
||||||
VkShaderModule create_shader_module(const std::string& code) const;
|
VkShaderModule create_shader_module(const std::string& code) const;
|
||||||
static std::vector<uint32_t> get_unique_family_indices(const QueueFamilyIndices& indices);
|
|
||||||
|
|
||||||
void pick_physical_device();
|
|
||||||
void create_logical_device();
|
void create_logical_device();
|
||||||
void create_swapchain();
|
void create_swapchain();
|
||||||
void create_image_views();
|
void create_image_views();
|
||||||
|
|||||||
@@ -84,6 +84,7 @@ namespace VkObjects
|
|||||||
destroyer_messenger(instance_, debug_messenger_, nullptr);
|
destroyer_messenger(instance_, debug_messenger_, nullptr);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
vkDestroyInstance(instance_, nullptr);
|
if(instance_ != nullptr)
|
||||||
|
vkDestroyInstance(instance_, nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,164 @@
|
|||||||
|
#include "PhysicalDevice.hpp"
|
||||||
|
|
||||||
|
#include <set>
|
||||||
|
|
||||||
|
#include "Surface.hpp"
|
||||||
|
#include "Instance.hpp"
|
||||||
|
#include "DeviceFunctions/DeviceFunctions.hpp"
|
||||||
|
#include "Log/Log.hpp"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
VkObjects::PhysicalDevice::QueueFamilyIndices VkObjects::PhysicalDevice::is_device_suitable(VkPhysicalDevice device, VkSurfaceKHR surface, const std::vector<const char*>& device_extensions)
|
||||||
|
{
|
||||||
|
VkPhysicalDeviceProperties device_properties;
|
||||||
|
VkPhysicalDeviceFeatures device_features;
|
||||||
|
vkGetPhysicalDeviceProperties(device, &device_properties);
|
||||||
|
vkGetPhysicalDeviceFeatures(device, &device_features);
|
||||||
|
|
||||||
|
if(check_device_extensions_support(device, device_extensions) == false)
|
||||||
|
throw std::runtime_error("Device not supported");
|
||||||
|
|
||||||
|
return find_queue_family_indices(device, surface);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VkObjects::PhysicalDevice::check_device_extensions_support(VkPhysicalDevice device, const std::vector<const char*>& device_extensions)
|
||||||
|
{
|
||||||
|
uint32_t extension_count;
|
||||||
|
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()))
|
||||||
|
|
||||||
|
for (const auto& extension : device_extensions)
|
||||||
|
{
|
||||||
|
bool isFind = false;
|
||||||
|
for (const auto& i : available_extensions)
|
||||||
|
{
|
||||||
|
if (std::strcmp(i.extensionName, extension) == 0)
|
||||||
|
{
|
||||||
|
isFind = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!isFind)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
VkObjects::PhysicalDevice::QueueFamilyIndices VkObjects::PhysicalDevice::find_queue_family_indices(
|
||||||
|
VkPhysicalDevice physical_device, VkSurfaceKHR surface)
|
||||||
|
{
|
||||||
|
QueueFamilyIndices queue_family_indices;
|
||||||
|
|
||||||
|
uint32_t queueFamilyCount = 0;
|
||||||
|
vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &queueFamilyCount, nullptr);
|
||||||
|
std::vector<VkQueueFamilyProperties> family_properties(queueFamilyCount);
|
||||||
|
vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &queueFamilyCount, family_properties.data());
|
||||||
|
|
||||||
|
// Find graphics
|
||||||
|
for(uint32_t i = 0; i < family_properties.size(); ++i)
|
||||||
|
{
|
||||||
|
if (family_properties[i].queueFlags & VK_QUEUE_GRAPHICS_BIT)
|
||||||
|
{
|
||||||
|
queue_family_indices.graphics_family = i;
|
||||||
|
queue_family_indices.is_find_graphics_family = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (queue_family_indices.is_find_graphics_family == false)
|
||||||
|
throw std::runtime_error("Failed to find a graphics queue family");
|
||||||
|
|
||||||
|
// Find present
|
||||||
|
VkBool32 present_support = false;
|
||||||
|
VK_CHECK(vkGetPhysicalDeviceSurfaceSupportKHR(physical_device, queue_family_indices.graphics_family, surface, &present_support))
|
||||||
|
// Если графическая очередь поддерживет презентацию кадров, то используем её
|
||||||
|
if (present_support == VK_TRUE)
|
||||||
|
{
|
||||||
|
queue_family_indices.present_family = queue_family_indices.graphics_family;
|
||||||
|
queue_family_indices.is_find_present_family = true;
|
||||||
|
}
|
||||||
|
// иначе ищем другую подходящую очередь
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for(uint32_t i = 0; i < family_properties.size(); ++i)
|
||||||
|
{
|
||||||
|
present_support = false;
|
||||||
|
VK_CHECK(vkGetPhysicalDeviceSurfaceSupportKHR(physical_device, i, surface, &present_support))
|
||||||
|
if (present_support == VK_TRUE)
|
||||||
|
{
|
||||||
|
queue_family_indices.present_family = i;
|
||||||
|
queue_family_indices.is_find_present_family = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (queue_family_indices.is_find_present_family == false)
|
||||||
|
throw std::runtime_error("Failed to find a present queue family");
|
||||||
|
|
||||||
|
// С начала пытаемся найти очередь специалезированную
|
||||||
|
// для копирования отличную от графической
|
||||||
|
for(uint32_t i = 0; i < family_properties.size(); ++i)
|
||||||
|
{
|
||||||
|
if (i == queue_family_indices.graphics_family)
|
||||||
|
continue;
|
||||||
|
if (family_properties[i].queueFlags & VK_QUEUE_TRANSFER_BIT)
|
||||||
|
{
|
||||||
|
queue_family_indices.transfer_family = i;
|
||||||
|
queue_family_indices.is_find_transfer_family = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Если не находим, то используем графическую
|
||||||
|
if (queue_family_indices.is_find_transfer_family == false)
|
||||||
|
{
|
||||||
|
queue_family_indices.transfer_family = queue_family_indices.graphics_family;
|
||||||
|
queue_family_indices.is_find_transfer_family = true;
|
||||||
|
}
|
||||||
|
return queue_family_indices;
|
||||||
|
}
|
||||||
|
|
||||||
|
VkObjects::PhysicalDevice::PhysicalDevice(const Instance& instance,
|
||||||
|
const Surface& surface,
|
||||||
|
const std::vector<const char*>& device_extensions)
|
||||||
|
{
|
||||||
|
uint32_t device_count = 0;
|
||||||
|
std::vector<VkPhysicalDevice> devices;
|
||||||
|
VK_CHECK(vkEnumeratePhysicalDevices(instance.get_native(), &device_count, nullptr))
|
||||||
|
devices.resize(device_count);
|
||||||
|
VK_CHECK(vkEnumeratePhysicalDevices(instance.get_native(), &device_count, devices.data()))
|
||||||
|
|
||||||
|
for (const auto& device : devices)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
queue_family_indices_ = is_device_suitable(device, surface.get_native(), device_extensions);
|
||||||
|
physical_device_ = device;
|
||||||
|
VkPhysicalDeviceProperties device_properties;
|
||||||
|
vkGetPhysicalDeviceProperties(physical_device_, &device_properties);
|
||||||
|
Loging::Log("Using device: " + std::string(device_properties.deviceName));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
catch(...)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (VK_NULL_HANDLE == physical_device_)
|
||||||
|
throw std::runtime_error("No suitable device found");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<uint32_t> VkObjects::PhysicalDevice::get_unique_family_indices() const
|
||||||
|
{
|
||||||
|
std::set<uint32_t> set_indices = {queue_family_indices_.graphics_family,
|
||||||
|
queue_family_indices_.present_family,
|
||||||
|
queue_family_indices_.transfer_family};
|
||||||
|
|
||||||
|
std::vector<uint32_t> arr_indices;
|
||||||
|
arr_indices.reserve(set_indices.size());
|
||||||
|
for (auto& i : set_indices)
|
||||||
|
arr_indices.push_back(i);
|
||||||
|
return arr_indices;
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <vulkan/vulkan_core.h>
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace VkObjects
|
||||||
|
{
|
||||||
|
class Surface;
|
||||||
|
class Instance;
|
||||||
|
|
||||||
|
class PhysicalDevice
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
struct QueueFamilyIndices
|
||||||
|
{
|
||||||
|
uint32_t graphics_family = 0;
|
||||||
|
uint32_t present_family = 0;
|
||||||
|
uint32_t transfer_family = 0;
|
||||||
|
bool is_find_graphics_family = false;
|
||||||
|
bool is_find_present_family = false;
|
||||||
|
bool is_find_transfer_family = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
QueueFamilyIndices queue_family_indices_{};
|
||||||
|
private:
|
||||||
|
VkPhysicalDevice physical_device_ = nullptr;
|
||||||
|
|
||||||
|
// Выбрасывает исключение если не подходит
|
||||||
|
static QueueFamilyIndices is_device_suitable(VkPhysicalDevice device, VkSurfaceKHR surface, const std::vector<const char*>& device_extensions);
|
||||||
|
static bool check_device_extensions_support(VkPhysicalDevice device, const std::vector<const char*>& device_extensions);
|
||||||
|
static QueueFamilyIndices find_queue_family_indices(VkPhysicalDevice physical_device,
|
||||||
|
VkSurfaceKHR surface);
|
||||||
|
public:
|
||||||
|
PhysicalDevice(const Instance& instance, const Surface& surface, const std::vector<const char*>& device_extensions);
|
||||||
|
|
||||||
|
inline VkPhysicalDevice get_native() const { return physical_device_; }
|
||||||
|
inline QueueFamilyIndices get_queue_family_indices() const { return queue_family_indices_; }
|
||||||
|
std::vector<uint32_t> get_unique_family_indices() const;
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -12,6 +12,7 @@ namespace VkObjects
|
|||||||
|
|
||||||
Surface::~Surface()
|
Surface::~Surface()
|
||||||
{
|
{
|
||||||
vkDestroySurfaceKHR(instance_.get_native(), surface_, nullptr);
|
if(surface_ != nullptr)
|
||||||
|
vkDestroySurfaceKHR(instance_.get_native(), surface_, nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user