1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-04-01 19:36:42 +00:00

Make use of the layer depth extension

This commit is contained in:
Mads Buvik Sandvei 2020-07-15 23:17:16 +02:00
parent bb16d66e02
commit 47b7837d7c
6 changed files with 107 additions and 19 deletions

View file

@ -111,6 +111,11 @@ namespace MWVR
return impl().getRecommendedSwapchainConfig(); return impl().getRecommendedSwapchainConfig();
} }
bool OpenXRManager::xrExtensionIsEnabled(const char* extensionName) const
{
return impl().xrExtensionIsEnabled(extensionName);
}
void void
OpenXRManager::CleanupOperation::operator()( OpenXRManager::CleanupOperation::operator()(
osg::GraphicsContext* gc) osg::GraphicsContext* gc)

View file

@ -83,6 +83,9 @@ namespace MWVR
//! Configuration hints for instantiating swapchains, queried from openxr. //! Configuration hints for instantiating swapchains, queried from openxr.
std::array<SwapchainConfig, 2> getRecommendedSwapchainConfig() const; std::array<SwapchainConfig, 2> getRecommendedSwapchainConfig() const;
//! Check whether a given openxr extension is enabled or not
bool xrExtensionIsEnabled(const char* extensionName) const;
OpenXRManagerImpl& impl() { return *mPrivate; } OpenXRManagerImpl& impl() { return *mPrivate; }
const OpenXRManagerImpl& impl() const { return *mPrivate; } const OpenXRManagerImpl& impl() const { return *mPrivate; }

View file

