diff --git a/RenderSystems/Vulkan/include/OgreVulkanRenderSystem.h b/RenderSystems/Vulkan/include/OgreVulkanRenderSystem.h index 2820fb00de..6a6dbf777a 100644 --- a/RenderSystems/Vulkan/include/OgreVulkanRenderSystem.h +++ b/RenderSystems/Vulkan/include/OgreVulkanRenderSystem.h @@ -56,7 +56,7 @@ namespace Ogre struct VulkanPhysicalDevice { VkPhysicalDevice physicalDevice; - long long physicalDeviceID; + uint64 physicalDeviceID; // deviceLUID on Windows String title; }; diff --git a/RenderSystems/Vulkan/src/OgreVulkanDevice.cpp b/RenderSystems/Vulkan/src/OgreVulkanDevice.cpp index cef88038ef..20b75f1e6c 100644 --- a/RenderSystems/Vulkan/src/OgreVulkanDevice.cpp +++ b/RenderSystems/Vulkan/src/OgreVulkanDevice.cpp @@ -424,24 +424,53 @@ namespace Ogre "VulkanRenderSystem::getVkPhysicalDevices" ); } + // prepare to obtain deviceLUID or deviceUUID + // vkEnumerateInstanceVersion is available since Vulkan 1.1 + PFN_vkEnumerateInstanceVersion enumerateInstanceVersion = + (PFN_vkEnumerateInstanceVersion)vkGetInstanceProcAddr( 0, "vkEnumerateInstanceVersion" ); + uint32_t apiVersion = VK_API_VERSION_1_0; + bool hasDeviceIDProperties = + enumerateInstanceVersion && enumerateInstanceVersion( &apiVersion ) == VK_SUCCESS && + apiVersion >= VK_API_VERSION_1_1 || + hasExtension( VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME ) || + hasExtension( VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME ) || + hasExtension( VK_KHR_EXTERNAL_FENCE_CAPABILITIES_EXTENSION_NAME ); + PFN_vkGetPhysicalDeviceProperties2KHR GetPhysicalDeviceProperties2KHR = + hasDeviceIDProperties ? (PFN_vkGetPhysicalDeviceProperties2KHR)vkGetInstanceProcAddr( + mVkInstance, "vkGetPhysicalDeviceProperties2KHR" ) + : nullptr; + VkPhysicalDeviceProperties2 deviceProps2; + VkPhysicalDeviceIDProperties deviceIDProps; + makeVkStruct( deviceProps2, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2 ); + makeVkStruct( deviceIDProps, VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES ); + if( hasDeviceIDProperties ) + deviceProps2.pNext = &deviceIDProps; + // assign unique names, allowing reordering/inserting/removing map::type sameNameCounter; mVulkanPhysicalDevices.clear(); mVulkanPhysicalDevices.reserve( devices.size() ); for( VkPhysicalDevice device : devices ) { - VkPhysicalDeviceProperties deviceProps; - vkGetPhysicalDeviceProperties( device, &deviceProps ); + if( hasDeviceIDProperties ) + GetPhysicalDeviceProperties2KHR( device, &deviceProps2 ); + else + vkGetPhysicalDeviceProperties( device, &deviceProps2.properties ); - String name( deviceProps.deviceName ); + String name( deviceProps2.properties.deviceName ); unsigned sameNameIndex = sameNameCounter[name]++; // inserted entry is zero-initialized if( sameNameIndex != 0 ) name += " (" + Ogre::StringConverter::toString( sameNameIndex + 1 ) + ")"; - // TODO: use deviceLUID or deviceUUID if available - uint64 hashResult[2] = {}; - OGRE_HASH128_FUNC( name.c_str(), (int)name.size(), IdString::Seed, hashResult ); - long long deviceLUID = hashResult[0]; + // use deviceLUID or deviceUUID if available + uint64 uid[2] = {}; + if( hasDeviceIDProperties && deviceIDProps.deviceLUIDValid ) + memcpy( uid, deviceIDProps.deviceLUID, VK_LUID_SIZE ); + else if( hasDeviceIDProperties ) + memcpy( uid, deviceIDProps.deviceUUID, VK_UUID_SIZE ); + else + OGRE_HASH128_FUNC( name.c_str(), (int)name.size(), IdString::Seed, uid ); + uint64 deviceLUID = uid[0] ^ uid[1]; LogManager::getSingleton().logMessage( "Vulkan: \"" + name + "\"" ); mVulkanPhysicalDevices.push_back( { device, deviceLUID, name } );