2020-12-30 14:03:40 +00:00
# include "openxrswapchainimage.hpp"
# include "openxrmanagerimpl.hpp"
# include "openxrplatform.hpp"
# include "vrenvironment.hpp"
// The OpenXR SDK's platform headers assume we've included platform headers
# ifdef _WIN32
# include <Windows.h>
# include <objbase.h>
# ifdef XR_USE_GRAPHICS_API_D3D11
# include <d3d11_1.h>
# endif
# elif __linux__
# include <X11/Xlib.h>
# include <GL/glx.h>
# undef None
# else
# error Unsupported platform
# endif
# include <openxr/openxr.h>
# include <openxr/openxr_platform.h>
# include <openxr/openxr_platform_defines.h>
# include <openxr/openxr_reflection.h>
# include <stdexcept>
# include <deque>
2021-01-01 18:50:52 +00:00
# include <cassert>
2020-12-30 14:03:40 +00:00
namespace MWVR
{
XrResult CheckXrResult ( XrResult res , const char * originator , const char * sourceLocation ) {
static bool initialized = false ;
static bool sLogAllXrCalls = false ;
static bool sContinueOnErrors = false ;
if ( ! initialized )
{
initialized = true ;
sLogAllXrCalls = Settings : : Manager : : getBool ( " log all openxr calls " , " VR Debug " ) ;
sContinueOnErrors = Settings : : Manager : : getBool ( " continue on errors " , " VR Debug " ) ;
}
auto resultString = XrResultString ( res ) ;
if ( XR_FAILED ( res ) ) {
std : : stringstream ss ;
# ifdef _WIN32
ss < < sourceLocation < < " : OpenXR[Error: " < < resultString < < " ][Thread: " < < std : : this_thread : : get_id ( ) < < " ]: " < < originator ;
# elif __linux__
ss < < sourceLocation < < " : OpenXR[Error: " < < resultString < < " ][Thread: " < < std : : this_thread : : get_id ( ) < < " ]: " < < originator ;
# endif
Log ( Debug : : Error ) < < ss . str ( ) ;
if ( res = = XR_ERROR_TIME_INVALID )
Log ( Debug : : Error ) < < " Breakpoint " ;
if ( ! sContinueOnErrors )
throw std : : runtime_error ( ss . str ( ) . c_str ( ) ) ;
}
else if ( res ! = XR_SUCCESS | | sLogAllXrCalls )
{
# ifdef _WIN32
Log ( Debug : : Verbose ) < < sourceLocation < < " : OpenXR[ " < < resultString < < " ][ " < < std : : this_thread : : get_id ( ) < < " ]: " < < originator ;
# elif __linux__
Log ( Debug : : Verbose ) < < sourceLocation < < " : OpenXR[ " < < resultString < < " ][ " < < std : : this_thread : : get_id ( ) < < " ]: " < < originator ;
# endif
}
return res ;
}
void OpenXRPlatform : : enumerateExtensions ( const char * layerName , int logIndent )
{
uint32_t extensionCount = 0 ;
std : : vector < XrExtensionProperties > availableExtensions ;
xrEnumerateInstanceExtensionProperties ( layerName , 0 , & extensionCount , nullptr ) ;
availableExtensions . resize ( extensionCount , XrExtensionProperties { XR_TYPE_EXTENSION_PROPERTIES } ) ;
xrEnumerateInstanceExtensionProperties ( layerName , availableExtensions . size ( ) , & extensionCount , availableExtensions . data ( ) ) ;
std : : vector < std : : string > extensionNames ;
const std : : string indentStr ( logIndent , ' ' ) ;
for ( auto & extension : availableExtensions )
{
if ( layerName )
mAvailableLayerExtensions [ layerName ] [ extension . extensionName ] = extension ;
else
mAvailableExtensions [ extension . extensionName ] = extension ;
Log ( Debug : : Verbose ) < < indentStr < < " Name= " < < extension . extensionName < < " SpecVersion= " < < extension . extensionVersion ;
}
}
struct OpenXRPlatformPrivate
{
OpenXRPlatformPrivate ( osg : : GraphicsContext * gc ) ;
~ OpenXRPlatformPrivate ( ) ;
# ifdef XR_USE_GRAPHICS_API_D3D11
typedef BOOL ( WINAPI * P_wglDXSetResourceShareHandleNV ) ( void * dxObject , HANDLE shareHandle ) ;
typedef HANDLE ( WINAPI * P_wglDXOpenDeviceNV ) ( void * dxDevice ) ;
typedef BOOL ( WINAPI * P_wglDXCloseDeviceNV ) ( HANDLE hDevice ) ;
typedef HANDLE ( WINAPI * P_wglDXRegisterObjectNV ) ( HANDLE hDevice , void * dxObject ,
GLuint name , GLenum type , GLenum access ) ;
typedef BOOL ( WINAPI * P_wglDXUnregisterObjectNV ) ( HANDLE hDevice , HANDLE hObject ) ;
typedef BOOL ( WINAPI * P_wglDXObjectAccessNV ) ( HANDLE hObject , GLenum access ) ;
typedef BOOL ( WINAPI * P_wglDXLockObjectsNV ) ( HANDLE hDevice , GLint count , HANDLE * hObjects ) ;
typedef BOOL ( WINAPI * P_wglDXUnlockObjectsNV ) ( HANDLE hDevice , GLint count , HANDLE * hObjects ) ;
void initializeD3D11 ( XrGraphicsRequirementsD3D11KHR requirements )
{
mD3D11Dll = LoadLibrary ( " D3D11.dll " ) ;
if ( ! mD3D11Dll )
throw std : : runtime_error ( " Current OpenXR runtime requires DirectX >= 11.0 but D3D11.dll was not found. " ) ;
pD3D11CreateDevice = reinterpret_cast < PFN_D3D11_CREATE_DEVICE > ( GetProcAddress ( mD3D11Dll , " D3D11CreateDevice " ) ) ;
if ( ! pD3D11CreateDevice )
throw std : : runtime_error ( " Symbol 'D3D11CreateDevice' not found in D3D11.dll " ) ;
// Create the device and device context objects
pD3D11CreateDevice (
nullptr ,
D3D_DRIVER_TYPE_HARDWARE ,
nullptr ,
0 ,
nullptr ,
0 ,
D3D11_SDK_VERSION ,
& mD3D11Device ,
nullptr ,
& mD3D11ImmediateContext ) ;
mD3D11bindings . device = mD3D11Device ;
//typedef HANDLE (WINAPI* P_wglDXOpenDeviceNV)(void* dxDevice);
//P_wglDXOpenDeviceNV wglDXOpenDeviceNV = reinterpret_cast<P_wglDXOpenDeviceNV>(wglGetProcAddress("wglDXOpenDeviceNV"));
//P_wglDXOpenDeviceNV wglDXOpenDeviceNV = reinterpret_cast<P_wglDXOpenDeviceNV>(wglGetProcAddress("wglDXOpenDeviceNV"));
# define LOAD_WGL(a) a = reinterpret_cast<decltype(a)>(wglGetProcAddress(#a)); if(!a) throw std::runtime_error("Extension WGL_NV_DX_interop2 required to run OpenMW VR via DirectX missing expected symbol '" #a "'.")
LOAD_WGL ( wglDXSetResourceShareHandleNV ) ;
LOAD_WGL ( wglDXOpenDeviceNV ) ;
LOAD_WGL ( wglDXCloseDeviceNV ) ;
LOAD_WGL ( wglDXRegisterObjectNV ) ;
LOAD_WGL ( wglDXUnregisterObjectNV ) ;
LOAD_WGL ( wglDXObjectAccessNV ) ;
LOAD_WGL ( wglDXLockObjectsNV ) ;
LOAD_WGL ( wglDXUnlockObjectsNV ) ;
# undef LOAD_WGL
wglDXDevice = wglDXOpenDeviceNV ( mD3D11Device ) ;
}
bool mWGL_NV_DX_interop2 = false ;
XrGraphicsBindingD3D11KHR mD3D11bindings { XR_TYPE_GRAPHICS_BINDING_D3D11_KHR } ;
ID3D11Device * mD3D11Device = nullptr ;
ID3D11DeviceContext * mD3D11ImmediateContext = nullptr ;
HMODULE mD3D11Dll = nullptr ;
PFN_D3D11_CREATE_DEVICE pD3D11CreateDevice = nullptr ;
P_wglDXSetResourceShareHandleNV wglDXSetResourceShareHandleNV = nullptr ;
P_wglDXOpenDeviceNV wglDXOpenDeviceNV = nullptr ;
P_wglDXCloseDeviceNV wglDXCloseDeviceNV = nullptr ;
P_wglDXRegisterObjectNV wglDXRegisterObjectNV = nullptr ;
P_wglDXUnregisterObjectNV wglDXUnregisterObjectNV = nullptr ;
P_wglDXObjectAccessNV wglDXObjectAccessNV = nullptr ;
P_wglDXLockObjectsNV wglDXLockObjectsNV = nullptr ;
P_wglDXUnlockObjectsNV wglDXUnlockObjectsNV = nullptr ;
HANDLE wglDXDevice = nullptr ;
# endif
} ;
OpenXRPlatformPrivate : : OpenXRPlatformPrivate ( osg : : GraphicsContext * gc )
{
# ifdef XR_USE_GRAPHICS_API_D3D11
typedef const char * ( WINAPI * PFNWGLGETEXTENSIONSSTRINGARBPROC ) ( HDC hdc ) ;
PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB = 0 ;
wglGetExtensionsStringARB = reinterpret_cast < PFNWGLGETEXTENSIONSSTRINGARBPROC > ( wglGetProcAddress ( " wglGetExtensionsStringARB " ) ) ;
if ( wglGetExtensionsStringARB )
{
std : : string wglExtensions = wglGetExtensionsStringARB ( wglGetCurrentDC ( ) ) ;
Log ( Debug : : Verbose ) < < " WGL Extensions: " < < wglExtensions ;
mWGL_NV_DX_interop2 = wglExtensions . find ( " WGL_NV_DX_interop2 " ) ! = std : : string : : npos ;
}
else
Log ( Debug : : Verbose ) < < " Unable to query WGL extensions " ;
# endif
}
OpenXRPlatformPrivate : : ~ OpenXRPlatformPrivate ( )
{
# ifdef XR_USE_GRAPHICS_API_D3D11
if ( wglDXDevice )
wglDXCloseDeviceNV ( wglDXDevice ) ;
if ( mD3D11ImmediateContext )
mD3D11ImmediateContext - > Release ( ) ;
if ( mD3D11Device )
mD3D11Device - > Release ( ) ;
if ( mD3D11Dll )
FreeLibrary ( mD3D11Dll ) ;
# endif
}
OpenXRPlatform : : OpenXRPlatform ( osg : : GraphicsContext * gc )
: mPrivate ( new OpenXRPlatformPrivate ( gc ) )
{
// Enumerate layers and their extensions.
uint32_t layerCount ;
CHECK_XRCMD ( xrEnumerateApiLayerProperties ( 0 , & layerCount , nullptr ) ) ;
std : : vector < XrApiLayerProperties > layers ( layerCount , XrApiLayerProperties { XR_TYPE_API_LAYER_PROPERTIES } ) ;
CHECK_XRCMD ( xrEnumerateApiLayerProperties ( ( uint32_t ) layers . size ( ) , & layerCount , layers . data ( ) ) ) ;
Log ( Debug : : Verbose ) < < " Available Extensions: " ;
enumerateExtensions ( nullptr , 2 ) ;
Log ( Debug : : Verbose ) < < " Available Layers: " ;
if ( layers . size ( ) = = 0 )
{
Log ( Debug : : Verbose ) < < " No layers available " ;
}
for ( const XrApiLayerProperties & layer : layers ) {
Log ( Debug : : Verbose ) < < " Name= " < < layer . layerName < < " SpecVersion= " < < layer . layerVersion ;
mAvailableLayers [ layer . layerName ] = layer ;
enumerateExtensions ( layer . layerName , 4 ) ;
}
setupExtensions ( ) ;
}
OpenXRPlatform : : ~ OpenXRPlatform ( )
{
}
# if !XR_KHR_composition_layer_depth \
| | ! XR_EXT_hp_mixed_reality_controller \
| | ! XR_EXT_debug_utils \
| | ! XR_HTC_vive_cosmos_controller_interaction \
| | ! XR_HUAWEI_controller_interaction
# error "OpenXR extensions missing. Please upgrade your copy of the OpenXR SDK to 1.0.13 minimum"
# endif
void OpenXRPlatform : : setupExtensions ( )
{
std : : vector < const char * > optionalExtensions = {
XR_KHR_COMPOSITION_LAYER_DEPTH_EXTENSION_NAME ,
XR_EXT_HP_MIXED_REALITY_CONTROLLER_EXTENSION_NAME ,
XR_HTC_VIVE_COSMOS_CONTROLLER_INTERACTION_EXTENSION_NAME ,
XR_HUAWEI_CONTROLLER_INTERACTION_EXTENSION_NAME
} ;
if ( Settings : : Manager : : getBool ( " enable XR_EXT_debug_utils " , " VR Debug " ) )
optionalExtensions . emplace_back ( XR_EXT_DEBUG_UTILS_EXTENSION_NAME ) ;
selectGraphicsAPIExtension ( ) ;
Log ( Debug : : Verbose ) < < " Using extensions: " ;
auto * graphicsAPIExtension = graphicsAPIExtensionName ( ) ;
if ( ! graphicsAPIExtension | | ! enableExtension ( graphicsAPIExtension , true ) )
{
throw std : : runtime_error ( " No graphics APIs supported by openmw are supported by the OpenXR runtime. " ) ;
}
for ( auto optionalExtension : optionalExtensions )
enableExtension ( optionalExtension , true ) ;
}
bool OpenXRPlatform : : selectDirectX ( )
{
# ifdef XR_USE_GRAPHICS_API_D3D11
if ( mPrivate - > mWGL_NV_DX_interop2 )
{
if ( mAvailableExtensions . count ( XR_KHR_D3D11_ENABLE_EXTENSION_NAME ) )
{
mGraphicsAPIExtension = XR_KHR_D3D11_ENABLE_EXTENSION_NAME ;
return true ;
}
else
Log ( Debug : : Warning ) < < " Warning: Failed to select DirectX swapchains: OpenXR runtime does not support essential extension ' " < < XR_KHR_D3D11_ENABLE_EXTENSION_NAME < < " ' " ;
}
else
Log ( Debug : : Warning ) < < " Warning: Failed to select DirectX swapchains: Essential WGL extension 'WGL_NV_DX_interop2' not supported by the graphics driver. " ;
# endif
return false ;
}
bool OpenXRPlatform : : selectOpenGL ( )
{
# ifdef XR_USE_GRAPHICS_API_OPENGL
if ( mAvailableExtensions . count ( XR_KHR_OPENGL_ENABLE_EXTENSION_NAME ) )
{
mGraphicsAPIExtension = XR_KHR_OPENGL_ENABLE_EXTENSION_NAME ;
return true ;
}
else
Log ( Debug : : Warning ) < < " Warning: Failed to select OpenGL swapchains: OpenXR runtime does not support essential extension ' " < < XR_KHR_OPENGL_ENABLE_EXTENSION_NAME < < " ' " ;
# endif
return false ;
}
# ifdef XR_USE_GRAPHICS_API_OPENGL
# if !XR_KHR_opengl_enable
# error "OpenXR extensions missing. Please upgrade your copy of the OpenXR SDK to 1.0.13 minimum"
# endif
# endif
# ifdef XR_USE_GRAPHICS_API_D3D11
# if !XR_KHR_D3D11_enable
# error "OpenXR extensions missing. Please upgrade your copy of the OpenXR SDK to 1.0.13 minimum"
# endif
# endif
const char * OpenXRPlatform : : graphicsAPIExtensionName ( )
{
return mGraphicsAPIExtension ;
}
void OpenXRPlatform : : selectGraphicsAPIExtension ( )
{
bool preferDirectX = Settings : : Manager : : getBool ( " Prefer DirectX swapchains " , " VR " ) ;
if ( preferDirectX )
if ( selectDirectX ( ) | | selectOpenGL ( ) )
return ;
if ( selectOpenGL ( ) | | selectDirectX ( ) )
return ;
Log ( Debug : : Verbose ) < < " Error: No graphics API supported by OpenMW VR is supported by the OpenXR runtime. " ;
throw std : : runtime_error ( " Error: No graphics API supported by OpenMW VR is supported by the OpenXR runtime. " ) ;
}
bool OpenXRPlatform : : supportsExtension ( const std : : string & extensionName ) const
{
return mAvailableExtensions . count ( extensionName ) > 0 ;
}
bool OpenXRPlatform : : supportsExtension ( const std : : string & extensionName , uint32_t minimumVersion ) const
{
auto it = mAvailableExtensions . find ( extensionName ) ;
return it ! = mAvailableExtensions . end ( ) & & it - > second . extensionVersion > minimumVersion ;
}
bool OpenXRPlatform : : supportsLayer ( const std : : string & layerName ) const
{
return mAvailableLayers . count ( layerName ) > 0 ;
}
bool OpenXRPlatform : : supportsLayer ( const std : : string & layerName , uint32_t minimumVersion ) const
{
auto it = mAvailableLayers . find ( layerName ) ;
return it ! = mAvailableLayers . end ( ) & & it - > second . layerVersion > minimumVersion ;
}
bool OpenXRPlatform : : enableExtension ( const std : : string & extensionName , bool optional )
{
auto it = mAvailableExtensions . find ( extensionName ) ;
if ( it ! = mAvailableExtensions . end ( ) )
{
Log ( Debug : : Verbose ) < < " " < < extensionName < < " : enabled " ;
mEnabledExtensions . push_back ( it - > second . extensionName ) ;
return true ;
}
else
{
Log ( Debug : : Verbose ) < < " " < < extensionName < < " : disabled (not supported) " ;
if ( ! optional )
{
throw std : : runtime_error ( std : : string ( " Required OpenXR extension " ) + extensionName + " not supported by the runtime " ) ;
}
return false ;
}
}
bool OpenXRPlatform : : enableExtension ( const std : : string & extensionName , bool optional , uint32_t minimumVersion )
{
auto it = mAvailableExtensions . find ( extensionName ) ;
if ( it ! = mAvailableExtensions . end ( ) & & it - > second . extensionVersion > minimumVersion )
{
Log ( Debug : : Verbose ) < < " " < < extensionName < < " : enabled " ;
mEnabledExtensions . push_back ( it - > second . extensionName ) ;
return true ;
}
else
{
Log ( Debug : : Verbose ) < < " " < < extensionName < < " : disabled (not supported) " ;
if ( ! optional )
{
throw std : : runtime_error ( std : : string ( " Required OpenXR extension " ) + extensionName + " not supported by the runtime " ) ;
}
return false ;
}
}
bool OpenXRPlatform : : extensionEnabled ( const std : : string & extensionName ) const
{
for ( auto * extension : mEnabledExtensions )
if ( extension = = extensionName )
return true ;
return false ;
}
XrInstance OpenXRPlatform : : createXrInstance ( const std : : string & name )
{
XrInstance instance = XR_NULL_HANDLE ;
XrInstanceCreateInfo createInfo { XR_TYPE_INSTANCE_CREATE_INFO } ;
createInfo . next = nullptr ;
createInfo . enabledExtensionCount = mEnabledExtensions . size ( ) ;
createInfo . enabledExtensionNames = mEnabledExtensions . data ( ) ;
strcpy ( createInfo . applicationInfo . applicationName , " openmw_vr " ) ;
createInfo . applicationInfo . apiVersion = XR_CURRENT_API_VERSION ;
CHECK_XRCMD ( xrCreateInstance ( & createInfo , & instance ) ) ;
return instance ;
}
XrSession OpenXRPlatform : : createXrSession ( XrInstance instance , XrSystemId systemId )
{
XrSession session = XR_NULL_HANDLE ;
# ifdef _WIN32
std : : string graphicsAPIExtension = graphicsAPIExtensionName ( ) ;
if ( graphicsAPIExtension = = XR_KHR_OPENGL_ENABLE_EXTENSION_NAME )
{
// Get system requirements
PFN_xrGetOpenGLGraphicsRequirementsKHR p_getRequirements = nullptr ;
xrGetInstanceProcAddr ( instance , " xrGetOpenGLGraphicsRequirementsKHR " , reinterpret_cast < PFN_xrVoidFunction * > ( & p_getRequirements ) ) ;
XrGraphicsRequirementsOpenGLKHR requirements { XR_TYPE_GRAPHICS_REQUIREMENTS_OPENGL_KHR } ;
CHECK_XRCMD ( p_getRequirements ( instance , systemId , & requirements ) ) ;
// TODO: Actually get system version
const XrVersion systemApiVersion = XR_MAKE_VERSION ( 4 , 6 , 0 ) ;
if ( requirements . minApiVersionSupported > systemApiVersion ) {
std : : cout < < " Runtime does not support desired Graphics API and/or version " < < std : : endl ;
}
// Create Session
auto DC = wglGetCurrentDC ( ) ;
auto GLRC = wglGetCurrentContext ( ) ;
XrGraphicsBindingOpenGLWin32KHR graphicsBindings ;
graphicsBindings . type = XR_TYPE_GRAPHICS_BINDING_OPENGL_WIN32_KHR ;
graphicsBindings . next = nullptr ;
graphicsBindings . hDC = DC ;
graphicsBindings . hGLRC = GLRC ;
if ( ! graphicsBindings . hDC )
Log ( Debug : : Warning ) < < " Missing DC " ;
XrSessionCreateInfo createInfo { XR_TYPE_SESSION_CREATE_INFO } ;
createInfo . next = & graphicsBindings ;
createInfo . systemId = systemId ;
CHECK_XRCMD ( xrCreateSession ( instance , & createInfo , & session ) ) ;
}
# ifdef XR_USE_GRAPHICS_API_D3D11
else if ( graphicsAPIExtension = = XR_KHR_D3D11_ENABLE_EXTENSION_NAME )
{
PFN_xrGetD3D11GraphicsRequirementsKHR p_getRequirements = nullptr ;
xrGetInstanceProcAddr ( instance , " xrGetD3D11GraphicsRequirementsKHR " , reinterpret_cast < PFN_xrVoidFunction * > ( & p_getRequirements ) ) ;
XrGraphicsRequirementsD3D11KHR requirements { XR_TYPE_GRAPHICS_REQUIREMENTS_D3D11_KHR } ;
CHECK_XRCMD ( p_getRequirements ( instance , systemId , & requirements ) ) ;
mPrivate - > initializeD3D11 ( requirements ) ;
XrSessionCreateInfo createInfo { XR_TYPE_SESSION_CREATE_INFO } ;
createInfo . next = & mPrivate - > mD3D11bindings ;
createInfo . systemId = systemId ;
CHECK_XRCMD ( xrCreateSession ( instance , & createInfo , & session ) ) ;
}
# endif
else
{
throw std : : logic_error ( " Enum value not implemented " ) ;
}
# elif __linux__
{ // Create Session
Display * xDisplay = XOpenDisplay ( NULL ) ;
GLXContext glxContext = glXGetCurrentContext ( ) ;
GLXDrawable glxDrawable = glXGetCurrentDrawable ( ) ;
// TODO: runtimes don't actually care (yet)
GLXFBConfig glxFBConfig = 0 ;
uint32_t visualid = 0 ;
XrGraphicsBindingOpenGLXlibKHR graphicsBindings ;
graphicsBindings . type = XR_TYPE_GRAPHICS_BINDING_OPENGL_XLIB_KHR ;
graphicsBindings . next = nullptr ;
graphicsBindings . xDisplay = xDisplay ;
graphicsBindings . glxContext = glxContext ;
graphicsBindings . glxDrawable = glxDrawable ;
graphicsBindings . glxFBConfig = glxFBConfig ;
graphicsBindings . visualid = visualid ;
if ( ! graphicsBindings . glxContext )
Log ( Debug : : Warning ) < < " Missing glxContext " ;
if ( ! graphicsBindings . glxDrawable )
Log ( Debug : : Warning ) < < " Missing glxDrawable " ;
XrSessionCreateInfo createInfo { XR_TYPE_SESSION_CREATE_INFO } ;
createInfo . next = & graphicsBindings ;
createInfo . systemId = systemId ;
CHECK_XRCMD ( xrCreateSession ( instance , & createInfo , & session ) ) ;
}
# endif
2021-01-01 18:50:52 +00:00
assert ( session ) ;
2020-12-30 14:03:40 +00:00
uint32_t swapchainFormatCount ;
CHECK_XRCMD ( xrEnumerateSwapchainFormats ( session , 0 , & swapchainFormatCount , nullptr ) ) ;
mSwapchainFormats . resize ( swapchainFormatCount ) ;
CHECK_XRCMD ( xrEnumerateSwapchainFormats ( session , ( uint32_t ) mSwapchainFormats . size ( ) , & swapchainFormatCount , mSwapchainFormats . data ( ) ) ) ;
std : : stringstream ss ;
ss < < " Available Swapchain formats: ( " < < swapchainFormatCount < < " ) " < < std : : endl ;
for ( auto format : mSwapchainFormats )
{
ss < < " Enum= " < < std : : dec < < format < < " (0x= " < < std : : hex < < format < < " ) " < < std : : dec < < std : : endl ;
}
Log ( Debug : : Verbose ) < < ss . str ( ) ;
return session ;
}
/*
* For reference : These are the DXGI formats offered by WMR when using D3D11 :
Enum = 29 //(0x=1d) DXGI_FORMAT_R8G8B8A8_UNORM_SRGB
Enum = 91 //(0x=5b) DXGI_FORMAT_B8G8R8A8_UNORM_SRGB
Enum = 28 //(0x=1c) DXGI_FORMAT_R8G8B8A8_UNORM
Enum = 87 //(0x=57) DXGI_FORMAT_B8G8R8A8_UNORM
Enum = 40 //(0x=28) DXGI_FORMAT_D32_FLOAT
Enum = 20 //(0x=14) DXGI_FORMAT_D32_FLOAT_S8X24_UINT
Enum = 45 //(0x=2d) DXGI_FORMAT_D24_UNORM_S8_UINT
Enum = 55 //(0x=37) DXGI_FORMAT_D16_UNORM
* And these extra formats are offered by SteamVR :
0xa , // DXGI_FORMAT_R16G16B16A16_FLOAT
0x18 , // DXGI_FORMAT_R10G10B10A2_UNORM
*/
int64_t OpenXRPlatform : : selectColorFormat ( )
{
std : : string graphicsAPIExtension = graphicsAPIExtensionName ( ) ;
if ( graphicsAPIExtension = = XR_KHR_OPENGL_ENABLE_EXTENSION_NAME )
{
// Find supported color swapchain format.
std : : vector < int64_t > requestedColorSwapchainFormats = {
0x8058 , // GL_RGBA8
0x8F97 , // GL_RGBA8_SNORM
0x881A , // GL_RGBA16F
0x881B , // GL_RGB16F
// Offered by SteamVR but is broken: // 0x805B, // GL_RGBA16
0x8C3A , // GL_R11F_G11F_B10F
// Don't need srgb: 0x8C43, // GL_SRGB8_ALPHA8
// Don't need srgb: 0x8C41, // GL_SRGB8
} ;
return selectFormat ( requestedColorSwapchainFormats ) ;
}
# ifdef XR_USE_GRAPHICS_API_D3D11
else if ( graphicsAPIExtension = = XR_KHR_D3D11_ENABLE_EXTENSION_NAME )
{
// Find supported color swapchain format.
std : : vector < int64_t > requestedColorSwapchainFormats = {
0x1c , // DXGI_FORMAT_R8G8B8A8_UNORM
0x57 , // DXGI_FORMAT_B8G8R8A8_UNORM
0xa , // DXGI_FORMAT_R16G16B16A16_FLOAT
0x18 , // DXGI_FORMAT_R10G10B10A2_UNORM
// Don't need srgb: 0x1d, // DXGI_FORMAT_R8G8B8A8_UNORM_SRGB
// Don't need srgb: 0x5b, // DXGI_FORMAT_B8G8R8A8_UNORM_SRGB
} ;
return selectFormat ( requestedColorSwapchainFormats ) ;
}
# endif
else
{
throw std : : logic_error ( " Enum value not implemented " ) ;
}
}
int64_t OpenXRPlatform : : selectDepthFormat ( )
{
std : : string graphicsAPIExtension = graphicsAPIExtensionName ( ) ;
if ( graphicsAPIExtension = = XR_KHR_OPENGL_ENABLE_EXTENSION_NAME )
{
// Find supported depth swapchain format.
std : : vector < int64_t > requestedDepthSwapchainFormats = {
0x88F0 , // GL_DEPTH24_STENCIL8
0x8CAC , // GL_DEPTH_COMPONENT32F
0x81A7 , // GL_DEPTH_COMPONENT32
0x8DAB , // GL_DEPTH_COMPONENT32F_NV
0x8CAD , // GL_DEPTH32_STENCIL8
0x81A6 , // GL_DEPTH_COMPONENT24
// Need 32bit minimum: // 0x81A5, // GL_DEPTH_COMPONENT16
} ;
return selectFormat ( requestedDepthSwapchainFormats ) ;
}
# ifdef XR_USE_GRAPHICS_API_D3D11
else if ( graphicsAPIExtension = = XR_KHR_D3D11_ENABLE_EXTENSION_NAME )
{
// Find supported color swapchain format.
std : : vector < int64_t > requestedDepthSwapchainFormats = {
0x2d , // DXGI_FORMAT_D24_UNORM_S8_UINT
0x14 , // DXGI_FORMAT_D32_FLOAT_S8X24_UINT
0x28 , // DXGI_FORMAT_D32_FLOAT
// Need 32bit minimum: 0x37, // DXGI_FORMAT_D16_UNORM
} ;
return selectFormat ( requestedDepthSwapchainFormats ) ;
}
# endif
else
{
throw std : : logic_error ( " Enum value not implemented " ) ;
}
}
int64_t OpenXRPlatform : : selectFormat ( const std : : vector < int64_t > & requestedFormats )
{
auto it =
std : : find_first_of ( std : : begin ( requestedFormats ) , std : : end ( requestedFormats ) ,
mSwapchainFormats . begin ( ) , mSwapchainFormats . end ( ) ) ;
if ( it = = std : : end ( requestedFormats ) )
{
return 0 ;
}
return * it ;
}
void * OpenXRPlatform : : DXRegisterObject ( void * dxResource , uint32_t glName , uint32_t glType , bool discard , void * ntShareHandle )
{
# ifdef XR_USE_GRAPHICS_API_D3D11
if ( ntShareHandle )
{
mPrivate - > wglDXSetResourceShareHandleNV ( dxResource , ntShareHandle ) ;
}
return mPrivate - > wglDXRegisterObjectNV ( mPrivate - > wglDXDevice , dxResource , glName , glType , 1 ) ;
# else
return nullptr ;
# endif
}
void OpenXRPlatform : : DXUnregisterObject ( void * dxResourceShareHandle )
{
# ifdef XR_USE_GRAPHICS_API_D3D11
mPrivate - > wglDXUnregisterObjectNV ( mPrivate - > wglDXDevice , dxResourceShareHandle ) ;
# endif
}
void OpenXRPlatform : : DXLockObject ( void * dxResourceShareHandle )
{
# ifdef XR_USE_GRAPHICS_API_D3D11
mPrivate - > wglDXLockObjectsNV ( mPrivate - > wglDXDevice , 1 , & dxResourceShareHandle ) ;
# endif
}
void OpenXRPlatform : : DXUnlockObject ( void * dxResourceShareHandle )
{
# ifdef XR_USE_GRAPHICS_API_D3D11
mPrivate - > wglDXUnlockObjectsNV ( mPrivate - > wglDXDevice , 1 , & dxResourceShareHandle ) ;
# endif
}
}