OpenXR - Add passthrough option (Quest only)

This commit is contained in:
Lubos 2023-06-17 16:33:21 +02:00
parent 6d4e5a0f3e
commit 4642e0a66f
6 changed files with 72 additions and 3 deletions

View file

@ -162,6 +162,7 @@ void InitVROnAndroid(void* vm, void* activity, const char* system, int version,
} else if ((strcmp(vendor, "META") == 0) || (strcmp(vendor, "OCULUS") == 0)) {
VR_SetPlatformFLag(VR_PLATFORM_CONTROLLER_QUEST, true);
VR_SetPlatformFLag(VR_PLATFORM_EXTENSION_FOVEATION, true);
VR_SetPlatformFLag(VR_PLATFORM_EXTENSION_PASSTHROUGH, true);
VR_SetPlatformFLag(VR_PLATFORM_EXTENSION_PERFORMANCE, true);
}
VR_SetPlatformFLag(VR_PLATFORM_RENDERER_VULKAN, (GPUBackend)g_Config.iGPUBackend == GPUBackend::VULKAN);
@ -792,6 +793,7 @@ bool StartVRRender() {
// Set customizations
__DisplaySetFramerate(g_Config.bForce72Hz ? 72 : 60);
VR_SetConfigFloat(VR_CONFIG_CANVAS_DISTANCE, g_Config.fCanvasDistance);
VR_SetConfig(VR_CONFIG_PASSTHROUGH, g_Config.bPassthrough);
vrMirroring[VR_MIRRORING_UPDATED] = false;
return true;
}
@ -828,6 +830,10 @@ bool IsMultiviewSupported() {
return false;
}
bool IsPassthroughSupported() {
return VR_GetPlatformFlag(VR_PLATFORM_EXTENSION_PASSTHROUGH);
}
bool IsFlatVRGame() {
return vrFlatGame;
}

View file

@ -51,6 +51,7 @@ void PostVRFrameRender();
int GetVRFBOIndex();
int GetVRPassesCount();
bool IsMultiviewSupported();
bool IsPassthroughSupported();
bool IsFlatVRGame();
bool IsFlatVRScene();
bool IsGameVRScene();

View file

