[dxvk] Refactor the way instance extensions are enabled

This commit is contained in:
Philip Rebohle 2018-05-16 21:38:11 +02:00
parent d1eddbdc3f
commit 796379a551
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
7 changed files with 61 additions and 43 deletions

View File

@ -160,23 +160,27 @@ namespace dxvk {
Rc<DxvkDevice> DxvkAdapter::createDevice(const VkPhysicalDeviceFeatures& enabledFeatures) {
// Query available extensions and enable the ones that are needed
vk::NameSet availableExtensions = vk::NameSet::enumerateDeviceExtensions(*m_vki, m_handle);
const Rc<DxvkDeviceExtensions> extensions = new DxvkDeviceExtensions();
extensions->enableExtensions(vk::NameSet::enumerateDeviceExtensions(*m_vki, m_handle));
extensions->enableExtensions(availableExtensions);
if (!extensions->checkSupportStatus())
throw DxvkError("DxvkAdapter: Failed to create device");
const vk::NameList enabledExtensions =
extensions->getEnabledExtensionNames();
// Generate list of extensions that we're actually going to use
vk::NameSet enabledExtensionSet = extensions->getEnabledExtensionNames();
vk::NameList enabledExtensionList = enabledExtensionSet.getNameList();
Logger::info("Enabled device extensions:");
this->logNameList(enabledExtensions);
this->logNameList(enabledExtensionList);
float queuePriority = 1.0f;
std::vector<VkDeviceQueueCreateInfo> queueInfos;
const uint32_t gIndex = this->graphicsQueueFamily();
const uint32_t pIndex = this->presentQueueFamily();
uint32_t gIndex = this->graphicsQueueFamily();
uint32_t pIndex = this->presentQueueFamily();
VkDeviceQueueCreateInfo graphicsQueue;
graphicsQueue.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
@ -201,8 +205,8 @@ namespace dxvk {
info.pQueueCreateInfos = queueInfos.data();
info.enabledLayerCount = 0;
info.ppEnabledLayerNames = nullptr;
info.enabledExtensionCount = enabledExtensions.count();
info.ppEnabledExtensionNames = enabledExtensions.names();
info.enabledExtensionCount = enabledExtensionList.count();
info.ppEnabledExtensionNames = enabledExtensionList.names();
info.pEnabledFeatures = &enabledFeatures;
VkDevice device = VK_NULL_HANDLE;

View File

@ -47,8 +47,8 @@ namespace dxvk {
}
vk::NameList DxvkExtensionList::getEnabledExtensionNames() const {
vk::NameList names;
vk::NameSet DxvkExtensionList::getEnabledExtensionNames() const {
vk::NameSet names;
for (auto ext : m_extensions) {
if (ext->enabled())

View File

@ -58,7 +58,7 @@ namespace dxvk {
* structs for device and instance creation.
* \returns Names of enabled Vulkan extensions
*/
vk::NameList getEnabledExtensionNames() const;
vk::NameSet getEnabledExtensionNames() const;
private:
@ -138,4 +138,15 @@ namespace dxvk {
DxvkExtension khrSwapchain = { this, VK_KHR_SWAPCHAIN_EXTENSION_NAME, DxvkExtensionType::Required };
};
/**
* \brief Instance extensions
*
* Lists all Vulkan extensions that are potentially
* used by DXVK if supported by the implementation.
*/
struct DxvkInstanceExtensions : public DxvkExtensionList {
DxvkExtension khrSurface = { this, VK_KHR_SURFACE_EXTENSION_NAME, DxvkExtensionType::Required };
DxvkExtension khrWin32Surface = { this, VK_KHR_WIN32_SURFACE_EXTENSION_NAME, DxvkExtensionType::Required };
};
}

View File

@ -40,13 +40,25 @@ namespace dxvk {
VkInstance DxvkInstance::createInstance() {
auto enabledLayers = this->getLayers();
auto enabledExtensions = this->getExtensions(enabledLayers);
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();
Logger::info("Enabled instance layers:");
this->logNameList(enabledLayers);
Logger::info("Enabled instance extensions:");
this->logNameList(enabledExtensions);
this->logNameList(enabledExtensionList);
VkApplicationInfo appInfo;
appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
@ -64,8 +76,8 @@ namespace dxvk {
info.pApplicationInfo = &appInfo;
info.enabledLayerCount = enabledLayers.count();
info.ppEnabledLayerNames = enabledLayers.names();
info.enabledExtensionCount = enabledExtensions.count();
info.ppEnabledExtensionNames = enabledExtensions.names();
info.enabledExtensionCount = enabledExtensionList.count();
info.ppEnabledExtensionNames = enabledExtensionList.names();
VkInstance result = VK_NULL_HANDLE;
if (m_vkl->vkCreateInstance(&info, nullptr, &result) != VK_SUCCESS)
@ -95,32 +107,6 @@ namespace dxvk {
}
vk::NameList DxvkInstance::getExtensions(const vk::NameList& layers) {
std::vector<const char*> extOptional = { };
std::vector<const char*> extRequired = {
VK_KHR_SURFACE_EXTENSION_NAME,
VK_KHR_WIN32_SURFACE_EXTENSION_NAME,
};
const vk::NameSet extensionsAvailable
= vk::NameSet::enumerateInstanceExtensions(*m_vkl, layers);
vk::NameList extensionsEnabled;
for (auto e : extOptional) {
if (extensionsAvailable.contains(e))
extensionsEnabled.add(e);
}
for (auto e : extRequired) {
if (!extensionsAvailable.contains(e))
throw DxvkError(str::format("DxvkInstance::getExtensions: Extension ", e, " not supported"));
extensionsEnabled.add(e);
}
return extensionsEnabled;
}
void DxvkInstance::logNameList(const vk::NameList& names) {
for (uint32_t i = 0; i < names.count(); i++)
Logger::info(str::format(" ", names.name(i)));

View File

@ -49,7 +49,6 @@ namespace dxvk {
VkInstance createInstance();
vk::NameList getLayers();
vk::NameList getExtensions(const vk::NameList& layers);
void logNameList(const vk::NameList& names);

View File

@ -73,4 +73,12 @@ namespace dxvk::vk {
this->add(ext.extensionName);
}
NameList NameSet::getNameList() const {
NameList result;
for (const std::string& name : m_names)
result.add(name.c_str());
return result;
}
}

View File

@ -96,6 +96,16 @@ namespace dxvk::vk {
const InstanceFn& vki,
VkPhysicalDevice device);
/**
* \brief Generates a name list
*
* The pointers to the names will have the same
* lifetime as the name set, and may be invalidated
* by modifications made to the name set.
* \returns Name list
*/
NameList getNameList() const;
private:
std::unordered_set<std::string> m_names;