mirror of
https://github.com/EduApps-CDG/OpenDX
synced 2024-12-30 09:45:37 +01:00
[dxvk] Use wineopenxr to apply required OpenXR extensions
This commit is contained in:
parent
a3065fca8e
commit
2405e474e5
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include "dxvk_instance.h"
|
#include "dxvk_instance.h"
|
||||||
#include "dxvk_openvr.h"
|
#include "dxvk_openvr.h"
|
||||||
|
#include "dxvk_openxr.h"
|
||||||
#include "dxvk_platform_exts.h"
|
#include "dxvk_platform_exts.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
@ -23,6 +24,9 @@ namespace dxvk {
|
|||||||
if (m_options.enableOpenVR)
|
if (m_options.enableOpenVR)
|
||||||
m_extProviders.push_back(&VrInstance::s_instance);
|
m_extProviders.push_back(&VrInstance::s_instance);
|
||||||
|
|
||||||
|
if (m_options.enableOpenXR)
|
||||||
|
m_extProviders.push_back(&DxvkXrProvider::s_instance);
|
||||||
|
|
||||||
Logger::info("Built-in extension providers:");
|
Logger::info("Built-in extension providers:");
|
||||||
for (const auto& provider : m_extProviders)
|
for (const auto& provider : m_extProviders)
|
||||||
Logger::info(str::format(" ", provider->getName()));
|
Logger::info(str::format(" ", provider->getName()));
|
||||||
|
168
src/dxvk/dxvk_openxr.cpp
Normal file
168
src/dxvk/dxvk_openxr.cpp
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
#include "dxvk_instance.h"
|
||||||
|
#include "dxvk_openxr.h"
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
using PFN___wineopenxr_GetVulkanInstanceExtensions = int (WINAPI *)(uint32_t, uint32_t *, char *);
|
||||||
|
using PFN___wineopenxr_GetVulkanDeviceExtensions = int (WINAPI *)(uint32_t, uint32_t *, char *);
|
||||||
|
|
||||||
|
namespace dxvk {
|
||||||
|
|
||||||
|
struct WineXrFunctions {
|
||||||
|
PFN___wineopenxr_GetVulkanInstanceExtensions __wineopenxr_GetVulkanInstanceExtensions = nullptr;
|
||||||
|
PFN___wineopenxr_GetVulkanDeviceExtensions __wineopenxr_GetVulkanDeviceExtensions = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
WineXrFunctions g_winexrFunctions;
|
||||||
|
DxvkXrProvider DxvkXrProvider::s_instance;
|
||||||
|
|
||||||
|
DxvkXrProvider:: DxvkXrProvider() { }
|
||||||
|
|
||||||
|
DxvkXrProvider::~DxvkXrProvider() { }
|
||||||
|
|
||||||
|
|
||||||
|
std::string_view DxvkXrProvider::getName() {
|
||||||
|
return "OpenXR";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DxvkNameSet DxvkXrProvider::getInstanceExtensions() {
|
||||||
|
std::lock_guard<std::mutex> lock(m_mutex);
|
||||||
|
return m_insExtensions;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DxvkNameSet DxvkXrProvider::getDeviceExtensions(uint32_t adapterId) {
|
||||||
|
std::lock_guard<std::mutex> lock(m_mutex);
|
||||||
|
return m_devExtensions;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DxvkXrProvider::initInstanceExtensions() {
|
||||||
|
std::lock_guard<std::mutex> lock(m_mutex);
|
||||||
|
|
||||||
|
if (!m_wineOxr)
|
||||||
|
m_wineOxr = this->loadLibrary();
|
||||||
|
|
||||||
|
if (!m_wineOxr || m_initializedInsExt)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!this->loadFunctions()) {
|
||||||
|
this->shutdown();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_insExtensions = this->queryInstanceExtensions();
|
||||||
|
m_initializedInsExt = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool DxvkXrProvider::loadFunctions() {
|
||||||
|
g_winexrFunctions.__wineopenxr_GetVulkanInstanceExtensions =
|
||||||
|
reinterpret_cast<PFN___wineopenxr_GetVulkanInstanceExtensions>(this->getSym("__wineopenxr_GetVulkanInstanceExtensions"));
|
||||||
|
g_winexrFunctions.__wineopenxr_GetVulkanDeviceExtensions =
|
||||||
|
reinterpret_cast<PFN___wineopenxr_GetVulkanDeviceExtensions>(this->getSym("__wineopenxr_GetVulkanDeviceExtensions"));
|
||||||
|
return g_winexrFunctions.__wineopenxr_GetVulkanInstanceExtensions != nullptr
|
||||||
|
&& g_winexrFunctions.__wineopenxr_GetVulkanDeviceExtensions != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DxvkXrProvider::initDeviceExtensions(const DxvkInstance* instance) {
|
||||||
|
std::lock_guard<std::mutex> lock(m_mutex);
|
||||||
|
|
||||||
|
if (!m_wineOxr || m_initializedDevExt)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_devExtensions = this->queryDeviceExtensions();
|
||||||
|
m_initializedDevExt = true;
|
||||||
|
|
||||||
|
this->shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DxvkNameSet DxvkXrProvider::queryInstanceExtensions() const {
|
||||||
|
int res;
|
||||||
|
uint32_t len;
|
||||||
|
|
||||||
|
res = g_winexrFunctions.__wineopenxr_GetVulkanInstanceExtensions(0, &len, nullptr);
|
||||||
|
if (res != 0) {
|
||||||
|
Logger::warn("OpenXR: Unable to get required Vulkan instance extensions size");
|
||||||
|
return DxvkNameSet();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<char> extensionList(len);
|
||||||
|
res = g_winexrFunctions.__wineopenxr_GetVulkanInstanceExtensions(len, &len, &extensionList[0]);
|
||||||
|
if (res != 0) {
|
||||||
|
Logger::warn("OpenXR: Unable to get required Vulkan instance extensions");
|
||||||
|
return DxvkNameSet();
|
||||||
|
}
|
||||||
|
|
||||||
|
return parseExtensionList(std::string(extensionList.data(), len));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DxvkNameSet DxvkXrProvider::queryDeviceExtensions() const {
|
||||||
|
int res;
|
||||||
|
|
||||||
|
uint32_t len;
|
||||||
|
res = g_winexrFunctions.__wineopenxr_GetVulkanDeviceExtensions(0, &len, nullptr);
|
||||||
|
if (res != 0) {
|
||||||
|
Logger::warn("OpenXR: Unable to get required Vulkan Device extensions size");
|
||||||
|
return DxvkNameSet();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<char> extensionList(len);
|
||||||
|
res = g_winexrFunctions.__wineopenxr_GetVulkanDeviceExtensions(len, &len, &extensionList[0]);
|
||||||
|
if (res != 0) {
|
||||||
|
Logger::warn("OpenXR: Unable to get required Vulkan Device extensions");
|
||||||
|
return DxvkNameSet();
|
||||||
|
}
|
||||||
|
|
||||||
|
return parseExtensionList(std::string(extensionList.data(), len));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DxvkNameSet DxvkXrProvider::parseExtensionList(const std::string& str) const {
|
||||||
|
DxvkNameSet result;
|
||||||
|
|
||||||
|
std::stringstream strstream(str);
|
||||||
|
std::string section;
|
||||||
|
|
||||||
|
while (std::getline(strstream, section, ' '))
|
||||||
|
result.add(section.c_str());
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DxvkXrProvider::shutdown() {
|
||||||
|
if (m_loadedOxrApi)
|
||||||
|
this->freeLibrary();
|
||||||
|
|
||||||
|
m_loadedOxrApi = false;
|
||||||
|
m_wineOxr = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SoHandle DxvkXrProvider::loadLibrary() {
|
||||||
|
SoHandle handle = nullptr;
|
||||||
|
if (!(handle = ::GetModuleHandle("wineopenxr.dll"))) {
|
||||||
|
handle = ::LoadLibrary("wineopenxr.dll");
|
||||||
|
m_loadedOxrApi = handle != nullptr;
|
||||||
|
}
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DxvkXrProvider::freeLibrary() {
|
||||||
|
::FreeLibrary(m_wineOxr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void* DxvkXrProvider::getSym(const char* sym) {
|
||||||
|
return reinterpret_cast<void*>(
|
||||||
|
::GetProcAddress(m_wineOxr, sym));
|
||||||
|
}
|
||||||
|
}
|
75
src/dxvk/dxvk_openxr.h
Normal file
75
src/dxvk/dxvk_openxr.h
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <mutex>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "dxvk_extension_provider.h"
|
||||||
|
|
||||||
|
#ifdef __WINE__
|
||||||
|
using SoHandle = void*;
|
||||||
|
#else
|
||||||
|
using SoHandle = HMODULE;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace dxvk {
|
||||||
|
|
||||||
|
class DxvkInstance;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief OpenXR instance
|
||||||
|
*
|
||||||
|
* Loads OpenXR to provide access to Vulkan extension queries.
|
||||||
|
*/
|
||||||
|
class DxvkXrProvider : public DxvkExtensionProvider {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
DxvkXrProvider();
|
||||||
|
~DxvkXrProvider();
|
||||||
|
|
||||||
|
std::string_view getName();
|
||||||
|
|
||||||
|
DxvkNameSet getInstanceExtensions();
|
||||||
|
|
||||||
|
DxvkNameSet getDeviceExtensions(
|
||||||
|
uint32_t adapterId);
|
||||||
|
|
||||||
|
void initInstanceExtensions();
|
||||||
|
|
||||||
|
void initDeviceExtensions(
|
||||||
|
const DxvkInstance* instance);
|
||||||
|
|
||||||
|
static DxvkXrProvider s_instance;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
std::mutex m_mutex;
|
||||||
|
SoHandle m_wineOxr = nullptr;
|
||||||
|
|
||||||
|
bool m_loadedOxrApi = false;
|
||||||
|
bool m_initializedInsExt = false;
|
||||||
|
bool m_initializedDevExt = false;
|
||||||
|
|
||||||
|
DxvkNameSet m_insExtensions;
|
||||||
|
DxvkNameSet m_devExtensions;
|
||||||
|
|
||||||
|
DxvkNameSet queryInstanceExtensions() const;
|
||||||
|
|
||||||
|
DxvkNameSet queryDeviceExtensions() const;
|
||||||
|
|
||||||
|
DxvkNameSet parseExtensionList(
|
||||||
|
const std::string& str) const;
|
||||||
|
|
||||||
|
bool loadFunctions();
|
||||||
|
|
||||||
|
void shutdown();
|
||||||
|
|
||||||
|
SoHandle loadLibrary();
|
||||||
|
|
||||||
|
void freeLibrary();
|
||||||
|
|
||||||
|
void* getSym(const char* sym);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
@ -5,6 +5,7 @@ namespace dxvk {
|
|||||||
DxvkOptions::DxvkOptions(const Config& config) {
|
DxvkOptions::DxvkOptions(const Config& config) {
|
||||||
enableStateCache = config.getOption<bool> ("dxvk.enableStateCache", true);
|
enableStateCache = config.getOption<bool> ("dxvk.enableStateCache", true);
|
||||||
enableOpenVR = config.getOption<bool> ("dxvk.enableOpenVR", true);
|
enableOpenVR = config.getOption<bool> ("dxvk.enableOpenVR", true);
|
||||||
|
enableOpenXR = config.getOption<bool> ("dxvk.enableOpenXR", true);
|
||||||
numCompilerThreads = config.getOption<int32_t> ("dxvk.numCompilerThreads", 0);
|
numCompilerThreads = config.getOption<int32_t> ("dxvk.numCompilerThreads", 0);
|
||||||
useRawSsbo = config.getOption<Tristate>("dxvk.useRawSsbo", Tristate::Auto);
|
useRawSsbo = config.getOption<Tristate>("dxvk.useRawSsbo", Tristate::Auto);
|
||||||
useEarlyDiscard = config.getOption<Tristate>("dxvk.useEarlyDiscard", Tristate::Auto);
|
useEarlyDiscard = config.getOption<Tristate>("dxvk.useEarlyDiscard", Tristate::Auto);
|
||||||
|
@ -14,6 +14,9 @@ namespace dxvk {
|
|||||||
/// Enables OpenVR loading
|
/// Enables OpenVR loading
|
||||||
bool enableOpenVR;
|
bool enableOpenVR;
|
||||||
|
|
||||||
|
/// Enables OpenXR loading
|
||||||
|
bool enableOpenXR;
|
||||||
|
|
||||||
/// Number of compiler threads
|
/// Number of compiler threads
|
||||||
/// when using the state cache
|
/// when using the state cache
|
||||||
int32_t numCompilerThreads;
|
int32_t numCompilerThreads;
|
||||||
|
@ -81,6 +81,7 @@ dxvk_src = files([
|
|||||||
'dxvk_meta_pack.cpp',
|
'dxvk_meta_pack.cpp',
|
||||||
'dxvk_meta_resolve.cpp',
|
'dxvk_meta_resolve.cpp',
|
||||||
'dxvk_openvr.cpp',
|
'dxvk_openvr.cpp',
|
||||||
|
'dxvk_openxr.cpp',
|
||||||
'dxvk_options.cpp',
|
'dxvk_options.cpp',
|
||||||
'dxvk_pipecache.cpp',
|
'dxvk_pipecache.cpp',
|
||||||
'dxvk_pipelayout.cpp',
|
'dxvk_pipelayout.cpp',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user