1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-02-18 04:54:15 +01:00

[dxvk] Implement extension provider system

This change introduces a new system for providing extra instance/device extensions.

This consolidates platform-specific and vr-related to its' own thing for potential future cross-platform/native Linux work.
This commit is contained in:
Joshua Ashton 2019-11-05 04:45:28 +00:00 committed by Philip Rebohle
parent 27898ebbfc
commit dbf2407fd3
10 changed files with 219 additions and 12 deletions

View File

@ -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;
}
}

View File

@ -0,0 +1,78 @@
#pragma once
#include "dxvk_include.h"
#include "dxvk_extensions.h"
#include <vector>
#include <string>
namespace dxvk {
class DxvkInstance;
class DxvkExtensionProvider;
using DxvkExtensionProviderList = std::vector<DxvkExtensionProvider*>;
/**
* \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;
};
}

View File

@ -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 };
};
}

View File

@ -1,7 +1,7 @@
#include <version.h>
#include "dxvk_instance.h"
#include "dxvk_openvr.h"
#include "dxvk_extension_provider.h"
#include <algorithm>
@ -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<DxvkExt*, 3> insExtensionList = {{
std::array<DxvkExt*, 2> 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:");

View File

@ -5,7 +5,6 @@
#include "dxvk_adapter.h"
#include "dxvk_device.h"
#include "dxvk_device_filter.h"
#include "dxvk_openvr.h"
namespace dxvk {

View File

@ -36,6 +36,11 @@ namespace dxvk {
VrInstance:: VrInstance() { }
VrInstance::~VrInstance() { }
std::string_view VrInstance::getName() {
return "OpenVR";
}
DxvkNameSet VrInstance::getInstanceExtensions() {

View File

@ -3,7 +3,7 @@
#include <mutex>
#include <vector>
#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

View File

@ -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;
}

View File

@ -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',

View File

@ -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;
}