@ -5,13 +5,16 @@
#include <components/debug/debuglog.hpp> #include <components/debug/debuglog.hpp>
#include <components/sdlutil/sdlgraphicswindow.hpp> #include <components/sdlutil/sdlgraphicswindow.hpp>
#include <components/esm/loadrace.hpp>
#include "../mwmechanics/actorutil.hpp" #include "../mwmechanics/actorutil.hpp"
#include "../mwbase/world.hpp" #include "../mwbase/world.hpp"
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwworld/class.hpp" #include "../mwworld/class.hpp"
#include "../mwworld/player.hpp" #include "../mwworld/player.hpp"
#include "../mwworld/esmstore.hpp" #include "../mwworld/esmstore.hpp"
#include <components/esm/loadrace.hpp>
// The OpenXR SDK assumes we've included Windows.h // The OpenXR SDK assumes we've included Windows.h
#include <Windows.h> #include <Windows.h>
@ -45,13 +48,18 @@ MAKE_TO_STRING_FUNC(XrResult);
MAKE_TO_STRING_FUNC(XrFormFactor); MAKE_TO_STRING_FUNC(XrFormFactor);
MAKE_TO_STRING_FUNC(XrStructureType); MAKE_TO_STRING_FUNC(XrStructureType);
#if !XR_KHR_composition_layer_depth || !XR_KHR_opengl_enable
#error "OpenXR extensions missing. Please upgrade your copy of the OpenXR SDK"
#endif
namespace MWVR namespace MWVR
{ {
OpenXRManagerImpl::OpenXRManagerImpl() OpenXRManagerImpl::OpenXRManagerImpl()
{ {
std::vector<const char*> extensions = { std::vector<const char*> extensions = {
XR_KHR_OPENGL_ENABLE_EXTENSION_NAME XR_KHR_OPENGL_ENABLE_EXTENSION_NAME,
XR_KHR_COMPOSITION_LAYER_DEPTH_EXTENSION_NAME,
}; };
{ // Create Instance { // Create Instance
@ -59,13 +67,57 @@ namespace MWVR
createInfo.next = nullptr; createInfo.next = nullptr;
createInfo.enabledExtensionCount = extensions.size(); createInfo.enabledExtensionCount = extensions.size();
createInfo.enabledExtensionNames = extensions.data(); createInfo.enabledExtensionNames = extensions.data();
strcpy(createInfo.applicationInfo.applicationName, "openmw_vr"); strcpy(createInfo.applicationInfo.applicationName, "openmw_vr");
createInfo.applicationInfo.apiVersion = XR_CURRENT_API_VERSION; createInfo.applicationInfo.apiVersion = XR_CURRENT_API_VERSION;
CHECK_XRCMD(xrCreateInstance(&createInfo, &mInstance)); // Iteratively strip extensions until instance creation succeeds.
XrResult result = xrCreateInstance(&createInfo, &mInstance);
while (result == XR_ERROR_EXTENSION_NOT_PRESENT)
{
createInfo.enabledExtensionCount--;
result = xrCreateInstance(&createInfo, &mInstance);
}
mEnabledExtensions.insert(extensions.begin(), extensions.end() + createInfo.enabledExtensionCount);
if (!xrExtensionIsEnabled(XR_KHR_OPENGL_ENABLE_EXTENSION_NAME))
throw std::runtime_error(std::string("Required OpenXR extension ") + XR_KHR_OPENGL_ENABLE_EXTENSION_NAME + " not supported");
Log(Debug::Verbose) << "OpenXR Extension status:";
for (auto* ext : extensions)
{
if (!xrExtensionIsEnabled(ext))
{
Log(Debug::Verbose) << " " << ext << ": disabled (not supported)";
}
else
{
Log(Debug::Verbose) << " " << ext << ": enabled";
}
}
assert(mInstance); assert(mInstance);
} }
{
// Layer depth is enabled, cache the invariant values
if (xrExtensionIsEnabled(XR_KHR_COMPOSITION_LAYER_DEPTH_EXTENSION_NAME))
{
GLfloat depthRange[2] = { 0.f, 1.f };
glGetFloatv(GL_DEPTH_RANGE, depthRange);
auto nearClip = Settings::Manager::getFloat("near clip", "Camera");
for (auto& layer : mLayerDepth)
{
layer.type = XR_TYPE_COMPOSITION_LAYER_DEPTH_INFO_KHR;
layer.next = nullptr;
layer.minDepth = depthRange[0];
layer.maxDepth = depthRange[1];
layer.nearZ = nearClip;
}
}
}
{ // Get system ID { // Get system ID
XrSystemGetInfo systemInfo{ XR_TYPE_SYSTEM_GET_INFO }; XrSystemGetInfo systemInfo{ XR_TYPE_SYSTEM_GET_INFO };
systemInfo.formFactor = mFormFactor = XR_FORM_FACTOR_HEAD_MOUNTED_DISPLAY; systemInfo.formFactor = mFormFactor = XR_FORM_FACTOR_HEAD_MOUNTED_DISPLAY;
@ -321,6 +373,18 @@ namespace MWVR
layer.views = compositionLayerProjectionViews.data(); layer.views = compositionLayerProjectionViews.data();
auto* xrLayerStack = reinterpret_cast<XrCompositionLayerBaseHeader*>(&layer); auto* xrLayerStack = reinterpret_cast<XrCompositionLayerBaseHeader*>(&layer);
std::array<XrCompositionLayerDepthInfoKHR, 2> compositionLayerDepth = mLayerDepth;
if (xrExtensionIsEnabled(XR_KHR_COMPOSITION_LAYER_DEPTH_EXTENSION_NAME))
{
auto farClip = Settings::Manager::getFloat("viewing distance", "Camera");
compositionLayerDepth[(int)Side::LEFT_SIDE].farZ = farClip;
compositionLayerDepth[(int)Side::RIGHT_SIDE].farZ = farClip;
compositionLayerDepth[(int)Side::LEFT_SIDE].subImage = layerStack[(int)Side::LEFT_SIDE].swapchain->impl().xrSubImageDepth();
compositionLayerDepth[(int)Side::RIGHT_SIDE].subImage = layerStack[(int)Side::RIGHT_SIDE].swapchain->impl().xrSubImageDepth();
compositionLayerProjectionViews[(int)Side::LEFT_SIDE].next = &compositionLayerDepth[(int)Side::LEFT_SIDE];
compositionLayerProjectionViews[(int)Side::RIGHT_SIDE].next = &compositionLayerDepth[(int)Side::RIGHT_SIDE];
}
XrFrameEndInfo frameEndInfo{ XR_TYPE_FRAME_END_INFO }; XrFrameEndInfo frameEndInfo{ XR_TYPE_FRAME_END_INFO };
frameEndInfo.displayTime = displayTime; frameEndInfo.displayTime = displayTime;
frameEndInfo.environmentBlendMode = mEnvironmentBlendMode; frameEndInfo.environmentBlendMode = mEnvironmentBlendMode;
@ -513,6 +577,11 @@ namespace MWVR
return referenceSpace; return referenceSpace;
} }
bool OpenXRManagerImpl::xrExtensionIsEnabled(const char* extensionName) const
{
return mEnabledExtensions.count(extensionName) != 0;
}
void OpenXRManagerImpl::enablePredictions() void OpenXRManagerImpl::enablePredictions()
{ {
mPredictionsEnabled = true; mPredictionsEnabled = true;

View file

@ -69,6 +69,7 @@ namespace MWVR
XrSpace getReferenceSpace(ReferenceSpace space); XrSpace getReferenceSpace(ReferenceSpace space);
XrSession xrSession() const { return mSession; }; XrSession xrSession() const { return mSession; };
XrInstance xrInstance() const { return mInstance; }; XrInstance xrInstance() const { return mInstance; };
bool xrExtensionIsEnabled(const char* extensionName) const;
protected: protected:
void LogLayersAndExtensions(); void LogLayersAndExtensions();
@ -78,6 +79,7 @@ namespace MWVR
void HandleSessionStateChanged(const XrEventDataSessionStateChanged& stateChangedEvent); void HandleSessionStateChanged(const XrEventDataSessionStateChanged& stateChangedEvent);
private: private:
bool initialized = false; bool initialized = false;
bool mPredictionsEnabled = false; bool mPredictionsEnabled = false;
XrInstance mInstance = XR_NULL_HANDLE; XrInstance mInstance = XR_NULL_HANDLE;
@ -98,6 +100,9 @@ namespace MWVR
bool mSessionRunning = false; bool mSessionRunning = false;
std::mutex mFrameStateMutex{}; std::mutex mFrameStateMutex{};
std::mutex mEventMutex{}; std::mutex mEventMutex{};
std::set<const char*> mEnabledExtensions;
std::array<XrCompositionLayerDepthInfoKHR, 2> mLayerDepth;
}; };
} }

