#include #include "dxvk_instance.h" #include "dxvk_openvr.h" #include "dxvk_platform_exts.h" #include 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::getExePath())); m_config.logOptions(); m_options = DxvkOptions(m_config); m_extProviders.push_back(&DxvkPlatformExts::s_instance); if (m_options.enableOpenVR) m_extProviders.push_back(&VrInstance::s_instance); Logger::info("Built-in extension providers:"); for (const auto& provider : m_extProviders) Logger::info(str::format(" ", provider->getName())); for (const auto& provider : m_extProviders) provider->initInstanceExtensions(); m_vkl = new vk::LibraryFn(); m_vki = new vk::InstanceFn(true, this->createInstance()); m_adapters = this->queryAdapters(); for (const auto& provider : m_extProviders) provider->initDeviceExtensions(this); for (uint32_t i = 0; i < m_adapters.size(); i++) { for (const auto& provider : m_extProviders) { m_adapters[i]->enableExtensions( provider->getDeviceExtensions(i)); } } } DxvkInstance::~DxvkInstance() { } Rc DxvkInstance::enumAdapters(uint32_t index) const { return index < m_adapters.size() ? m_adapters[index] : nullptr; } Rc 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 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 insExtensionList = {{ &insExtensions.khrGetSurfaceCapabilities2, &insExtensions.khrSurface, }}; 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 for (const auto& provider : m_extProviders) extensionsEnabled.merge(provider->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(1, 7, 3); 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_SUCCESS) throw DxvkError("DxvkInstance::createInstance: Failed to create Vulkan 1.1 instance"); return result; } std::vector> 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 adapters(numAdapters); 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++) { 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])); } std::sort(result.begin(), result.end(), [] (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; }); 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))); } }