Skip to content

Commit

Permalink
Merge pull request #17591 from lvonasek/feature_openxr_passthrough
Browse files Browse the repository at this point in the history
OpenXR - Add passthrough option (Quest only)
  • Loading branch information
hrydgard authored Jun 17, 2023
2 parents efd8565 + cef7c5a commit 93fbb5c
Show file tree
Hide file tree
Showing 10 changed files with 78 additions and 3 deletions.
6 changes: 6 additions & 0 deletions Common/VR/PPSSPPVR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -828,6 +830,10 @@ bool IsMultiviewSupported() {
return false;
}

bool IsPassthroughSupported() {
return VR_GetPlatformFlag(VR_PLATFORM_EXTENSION_PASSTHROUGH);
}

bool IsFlatVRGame() {
return vrFlatGame;
}
Expand Down
1 change: 1 addition & 0 deletions Common/VR/PPSSPPVR.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ void PostVRFrameRender();
int GetVRFBOIndex();
int GetVRPassesCount();
bool IsMultiviewSupported();
bool IsPassthroughSupported();
bool IsFlatVRGame();
bool IsFlatVRScene();
bool IsGameVRScene();
Expand Down
3 changes: 3 additions & 0 deletions Common/VR/VRBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
7 changes: 6 additions & 1 deletion Common/VR/VRBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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,
Expand Down
54 changes: 54 additions & 0 deletions Common/VR/VRRenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {};

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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)) {
Expand Down
4 changes: 2 additions & 2 deletions Common/VR/VRRenderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions Core/Config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -839,6 +839,7 @@ static const ConfigSetting vrSettings[] = {
ConfigSetting("VREnableMotions", &g_Config.bEnableMotions, true, CfgFlag::PER_GAME),
ConfigSetting("VRForce72Hz", &g_Config.bForce72Hz, true, CfgFlag::PER_GAME),
ConfigSetting("VRManualForceVR", &g_Config.bManualForceVR, false, CfgFlag::PER_GAME),
ConfigSetting("VRPassthrough", &g_Config.bPassthrough, false, CfgFlag::PER_GAME),
ConfigSetting("VRRescaleHUD", &g_Config.bRescaleHUD, true, CfgFlag::PER_GAME),
ConfigSetting("VRCameraDistance", &g_Config.fCameraDistance, 0.0f, CfgFlag::PER_GAME),
ConfigSetting("VRCameraHeight", &g_Config.fCameraHeight, 0.0f, CfgFlag::PER_GAME),
Expand Down
1 change: 1 addition & 0 deletions Core/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,7 @@ struct Config {
bool bEnableMotions;
bool bForce72Hz;
bool bManualForceVR;
bool bPassthrough;
bool bRescaleHUD;
float fCameraDistance;
float fCameraHeight;
Expand Down
3 changes: 3 additions & 0 deletions UI/GameSettingsScreen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1093,6 +1093,9 @@ void GameSettingsScreen::CreateVRSettings(UI::ViewGroup *vrSettings) {
vr6DoF->SetEnabledPtr(&g_Config.bEnableVR);
vrSettings->Add(new CheckBox(&g_Config.bEnableStereo, vr->T("Stereoscopic vision (Experimental)")));
vrSettings->Add(new CheckBox(&g_Config.bForce72Hz, vr->T("Force 72Hz update")));
if (IsPassthroughSupported()) {
vrSettings->Add(new CheckBox(&g_Config.bPassthrough, vr->T("Enable passthrough")));
}

vrSettings->Add(new ItemHeader(vr->T("VR camera")));
vrSettings->Add(new PopupSliderChoiceFloat(&g_Config.fCanvasDistance, 1.0f, 15.0f, 12.0f, vr->T("Distance to 2D menus and scenes"), 1.0f, screenManager(), ""));
Expand Down
1 change: 1 addition & 0 deletions android/VRManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

<uses-feature android:glEsVersion="0x00030001" />
<uses-feature android:name="android.hardware.vr.headtracking" android:version="1" android:required="true" />
<uses-feature android:name="com.oculus.feature.PASSTHROUGH" android:required="false" />

<application
android:allowBackup="true"
Expand Down

0 comments on commit 93fbb5c

Please sign in to comment.