From 707967ac1dbfaa2594001325c8e7be1dd149fad8 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Fri, 18 May 2018 16:46:34 +0200 Subject: [PATCH] [vr] Add OpenVR loader Provides methods to query required Vulkan instance and device extensions. --- src/dxvk/dxvk_openvr.cpp | 87 ++++++++++++++++++++++++++++++++++++++++ src/dxvk/dxvk_openvr.h | 48 ++++++++++++++++++++++ src/dxvk/meson.build | 1 + 3 files changed, 136 insertions(+) create mode 100644 src/dxvk/dxvk_openvr.cpp create mode 100644 src/dxvk/dxvk_openvr.h diff --git a/src/dxvk/dxvk_openvr.cpp b/src/dxvk/dxvk_openvr.cpp new file mode 100644 index 00000000..73812839 --- /dev/null +++ b/src/dxvk/dxvk_openvr.cpp @@ -0,0 +1,87 @@ +#include "dxvk_openvr.h" + +#include + +namespace dxvk { + + VrInstance::VrInstance() + : m_compositor(getCompositor()) { + + } + + + VrInstance::~VrInstance() { + + } + + + vk::NameSet VrInstance::queryInstanceExtensions() const { + if (m_compositor != nullptr) { + uint32_t len = m_compositor->GetVulkanInstanceExtensionsRequired(nullptr, 0); + std::vector extensionList(len); + len = m_compositor->GetVulkanInstanceExtensionsRequired(extensionList.data(), len); + return parseExtensionList(std::string(extensionList.data(), len)); + } return vk::NameSet(); + } + + + vk::NameSet VrInstance::queryDeviceExtensions(VkPhysicalDevice adapter) const { + if (m_compositor != nullptr) { + uint32_t len = m_compositor->GetVulkanDeviceExtensionsRequired(adapter, nullptr, 0); + std::vector extensionList(len); + len = m_compositor->GetVulkanDeviceExtensionsRequired(adapter, extensionList.data(), len); + return parseExtensionList(std::string(extensionList.data(), len)); + } return vk::NameSet(); + } + + + vk::NameSet VrInstance::parseExtensionList(const std::string& str) { + vk::NameSet result; + + std::stringstream strstream(str); + std::string section; + + while (std::getline(strstream, section, ' ')) + result.add(section); + + return result; + } + + + vr::IVRCompositor* VrInstance::getCompositor() { + using GetGenericInterfaceProc = + void* VR_CALLTYPE (*)(const char*, vr::EVRInitError*); + + // Locate the OpenVR DLL if loaded by the process + HMODULE ovrApi = ::GetModuleHandle("openvr_api.dll"); + + if (ovrApi == nullptr) { + Logger::warn("OpenVR: Failed to locate module"); + return nullptr; + } + + // Load method used to retrieve the IVRCompositor interface + auto vrGetGenericInterface = reinterpret_cast( + ::GetProcAddress(ovrApi, "VR_GetGenericInterface")); + + if (vrGetGenericInterface == nullptr) { + Logger::warn("OpenVR: VR_GetGenericInterface not found"); + return nullptr; + } + + // Retrieve the compositor interface + vr::EVRInitError error = vr::VRInitError_None; + + auto compositor = reinterpret_cast( + vrGetGenericInterface(vr::IVRCompositor_Version, &error)); + + if (error != vr::VRInitError_None) { + Logger::warn(str::format("OpenVR: Failed to retrieve ", vr::IVRCompositor_Version)); + return nullptr; + } + + Logger::warn("OpenVR: Compositor interface found"); + return compositor; + } + +} \ No newline at end of file diff --git a/src/dxvk/dxvk_openvr.h b/src/dxvk/dxvk_openvr.h new file mode 100644 index 00000000..acb61f81 --- /dev/null +++ b/src/dxvk/dxvk_openvr.h @@ -0,0 +1,48 @@ +#pragma once + +#include "dxvk_include.h" + +namespace vr { + class IVRCompositor; +} + +namespace dxvk { + + /** + * \brief OpenVR instance + * + * Loads Initializes OpenVR to provide + * access to Vulkan extension queries. + */ + class VrInstance { + + public: + + VrInstance(); + ~VrInstance(); + + /** + * \brief Queries required instance extensions + * \returns Set of required instance extensions + */ + vk::NameSet queryInstanceExtensions() const; + + /** + * \brief Queries required device extensions + * + * \param [in] adapter The Vulkan device to query + * \returns Set of required device extensions + */ + vk::NameSet queryDeviceExtensions(VkPhysicalDevice adapter) const; + + private: + + vr::IVRCompositor* m_compositor = nullptr; + + static vk::NameSet parseExtensionList(const std::string& str); + + static vr::IVRCompositor* getCompositor(); + + }; + +} \ No newline at end of file diff --git a/src/dxvk/meson.build b/src/dxvk/meson.build index 1c563df9..02bf5cf9 100644 --- a/src/dxvk/meson.build +++ b/src/dxvk/meson.build @@ -42,6 +42,7 @@ dxvk_src = files([ 'dxvk_memory.cpp', 'dxvk_meta_clear.cpp', 'dxvk_meta_resolve.cpp', + 'dxvk_openvr.cpp', 'dxvk_pipecache.cpp', 'dxvk_pipecompiler.cpp', 'dxvk_pipelayout.cpp',