Вынес работу с VpPhysicalDevice в отдельный класс

This commit is contained in:
Jiga228
2026-06-23 18:35:48 +07:00
parent 70956e2032
commit 3cbe642fca
6 changed files with 233 additions and 193 deletions
@@ -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;
}