View file

@ -91,7 +91,7 @@ namespace MWVR {
// Now create the swapchain of depth buffers. // Now create the swapchain of depth buffers.
swapchainCreateInfo.format = mSwapchainDepthFormat; swapchainCreateInfo.format = mSwapchainDepthFormat;
swapchainCreateInfo.usageFlags = XR_SWAPCHAIN_USAGE_SAMPLED_BIT | XR_SWAPCHAIN_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; swapchainCreateInfo.usageFlags = XR_SWAPCHAIN_USAGE_SAMPLED_BIT | XR_SWAPCHAIN_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
res = xrCreateSwapchain(xr->impl().xrSession(), &swapchainCreateInfo, &mDepthSwapchain); res = xrCreateSwapchain(xr->impl().xrSession(), &swapchainCreateInfo, &mSwapchainDepth);
if (XR_SUCCEEDED(res)) if (XR_SUCCEEDED(res))
break; break;
else else
@ -100,19 +100,22 @@ namespace MWVR {
uint32_t imageCount = 0; uint32_t imageCount = 0;
CHECK_XRCMD(xrEnumerateSwapchainImages(mSwapchain, 0, &imageCount, nullptr)); CHECK_XRCMD(xrEnumerateSwapchainImages(mSwapchain, 0, &imageCount, nullptr));
mSwapchainImageBuffers.resize(imageCount, { XR_TYPE_SWAPCHAIN_IMAGE_OPENGL_KHR }); mSwapchainColorBuffers.resize(imageCount, { XR_TYPE_SWAPCHAIN_IMAGE_OPENGL_KHR });
CHECK_XRCMD(xrEnumerateSwapchainImages(mSwapchain, imageCount, &imageCount, reinterpret_cast<XrSwapchainImageBaseHeader*>(mSwapchainImageBuffers.data()))); CHECK_XRCMD(xrEnumerateSwapchainImages(mSwapchain, imageCount, &imageCount, reinterpret_cast<XrSwapchainImageBaseHeader*>(mSwapchainColorBuffers.data())));
CHECK_XRCMD(xrEnumerateSwapchainImages(mDepthSwapchain, 0, &imageCount, nullptr)); CHECK_XRCMD(xrEnumerateSwapchainImages(mSwapchainDepth, 0, &imageCount, nullptr));
mDepthSwapchainImageBuffers.resize(imageCount, { XR_TYPE_SWAPCHAIN_IMAGE_OPENGL_KHR }); mSwapchainDepthBuffers.resize(imageCount, { XR_TYPE_SWAPCHAIN_IMAGE_OPENGL_KHR });
CHECK_XRCMD(xrEnumerateSwapchainImages(mDepthSwapchain, imageCount, &imageCount, reinterpret_cast<XrSwapchainImageBaseHeader*>(mDepthSwapchainImageBuffers.data()))); CHECK_XRCMD(xrEnumerateSwapchainImages(mSwapchainDepth, imageCount, &imageCount, reinterpret_cast<XrSwapchainImageBaseHeader*>(mSwapchainDepthBuffers.data())));
for (unsigned i = 0; i < imageCount; i++) for (unsigned i = 0; i < imageCount; i++)
mRenderBuffers.emplace_back(new VRFramebuffer(state, mWidth, mHeight, mSamples, mSwapchainImageBuffers[i].image, mDepthSwapchainImageBuffers[i].image)); mRenderBuffers.emplace_back(new VRFramebuffer(state, mWidth, mHeight, mSamples, mSwapchainColorBuffers[i].image, mSwapchainDepthBuffers[i].image));
mSubImage.swapchain = mSwapchain; mSubImage.swapchain = mSwapchain;
mSubImage.imageRect.offset = { 0, 0 }; mSubImage.imageRect.offset = { 0, 0 };
mSubImage.imageRect.extent = { mWidth, mHeight }; mSubImage.imageRect.extent = { mWidth, mHeight };
mSubImageDepth.swapchain = mSwapchainDepth;
mSubImageDepth.imageRect.offset = { 0, 0 };
mSubImageDepth.imageRect.extent = { mWidth, mHeight };
} }
OpenXRSwapchainImpl::~OpenXRSwapchainImpl() OpenXRSwapchainImpl::~OpenXRSwapchainImpl()
@ -130,13 +133,13 @@ namespace MWVR {
uint32_t OpenXRSwapchainImpl::acquiredColorTexture() const uint32_t OpenXRSwapchainImpl::acquiredColorTexture() const
{ {
checkAcquired(); checkAcquired();
return mSwapchainImageBuffers[mAcquiredImageIndex].image; return mSwapchainColorBuffers[mAcquiredImageIndex].image;
} }
uint32_t OpenXRSwapchainImpl::acquiredDepthTexture() const uint32_t OpenXRSwapchainImpl::acquiredDepthTexture() const
{ {
checkAcquired(); checkAcquired();
return mSwapchainImageBuffers[mAcquiredImageIndex].image; return mSwapchainColorBuffers[mAcquiredImageIndex].image;
} }
bool OpenXRSwapchainImpl::isAcquired() const bool OpenXRSwapchainImpl::isAcquired() const
@ -167,14 +170,14 @@ namespace MWVR {
// If some dumb ass implementation decides to violate this we'll just have to work around that if it actually happens. // If some dumb ass implementation decides to violate this we'll just have to work around that if it actually happens.
CHECK_XRCMD(xrAcquireSwapchainImage(mSwapchain, &acquireInfo, &mAcquiredImageIndex)); CHECK_XRCMD(xrAcquireSwapchainImage(mSwapchain, &acquireInfo, &mAcquiredImageIndex));
uint32_t depthIndex = 0; uint32_t depthIndex = 0;
CHECK_XRCMD(xrAcquireSwapchainImage(mDepthSwapchain, &acquireInfo, &depthIndex)); CHECK_XRCMD(xrAcquireSwapchainImage(mSwapchainDepth, &acquireInfo, &depthIndex));
if (depthIndex != mAcquiredImageIndex) if (depthIndex != mAcquiredImageIndex)
Log(Debug::Warning) << "Depth and color indices diverged"; Log(Debug::Warning) << "Depth and color indices diverged";
XrSwapchainImageWaitInfo waitInfo{ XR_TYPE_SWAPCHAIN_IMAGE_WAIT_INFO }; XrSwapchainImageWaitInfo waitInfo{ XR_TYPE_SWAPCHAIN_IMAGE_WAIT_INFO };
waitInfo.timeout = XR_INFINITE_DURATION; waitInfo.timeout = XR_INFINITE_DURATION;
CHECK_XRCMD(xrWaitSwapchainImage(mSwapchain, &waitInfo)); CHECK_XRCMD(xrWaitSwapchainImage(mSwapchain, &waitInfo));
CHECK_XRCMD(xrWaitSwapchainImage(mDepthSwapchain, &waitInfo)); CHECK_XRCMD(xrWaitSwapchainImage(mSwapchainDepth, &waitInfo));
mIsAcquired = true; mIsAcquired = true;
} }
@ -185,7 +188,7 @@ namespace MWVR {
XrSwapchainImageReleaseInfo releaseInfo{ XR_TYPE_SWAPCHAIN_IMAGE_RELEASE_INFO }; XrSwapchainImageReleaseInfo releaseInfo{ XR_TYPE_SWAPCHAIN_IMAGE_RELEASE_INFO };
CHECK_XRCMD(xrReleaseSwapchainImage(mSwapchain, &releaseInfo)); CHECK_XRCMD(xrReleaseSwapchainImage(mSwapchain, &releaseInfo));
CHECK_XRCMD(xrReleaseSwapchainImage(mDepthSwapchain, &releaseInfo)); CHECK_XRCMD(xrReleaseSwapchainImage(mSwapchainDepth, &releaseInfo));
} }
void OpenXRSwapchainImpl::checkAcquired() const void OpenXRSwapchainImpl::checkAcquired() const
{ {

View file

@ -24,7 +24,9 @@ namespace MWVR
bool isAcquired() const; bool isAcquired() const;
XrSwapchain xrSwapchain(void) const { return mSwapchain; }; XrSwapchain xrSwapchain(void) const { return mSwapchain; };
XrSwapchain xrSwapchainDepth(void) const { return mSwapchainDepth; };
XrSwapchainSubImage xrSubImage(void) const { return mSubImage; }; XrSwapchainSubImage xrSubImage(void) const { return mSubImage; };
XrSwapchainSubImage xrSubImageDepth(void) const { return mSubImageDepth; };
int width() const { return mWidth; }; int width() const { return mWidth; };
int height() const { return mHeight; }; int height() const { return mHeight; };
int samples() const { return mSamples; }; int samples() const { return mSamples; };
@ -39,10 +41,11 @@ namespace MWVR
private: private:
XrSwapchain mSwapchain = XR_NULL_HANDLE; XrSwapchain mSwapchain = XR_NULL_HANDLE;
XrSwapchain mDepthSwapchain = XR_NULL_HANDLE; XrSwapchain mSwapchainDepth = XR_NULL_HANDLE;
std::vector<XrSwapchainImageOpenGLKHR> mSwapchainImageBuffers{}; std::vector<XrSwapchainImageOpenGLKHR> mSwapchainColorBuffers{};
std::vector<XrSwapchainImageOpenGLKHR> mDepthSwapchainImageBuffers{}; std::vector<XrSwapchainImageOpenGLKHR> mSwapchainDepthBuffers{};
XrSwapchainSubImage mSubImage{}; XrSwapchainSubImage mSubImage{};
XrSwapchainSubImage mSubImageDepth{};
int32_t mWidth = -1; int32_t mWidth = -1;
int32_t mHeight = -1; int32_t mHeight = -1;
int32_t mSamples = -1; int32_t mSamples = -1;