[dxvk] Refactor Vulkan extension management

Adding an extension will now require an additional step, but
this evolved version of the extension list code is more sane
and the structures can be more easily copied around.
This commit is contained in:
Philip Rebohle 2018-07-23 20:07:21 +02:00
parent 6d24f767c6
commit 656cb2e4aa
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
15 changed files with 403 additions and 400 deletions

View File

@ -160,23 +160,37 @@ 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(availableExtensions);
if (!extensions->checkSupportStatus())
DxvkDeviceExtensions devExtensions;
std::array<DxvkExt*, 11> devExtensionList = {{
&devExtensions.extShaderViewportIndexLayer,
&devExtensions.extVertexAttributeDivisor,
&devExtensions.khrDedicatedAllocation,
&devExtensions.khrDescriptorUpdateTemplate,
&devExtensions.khrGetMemoryRequirements2,
&devExtensions.khrImageFormatList,
&devExtensions.khrMaintenance1,
&devExtensions.khrMaintenance2,
&devExtensions.khrSamplerMirrorClampToEdge,
&devExtensions.khrShaderDrawParameters,
&devExtensions.khrSwapchain,
}};
DxvkNameSet extensionsEnabled;
DxvkNameSet extensionsAvailable = DxvkNameSet::enumDeviceExtensions(m_vki, m_handle);
if (!extensionsAvailable.enableExtensions(
devExtensionList.size(),
devExtensionList.data(),
extensionsEnabled))
throw DxvkError("DxvkAdapter: Failed to create device");
// Generate list of extensions that we're actually going to use
vk::NameSet enabledExtensionSet = extensions->getEnabledExtensionNames();
enabledExtensionSet.merge(g_vrInstance.getDeviceExtensions(getAdapterIndex()));
vk::NameList enabledExtensionList = enabledExtensionSet.getNameList();
// Enable additional extensions if necessary
extensionsEnabled.merge(g_vrInstance.getDeviceExtensions(getAdapterIndex()));
DxvkNameList extensionNameList = extensionsEnabled.toNameList();
Logger::info("Enabled device extensions:");
this->logNameList(enabledExtensionList);
this->logNameList(extensionNameList);
float queuePriority = 1.0f;
std::vector<VkDeviceQueueCreateInfo> queueInfos;
@ -207,8 +221,8 @@ namespace dxvk {
info.pQueueCreateInfos = queueInfos.data();
info.enabledLayerCount = 0;
info.ppEnabledLayerNames = nullptr;
info.enabledExtensionCount = enabledExtensionList.count();
info.ppEnabledExtensionNames = enabledExtensionList.names();
info.enabledExtensionCount = extensionNameList.count();
info.ppEnabledExtensionNames = extensionNameList.names();
info.pEnabledFeatures = &enabledFeatures;
VkDevice device = VK_NULL_HANDLE;
@ -218,7 +232,7 @@ namespace dxvk {
Rc<DxvkDevice> result = new DxvkDevice(this,
new vk::DeviceFn(m_vki->instance(), device),
extensions, enabledFeatures);
devExtensions, enabledFeatures);
result->initResources();
return result;
}
@ -271,7 +285,7 @@ namespace dxvk {
}
void DxvkAdapter::logNameList(const vk::NameList& names) {
void DxvkAdapter::logNameList(const DxvkNameList& names) {
for (uint32_t i = 0; i < names.count(); i++)
Logger::info(str::format(" ", names.name(i)));
}

View File

@ -1,7 +1,6 @@
#pragma once
#include "./vulkan/dxvk_vulkan_extensions.h"
#include "dxvk_extensions.h"
#include "dxvk_include.h"
namespace dxvk {
@ -171,7 +170,7 @@ namespace dxvk {
uint32_t getAdapterIndex() const;
static void logNameList(const vk::NameList& names);
static void logNameList(const DxvkNameList& names);
};

View File

@ -6,7 +6,7 @@ namespace dxvk {
DxvkDevice::DxvkDevice(
const Rc<DxvkAdapter>& adapter,
const Rc<vk::DeviceFn>& vkd,
const Rc<DxvkDeviceExtensions>& extensions,
const DxvkDeviceExtensions& extensions,
const VkPhysicalDeviceFeatures& features)
: m_adapter (adapter),
m_vkd (vkd),

View File

@ -64,7 +64,7 @@ namespace dxvk {
DxvkDevice(
const Rc<DxvkAdapter>& adapter,
const Rc<vk::DeviceFn>& vkd,
const Rc<DxvkDeviceExtensions>& extensions,
const DxvkDeviceExtensions& extensions,
const VkPhysicalDeviceFeatures& features);
~DxvkDevice();
@ -112,7 +112,7 @@ namespace dxvk {
* \returns Enabled device extensions
*/
const DxvkDeviceExtensions& extensions() const {
return *m_extensions;
return m_extensions;
}
/**
@ -373,7 +373,7 @@ namespace dxvk {
Rc<DxvkAdapter> m_adapter;
Rc<vk::DeviceFn> m_vkd;
Rc<DxvkDeviceExtensions> m_extensions;
DxvkDeviceExtensions m_extensions;
VkPhysicalDeviceFeatures m_features;
VkPhysicalDeviceProperties m_properties;

View File

@ -2,74 +2,114 @@
namespace dxvk {
DxvkExtensionList:: DxvkExtensionList() { }
DxvkExtensionList::~DxvkExtensionList() { }
void DxvkExtensionList::enableExtensions(const vk::NameSet& extensions) {
for (auto ext : m_extensions) {
if (extensions.contains(ext->name()))
ext->setEnabled(true);
}
DxvkNameSet::DxvkNameSet() { }
DxvkNameSet::~DxvkNameSet() { }
void DxvkNameSet::add(const char* pName) {
m_names.insert(pName);
}
bool DxvkExtensionList::checkSupportStatus() {
bool requiredExtensionsEnabled = true;
for (auto ext : m_extensions) {
if (!ext->enabled()) {
switch (ext->type()) {
case DxvkExtensionType::Optional:
// An optional extension should not have any impact on
// the functionality of an application, so inform the
// user only if verbose debug messages are enabled
Logger::debug(str::format("Optional Vulkan extension ", ext->name(), " not supported"));
break;
case DxvkExtensionType::Desired:
// If a desired extension is not supported, applications
// should keep working but may exhibit unexpected behaviour,
// so we'll inform the user anyway
Logger::warn(str::format("Vulkan extension ", ext->name(), " not supported"));
break;
case DxvkExtensionType::Required:
// Do not exit early so we can catch all unsupported extensions.
requiredExtensionsEnabled = false;
Logger::err(str::format("Required Vulkan extension ", ext->name(), " not supported"));
break;
void DxvkNameSet::merge(const DxvkNameSet& names) {
for (const std::string& name : names.m_names)
m_names.insert(name);
}
bool DxvkNameSet::supports(const char* pName) const {
return m_names.find(pName) != m_names.end();
}
bool DxvkNameSet::enableExtensions(
uint32_t numExtensions,
DxvkExt** ppExtensions,
DxvkNameSet& nameSet) const {
bool allRequiredEnabled = true;
for (uint32_t i = 0; i < numExtensions; i++) {
DxvkExt* ext = ppExtensions[i];
if (ext->mode() != DxvkExtMode::Disabled) {
bool supported = supports(ext->name());
if (supported) {
nameSet.add(ext->name());
ext->enable();
} else if (ext->mode() == DxvkExtMode::Required) {
Logger::info(str::format(
"Required Vulkan extension ", ext->name(), " not supported"));
allRequiredEnabled = false;
}
}
}
return allRequiredEnabled;
}
DxvkNameList DxvkNameSet::toNameList() const {
DxvkNameList nameList;
for (const std::string& name : m_names)
nameList.add(name.c_str());
return nameList;
}
DxvkNameSet DxvkNameSet::enumInstanceLayers(const Rc<vk::LibraryFn>& vkl) {
uint32_t entryCount = 0;
if (vkl->vkEnumerateInstanceLayerProperties(
&entryCount, nullptr) != VK_SUCCESS)
return DxvkNameSet();
return requiredExtensionsEnabled;
std::vector<VkLayerProperties> entries(entryCount);
if (vkl->vkEnumerateInstanceLayerProperties(
&entryCount, entries.data()) != VK_SUCCESS)
return DxvkNameSet();
DxvkNameSet set;
for (uint32_t i = 0; i < entryCount; i++)
set.m_names.insert(entries[i].layerName);
return set;
}
vk::NameSet DxvkExtensionList::getEnabledExtensionNames() const {
vk::NameSet names;
DxvkNameSet DxvkNameSet::enumInstanceExtensions(const Rc<vk::LibraryFn>& vkl) {
uint32_t entryCount = 0;
if (vkl->vkEnumerateInstanceExtensionProperties(
nullptr, &entryCount, nullptr) != VK_SUCCESS)
return DxvkNameSet();
for (auto ext : m_extensions) {
if (ext->enabled())
names.add(ext->name());
}
std::vector<VkExtensionProperties> entries(entryCount);
if (vkl->vkEnumerateInstanceExtensionProperties(
nullptr, &entryCount, entries.data()) != VK_SUCCESS)
return DxvkNameSet();
DxvkNameSet set;
for (uint32_t i = 0; i < entryCount; i++)
set.m_names.insert(entries[i].extensionName);
return set;
}
DxvkNameSet DxvkNameSet::enumDeviceExtensions(
const Rc<vk::InstanceFn>& vki,
VkPhysicalDevice device) {
uint32_t entryCount = 0;
if (vki->vkEnumerateDeviceExtensionProperties(
device, nullptr, &entryCount, nullptr) != VK_SUCCESS)
return DxvkNameSet();
return names;
}
void DxvkExtensionList::registerExtension(DxvkExtension* extension) {
m_extensions.push_back(extension);
}
DxvkExtension::DxvkExtension(
DxvkExtensionList* parent,
const char* name,
DxvkExtensionType type)
: m_name(name), m_type(type), m_enabled(false) {
parent->registerExtension(this);
std::vector<VkExtensionProperties> entries(entryCount);
if (vki->vkEnumerateDeviceExtensionProperties(
device, nullptr, &entryCount, entries.data()) != VK_SUCCESS)
return DxvkNameSet();
DxvkNameSet set;
for (uint32_t i = 0; i < entryCount; i++)
set.m_names.insert(entries[i].extensionName);
return set;
}
}

View File

@ -1,91 +1,40 @@
#pragma once
#include <set>
#include "dxvk_include.h"
namespace dxvk {
// Forward declarations
class DxvkExtension;
class DxvkExtensionList;
/**
* \brief Extension type
*/
enum class DxvkExtensionType {
Optional, ///< Nothing will happen if not supported
Desired, ///< A warning will be issued if not supported
Required, ///< Device creation will fail if not supported
};
/**
* \brief Vulkan extension list
* \brief Vulkan extension mode
*
* Convenience class to manage a set of extensions
* which can be either required or optional.
* Defines whether an extension is
* optional, required, or disabled.
*/
class DxvkExtensionList : public RcObject {
friend class DxvkExtension;
public:
DxvkExtensionList();
~DxvkExtensionList();
DxvkExtensionList (const DxvkExtensionList&) = delete;
DxvkExtensionList& operator = (const DxvkExtensionList&) = delete;
/**
* \brief Enables Vulkan extensions
*
* Marks all extension in the list as enabled.
* \param [in] extensions Supported extensions
*/
void enableExtensions(
const vk::NameSet& extensions);
/**
* \brief Checks extension support status
*
* Checks whether all required extensions are present
* and logs the name of any unsupported extension.
* \returns \c true if required extensions are present
*/
bool checkSupportStatus();
/**
* \brief Creates a list of enabled extensions
*
* The resulting list can be fed into the Vulkan
* structs for device and instance creation.
* \returns Names of enabled Vulkan extensions
*/
vk::NameSet getEnabledExtensionNames() const;
private:
std::vector<DxvkExtension*> m_extensions;
void registerExtension(DxvkExtension* extension);
enum class DxvkExtMode {
Disabled,
Optional,
Required,
};
/**
* \brief Extension class
* \brief Vulkan extension info
*
* Stores the name, type and support
* status of a single Vulkan extension.
* Stores information for a single extension.
* The renderer can use this information to
* find out which extensions are enabled.
*/
class DxvkExtension {
friend class DxvkExtensionList;
class DxvkExt {
public:
DxvkExtension(
DxvkExtensionList* parent,
const char* name,
DxvkExtensionType type);
DxvkExtension (const DxvkExtension&) = delete;
DxvkExtension& operator = (const DxvkExtension&) = delete;
DxvkExt(
const char* pName,
DxvkExtMode mode)
: m_name(pName), m_mode(mode) { }
/**
* \brief Extension name
* \returns Extension name
@ -93,53 +42,223 @@ namespace dxvk {
const char* name() const {
return m_name;
}
/**
* \brief Extension type
* \returns Extension type
* \brief Extension mode
* \returns Extension mode
*/
DxvkExtensionType type() const {
return m_type;
DxvkExtMode mode() const {
return m_mode;
}
/**
* \brief Extension support status
* \returns \c true if supported
* \brief Checks whether the extension is enabled
*
* If an extension is enabled, the features
* provided by the extension can be used.
* \returns \c true if the extension is enabled
*/
bool enabled() const {
operator bool () const {
return m_enabled;
}
private:
const char* m_name;
DxvkExtensionType m_type;
bool m_enabled;
void setEnabled(bool enabled) {
m_enabled = enabled;
/**
* \brief Changes extension mode
*
* In some cases, it may be useful to change the
* default mode dynamically after initialization.
*/
void setMode(DxvkExtMode mode) {
m_mode = mode;
}
/**
* \brief Enables the extension
*/
void enable() {
m_enabled = true;
}
private:
const char* m_name = nullptr;
DxvkExtMode m_mode = DxvkExtMode::Disabled;
bool m_enabled = false;
};
/**
* \brief Vulkan name list
*
* A simple \c vector wrapper that can
* be used to build a list of layer and
* extension names.
*/
class DxvkNameList {
public:
/**
* \brief Adds a name
* \param [in] pName The name
*/
void add(const char* pName) {
m_names.push_back(pName);
}
/**
* \brief Number of names
* \returns Name count
*/
uint32_t count() const {
return m_names.size();
}
/**
* \brief Name list
* \returns Name list
*/
const char* const* names() const {
return m_names.data();
}
/**
* \brief Retrieves a single name
*
* \param [in] index Name index
* \returns The given name
*/
const char* name(uint32_t index) const {
return m_names.at(index);
}
private:
std::vector<const char*> m_names;
};
/**
* \brief Vulkan extension set
*
* Stores a set of extensions or layers
* supported by the Vulkan implementation.
*/
class DxvkNameSet {
public:
DxvkNameSet();
~DxvkNameSet();
/**
* \brief Adds a name to the set
* \param [in] pName Extension name
*/
void add(
const char* pName);
/**
* \brief Merges two name sets
*
* Adds all names from the given name set to
* this name set, avoiding duplicate entries.
* \param [in] names Name set to merge
*/
void merge(
const DxvkNameSet& names);
/**
* \brief Checks whether an extension is supported
*
* \param [in] pName Extension name
* \returns \c true if the extension is supported
*/
bool supports(
const char* pName) const;
/**
* \brief Enables requested extensions
*
* Walks over a set of extensions and enables all
* extensions that are supported and not disabled.
* This also checks whether all required extensions
* could be enabled, and returns \c false otherwise.
* \param [in] numExtensions Number of extensions
* \param [in] ppExtensions List of extensions
* \param [out] nameSet Extension name set
* \returns \c true on success
*/
bool enableExtensions(
uint32_t numExtensions,
DxvkExt** ppExtensions,
DxvkNameSet& nameSet) const;
/**
* \brief Creates name list from name set
*
* Adds all names contained in the name set
* to a name list, which can then be passed
* to Vulkan functions.
* \returns Name list
*/
DxvkNameList toNameList() const;
/**
* \brief Enumerates instance layers
*
* \param [in] vkl Vulkan library functions
* \returns Set of available instance layers
*/
static DxvkNameSet enumInstanceLayers(
const Rc<vk::LibraryFn>& vkl);
/**
* \brief Enumerates instance extensions
*
* \param [in] vkl Vulkan library functions
* \returns Set of available instance extensions
*/
static DxvkNameSet enumInstanceExtensions(
const Rc<vk::LibraryFn>& vkl);
/**
* \brief Enumerates device extensions
*
* \param [in] vki Vulkan instance functions
* \param [in] device The device to query
* \returns Set of available device extensions
*/
static DxvkNameSet enumDeviceExtensions(
const Rc<vk::InstanceFn>& vki,
VkPhysicalDevice device);
private:
std::set<std::string> m_names;
};
/**
* \brief Device extensions
*
* Lists all Vulkan extensions that are potentially
* used by DXVK if supported by the implementation.
*/
struct DxvkDeviceExtensions : public DxvkExtensionList {
DxvkExtension extShaderViewportIndexLayer = { this, VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_EXTENSION_NAME, DxvkExtensionType::Desired };
DxvkExtension extVertexAttributeDivisor = { this, VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME, DxvkExtensionType::Desired };
DxvkExtension khrDedicatedAllocation = { this, VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME, DxvkExtensionType::Required };
DxvkExtension khrDescriptorUpdateTemplate = { this, VK_KHR_DESCRIPTOR_UPDATE_TEMPLATE_EXTENSION_NAME, DxvkExtensionType::Required };
DxvkExtension khrGetMemoryRequirements2 = { this, VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME, DxvkExtensionType::Required };
DxvkExtension khrImageFormatList = { this, VK_KHR_IMAGE_FORMAT_LIST_EXTENSION_NAME, DxvkExtensionType::Required };
DxvkExtension khrMaintenance1 = { this, VK_KHR_MAINTENANCE1_EXTENSION_NAME, DxvkExtensionType::Required };
DxvkExtension khrMaintenance2 = { this, VK_KHR_MAINTENANCE2_EXTENSION_NAME, DxvkExtensionType::Required };
DxvkExtension khrSamplerMirrorClampToEdge = { this, VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_EXTENSION_NAME, DxvkExtensionType::Desired };
DxvkExtension khrShaderDrawParameters = { this, VK_KHR_SHADER_DRAW_PARAMETERS_EXTENSION_NAME, DxvkExtensionType::Required };
DxvkExtension khrSwapchain = { this, VK_KHR_SWAPCHAIN_EXTENSION_NAME, DxvkExtensionType::Required };
struct DxvkDeviceExtensions {
DxvkExt extShaderViewportIndexLayer = { VK_EXT_SHADER_VIEWPORT_INDEX_LAYER_EXTENSION_NAME, DxvkExtMode::Optional };
DxvkExt extVertexAttributeDivisor = { VK_EXT_VERTEX_ATTRIBUTE_DIVISOR_EXTENSION_NAME, DxvkExtMode::Optional };
DxvkExt khrDedicatedAllocation = { VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME, DxvkExtMode::Required };
DxvkExt khrDescriptorUpdateTemplate = { VK_KHR_DESCRIPTOR_UPDATE_TEMPLATE_EXTENSION_NAME, DxvkExtMode::Required };
DxvkExt khrGetMemoryRequirements2 = { VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME, DxvkExtMode::Required };
DxvkExt khrImageFormatList = { VK_KHR_IMAGE_FORMAT_LIST_EXTENSION_NAME, DxvkExtMode::Required };
DxvkExt khrMaintenance1 = { VK_KHR_MAINTENANCE1_EXTENSION_NAME, DxvkExtMode::Required };
DxvkExt khrMaintenance2 = { VK_KHR_MAINTENANCE2_EXTENSION_NAME, DxvkExtMode::Required };
DxvkExt khrSamplerMirrorClampToEdge = { VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_EXTENSION_NAME, DxvkExtMode::Optional };
DxvkExt khrShaderDrawParameters = { VK_KHR_SHADER_DRAW_PARAMETERS_EXTENSION_NAME, DxvkExtMode::Required };
DxvkExt khrSwapchain = { VK_KHR_SWAPCHAIN_EXTENSION_NAME, DxvkExtMode::Required };
};
/**
@ -148,10 +267,10 @@ namespace dxvk {
* Lists all Vulkan extensions that are potentially
* used by DXVK if supported by the implementation.
*/
struct DxvkInstanceExtensions : public DxvkExtensionList {
DxvkExtension khrGetPhysicalDeviceProperties2 = { this, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, DxvkExtensionType::Required };
DxvkExtension khrSurface = { this, VK_KHR_SURFACE_EXTENSION_NAME, DxvkExtensionType::Required };
DxvkExtension khrWin32Surface = { this, VK_KHR_WIN32_SURFACE_EXTENSION_NAME, DxvkExtensionType::Required };
struct DxvkInstanceExtensions {
DxvkExt khrGetPhysicalDeviceProperties2 = { VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, DxvkExtMode::Required };
DxvkExt khrSurface = { VK_KHR_SURFACE_EXTENSION_NAME, DxvkExtMode::Required };
DxvkExt khrWin32Surface = { VK_KHR_WIN32_SURFACE_EXTENSION_NAME, DxvkExtMode::Required };
};
}

View File

@ -260,7 +260,7 @@ namespace dxvk {
viInfo.pNext = viDivisorInfo.pNext;
// TODO remove this once the extension is widely supported
if (!m_device->extensions().extVertexAttributeDivisor.enabled())
if (!m_device->extensions().extVertexAttributeDivisor)
viInfo.pNext = viDivisorInfo.pNext;
VkPipelineInputAssemblyStateCreateInfo iaInfo;

View File

@ -16,6 +16,5 @@
#include "../util/sync/sync_spinlock.h"
#include "./vulkan/dxvk_vulkan_extensions.h"
#include "./vulkan/dxvk_vulkan_loader.h"
#include "./vulkan/dxvk_vulkan_names.h"

View File

@ -34,23 +34,29 @@ namespace dxvk {
VkInstance DxvkInstance::createInstance() {
// Query available extensions and enable the ones that are needed
vk::NameSet availableExtensions = vk::NameSet::enumerateInstanceExtensions(*m_vkl);
DxvkInstanceExtensions insExtensions;
std::array<DxvkExt*, 3> insExtensionList = {{
&insExtensions.khrGetPhysicalDeviceProperties2,
&insExtensions.khrSurface,
&insExtensions.khrWin32Surface,
}};
DxvkNameSet extensionsEnabled;
DxvkNameSet extensionsAvailable = DxvkNameSet::enumInstanceExtensions(m_vkl);
DxvkInstanceExtensions extensionsToEnable;
extensionsToEnable.enableExtensions(availableExtensions);
if (!extensionsToEnable.checkSupportStatus())
if (!extensionsAvailable.enableExtensions(
insExtensionList.size(),
insExtensionList.data(),
extensionsEnabled))
throw DxvkError("DxvkInstance: Failed to create instance");
// Generate list of extensions that we're actually going to use
vk::NameSet enabledExtensionSet = extensionsToEnable.getEnabledExtensionNames();
enabledExtensionSet.merge(g_vrInstance.getInstanceExtensions());
vk::NameList enabledExtensionList = enabledExtensionSet.getNameList();
// Enable additional extensions if necessary
extensionsEnabled.merge(g_vrInstance.getInstanceExtensions());
DxvkNameList extensionNameList = extensionsEnabled.toNameList();
Logger::info("Enabled instance extensions:");
this->logNameList(enabledExtensionList);
this->logNameList(extensionNameList);
VkApplicationInfo appInfo;
appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
@ -68,8 +74,8 @@ namespace dxvk {
info.pApplicationInfo = &appInfo;
info.enabledLayerCount = 0;
info.ppEnabledLayerNames = nullptr;
info.enabledExtensionCount = enabledExtensionList.count();
info.ppEnabledExtensionNames = enabledExtensionList.names();
info.enabledExtensionCount = extensionNameList.count();
info.ppEnabledExtensionNames = extensionNameList.names();
VkInstance result = VK_NULL_HANDLE;
if (m_vkl->vkCreateInstance(&info, nullptr, &result) != VK_SUCCESS)
@ -101,7 +107,7 @@ namespace dxvk {
}
void DxvkInstance::logNameList(const vk::NameList& names) {
void DxvkInstance::logNameList(const DxvkNameList& names) {
for (uint32_t i = 0; i < names.count(); i++)
Logger::info(str::format(" ", names.name(i)));
}

View File

@ -56,7 +56,7 @@ namespace dxvk {
std::vector<Rc<DxvkAdapter>> queryAdapters();
static void logNameList(const vk::NameList& names);
static void logNameList(const DxvkNameList& names);
};

View File

@ -26,19 +26,19 @@ namespace dxvk {
VrInstance::~VrInstance() { }
vk::NameSet VrInstance::getInstanceExtensions() {
DxvkNameSet VrInstance::getInstanceExtensions() {
std::lock_guard<std::mutex> lock(m_mutex);
return m_insExtensions;
}
vk::NameSet VrInstance::getDeviceExtensions(uint32_t adapterId) {
DxvkNameSet VrInstance::getDeviceExtensions(uint32_t adapterId) {
std::lock_guard<std::mutex> lock(m_mutex);
if (adapterId < m_devExtensions.size())
return m_devExtensions[adapterId];
return vk::NameSet();
return DxvkNameSet();
}
@ -72,7 +72,7 @@ namespace dxvk {
}
vk::NameSet VrInstance::queryInstanceExtensions() const {
DxvkNameSet VrInstance::queryInstanceExtensions() const {
uint32_t len = m_compositor->GetVulkanInstanceExtensionsRequired(nullptr, 0);
std::vector<char> extensionList(len);
len = m_compositor->GetVulkanInstanceExtensionsRequired(extensionList.data(), len);
@ -80,7 +80,7 @@ namespace dxvk {
}
vk::NameSet VrInstance::queryDeviceExtensions(VkPhysicalDevice adapter) const {
DxvkNameSet VrInstance::queryDeviceExtensions(VkPhysicalDevice adapter) const {
uint32_t len = m_compositor->GetVulkanDeviceExtensionsRequired(adapter, nullptr, 0);
std::vector<char> extensionList(len);
len = m_compositor->GetVulkanDeviceExtensionsRequired(adapter, extensionList.data(), len);
@ -88,14 +88,14 @@ namespace dxvk {
}
vk::NameSet VrInstance::parseExtensionList(const std::string& str) const {
vk::NameSet result;
DxvkNameSet VrInstance::parseExtensionList(const std::string& str) const {
DxvkNameSet result;
std::stringstream strstream(str);
std::string section;
while (std::getline(strstream, section, ' '))
result.add(section);
result.add(section.c_str());
return result;
}

View File

@ -31,7 +31,7 @@ namespace dxvk {
* \brief Query instance extensions
* \returns Instance extensions
*/
vk::NameSet getInstanceExtensions();
DxvkNameSet getInstanceExtensions();
/**
* \brief Query device extensions
@ -41,7 +41,7 @@ namespace dxvk {
* the same across multiple Vulkan instances.
* \param [in] adapterId Adapter index
*/
vk::NameSet getDeviceExtensions(
DxvkNameSet getDeviceExtensions(
uint32_t adapterId);
/**
@ -73,15 +73,15 @@ namespace dxvk {
bool m_initializedInsExt = false;
bool m_initializedDevExt = false;
vk::NameSet m_insExtensions;
std::vector<vk::NameSet> m_devExtensions;
DxvkNameSet m_insExtensions;
std::vector<DxvkNameSet> m_devExtensions;
vk::NameSet queryInstanceExtensions() const;
DxvkNameSet queryInstanceExtensions() const;
vk::NameSet queryDeviceExtensions(
DxvkNameSet queryDeviceExtensions(
VkPhysicalDevice adapter) const;
vk::NameSet parseExtensionList(
DxvkNameSet parseExtensionList(
const std::string& str) const;
vr::IVRCompositor* getCompositor();

View File

@ -85,7 +85,6 @@ dxvk_src = files([
'hud/dxvk_hud_renderer.cpp',
'hud/dxvk_hud_stats.cpp',
'vulkan/dxvk_vulkan_extensions.cpp',
'vulkan/dxvk_vulkan_loader.cpp',
'vulkan/dxvk_vulkan_names.cpp',
])

View File

@ -1,63 +0,0 @@
#include "dxvk_vulkan_extensions.h"
namespace dxvk::vk {
void NameSet::add(const std::string& name) {
m_names.insert(name);
}
void NameSet::merge(const NameSet& other) {
for (const auto& entry : other.m_names)
this->add(entry);
}
bool NameSet::contains(const std::string& name) const {
return m_names.find(name) != m_names.end();
}
NameSet NameSet::enumerateInstanceExtensions(
const LibraryFn& vkl) {
uint32_t extCount = 0;
if (vkl.vkEnumerateInstanceExtensionProperties(nullptr, &extCount, nullptr) != VK_SUCCESS)
throw DxvkError("ExtensionSet::addInstanceExtensions: Failed to query instance extensions");
std::vector<VkExtensionProperties> extensions(extCount);
if (vkl.vkEnumerateInstanceExtensionProperties(nullptr, &extCount, extensions.data()) != VK_SUCCESS)
throw DxvkError("ExtensionSet::addInstanceExtensions: Failed to query instance extensions");
NameSet result;
for (const auto& ext : extensions)
result.add(ext.extensionName);
return result;
}
NameSet NameSet::enumerateDeviceExtensions(
const InstanceFn& vki,
VkPhysicalDevice device) {
uint32_t extCount = 0;
if (vki.vkEnumerateDeviceExtensionProperties(device, nullptr, &extCount, nullptr) != VK_SUCCESS)
throw DxvkError("ExtensionSet::addDeviceExtensions: Failed to query device extensions");
std::vector<VkExtensionProperties> extensions(extCount);
if (vki.vkEnumerateDeviceExtensionProperties(device, nullptr, &extCount, extensions.data()) != VK_SUCCESS)
throw DxvkError("ExtensionSet::addDeviceExtensions: Failed to query device extensions");
NameSet result;
for (const auto& ext : extensions)
result.add(ext.extensionName);
return result;
}
NameList NameSet::getNameList() const {
NameList result;
for (const std::string& name : m_names)
result.add(name.c_str());
return result;
}
}

View File

@ -1,110 +0,0 @@
#pragma once
#include <set>
#include <string>
#include <vector>
#include "dxvk_vulkan_loader.h"
#include "../../util/util_error.h"
#include "../../util/util_string.h"
namespace dxvk::vk {
/**
* \brief Name list
*
* Stores a list of extension or layer names.
* Note that only name constants may be added
* to a name list. Adding dynamically allocated
* strings will result in udefined behaviour.
*/
class NameList {
public:
void add(const char* name) {
m_list.push_back(name);
}
auto name(size_t i) const {
return m_list[i];
}
auto names() const { return m_list.data(); }
auto count() const { return m_list.size(); }
private:
std::vector<const char*> m_list;
};
/**
* \brief Name set
*
* Stores a set of supported layers or extensions and
* provides methods to query their support status.
*/
class NameSet {
public:
/**
* \brief Adds an extension to the set
* \param [in] name The extension to add
*/
void add(const std::string& name);
/**
* \brief Merges two name sets
* \param [in] other Name set to merge
*/
void merge(const NameSet& other);
/**
* \brief Checks whether an extension or layer is supported
*
* \param [in] name The layer or extension name
* \returns \c true if the entity is supported
*/
bool contains(const std::string& name) const;
/**
* \brief Enumerates instance extensions
*
* \param [in] vkl Vulkan library functions
* \returns Available instance extensions
*/
static NameSet enumerateInstanceExtensions(
const LibraryFn& vkl);
/**
* \brief Enumerates device extensions
*
* \param [in] vki Vulkan instance functions
* \param [in] device The physical device
* \returns Available device extensions
*/
static NameSet enumerateDeviceExtensions(
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::set<std::string> m_names;
};
}