mirror of
https://github.com/EduApps-CDG/OpenDX
synced 2024-12-30 09:45:37 +01:00
[vr] Maintain global extension sets
Preserves the per-instance and per-adapter extension sets across multiple Vulkan instances. Works around initialization order issues with Unity-based VR apps.
This commit is contained in:
parent
eb39cf4b11
commit
0e6e985210
@ -171,7 +171,7 @@ namespace dxvk {
|
|||||||
|
|
||||||
// Generate list of extensions that we're actually going to use
|
// Generate list of extensions that we're actually going to use
|
||||||
vk::NameSet enabledExtensionSet = extensions->getEnabledExtensionNames();
|
vk::NameSet enabledExtensionSet = extensions->getEnabledExtensionNames();
|
||||||
enabledExtensionSet.merge(m_instance->queryExtraDeviceExtensions(this));
|
enabledExtensionSet.merge(g_vrInstance.getDeviceExtensions(getAdapterIndex()));
|
||||||
|
|
||||||
vk::NameList enabledExtensionList = enabledExtensionSet.getNameList();
|
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) {
|
void DxvkAdapter::logNameList(const vk::NameList& names) {
|
||||||
for (uint32_t i = 0; i < names.count(); i++)
|
for (uint32_t i = 0; i < names.count(); i++)
|
||||||
Logger::info(str::format(" ", names.name(i)));
|
Logger::info(str::format(" ", names.name(i)));
|
||||||
|
@ -168,6 +168,8 @@ namespace dxvk {
|
|||||||
VkPhysicalDevice m_handle;
|
VkPhysicalDevice m_handle;
|
||||||
|
|
||||||
std::vector<VkQueueFamilyProperties> m_queueFamilies;
|
std::vector<VkQueueFamilyProperties> m_queueFamilies;
|
||||||
|
|
||||||
|
uint32_t getAdapterIndex() const;
|
||||||
|
|
||||||
static void logNameList(const vk::NameList& names);
|
static void logNameList(const vk::NameList& names);
|
||||||
|
|
||||||
|
@ -5,10 +5,14 @@
|
|||||||
|
|
||||||
namespace dxvk {
|
namespace dxvk {
|
||||||
|
|
||||||
DxvkInstance::DxvkInstance()
|
DxvkInstance::DxvkInstance() {
|
||||||
: m_vkl(new vk::LibraryFn()),
|
g_vrInstance.initInstanceExtensions();
|
||||||
m_vki(new vk::InstanceFn(this->createInstance())) {
|
|
||||||
this->createAdapters();
|
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() {
|
VkInstance DxvkInstance::createInstance() {
|
||||||
// Query available extensions and enable the ones that are needed
|
// Query available extensions and enable the ones that are needed
|
||||||
vk::NameSet availableExtensions = vk::NameSet::enumerateInstanceExtensions(*m_vkl);
|
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
|
// Generate list of extensions that we're actually going to use
|
||||||
vk::NameSet enabledExtensionSet = extensionsToEnable.getEnabledExtensionNames();
|
vk::NameSet enabledExtensionSet = extensionsToEnable.getEnabledExtensionNames();
|
||||||
enabledExtensionSet.merge(m_vr.queryInstanceExtensions());
|
enabledExtensionSet.merge(g_vrInstance.getInstanceExtensions());
|
||||||
|
|
||||||
vk::NameList enabledExtensionList = enabledExtensionSet.getNameList();
|
vk::NameList enabledExtensionList = enabledExtensionSet.getNameList();
|
||||||
|
|
||||||
@ -74,7 +73,7 @@ namespace dxvk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DxvkInstance::createAdapters() {
|
std::vector<Rc<DxvkAdapter>> DxvkInstance::queryAdapters() {
|
||||||
uint32_t numAdapters = 0;
|
uint32_t numAdapters = 0;
|
||||||
if (m_vki->vkEnumeratePhysicalDevices(m_vki->instance(), &numAdapters, nullptr) != VK_SUCCESS)
|
if (m_vki->vkEnumeratePhysicalDevices(m_vki->instance(), &numAdapters, nullptr) != VK_SUCCESS)
|
||||||
throw DxvkError("DxvkInstance::enumAdapters: Failed to enumerate adapters");
|
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)
|
if (m_vki->vkEnumeratePhysicalDevices(m_vki->instance(), &numAdapters, adapters.data()) != VK_SUCCESS)
|
||||||
throw DxvkError("DxvkInstance::enumAdapters: Failed to enumerate adapters");
|
throw DxvkError("DxvkInstance::enumAdapters: Failed to enumerate adapters");
|
||||||
|
|
||||||
|
std::vector<Rc<DxvkAdapter>> result;
|
||||||
for (uint32_t i = 0; i < numAdapters; i++)
|
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<DxvkAdapter>& a, const Rc<DxvkAdapter>& b) -> bool {
|
[this] (const Rc<DxvkAdapter>& a, const Rc<DxvkAdapter>& b) -> bool {
|
||||||
return a->deviceProperties().deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU
|
return a->deviceProperties().deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU
|
||||||
&& b->deviceProperties().deviceType != VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU;
|
&& b->deviceProperties().deviceType != VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -45,19 +45,8 @@ namespace dxvk {
|
|||||||
Rc<DxvkAdapter> enumAdapters(
|
Rc<DxvkAdapter> enumAdapters(
|
||||||
uint32_t index) const;
|
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:
|
private:
|
||||||
|
|
||||||
VrInstance m_vr;
|
|
||||||
|
|
||||||
Rc<vk::LibraryFn> m_vkl;
|
Rc<vk::LibraryFn> m_vkl;
|
||||||
Rc<vk::InstanceFn> m_vki;
|
Rc<vk::InstanceFn> m_vki;
|
||||||
|
|
||||||
@ -65,9 +54,9 @@ namespace dxvk {
|
|||||||
|
|
||||||
VkInstance createInstance();
|
VkInstance createInstance();
|
||||||
|
|
||||||
void createAdapters();
|
std::vector<Rc<DxvkAdapter>> queryAdapters();
|
||||||
|
|
||||||
void logNameList(const vk::NameList& names);
|
static void logNameList(const vk::NameList& names);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#include "dxvk_instance.h"
|
||||||
#include "dxvk_openvr.h"
|
#include "dxvk_openvr.h"
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
@ -8,34 +9,77 @@
|
|||||||
|
|
||||||
namespace dxvk {
|
namespace dxvk {
|
||||||
|
|
||||||
VrInstance::VrInstance()
|
VrInstance g_vrInstance;
|
||||||
: m_compositor(getCompositor()) {
|
|
||||||
|
VrInstance:: VrInstance() { }
|
||||||
|
VrInstance::~VrInstance() { }
|
||||||
|
|
||||||
|
|
||||||
|
vk::NameSet VrInstance::getInstanceExtensions() {
|
||||||
|
std::lock_guard<std::mutex> lock(m_mutex);
|
||||||
|
return m_insExtensions;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
vk::NameSet VrInstance::getDeviceExtensions(uint32_t adapterId) {
|
||||||
|
std::lock_guard<std::mutex> lock(m_mutex);
|
||||||
|
|
||||||
}
|
if (adapterId < m_devExtensions.size())
|
||||||
|
return m_devExtensions[adapterId];
|
||||||
|
|
||||||
VrInstance::~VrInstance() {
|
|
||||||
|
|
||||||
|
return vk::NameSet();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void VrInstance::initInstanceExtensions() {
|
||||||
|
std::lock_guard<std::mutex> 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<std::mutex> 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<char> extensionList(len);
|
||||||
|
len = compositor->GetVulkanInstanceExtensionsRequired(extensionList.data(), len);
|
||||||
|
return parseExtensionList(std::string(extensionList.data(), len));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
vk::NameSet VrInstance::queryInstanceExtensions() const {
|
vk::NameSet VrInstance::queryDeviceExtensions(vr::IVRCompositor* compositor, VkPhysicalDevice adapter) const {
|
||||||
if (m_compositor != nullptr) {
|
uint32_t len = compositor->GetVulkanDeviceExtensionsRequired(adapter, nullptr, 0);
|
||||||
uint32_t len = m_compositor->GetVulkanInstanceExtensionsRequired(nullptr, 0);
|
std::vector<char> extensionList(len);
|
||||||
std::vector<char> extensionList(len);
|
len = compositor->GetVulkanDeviceExtensionsRequired(adapter, extensionList.data(), len);
|
||||||
len = m_compositor->GetVulkanInstanceExtensionsRequired(extensionList.data(), len);
|
return parseExtensionList(std::string(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<char> extensionList(len);
|
|
||||||
len = m_compositor->GetVulkanDeviceExtensionsRequired(adapter, extensionList.data(), len);
|
|
||||||
return parseExtensionList(std::string(extensionList.data(), len));
|
|
||||||
} return vk::NameSet();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <mutex>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "dxvk_include.h"
|
#include "dxvk_include.h"
|
||||||
|
|
||||||
namespace vr {
|
namespace vr {
|
||||||
@ -7,6 +10,8 @@ namespace vr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
namespace dxvk {
|
namespace dxvk {
|
||||||
|
|
||||||
|
class DxvkInstance;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief OpenVR instance
|
* \brief OpenVR instance
|
||||||
@ -20,29 +25,65 @@ namespace dxvk {
|
|||||||
|
|
||||||
VrInstance();
|
VrInstance();
|
||||||
~VrInstance();
|
~VrInstance();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Queries required instance extensions
|
* \brief Query instance extensions
|
||||||
* \returns Set of required 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
|
* Retrieves the extensions required for a specific
|
||||||
* \returns Set of required device extensions
|
* 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:
|
private:
|
||||||
|
|
||||||
|
std::mutex m_mutex;
|
||||||
|
|
||||||
|
bool m_initializedInsExt = false;
|
||||||
|
bool m_initializedDevExt = false;
|
||||||
|
|
||||||
|
vk::NameSet m_insExtensions;
|
||||||
|
std::vector<vk::NameSet> 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 vk::NameSet parseExtensionList(const std::string& str);
|
||||||
|
|
||||||
static vr::IVRCompositor* getCompositor();
|
static vr::IVRCompositor* getCompositor();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern VrInstance g_vrInstance;
|
||||||
|
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user