diff --git a/src/dxvk/dxvk_extension_provider.cpp b/src/dxvk/dxvk_extension_provider.cpp new file mode 100644 index 00000000..520e4296 --- /dev/null +++ b/src/dxvk/dxvk_extension_provider.cpp @@ -0,0 +1,17 @@ +#include "dxvk_extension_provider.h" + +#include "dxvk_openvr.h" +#include "dxvk_platform_exts.h" + +namespace dxvk { + + DxvkExtensionProviderList DxvkExtensionProvider::s_extensionProviders = { + &g_platformInstance, + &g_vrInstance + }; + + const DxvkExtensionProviderList& DxvkExtensionProvider::getExtensionProviders() { + return s_extensionProviders; + } + +} \ No newline at end of file diff --git a/src/dxvk/dxvk_extension_provider.h b/src/dxvk/dxvk_extension_provider.h new file mode 100644 index 00000000..dce426e2 --- /dev/null +++ b/src/dxvk/dxvk_extension_provider.h @@ -0,0 +1,78 @@ +#pragma once + +#include "dxvk_include.h" +#include "dxvk_extensions.h" + +#include +#include + +namespace dxvk { + + class DxvkInstance; + class DxvkExtensionProvider; + + using DxvkExtensionProviderList = std::vector; + + /** + * \brief Extension provider base + * + * Abstract interface for extension + * providers + */ + class DxvkExtensionProvider { + + public: + + /** + * \brief Extension provider name + * \returns The extension provider's name + */ + virtual std::string_view getName() = 0; + + /** + * \brief Query instance extensions + * \returns Instance extensions + */ + virtual DxvkNameSet getInstanceExtensions() = 0; + + /** + * \brief Query device extensions + * + * Retrieves the extensions required for a specific + * physical device. The adapter index should remain + * the same across multiple Vulkan instances. + * \param [in] adapterId Adapter index + */ + virtual DxvkNameSet getDeviceExtensions( + uint32_t adapterId) = 0; + + /** + * \brief Initializes instance extension set + * + * Should be called before creating + * the first Vulkan instance. + */ + virtual void initInstanceExtensions() = 0; + + /** + * \brief Initializes device extension sets + * + * Should be called after setting + * up the Vulkan physical devices. + * \param [in] instance DXVK instance + */ + virtual void initDeviceExtensions( + const DxvkInstance* instance) = 0; + + /** + * \brief Get list of ptrs to the extension providers + */ + static const DxvkExtensionProviderList& getExtensionProviders(); + + private: + + static DxvkExtensionProviderList s_extensionProviders; + + }; + +} \ No newline at end of file diff --git a/src/dxvk/dxvk_extensions.h b/src/dxvk/dxvk_extensions.h index c5217d30..813b1735 100644 --- a/src/dxvk/dxvk_extensions.h +++ b/src/dxvk/dxvk_extensions.h @@ -294,7 +294,6 @@ namespace dxvk { 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 }; }; } \ No newline at end of file diff --git a/src/dxvk/dxvk_instance.cpp b/src/dxvk/dxvk_instance.cpp index b1b331d2..8a27a015 100644 --- a/src/dxvk/dxvk_instance.cpp +++ b/src/dxvk/dxvk_instance.cpp @@ -1,7 +1,7 @@ #include #include "dxvk_instance.h" -#include "dxvk_openvr.h" +#include "dxvk_extension_provider.h" #include @@ -15,17 +15,28 @@ namespace dxvk { m_config.merge(Config::getAppConfig(env::getExePath())); m_config.logOptions(); - g_vrInstance.initInstanceExtensions(); + const auto& extProviders = DxvkExtensionProvider::getExtensionProviders(); + + Logger::info("Built-in extension providers:"); + for (const auto& provider : extProviders) + Logger::info(str::format(" ", provider->getName())); + + for (const auto& provider : extProviders) + provider->initInstanceExtensions(); m_vkl = new vk::LibraryFn(); m_vki = new vk::InstanceFn(true, this->createInstance()); m_adapters = this->queryAdapters(); - g_vrInstance.initDeviceExtensions(this); + + for (const auto& provider : extProviders) + provider->initDeviceExtensions(this); for (uint32_t i = 0; i < m_adapters.size(); i++) { - m_adapters[i]->enableExtensions( - g_vrInstance.getDeviceExtensions(i)); + for (const auto& provider : extProviders) { + m_adapters[i]->enableExtensions( + provider->getDeviceExtensions(i)); + } } m_options = DxvkOptions(m_config); @@ -72,10 +83,9 @@ namespace dxvk { VkInstance DxvkInstance::createInstance() { DxvkInstanceExtensions insExtensions; - std::array insExtensionList = {{ + std::array insExtensionList = {{ &insExtensions.khrGetPhysicalDeviceProperties2, &insExtensions.khrSurface, - &insExtensions.khrWin32Surface, }}; DxvkNameSet extensionsEnabled; @@ -86,9 +96,12 @@ namespace dxvk { insExtensionList.data(), extensionsEnabled)) throw DxvkError("DxvkInstance: Failed to create instance"); + + const auto& extProviders = DxvkExtensionProvider::getExtensionProviders(); // Enable additional extensions if necessary - extensionsEnabled.merge(g_vrInstance.getInstanceExtensions()); + for (const auto& provider : extProviders) + extensionsEnabled.merge(provider->getInstanceExtensions()); DxvkNameList extensionNameList = extensionsEnabled.toNameList(); Logger::info("Enabled instance extensions:"); diff --git a/src/dxvk/dxvk_instance.h b/src/dxvk/dxvk_instance.h index 53288231..2bb4760a 100644 --- a/src/dxvk/dxvk_instance.h +++ b/src/dxvk/dxvk_instance.h @@ -5,7 +5,6 @@ #include "dxvk_adapter.h" #include "dxvk_device.h" #include "dxvk_device_filter.h" -#include "dxvk_openvr.h" namespace dxvk { diff --git a/src/dxvk/dxvk_openvr.cpp b/src/dxvk/dxvk_openvr.cpp index c1d60a0c..5bc29095 100644 --- a/src/dxvk/dxvk_openvr.cpp +++ b/src/dxvk/dxvk_openvr.cpp @@ -36,6 +36,11 @@ namespace dxvk { VrInstance:: VrInstance() { } VrInstance::~VrInstance() { } + + + std::string_view VrInstance::getName() { + return "OpenVR"; + } DxvkNameSet VrInstance::getInstanceExtensions() { diff --git a/src/dxvk/dxvk_openvr.h b/src/dxvk/dxvk_openvr.h index f5058c87..a8037dda 100644 --- a/src/dxvk/dxvk_openvr.h +++ b/src/dxvk/dxvk_openvr.h @@ -3,7 +3,7 @@ #include #include -#include "dxvk_include.h" +#include "dxvk_extension_provider.h" #ifdef __WINE__ using SoHandle = void*; @@ -26,13 +26,19 @@ namespace dxvk { * Loads Initializes OpenVR to provide * access to Vulkan extension queries. */ - class VrInstance { + class VrInstance : public DxvkExtensionProvider { public: VrInstance(); ~VrInstance(); + /** + * \brief Extension provider name + * \returns The extension provider's name + */ + std::string_view getName(); + /** * \brief Query instance extensions * \returns Instance extensions diff --git a/src/dxvk/dxvk_platform_exts.h b/src/dxvk/dxvk_platform_exts.h new file mode 100644 index 00000000..c192162c --- /dev/null +++ b/src/dxvk/dxvk_platform_exts.h @@ -0,0 +1,53 @@ +#include "dxvk_extension_provider.h" + +namespace dxvk { + + class DxvkPlatformExts : public DxvkExtensionProvider { + + public: + + /** + * \brief Extension provider name + * \returns The extension provider's name + */ + std::string_view getName(); + + /** + * \brief Query instance extensions + * \returns Instance extensions + */ + DxvkNameSet getInstanceExtensions(); + + /** + * \brief Query device extensions + * + * Retrieves the extensions required for a specific + * physical device. The adapter index should remain + * the same across multiple Vulkan instances. + * \param [in] adapterId Adapter index + */ + DxvkNameSet getDeviceExtensions( + uint32_t adapterId); + + /** + * \brief Initializes instance extension set + * + * Should be called before creating + * the first Vulkan instance. + */ + void initInstanceExtensions(); + + /** + * \brief Initializes device extension sets + * + * Should be called after setting + * up the Vulkan physical devices. + * \param [in] instance DXVK instance + */ + void initDeviceExtensions( + const DxvkInstance* instance); + }; + + extern DxvkPlatformExts g_platformInstance; + +} \ No newline at end of file diff --git a/src/dxvk/meson.build b/src/dxvk/meson.build index 67118b08..8b14592b 100644 --- a/src/dxvk/meson.build +++ b/src/dxvk/meson.build @@ -98,6 +98,9 @@ dxvk_src = files([ 'dxvk_stats.cpp', 'dxvk_unbound.cpp', 'dxvk_util.cpp', + 'dxvk_extension_provider.cpp', + + 'platform/dxvk_win32_exts.cpp', 'hud/dxvk_hud.cpp', 'hud/dxvk_hud_config.cpp', diff --git a/src/dxvk/platform/dxvk_win32_exts.cpp b/src/dxvk/platform/dxvk_win32_exts.cpp new file mode 100644 index 00000000..706a1083 --- /dev/null +++ b/src/dxvk/platform/dxvk_win32_exts.cpp @@ -0,0 +1,34 @@ +#include "../dxvk_platform_exts.h" + +namespace dxvk { + + + std::string_view DxvkPlatformExts::getName() { + return "Win32 WSI"; + } + + + DxvkNameSet DxvkPlatformExts::getInstanceExtensions() { + DxvkNameSet names; + names.add(VK_KHR_WIN32_SURFACE_EXTENSION_NAME); + + return names; + } + + + DxvkNameSet DxvkPlatformExts::getDeviceExtensions( + uint32_t adapterId) { + return DxvkNameSet(); + } + + + void DxvkPlatformExts::initInstanceExtensions() {} + + + void DxvkPlatformExts::initDeviceExtensions( + const DxvkInstance* instance) {} + + + DxvkPlatformExts g_platformInstance; + +} \ No newline at end of file