Files
FGL-Engine/src/engine/rendering/PhysicalDevice.cpp
2024-08-09 07:59:11 -04:00

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