[vr] Add OpenVR loader

Provides methods to query required Vulkan instance and device extensions.
This commit is contained in:
Philip Rebohle 2018-05-18 16:46:34 +02:00
parent 14beaaf8d4
commit 707967ac1d
No known key found for this signature in database
GPG Key ID: C8CC613427A31C99
3 changed files with 136 additions and 0 deletions

87
src/dxvk/dxvk_openvr.cpp Normal file
View File

@ -0,0 +1,87 @@
#include "dxvk_openvr.h"
#include <openvr/openvr.hpp>
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<char> 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<char> 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<GetGenericInterfaceProc>(
::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<vr::IVRCompositor*>(
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;
}
}

48
src/dxvk/dxvk_openvr.h Normal file
View File

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

View File

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