1
0
mirror of https://github.com/EduApps-CDG/OpenDX synced 2024-12-30 09:45:37 +01:00
OpenDX/src/dxvk/dxvk_instance.cpp
Philip Rebohle 652525119f
[vr] Query required device extensions during instance creation
After the DXGI device refactor in c5deedef2dcc920f29061c50e097f66a32f1f05e,
device extensions required for OpenVR interop would not be enabled correctly
because the VR-related code is now being called from both the D3D11 and DXGI
DLLs rather than just the DXGI DLL, and the D3D11 one is not in the expected
state when querying required device extensions. Querying them during instance
creation fixes that problem as it moves the relevant code back to the same
DLL which creates the Vulkan instance.
2018-12-20 01:32:56 +01:00

174 lines
5.4 KiB
C++

#include <version.h>
#include "dxvk_instance.h"
#include "dxvk_openvr.h"
#include <algorithm>
namespace dxvk {
DxvkInstance::DxvkInstance() {
Logger::info(str::format("Game: ", env::getExeName()));
Logger::info(str::format("DXVK: ", DXVK_VERSION));
m_config = Config::getUserConfig();
m_config.merge(Config::getAppConfig(env::getExeName()));
m_config.logOptions();
g_vrInstance.initInstanceExtensions();
m_vkl = new vk::LibraryFn();
m_vki = new vk::InstanceFn(true, this->createInstance());
m_adapters = this->queryAdapters();
g_vrInstance.initDeviceExtensions(this);
for (uint32_t i = 0; i < m_adapters.size(); i++) {
m_adapters[i]->enableExtensions(
g_vrInstance.getDeviceExtensions(i));
}
m_options = DxvkOptions(m_config);
}
DxvkInstance::~DxvkInstance() {
}
Rc<DxvkAdapter> DxvkInstance::enumAdapters(uint32_t index) const {
return index < m_adapters.size()
? m_adapters[index]
: nullptr;
}
Rc<DxvkAdapter> DxvkInstance::findAdapterByLuid(const void* luid) const {
for (const auto& adapter : m_adapters) {
const auto& props = adapter->devicePropertiesExt().coreDeviceId;
if (props.deviceLUIDValid && !std::memcmp(luid, props.deviceLUID, VK_LUID_SIZE))
return adapter;
}
return nullptr;
}
Rc<DxvkAdapter> DxvkInstance::findAdapterByDeviceId(uint16_t vendorId, uint16_t deviceId) const {
for (const auto& adapter : m_adapters) {
const auto& props = adapter->deviceProperties();
if (props.vendorID == vendorId
&& props.deviceID == deviceId)
return adapter;
}
return nullptr;
}
VkInstance DxvkInstance::createInstance() {
DxvkInstanceExtensions insExtensions;
std::array<DxvkExt*, 3> insExtensionList = {{
&insExtensions.khrGetPhysicalDeviceProperties2,
&insExtensions.khrSurface,
&insExtensions.khrWin32Surface,
}};
DxvkNameSet extensionsEnabled;
DxvkNameSet extensionsAvailable = DxvkNameSet::enumInstanceExtensions(m_vkl);
if (!extensionsAvailable.enableExtensions(
insExtensionList.size(),
insExtensionList.data(),
extensionsEnabled))
throw DxvkError("DxvkInstance: Failed to create instance");
// Enable additional extensions if necessary
extensionsEnabled.merge(g_vrInstance.getInstanceExtensions());
DxvkNameList extensionNameList = extensionsEnabled.toNameList();
Logger::info("Enabled instance extensions:");
this->logNameList(extensionNameList);
std::string appName = env::getExeName();
VkApplicationInfo appInfo;
appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
appInfo.pNext = nullptr;
appInfo.pApplicationName = appName.c_str();
appInfo.applicationVersion = 0;
appInfo.pEngineName = "DXVK";
appInfo.engineVersion = VK_MAKE_VERSION(0, 9, 4);
appInfo.apiVersion = VK_MAKE_VERSION(1, 1, 0);
VkInstanceCreateInfo info;
info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
info.pNext = nullptr;
info.flags = 0;
info.pApplicationInfo = &appInfo;
info.enabledLayerCount = 0;
info.ppEnabledLayerNames = nullptr;
info.enabledExtensionCount = extensionNameList.count();
info.ppEnabledExtensionNames = extensionNameList.names();
VkInstance result = VK_NULL_HANDLE;
VkResult status = m_vkl->vkCreateInstance(&info, nullptr, &result);
if (status == VK_ERROR_INCOMPATIBLE_DRIVER) {
Logger::warn("Failed to create Vulkan 1.1 instance, falling back to 1.0");
appInfo.apiVersion = 0; /* some very old drivers may not accept 1.0 */
status = m_vkl->vkCreateInstance(&info, nullptr, &result);
}
if (status != VK_SUCCESS)
throw DxvkError("DxvkInstance::createInstance: Failed to create Vulkan instance");
return result;
}
std::vector<Rc<DxvkAdapter>> DxvkInstance::queryAdapters() {
DxvkDeviceFilter filter;
uint32_t numAdapters = 0;
if (m_vki->vkEnumeratePhysicalDevices(m_vki->instance(), &numAdapters, nullptr) != VK_SUCCESS)
throw DxvkError("DxvkInstance::enumAdapters: Failed to enumerate adapters");
std::vector<VkPhysicalDevice> adapters(numAdapters);
if (m_vki->vkEnumeratePhysicalDevices(m_vki->instance(), &numAdapters, adapters.data()) != VK_SUCCESS)
throw DxvkError("DxvkInstance::enumAdapters: Failed to enumerate adapters");
std::vector<Rc<DxvkAdapter>> result;
for (uint32_t i = 0; i < numAdapters; i++) {
Rc<DxvkAdapter> adapter = new DxvkAdapter(this, adapters[i]);
if (filter.testAdapter(adapter))
result.push_back(adapter);
}
std::sort(result.begin(), result.end(),
[this] (const Rc<DxvkAdapter>& a, const Rc<DxvkAdapter>& b) -> bool {
return a->deviceProperties().deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU
&& b->deviceProperties().deviceType != VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU;
});
if (result.size() == 0) {
Logger::warn("DXVK: No adapters found. Please check your "
"device filter settings and Vulkan setup.");
}
return result;
}
void DxvkInstance::logNameList(const DxvkNameList& names) {
for (uint32_t i = 0; i < names.count(); i++)
Logger::info(str::format(" ", names.name(i)));
}
}