diff --git a/src/dxvk/dxvk_adapter.cpp b/src/dxvk/dxvk_adapter.cpp index ca6bc44b..a7f78d8d 100644 --- a/src/dxvk/dxvk_adapter.cpp +++ b/src/dxvk/dxvk_adapter.cpp @@ -171,7 +171,7 @@ namespace dxvk { // Generate list of extensions that we're actually going to use vk::NameSet enabledExtensionSet = extensions->getEnabledExtensionNames(); - enabledExtensionSet.merge(m_instance->queryExtraDeviceExtensions(this)); + enabledExtensionSet.merge(g_vrInstance.getDeviceExtensions(getAdapterIndex())); vk::NameList enabledExtensionList = enabledExtensionSet.getNameList(); @@ -261,6 +261,16 @@ namespace dxvk { } + uint32_t DxvkAdapter::getAdapterIndex() const { + for (uint32_t i = 0; m_instance->enumAdapters(i) != nullptr; i++) { + if (m_instance->enumAdapters(i).ptr() == this) + return i; + } + + return ~0u; + } + + void DxvkAdapter::logNameList(const vk::NameList& names) { for (uint32_t i = 0; i < names.count(); i++) Logger::info(str::format(" ", names.name(i))); diff --git a/src/dxvk/dxvk_adapter.h b/src/dxvk/dxvk_adapter.h index aa693508..1d7cfc0a 100644 --- a/src/dxvk/dxvk_adapter.h +++ b/src/dxvk/dxvk_adapter.h @@ -168,6 +168,8 @@ namespace dxvk { VkPhysicalDevice m_handle; std::vector m_queueFamilies; + + uint32_t getAdapterIndex() const; static void logNameList(const vk::NameList& names); diff --git a/src/dxvk/dxvk_instance.cpp b/src/dxvk/dxvk_instance.cpp index f83c2f40..4b3e7532 100644 --- a/src/dxvk/dxvk_instance.cpp +++ b/src/dxvk/dxvk_instance.cpp @@ -5,10 +5,14 @@ namespace dxvk { - DxvkInstance::DxvkInstance() - : m_vkl(new vk::LibraryFn()), - m_vki(new vk::InstanceFn(this->createInstance())) { - this->createAdapters(); + DxvkInstance::DxvkInstance() { + g_vrInstance.initInstanceExtensions(); + + m_vkl = new vk::LibraryFn(); + m_vki = new vk::InstanceFn(this->createInstance()); + + m_adapters = this->queryAdapters(); + g_vrInstance.initDeviceExtensions(this); } @@ -24,11 +28,6 @@ namespace dxvk { } - vk::NameSet DxvkInstance::queryExtraDeviceExtensions(const DxvkAdapter* adapter) const { - return m_vr.queryDeviceExtensions(adapter->handle()); - } - - VkInstance DxvkInstance::createInstance() { // Query available extensions and enable the ones that are needed vk::NameSet availableExtensions = vk::NameSet::enumerateInstanceExtensions(*m_vkl); @@ -41,7 +40,7 @@ namespace dxvk { // Generate list of extensions that we're actually going to use vk::NameSet enabledExtensionSet = extensionsToEnable.getEnabledExtensionNames(); - enabledExtensionSet.merge(m_vr.queryInstanceExtensions()); + enabledExtensionSet.merge(g_vrInstance.getInstanceExtensions()); vk::NameList enabledExtensionList = enabledExtensionSet.getNameList(); @@ -74,7 +73,7 @@ namespace dxvk { } - void DxvkInstance::createAdapters() { + std::vector> DxvkInstance::queryAdapters() { uint32_t numAdapters = 0; if (m_vki->vkEnumeratePhysicalDevices(m_vki->instance(), &numAdapters, nullptr) != VK_SUCCESS) throw DxvkError("DxvkInstance::enumAdapters: Failed to enumerate adapters"); @@ -83,14 +82,17 @@ namespace dxvk { if (m_vki->vkEnumeratePhysicalDevices(m_vki->instance(), &numAdapters, adapters.data()) != VK_SUCCESS) throw DxvkError("DxvkInstance::enumAdapters: Failed to enumerate adapters"); + std::vector> result; for (uint32_t i = 0; i < numAdapters; i++) - m_adapters.push_back(new DxvkAdapter(this, adapters[i])); + result.push_back(new DxvkAdapter(this, adapters[i])); - std::sort(m_adapters.begin(), m_adapters.end(), + std::sort(result.begin(), result.end(), [this] (const Rc& a, const Rc& b) -> bool { return a->deviceProperties().deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU && b->deviceProperties().deviceType != VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU; }); + + return result; } diff --git a/src/dxvk/dxvk_instance.h b/src/dxvk/dxvk_instance.h index de176cfe..c3b3878d 100644 --- a/src/dxvk/dxvk_instance.h +++ b/src/dxvk/dxvk_instance.h @@ -45,19 +45,8 @@ namespace dxvk { Rc enumAdapters( uint32_t index) const; - /** - * \brief Queries extra device extensions - * - * \param [in] adapter The device to query - * \returns Extra device extensions - */ - vk::NameSet queryExtraDeviceExtensions( - const DxvkAdapter* adapter) const; - private: - VrInstance m_vr; - Rc m_vkl; Rc m_vki; @@ -65,9 +54,9 @@ namespace dxvk { VkInstance createInstance(); - void createAdapters(); + std::vector> queryAdapters(); - void logNameList(const vk::NameList& names); + static void logNameList(const vk::NameList& names); }; diff --git a/src/dxvk/dxvk_openvr.cpp b/src/dxvk/dxvk_openvr.cpp index d50fb400..5d15463a 100644 --- a/src/dxvk/dxvk_openvr.cpp +++ b/src/dxvk/dxvk_openvr.cpp @@ -1,3 +1,4 @@ +#include "dxvk_instance.h" #include "dxvk_openvr.h" #ifdef __GNUC__ @@ -8,34 +9,77 @@ namespace dxvk { - VrInstance::VrInstance() - : m_compositor(getCompositor()) { + VrInstance g_vrInstance; + + VrInstance:: VrInstance() { } + VrInstance::~VrInstance() { } + + + vk::NameSet VrInstance::getInstanceExtensions() { + std::lock_guard lock(m_mutex); + return m_insExtensions; + } + + + vk::NameSet VrInstance::getDeviceExtensions(uint32_t adapterId) { + std::lock_guard lock(m_mutex); - } - - - VrInstance::~VrInstance() { + if (adapterId < m_devExtensions.size()) + return m_devExtensions[adapterId]; + return vk::NameSet(); + } + + + void VrInstance::initInstanceExtensions() { + std::lock_guard lock(m_mutex); + + if (m_initializedInsExt) + return; + + vr::IVRCompositor* compositor = this->getCompositor(); + + if (compositor == nullptr) + return; + + m_insExtensions = this->queryInstanceExtensions(compositor); + m_initializedInsExt = true; + } + + + void VrInstance::initDeviceExtensions(const DxvkInstance* instance) { + std::lock_guard lock(m_mutex); + + if (m_initializedDevExt) + return; + + vr::IVRCompositor* compositor = this->getCompositor(); + + if (compositor == nullptr) + return; + + for (uint32_t i = 0; instance->enumAdapters(i) != nullptr; i++) { + m_devExtensions.push_back(this->queryDeviceExtensions( + compositor, instance->enumAdapters(i)->handle())); + } + + m_initializedDevExt = true; + } + + + vk::NameSet VrInstance::queryInstanceExtensions(vr::IVRCompositor* compositor) const { + uint32_t len = compositor->GetVulkanInstanceExtensionsRequired(nullptr, 0); + std::vector extensionList(len); + len = compositor->GetVulkanInstanceExtensionsRequired(extensionList.data(), len); + return parseExtensionList(std::string(extensionList.data(), len)); } - vk::NameSet VrInstance::queryInstanceExtensions() const { - if (m_compositor != nullptr) { - uint32_t len = m_compositor->GetVulkanInstanceExtensionsRequired(nullptr, 0); - std::vector extensionList(len); - len = m_compositor->GetVulkanInstanceExtensionsRequired(extensionList.data(), len); - return parseExtensionList(std::string(extensionList.data(), len)); - } return vk::NameSet(); - } - - - vk::NameSet VrInstance::queryDeviceExtensions(VkPhysicalDevice adapter) const { - if (m_compositor != nullptr) { - uint32_t len = m_compositor->GetVulkanDeviceExtensionsRequired(adapter, nullptr, 0); - std::vector extensionList(len); - len = m_compositor->GetVulkanDeviceExtensionsRequired(adapter, extensionList.data(), len); - return parseExtensionList(std::string(extensionList.data(), len)); - } return vk::NameSet(); + vk::NameSet VrInstance::queryDeviceExtensions(vr::IVRCompositor* compositor, VkPhysicalDevice adapter) const { + uint32_t len = compositor->GetVulkanDeviceExtensionsRequired(adapter, nullptr, 0); + std::vector extensionList(len); + len = compositor->GetVulkanDeviceExtensionsRequired(adapter, extensionList.data(), len); + return parseExtensionList(std::string(extensionList.data(), len)); } diff --git a/src/dxvk/dxvk_openvr.h b/src/dxvk/dxvk_openvr.h index acb61f81..16dfbb1f 100644 --- a/src/dxvk/dxvk_openvr.h +++ b/src/dxvk/dxvk_openvr.h @@ -1,5 +1,8 @@ #pragma once +#include +#include + #include "dxvk_include.h" namespace vr { @@ -7,6 +10,8 @@ namespace vr { } namespace dxvk { + + class DxvkInstance; /** * \brief OpenVR instance @@ -20,29 +25,65 @@ namespace dxvk { VrInstance(); ~VrInstance(); - + /** - * \brief Queries required instance extensions - * \returns Set of required instance extensions + * \brief Query instance extensions + * \returns Instance extensions */ - vk::NameSet queryInstanceExtensions() const; - + vk::NameSet getInstanceExtensions(); + /** - * \brief Queries required device extensions + * \brief Query device extensions * - * \param [in] adapter The Vulkan device to query - * \returns Set of required device extensions + * Retrieves the extensions required for a specific + * physical device. The adapter index should remain + * the same across multiple Vulkan instances. + * \param [in] adapterId Adapter index */ - vk::NameSet queryDeviceExtensions(VkPhysicalDevice adapter) const; + vk::NameSet getDeviceExtensions( + uint32_t adapterId); + /** + * \brief Initializes instance extension set + * + * Should be called before creating + * the first Vulkan instance. + */ + void initInstanceExtensions(); + + /** + * \brief Initializes device extension sets + * + * Should be called after setting + * up the Vulkan physical devices. + * \param [in] instance DXVK instance + */ + void initDeviceExtensions( + const DxvkInstance* instance); + private: + + std::mutex m_mutex; + + bool m_initializedInsExt = false; + bool m_initializedDevExt = false; + + vk::NameSet m_insExtensions; + std::vector m_devExtensions; - vr::IVRCompositor* m_compositor = nullptr; - + vk::NameSet queryInstanceExtensions( + vr::IVRCompositor* compositor) const; + + vk::NameSet queryDeviceExtensions( + vr::IVRCompositor* compositor, + VkPhysicalDevice adapter) const; + static vk::NameSet parseExtensionList(const std::string& str); static vr::IVRCompositor* getCompositor(); }; + + extern VrInstance g_vrInstance; } \ No newline at end of file