Вынес работу с VpPhysicalDevice в отдельный класс
This commit is contained in:
@@ -84,6 +84,7 @@ namespace VkObjects
|
||||
destroyer_messenger(instance_, debug_messenger_, nullptr);
|
||||
}
|
||||
#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()
|
||||
{
|
||||
vkDestroySurfaceKHR(instance_.get_native(), surface_, nullptr);
|
||||
if(surface_ != nullptr)
|
||||
vkDestroySurfaceKHR(instance_.get_native(), surface_, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user