@ -61,6 +61,9 @@ void VR_Init( void* system, const char* name, int version ) {
if (VR_GetPlatformFlag(VR_PLATFORM_EXTENSION_INSTANCE)) {
extensions.push_back(XR_KHR_ANDROID_CREATE_INSTANCE_EXTENSION_NAME);
}
if (VR_GetPlatformFlag(VR_PLATFORM_EXTENSION_PASSTHROUGH)) {
extensions.push_back(XR_FB_PASSTHROUGH_EXTENSION_NAME);
}
if (VR_GetPlatformFlag(VR_PLATFORM_EXTENSION_PERFORMANCE)) {
extensions.push_back(XR_EXT_PERFORMANCE_SETTINGS_EXTENSION_NAME);
extensions.push_back(XR_KHR_ANDROID_THREAD_SETTINGS_EXTENSION_NAME);

View file

@ -42,12 +42,16 @@ static void OXR_CheckErrors(XrInstance instance, XrResult result, const char* fu
#define OXR(func) func;
#endif
enum { ovrMaxLayerCount = 2 };
#define DECL_PFN(pfn) PFN_##pfn pfn = nullptr
#define INIT_PFN(pfn) OXR(xrGetInstanceProcAddr(engine->appState.Instance, #pfn, (PFN_xrVoidFunction*)(&pfn)))
enum { ovrMaxLayerCount = 3 };
enum { ovrMaxNumEyes = 2 };
typedef union {
XrCompositionLayerProjection Projection;
XrCompositionLayerCylinderKHR Cylinder;
XrCompositionLayerPassthroughFB Passthrough;
} ovrCompositorLayer_Union;
typedef struct {
@ -122,6 +126,7 @@ enum VRPlatformFlag {
VR_PLATFORM_CONTROLLER_QUEST,
VR_PLATFORM_EXTENSION_FOVEATION,
VR_PLATFORM_EXTENSION_INSTANCE,
VR_PLATFORM_EXTENSION_PASSTHROUGH,
VR_PLATFORM_EXTENSION_PERFORMANCE,
VR_PLATFORM_RENDERER_VULKAN,
VR_PLATFORM_TRACKING_FLOOR,

View file

@ -20,6 +20,17 @@ float vrConfigFloat[VR_CONFIG_FLOAT_MAX] = {};
XrVector3f hmdorientation;
XrPassthroughFB passthrough = XR_NULL_HANDLE;
XrPassthroughLayerFB passthroughLayer = XR_NULL_HANDLE;
DECL_PFN(xrCreatePassthroughFB);
DECL_PFN(xrDestroyPassthroughFB);
DECL_PFN(xrPassthroughStartFB);
DECL_PFN(xrPassthroughPauseFB);
DECL_PFN(xrCreatePassthroughLayerFB);
DECL_PFN(xrDestroyPassthroughLayerFB);
DECL_PFN(xrPassthroughLayerPauseFB);
DECL_PFN(xrPassthroughLayerResumeFB);
void VR_UpdateStageBounds(ovrApp* pappState) {
XrExtent2Df stageBounds = {};
@ -179,6 +190,17 @@ void VR_InitRenderer( engine_t* engine, bool multiview ) {
VR_DestroyRenderer(engine);
}
if (VR_GetPlatformFlag(VRPlatformFlag::VR_PLATFORM_EXTENSION_PASSTHROUGH)) {
INIT_PFN(xrCreatePassthroughFB);
INIT_PFN(xrDestroyPassthroughFB);
INIT_PFN(xrPassthroughStartFB);
INIT_PFN(xrPassthroughPauseFB);
INIT_PFN(xrCreatePassthroughLayerFB);
INIT_PFN(xrDestroyPassthroughLayerFB);
INIT_PFN(xrPassthroughLayerPauseFB);
INIT_PFN(xrPassthroughLayerResumeFB);
}
int eyeW, eyeH;
VR_GetResolution(engine, &eyeW, &eyeH);
VR_SetConfig(VR_CONFIG_VIEWPORT_WIDTH, eyeW);
@ -221,10 +243,32 @@ void VR_InitRenderer( engine_t* engine, bool multiview ) {
ovrRenderer_SetFoveation(&engine->appState.Instance, &engine->appState.Session, &engine->appState.Renderer, XR_FOVEATION_LEVEL_HIGH_TOP_FB, 0, XR_FOVEATION_DYNAMIC_LEVEL_ENABLED_FB);
}
#endif
if (VR_GetPlatformFlag(VRPlatformFlag::VR_PLATFORM_EXTENSION_PASSTHROUGH)) {
XrPassthroughCreateInfoFB ptci = {XR_TYPE_PASSTHROUGH_CREATE_INFO_FB};
XrResult result;
OXR(result = xrCreatePassthroughFB(engine->appState.Session, &ptci, &passthrough));
if (XR_SUCCEEDED(result)) {
XrPassthroughLayerCreateInfoFB plci = {XR_TYPE_PASSTHROUGH_LAYER_CREATE_INFO_FB};
plci.passthrough = passthrough;
plci.purpose = XR_PASSTHROUGH_LAYER_PURPOSE_RECONSTRUCTION_FB;
OXR(xrCreatePassthroughLayerFB(engine->appState.Session, &plci, &passthroughLayer));
}
OXR(xrPassthroughStartFB(passthrough));
OXR(xrPassthroughLayerResumeFB(passthroughLayer));
}
initialized = true;
}
void VR_DestroyRenderer( engine_t* engine ) {
if (VR_GetPlatformFlag(VRPlatformFlag::VR_PLATFORM_EXTENSION_PASSTHROUGH)) {
OXR(xrPassthroughLayerPauseFB(passthroughLayer));
OXR(xrPassthroughPauseFB(passthrough));
OXR(xrDestroyPassthroughFB(passthrough));
passthrough = XR_NULL_HANDLE;
}
ovrRenderer_Destroy(&engine->appState.Renderer);
free(projections);
initialized = false;
@ -328,6 +372,16 @@ void VR_EndFrame( engine_t* engine ) {
void VR_FinishFrame( engine_t* engine ) {
if (VR_GetPlatformFlag(VRPlatformFlag::VR_PLATFORM_EXTENSION_PASSTHROUGH) && VR_GetConfig(VR_CONFIG_PASSTHROUGH)) {
if (passthroughLayer != XR_NULL_HANDLE) {
XrCompositionLayerPassthroughFB passthrough_layer = {XR_TYPE_COMPOSITION_LAYER_PASSTHROUGH_FB};
passthrough_layer.layerHandle = passthroughLayer;
passthrough_layer.flags = XR_COMPOSITION_LAYER_BLEND_TEXTURE_SOURCE_ALPHA_BIT;
passthrough_layer.space = XR_NULL_HANDLE;
engine->appState.Layers[engine->appState.LayerCount++].Passthrough = passthrough_layer;
}
}
int vrMode = vrConfig[VR_CONFIG_MODE];
XrCompositionLayerProjectionView projection_layer_elements[2] = {};
if ((vrMode == VR_MODE_MONO_6DOF) || (vrMode == VR_MODE_STEREO_6DOF)) {

View file

@ -4,8 +4,8 @@
#include "VRMath.h"
enum VRConfig {
//switching between 2D and 3D
VR_CONFIG_MODE,
//switching between mode
VR_CONFIG_MODE, VR_CONFIG_PASSTHROUGH,
//mouse cursor
VR_CONFIG_MOUSE_SIZE, VR_CONFIG_MOUSE_X, VR_CONFIG_MOUSE_Y,
//viewport setup