Skip to content

Commit

Permalink
[Vk] Identify physical devices by name rather than by index. Assign u…
Browse files Browse the repository at this point in the history
…nique names that are robust to devices addition/removing by adding suffixes only if necessary.
  • Loading branch information
eugenegff committed Nov 7, 2024
1 parent 9a66c04 commit 87326b4
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 96 deletions.
4 changes: 2 additions & 2 deletions RenderSystems/Vulkan/include/OgreVulkanDevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ namespace Ogre
FastArray<VkDeviceQueueCreateInfo> &outQueueCiArray );

public:
VulkanDevice( VkInstance instance, uint32 deviceIdx, VulkanRenderSystem *renderSystem );
VulkanDevice( VkInstance instance, const String &deviceName, VulkanRenderSystem *renderSystem );
VulkanDevice( VkInstance instance, const VulkanExternalDevice &externalDevice,
VulkanRenderSystem *renderSystem );
~VulkanDevice();
Expand All @@ -153,7 +153,7 @@ namespace Ogre
static void addExternalInstanceExtensions( FastArray<VkExtensionProperties> &extensions );

protected:
void createPhysicalDevice( uint32 deviceIdx );
void createPhysicalDevice( const String &deviceName );

public:
void createDevice( FastArray<const char *> &extensions, uint32 maxComputeQueues,
Expand Down
11 changes: 9 additions & 2 deletions RenderSystems/Vulkan/include/OgreVulkanRenderSystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,13 @@ namespace Ogre
struct VulkanHlmsPso;
class VulkanSupport;

struct VulkanPhysicalDevice
{
VkPhysicalDevice physicalDevice;
String title;
};
typedef std::vector<VulkanPhysicalDevice> VulkanPhysicalDeviceList;

/**
Implementation of Vulkan as a rendering system.
*/
Expand All @@ -74,7 +81,7 @@ namespace Ogre
VulkanProgramFactory *mVulkanProgramFactory3;

VkInstance mVkInstance;
FastArray<VkPhysicalDevice> mVkPhysicalDeviceList;
VulkanPhysicalDeviceList mVulkanPhysicalDeviceList;
VulkanSupport *mVulkanSupport;

std::map<IdString, VulkanSupport *> mAvailableVulkanSupports;
Expand Down Expand Up @@ -200,7 +207,7 @@ namespace Ogre
void sharedVkInitialization();

VkInstance getVkInstance() const { return mVkInstance; }
const FastArray<VkPhysicalDevice> &getVkPhysicalDevices( bool refreshList = false );
const VulkanPhysicalDeviceList &getVulkanPhysicalDevices( bool refreshList = false );

Window *_initialise( bool autoCreateWindow,
const String &windowTitle = "OGRE Render Window" ) override;
Expand Down
6 changes: 1 addition & 5 deletions RenderSystems/Vulkan/include/OgreVulkanSupport.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,8 @@ namespace Ogre

class _OgreVulkanExport VulkanSupport
{
FastArray<String> mDevices;

bool mSupported;

void enumerateDevices( VulkanRenderSystem *renderSystem );

void initialize( VulkanRenderSystem *renderSystem );

public:
Expand All @@ -66,7 +62,7 @@ namespace Ogre

virtual String validateConfigOptions();

uint32 getSelectedDeviceIdx() const;
String getSelectedDeviceName() const;

ConfigOptionMap &getConfigOptions( VulkanRenderSystem *renderSystem );

Expand Down
37 changes: 14 additions & 23 deletions RenderSystems/Vulkan/src/OgreVulkanDevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ namespace Ogre
{
static FastArray<IdString> msInstanceExtensions;

VulkanDevice::VulkanDevice( VkInstance instance, uint32 deviceIdx,
VulkanDevice::VulkanDevice( VkInstance instance, const String &deviceName,
VulkanRenderSystem *renderSystem ) :
mInstance( instance ),
mPhysicalDevice( 0 ),
Expand All @@ -62,7 +62,7 @@ namespace Ogre
mIsExternal( false )
{
memset( &mDeviceMemoryProperties, 0, sizeof( mDeviceMemoryProperties ) );
createPhysicalDevice( deviceIdx );
createPhysicalDevice( deviceName );
}
//-------------------------------------------------------------------------
VulkanDevice::VulkanDevice( VkInstance instance, const VulkanExternalDevice &externalDevice,
Expand Down Expand Up @@ -397,30 +397,21 @@ namespace Ogre
std::sort( msInstanceExtensions.begin(), msInstanceExtensions.end() );
}
//-------------------------------------------------------------------------
void VulkanDevice::createPhysicalDevice( uint32 deviceIdx )
void VulkanDevice::createPhysicalDevice( const String &deviceName )
{
VkResult result = VK_SUCCESS;

const FastArray<VkPhysicalDevice>& devices = mRenderSystem->getVkPhysicalDevices();
uint numDevices = devices.size();

const String numDevicesStr = StringConverter::toString( numDevices );
String deviceIdsStr = StringConverter::toString( deviceIdx );

LogManager::getSingleton().logMessage( "[Vulkan] Found " + numDevicesStr + " devices" );

if( deviceIdx >= numDevices )
{
LogManager::getSingleton().logMessage( "[Vulkan] Requested device index " + deviceIdsStr +
" but there's only " +
StringConverter::toString( numDevices ) + "devices" );
deviceIdx = 0u;
deviceIdsStr = "0";
}
const auto& devices = mRenderSystem->getVulkanPhysicalDevices();
size_t deviceIdx = 0;
for( size_t i = 0; i < devices.size(); ++i )
if( devices[i].title == deviceName )
{
deviceIdx = i;
break;
}

LogManager::getSingleton().logMessage( "[Vulkan] Selecting device " + deviceIdsStr );
LogManager::getSingleton().logMessage( "[Vulkan] Requested \"" + deviceName + "\", selected \"" +
devices[deviceIdx].title + "\"" );

mPhysicalDevice = devices[deviceIdx];
mPhysicalDevice = devices[deviceIdx].physicalDevice;

vkGetPhysicalDeviceMemoryProperties( mPhysicalDevice, &mDeviceMemoryProperties );

Expand Down
40 changes: 31 additions & 9 deletions RenderSystems/Vulkan/src/OgreVulkanRenderSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1321,12 +1321,15 @@ namespace Ogre
#endif
}
//-------------------------------------------------------------------------
const FastArray<VkPhysicalDevice>& VulkanRenderSystem::getVkPhysicalDevices( bool refreshList )
const VulkanPhysicalDeviceList &VulkanRenderSystem::getVulkanPhysicalDevices( bool refreshList )
{
if( refreshList || mVkPhysicalDeviceList.empty() )

if( refreshList || mVulkanPhysicalDeviceList.empty() )
{
mVkPhysicalDeviceList.clear();
LogManager::getSingleton().logMessage( "[Vulkan] Device detection starts" );

// enumerate
std::vector<VkPhysicalDevice> devices;
VkResult result = VK_SUCCESS;
do
{
Expand All @@ -1340,16 +1343,35 @@ namespace Ogre
"VulkanRenderSystem::getVkPhysicalDevices" );
}

mVkPhysicalDeviceList.resize( numDevices );
result = vkEnumeratePhysicalDevices( mVkInstance, &numDevices,
mVkPhysicalDeviceList.begin() );
mVkPhysicalDeviceList.resize( numDevices );
devices.resize( numDevices );
result = vkEnumeratePhysicalDevices( mVkInstance, &numDevices, devices.data() );
devices.resize( numDevices );
if( result != VK_INCOMPLETE )
checkVkResult( result, "vkEnumeratePhysicalDevices" );

} while( result == VK_INCOMPLETE );

// assign unique names, allowing reordering/inserting/removing
map<String, unsigned>::type sameNameCounter;
mVulkanPhysicalDeviceList.clear();
mVulkanPhysicalDeviceList.reserve(devices.size());
for (auto device : devices)
{
VkPhysicalDeviceProperties deviceProps;
vkGetPhysicalDeviceProperties( device, &deviceProps );

String name( deviceProps.deviceName );
unsigned sameNameIndex = sameNameCounter[name]++; // inserted entry is zero-initialized
if( sameNameIndex != 0 )
name += " (" + Ogre::StringConverter::toString( sameNameIndex + 1 ) + ")";

LogManager::getSingleton().logMessage( "[Vulkan] \"" + name + "\"" );
mVulkanPhysicalDeviceList.push_back( { device, name } );
}

LogManager::getSingleton().logMessage( "[Vulkan] Device detection ends" );
}
return mVkPhysicalDeviceList;
return mVulkanPhysicalDeviceList;
}
//-------------------------------------------------------------------------
Window *VulkanRenderSystem::_initialise( bool autoCreateWindow, const String &windowTitle )
Expand Down Expand Up @@ -1447,7 +1469,7 @@ namespace Ogre
initializeVkInstance();

if( !externalDevice )
mDevice = new VulkanDevice( mVkInstance, mVulkanSupport->getSelectedDeviceIdx(), this );
mDevice = new VulkanDevice( mVkInstance, mVulkanSupport->getSelectedDeviceName(), this );
else
mDevice = new VulkanDevice( mVkInstance, *externalDevice, this );

Expand Down
64 changes: 9 additions & 55 deletions RenderSystems/Vulkan/src/OgreVulkanSupport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,43 +34,10 @@ Copyright (c) 2000-present Torus Knot Software Ltd

namespace Ogre
{
void VulkanSupport::enumerateDevices( VulkanRenderSystem *renderSystem )
{
mDevices.clear();

const FastArray<VkPhysicalDevice> &devices = renderSystem->getVkPhysicalDevices();
uint numDevices = devices.size();

char tmpBuffer[VK_MAX_PHYSICAL_DEVICE_NAME_SIZE + 32];
LwString logStr( LwString::FromEmptyPointer( tmpBuffer, sizeof( tmpBuffer ) ) );

logStr.clear();
logStr.a( "[Vulkan] Found ", numDevices, " devices" );
LogManager::getSingleton().logMessage( logStr.c_str() );

LogManager::getSingleton().logMessage( "[Vulkan] Found devices:" );

mDevices.reserve( numDevices );
for( uint32 i = 0u; i < numDevices; ++i )
{
VkPhysicalDeviceProperties deviceProps;
vkGetPhysicalDeviceProperties( devices[i], &deviceProps );

logStr.clear();
logStr.a( deviceProps.deviceName, " #", i );
mDevices.push_back( logStr.c_str() );

LogManager::getSingleton().logMessage( logStr.c_str() );
}
}
//-------------------------------------------------------------------------
void VulkanSupport::initialize( VulkanRenderSystem *renderSystem )
{
if( !renderSystem->getVkInstance() )
renderSystem->initializeVkInstance();

if( mDevices.empty() )
enumerateDevices( renderSystem );
}
//-------------------------------------------------------------------------
void VulkanSupport::setSupported() { mSupported = true; }
Expand All @@ -85,16 +52,11 @@ namespace Ogre
ConfigOption optSRGB;

optDevices.name = "Device";

FastArray<String>::const_iterator itor = mDevices.begin();
FastArray<String>::const_iterator endt = mDevices.end();

optDevices.possibleValues.push_back( "(default)" );

while( itor != endt )
optDevices.possibleValues.push_back( *itor++ );

optDevices.currentValue = mDevices.front();
const auto &devices = renderSystem->getVulkanPhysicalDevices();
for( auto &device : devices )
optDevices.possibleValues.push_back( device.title );
optDevices.currentValue = optDevices.possibleValues.front();
optDevices.immutable = false;

optInterfaces.name = "Interface";
Expand Down Expand Up @@ -169,8 +131,8 @@ namespace Ogre
if( it != mOptions.end() )
{
const String deviceName = it->second.currentValue;
if( deviceName != "(default)" &&
std::find( mDevices.begin(), mDevices.end(), deviceName ) == mDevices.end() )
if( std::find( it->second.possibleValues.begin(), it->second.possibleValues.end(),
deviceName ) == it->second.possibleValues.end() )
{
setConfigOption( "Device", "(default)" );
return "Requested rendering device could not be found, default will be used instead.";
Expand All @@ -180,21 +142,13 @@ namespace Ogre
return BLANKSTRING;
}
//-------------------------------------------------------------------------
uint32 VulkanSupport::getSelectedDeviceIdx() const
String VulkanSupport::getSelectedDeviceName() const
{
uint32 deviceIdx = 0u;

ConfigOptionMap::const_iterator it = mOptions.find( "Device" );
if( it != mOptions.end() )
{
const String deviceName = it->second.currentValue;
FastArray<String>::const_iterator itDevice =
std::find( mDevices.begin(), mDevices.end(), deviceName );
if( itDevice != mDevices.end() )
deviceIdx = uint32( itDevice - mDevices.begin() );
}
return it->second.currentValue;

return deviceIdx;
return "(default)";
}
//-------------------------------------------------------------------------
ConfigOptionMap &VulkanSupport::getConfigOptions( VulkanRenderSystem *renderSystem )
Expand Down

0 comments on commit 87326b4

Please sign in to comment.