Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OpenXR - Add passthrough option (Quest only) #17591

Merged
merged 2 commits into from
Jun 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -1152,6 +1152,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