109 lines
2.9 KiB
C++
109 lines
2.9 KiB
C++
//
|
|
// Created by kj16609 on 6/20/24.
|
|
//
|
|
|
|
#include "PhysicalDevice.hpp"
|
|
|
|
#include "Instance.hpp"
|
|
#include "Surface.hpp"
|
|
#include "engine/logging/logging.hpp"
|
|
|
|
namespace fgl::engine
|
|
{
|
|
|
|
PhysicalDevice::PhysicalDevice( Instance& instance, Surface& surface ) :
|
|
m_phy_device( pickPhysicalDevice( instance, surface ) ),
|
|
queue_pool( m_phy_device, surface )
|
|
{}
|
|
|
|
//! Checks that a device has a graphics capable queue and can present to the given surface.
|
|
bool isDeviceSupported( const vk::raii::PhysicalDevice& device, Surface& surface )
|
|
{
|
|
const std::vector< vk::QueueFamilyProperties > family_props { device.getQueueFamilyProperties() };
|
|
|
|
bool has_graphics_queue { false };
|
|
bool has_present_queue { false };
|
|
|
|
int idx { 0 };
|
|
for ( const auto& queue_family : family_props )
|
|
{
|
|
if ( queue_family.queueCount <= 0 )
|
|
{
|
|
++idx;
|
|
continue;
|
|
}
|
|
|
|
// We need at least 1 queue that can do graphics.
|
|
if ( queue_family.queueFlags & vk::QueueFlagBits::eGraphics )
|
|
{
|
|
log::debug( "Graphics capable queue found at idx: {}", idx );
|
|
has_graphics_queue = true;
|
|
}
|
|
|
|
// Check if the device can present to the surface.
|
|
vk::Bool32 can_present { device.getSurfaceSupportKHR( idx, surface ) };
|
|
if ( can_present == VK_TRUE )
|
|
{
|
|
log::debug( "Present capable queue found at idx: {}", idx );
|
|
has_present_queue = true;
|
|
}
|
|
|
|
if ( has_graphics_queue && has_present_queue ) return true;
|
|
|
|
++idx;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
vk::raii::PhysicalDevice PhysicalDevice::pickPhysicalDevice( Instance& instance, Surface& surface )
|
|
{
|
|
std::vector< vk::raii::PhysicalDevice > devices { instance.handle().enumeratePhysicalDevices() };
|
|
|
|
for ( auto& device : devices )
|
|
{
|
|
if ( isDeviceSupported( device, surface ) )
|
|
{
|
|
//We found a device we can use.
|
|
log::info( "Found device for surface" );
|
|
|
|
vk::raii::PhysicalDevice selected_device { std::move( device ) };
|
|
|
|
return selected_device;
|
|
}
|
|
}
|
|
|
|
throw std::runtime_error( "Failed to find a valid device" );
|
|
}
|
|
|
|
const static std::vector< const char* > required_device_extensions { VK_KHR_SWAPCHAIN_EXTENSION_NAME,
|
|
VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME,
|
|
#if ENABLE_CALIBRATED_PROFILING
|
|
VK_KHR_CALIBRATED_TIMESTAMPS_EXTENSION_NAME
|
|
#endif
|
|
};
|
|
|
|
bool PhysicalDevice::supportsRequiredExtensions()
|
|
{
|
|
const std::vector< vk::ExtensionProperties > device_extentions {
|
|
m_phy_device.enumerateDeviceExtensionProperties()
|
|
};
|
|
|
|
for ( const auto required : required_device_extensions )
|
|
{
|
|
if ( std::find_if(
|
|
device_extentions.begin(),
|
|
device_extentions.end(),
|
|
[ &required ]( const vk::ExtensionProperties& props )
|
|
{ return std::strcmp( props.extensionName, required ); } )
|
|
== device_extentions.end() )
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
} // namespace fgl::engine
|