2017-10-10 23:32:13 +02:00
|
|
|
#include "dxvk_instance.h"
|
|
|
|
|
2018-05-16 16:17:39 +02:00
|
|
|
#include <algorithm>
|
|
|
|
|
2017-10-10 23:32:13 +02:00
|
|
|
namespace dxvk {
|
|
|
|
|
|
|
|
DxvkInstance::DxvkInstance()
|
|
|
|
: m_vkl(new vk::LibraryFn()),
|
|
|
|
m_vki(new vk::InstanceFn(this->createInstance())) {
|
2017-11-26 14:01:41 +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
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
std::vector<Rc<DxvkAdapter>> DxvkInstance::enumAdapters() {
|
|
|
|
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++)
|
|
|
|
result.push_back(new DxvkAdapter(this, adapters[i]));
|
2018-05-16 16:17:39 +02:00
|
|
|
|
|
|
|
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;
|
|
|
|
});
|
|
|
|
|
2017-10-10 23:32:13 +02:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
VkInstance DxvkInstance::createInstance() {
|
2018-05-16 21:38:11 +02:00
|
|
|
auto enabledLayers = this->getLayers();
|
|
|
|
|
|
|
|
// Query available extensions and enable the ones that are needed
|
|
|
|
vk::NameSet availableExtensions = vk::NameSet::enumerateInstanceExtensions(*m_vkl, enabledLayers);
|
|
|
|
|
|
|
|
DxvkInstanceExtensions extensionsToEnable;
|
|
|
|
extensionsToEnable.enableExtensions(availableExtensions);
|
|
|
|
|
|
|
|
if (!extensionsToEnable.checkSupportStatus())
|
|
|
|
throw DxvkError("DxvkInstance: Failed to create instance");
|
|
|
|
|
|
|
|
// Generate list of extensions that we're actually going to use
|
|
|
|
vk::NameSet enabledExtensionSet = extensionsToEnable.getEnabledExtensionNames();
|
|
|
|
vk::NameList enabledExtensionList = enabledExtensionSet.getNameList();
|
2017-10-10 23:32:13 +02:00
|
|
|
|
2017-10-11 00:27:33 +02:00
|
|
|
Logger::info("Enabled instance layers:");
|
|
|
|
this->logNameList(enabledLayers);
|
|
|
|
Logger::info("Enabled instance extensions:");
|
2018-05-16 21:38:11 +02:00
|
|
|
this->logNameList(enabledExtensionList);
|
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;
|
|
|
|
appInfo.pApplicationName = nullptr;
|
|
|
|
appInfo.applicationVersion = 0;
|
|
|
|
appInfo.pEngineName = "DXVK";
|
|
|
|
appInfo.engineVersion = VK_MAKE_VERSION(0, 0, 1);
|
|
|
|
appInfo.apiVersion = VK_MAKE_VERSION(1, 0, 47);
|
|
|
|
|
|
|
|
VkInstanceCreateInfo info;
|
|
|
|
info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
|
|
|
|
info.pNext = nullptr;
|
|
|
|
info.flags = 0;
|
|
|
|
info.pApplicationInfo = &appInfo;
|
|
|
|
info.enabledLayerCount = enabledLayers.count();
|
|
|
|
info.ppEnabledLayerNames = enabledLayers.names();
|
2018-05-16 21:38:11 +02:00
|
|
|
info.enabledExtensionCount = enabledExtensionList.count();
|
|
|
|
info.ppEnabledExtensionNames = enabledExtensionList.names();
|
2017-10-10 23:32:13 +02:00
|
|
|
|
|
|
|
VkInstance result = VK_NULL_HANDLE;
|
|
|
|
if (m_vkl->vkCreateInstance(&info, nullptr, &result) != VK_SUCCESS)
|
|
|
|
throw DxvkError("DxvkInstance::createInstance: Failed to create Vulkan instance");
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
vk::NameList DxvkInstance::getLayers() {
|
2017-12-08 01:32:02 +01:00
|
|
|
std::vector<const char*> layers = { };
|
|
|
|
|
|
|
|
if (env::getEnvVar(L"DXVK_DEBUG_LAYERS") == "1")
|
|
|
|
layers.push_back("VK_LAYER_LUNARG_standard_validation");
|
2017-10-10 23:32:13 +02:00
|
|
|
|
|
|
|
const vk::NameSet layersAvailable
|
|
|
|
= vk::NameSet::enumerateInstanceLayers(*m_vkl);
|
|
|
|
|
|
|
|
vk::NameList layersEnabled;
|
|
|
|
for (auto l : layers) {
|
2018-05-16 20:52:24 +02:00
|
|
|
if (layersAvailable.contains(l))
|
2017-10-10 23:32:13 +02:00
|
|
|
layersEnabled.add(l);
|
2018-02-24 23:07:31 +02:00
|
|
|
else
|
|
|
|
throw DxvkError(str::format("Requested layer not installed: ", l));
|
2017-10-10 23:32:13 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return layersEnabled;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-10-11 00:27:33 +02:00
|
|
|
void DxvkInstance::logNameList(const vk::NameList& names) {
|
|
|
|
for (uint32_t i = 0; i < names.count(); i++)
|
|
|
|
Logger::info(str::format(" ", names.name(i)));
|
|
|
|
}
|
|
|
|
|
2017-10-10 23:32:13 +02:00
|
|
|
}
|