2018-07-11 17:24:30 +02:00
|
|
|
#include <version.h>
|
|
|
|
|
2017-10-10 23:32:13 +02:00
|
|
|
#include "dxvk_instance.h"
|
2019-11-11 23:30:07 +01:00
|
|
|
#include "dxvk_openvr.h"
|
2021-01-04 14:33:11 -06:00
|
|
|
#include "dxvk_openxr.h"
|
2019-11-11 23:30:07 +01:00
|
|
|
#include "dxvk_platform_exts.h"
|
2017-10-10 23:32:13 +02:00
|
|
|
|
2018-05-16 16:17:39 +02:00
|
|
|
#include <algorithm>
|
|
|
|
|
2017-10-10 23:32:13 +02:00
|
|
|
namespace dxvk {
|
|
|
|
|
2018-06-26 15:51:15 +02:00
|
|
|
DxvkInstance::DxvkInstance() {
|
2018-07-11 17:24:30 +02:00
|
|
|
Logger::info(str::format("Game: ", env::getExeName()));
|
|
|
|
Logger::info(str::format("DXVK: ", DXVK_VERSION));
|
|
|
|
|
2018-08-07 16:58:16 +02:00
|
|
|
m_config = Config::getUserConfig();
|
2019-08-17 11:46:56 +02:00
|
|
|
m_config.merge(Config::getAppConfig(env::getExePath()));
|
2018-09-09 13:46:57 +02:00
|
|
|
m_config.logOptions();
|
2018-08-07 14:14:41 +02:00
|
|
|
|
2019-11-11 23:30:07 +01:00
|
|
|
m_options = DxvkOptions(m_config);
|
|
|
|
|
|
|
|
m_extProviders.push_back(&DxvkPlatformExts::s_instance);
|
2019-11-11 23:30:35 +01:00
|
|
|
|
|
|
|
if (m_options.enableOpenVR)
|
|
|
|
m_extProviders.push_back(&VrInstance::s_instance);
|
2019-11-05 04:45:28 +00:00
|
|
|
|
2021-01-04 14:33:11 -06:00
|
|
|
if (m_options.enableOpenXR)
|
|
|
|
m_extProviders.push_back(&DxvkXrProvider::s_instance);
|
|
|
|
|
2019-11-05 04:45:28 +00:00
|
|
|
Logger::info("Built-in extension providers:");
|
2019-11-11 23:30:07 +01:00
|
|
|
for (const auto& provider : m_extProviders)
|
2019-11-05 04:45:28 +00:00
|
|
|
Logger::info(str::format(" ", provider->getName()));
|
|
|
|
|
2019-11-11 23:30:07 +01:00
|
|
|
for (const auto& provider : m_extProviders)
|
2019-11-05 04:45:28 +00:00
|
|
|
provider->initInstanceExtensions();
|
2018-06-26 15:51:15 +02:00
|
|
|
|
|
|
|
m_vkl = new vk::LibraryFn();
|
2018-11-02 14:05:05 +01:00
|
|
|
m_vki = new vk::InstanceFn(true, this->createInstance());
|
2018-06-26 15:51:15 +02:00
|
|
|
|
|
|
|
m_adapters = this->queryAdapters();
|
2019-11-05 04:45:28 +00:00
|
|
|
|
2019-11-11 23:30:07 +01:00
|
|
|
for (const auto& provider : m_extProviders)
|
2019-11-05 04:45:28 +00:00
|
|
|
provider->initDeviceExtensions(this);
|
2018-11-20 15:50:01 +01:00
|
|
|
|
2018-12-20 01:27:49 +01:00
|
|
|
for (uint32_t i = 0; i < m_adapters.size(); i++) {
|
2019-11-11 23:30:07 +01:00
|
|
|
for (const auto& provider : m_extProviders) {
|
2019-11-05 04:45:28 +00:00
|
|
|
m_adapters[i]->enableExtensions(
|
|
|
|
provider->getDeviceExtensions(i));
|
|
|
|
}
|
2018-12-20 01:27:49 +01:00
|
|
|
}
|
2017-10-10 23:32:13 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
DxvkInstance::~DxvkInstance() {
|
2017-12-11 19:48:00 +01:00
|
|
|
|
2017-10-10 23:32:13 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-06-26 12:33:26 +02:00
|
|
|
Rc<DxvkAdapter> DxvkInstance::enumAdapters(uint32_t index) const {
|
|
|
|
return index < m_adapters.size()
|
|
|
|
? m_adapters[index]
|
|
|
|
: nullptr;
|
2017-10-10 23:32:13 +02:00
|
|
|
}
|
2018-12-03 21:18:19 +01:00
|
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
2017-10-10 23:32:13 +02:00
|
|
|
|
|
|
|
|
|
|
|
VkInstance DxvkInstance::createInstance() {
|
2018-07-23 20:07:21 +02:00
|
|
|
DxvkInstanceExtensions insExtensions;
|
|
|
|
|
2020-01-16 19:59:56 +01:00
|
|
|
std::array<DxvkExt*, 2> insExtensionList = {{
|
2019-12-03 01:28:28 +01:00
|
|
|
&insExtensions.khrGetSurfaceCapabilities2,
|
2018-07-23 20:07:21 +02:00
|
|
|
&insExtensions.khrSurface,
|
|
|
|
}};
|
|
|
|
|
|
|
|
DxvkNameSet extensionsEnabled;
|
|
|
|
DxvkNameSet extensionsAvailable = DxvkNameSet::enumInstanceExtensions(m_vkl);
|
2018-05-16 21:38:11 +02:00
|
|
|
|
2018-07-23 20:07:21 +02:00
|
|
|
if (!extensionsAvailable.enableExtensions(
|
|
|
|
insExtensionList.size(),
|
|
|
|
insExtensionList.data(),
|
|
|
|
extensionsEnabled))
|
2018-05-16 21:38:11 +02:00
|
|
|
throw DxvkError("DxvkInstance: Failed to create instance");
|
2019-11-05 04:45:28 +00:00
|
|
|
|
2018-07-23 20:07:21 +02:00
|
|
|
// Enable additional extensions if necessary
|
2019-11-11 23:30:07 +01:00
|
|
|
for (const auto& provider : m_extProviders)
|
2019-11-05 04:45:28 +00:00
|
|
|
extensionsEnabled.merge(provider->getInstanceExtensions());
|
2019-11-11 23:30:07 +01:00
|
|
|
|
2018-07-23 20:07:21 +02:00
|
|
|
DxvkNameList extensionNameList = extensionsEnabled.toNameList();
|
2017-10-10 23:32:13 +02:00
|
|
|
|
2017-10-11 00:27:33 +02:00
|
|
|
Logger::info("Enabled instance extensions:");
|
2018-07-23 20:07:21 +02:00
|
|
|
this->logNameList(extensionNameList);
|
2018-11-07 21:52:54 +01:00
|
|
|
|
|
|
|
std::string appName = env::getExeName();
|
2017-10-11 00:27:33 +02:00
|
|
|
|
2017-10-10 23:32:13 +02:00
|
|
|
VkApplicationInfo appInfo;
|
|
|
|
appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
|
|
|
|
appInfo.pNext = nullptr;
|
2018-11-07 21:52:54 +01:00
|
|
|
appInfo.pApplicationName = appName.c_str();
|
2017-10-10 23:32:13 +02:00
|
|
|
appInfo.applicationVersion = 0;
|
|
|
|
appInfo.pEngineName = "DXVK";
|
2020-12-02 16:03:19 +01:00
|
|
|
appInfo.engineVersion = VK_MAKE_VERSION(1, 7, 3);
|
2018-11-07 19:39:38 +01:00
|
|
|
appInfo.apiVersion = VK_MAKE_VERSION(1, 1, 0);
|
2017-10-10 23:32:13 +02:00
|
|
|
|
|
|
|
VkInstanceCreateInfo info;
|
|
|
|
info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
|
|
|
|
info.pNext = nullptr;
|
|
|
|
info.flags = 0;
|
|
|
|
info.pApplicationInfo = &appInfo;
|
2018-05-16 22:30:04 +02:00
|
|
|
info.enabledLayerCount = 0;
|
|
|
|
info.ppEnabledLayerNames = nullptr;
|
2018-07-23 20:07:21 +02:00
|
|
|
info.enabledExtensionCount = extensionNameList.count();
|
|
|
|
info.ppEnabledExtensionNames = extensionNameList.names();
|
2017-10-10 23:32:13 +02:00
|
|
|
|
|
|
|
VkInstance result = VK_NULL_HANDLE;
|
2018-11-07 19:39:38 +01:00
|
|
|
VkResult status = m_vkl->vkCreateInstance(&info, nullptr, &result);
|
|
|
|
|
|
|
|
if (status != VK_SUCCESS)
|
2020-01-16 19:47:04 +01:00
|
|
|
throw DxvkError("DxvkInstance::createInstance: Failed to create Vulkan 1.1 instance");
|
2018-11-07 19:39:38 +01:00
|
|
|
|
2017-10-10 23:32:13 +02:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-06-26 15:51:15 +02:00
|
|
|
std::vector<Rc<DxvkAdapter>> DxvkInstance::queryAdapters() {
|
2018-08-27 14:22:14 +02:00
|
|
|
DxvkDeviceFilter filter;
|
|
|
|
|
2018-06-26 12:33:26 +02:00
|
|
|
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");
|
|
|
|
|
2018-06-26 15:51:15 +02:00
|
|
|
std::vector<Rc<DxvkAdapter>> result;
|
2018-08-27 14:22:14 +02:00
|
|
|
for (uint32_t i = 0; i < numAdapters; i++) {
|
2020-02-03 11:30:39 +01:00
|
|
|
VkPhysicalDeviceProperties deviceProperties;
|
|
|
|
m_vki->vkGetPhysicalDeviceProperties(adapters[i], &deviceProperties);
|
|
|
|
|
|
|
|
if (deviceProperties.apiVersion < VK_MAKE_VERSION(1, 1, 0))
|
|
|
|
Logger::warn(str::format("Skipping Vulkan 1.0 adapter: ", deviceProperties.deviceName));
|
|
|
|
else if (filter.testAdapter(deviceProperties))
|
|
|
|
result.push_back(new DxvkAdapter(m_vki, adapters[i]));
|
2018-08-27 14:22:14 +02:00
|
|
|
}
|
2018-06-26 12:33:26 +02:00
|
|
|
|
2018-06-26 15:51:15 +02:00
|
|
|
std::sort(result.begin(), result.end(),
|
2019-03-25 16:12:59 -05:00
|
|
|
[] (const Rc<DxvkAdapter>& a, const Rc<DxvkAdapter>& b) -> bool {
|
2018-06-26 12:33:26 +02:00
|
|
|
return a->deviceProperties().deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU
|
|
|
|
&& b->deviceProperties().deviceType != VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU;
|
|
|
|
});
|
2018-06-26 15:51:15 +02:00
|
|
|
|
2018-08-27 14:22:14 +02:00
|
|
|
if (result.size() == 0) {
|
|
|
|
Logger::warn("DXVK: No adapters found. Please check your "
|
|
|
|
"device filter settings and Vulkan setup.");
|
|
|
|
}
|
|
|
|
|
2018-06-26 15:51:15 +02:00
|
|
|
return result;
|
2018-06-26 12:33:26 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-07-23 20:07:21 +02:00
|
|
|
void DxvkInstance::logNameList(const DxvkNameList& names) {
|
2017-10-11 00:27:33 +02:00
|
|
|
for (uint32_t i = 0; i < names.count(); i++)
|
|
|
|
Logger::info(str::format(" ", names.name(i)));
|
|
|
|
}
|
|
|
|
|
2017-10-10 23:32:13 +02:00
|
|
|
}
|