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

Oculus Quest native support #15659

Merged
merged 32 commits into from
Jul 31, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
71da6a9
OpenXR - Quest target into Android Studio project added
lvonasek Jul 6, 2022
99a4a06
OpenXR - SDK added
lvonasek Jul 7, 2022
8ba87bf
OpenXR - Hide options which are not relevant for VR
lvonasek Jul 7, 2022
dc977a2
OpenXR - VR framebuffer class added
lvonasek Jul 7, 2022
9893e5c
OpenXR - VR mode initialization added
lvonasek Jul 8, 2022
f693850
OpenXR - Initial version of VR renderer added
lvonasek Jul 12, 2022
d109e7c
Merge branch 'master' into feature_openxr_quest
lvonasek Jul 12, 2022
08e01c9
OpenXR - Dummy rendering working
lvonasek Jul 15, 2022
553363a
OpenXR - Rendering into VR framebuffer works
lvonasek Jul 15, 2022
48cd392
OpenXR - Rendering UI fixed
lvonasek Jul 15, 2022
0d41691
OpenXR - Input class added
lvonasek Jul 17, 2022
a08325e
OpenXR - UI scale/resolution fixed
lvonasek Jul 17, 2022
29ff6af
OpenXR - UI controls integrated
lvonasek Jul 17, 2022
cc833fa
OpenXR - Hacky mapping to make the games playable
lvonasek Jul 17, 2022
67821ca
OpenXR - Controller mapping better
lvonasek Jul 22, 2022
28d598b
OpenXR - Button repeating implemented
lvonasek Jul 22, 2022
9dade20
OpenXR - Code formatting {
lvonasek Jul 23, 2022
7d9260e
OpenXR - Code formatting global variables
lvonasek Jul 23, 2022
18ad9ea
OpenXR - Code formatting header removal
lvonasek Jul 23, 2022
9fe7bbd
OpenXR - Pragma once instead of ifdefs
lvonasek Jul 24, 2022
8daba0d
OpenXR - Finalize VR renderer interface
lvonasek Jul 24, 2022
13221ed
OpenXR - VR code formatting fixed
lvonasek Jul 24, 2022
8c9fd58
OpenXR - Hide unsupported menus
lvonasek Jul 24, 2022
8f2904e
OpenXR - Default device config added
lvonasek Jul 24, 2022
eb2b305
OpenXR - Disable HW scaler on VR headsets
lvonasek Jul 24, 2022
b1e3d8b
OpenXR - Code formatting fixed
lvonasek Jul 24, 2022
c543c8f
Merge branch 'master' into feature_openxr_quest
lvonasek Jul 26, 2022
19ebbb6
OpenXR - Integrate SYSPROP_HAS_FILE_BROWSER
lvonasek Jul 26, 2022
b2509ad
OpenXR - Version info refactor
lvonasek Jul 26, 2022
ab9a48d
OpenXR - Static added to global variables
lvonasek Jul 26, 2022
89f5038
OpenXR - Move VR folder under Common
lvonasek Jul 26, 2022
4691b37
OpenXR - Use a build variant instead of a module
lvonasek Jul 31, 2022
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
22 changes: 22 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,14 @@ include(GNUInstallDirs)

add_definitions(-DASSETS_DIR="${CMAKE_INSTALL_FULL_DATADIR}/ppsspp/assets/")

if(OPENXR)
add_definitions(-DOPENXR)
add_library(openxr SHARED IMPORTED)
include_directories(ext/openxr)
set_property(TARGET openxr PROPERTY IMPORTED_LOCATION "${CMAKE_SOURCE_DIR}/ext/openxr/libs/arm64-v8a/libopenxr_loader.so")
message("OpenXR enabled")
endif()

if(GOLD)
add_definitions(-DGOLD)
message("Gold Build")
Expand Down Expand Up @@ -1056,6 +1064,20 @@ if(ANDROID)
android/jni/OpenSLContext.cpp
android/jni/OpenSLContext.h
)

if (OPENXR)
set(nativeExtra ${nativeExtra}
Common/VR/VRBase.cpp
Common/VR/VRBase.h
Common/VR/VRFramebuffer.cpp
Common/VR/VRFramebuffer.h
Common/VR/VRInput.cpp
Common/VR/VRInput.h
Common/VR/VRRenderer.cpp
Common/VR/VRRenderer.h
)
set(nativeExtraLibs ${nativeExtraLibs} openxr)
endif()
# No target
elseif(IOS)
set(nativeExtra ${nativeExtra}
Expand Down
9 changes: 9 additions & 0 deletions Common/GPU/OpenGL/GLQueueRunner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ static constexpr int TEXCACHE_NAME_CACHE_SIZE = 16;
extern void bindDefaultFBO();
#endif

#ifdef OPENXR
#include "VR/VRBase.h"
#include "VR/VRRenderer.h"
#endif

// Workaround for Retroarch. Simply declare
// extern GLuint g_defaultFBO;
// and set is as appropriate. Can adjust the variables in ext/native/base/display.h as
Expand Down Expand Up @@ -1653,6 +1658,10 @@ void GLQueueRunner::fbo_unbind() {
bindDefaultFBO();
#endif

#ifdef OPENXR
VR_BindFramebuffer(VR_GetEngine(), 0);
#endif

currentDrawHandle_ = 0;
currentReadHandle_ = 0;
CHECK_GL_ERROR_IF_DEBUG();
Expand Down
12 changes: 12 additions & 0 deletions Common/GPU/OpenGL/GLRenderManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@
#include "Common/MemoryUtil.h"
#include "Common/Math/math_util.h"

#ifdef OPENXR
#include "VR/VRBase.h"
#include "VR/VRRenderer.h"
#endif

#if 0 // def _DEBUG
#define VLOG(...) INFO_LOG(G3D, __VA_ARGS__)
#else
Expand Down Expand Up @@ -202,6 +207,9 @@ bool GLRenderManager::ThreadFrame() {
std::unique_lock<std::mutex> lock(mutex_);
if (!run_)
return false;
#ifdef OPENXR
VR_BeginFrame(VR_GetEngine());
#endif

// In case of syncs or other partial completion, we keep going until we complete a frame.
do {
Expand Down Expand Up @@ -240,6 +248,9 @@ bool GLRenderManager::ThreadFrame() {
Run(threadFrame_);
VLOG("PULL: Finished frame %d", threadFrame_);
} while (!nextFrame);
#ifdef OPENXR
VR_EndFrame(VR_GetEngine());
#endif
return true;
}

Expand Down Expand Up @@ -300,6 +311,7 @@ void GLRenderManager::BindFramebufferAsRenderTarget(GLRFramebuffer *fb, GLRRende
#ifdef _DEBUG
curProgram_ = nullptr;
#endif

// Eliminate dupes.
if (steps_.size() && steps_.back()->render.framebuffer == fb && steps_.back()->stepType == GLRStepType::RENDER) {
if (color != GLRRenderPassAction::CLEAR && depth != GLRRenderPassAction::CLEAR && stencil != GLRRenderPassAction::CLEAR) {
Expand Down
6 changes: 6 additions & 0 deletions Common/GPU/Vulkan/VulkanLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,12 @@ void VulkanSetAvailable(bool available) {
}

bool VulkanMayBeAvailable() {

#ifdef OPENXR
//unsupported at the moment
return false;
#endif

if (g_vulkanAvailabilityChecked) {
return g_vulkanMayBeAvailable;
}
Expand Down
2 changes: 2 additions & 0 deletions Common/Input/InputState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ const char *GetDeviceName(int deviceId) {
case DEVICE_ID_XINPUT_3: return "x360_4";
case DEVICE_ID_ACCELEROMETER: return "accelerometer";
case DEVICE_ID_MOUSE: return "mouse";
case DEVICE_ID_XR_CONTROLLER_LEFT: return "xr_l";
case DEVICE_ID_XR_CONTROLLER_RIGHT: return "xr_r";
default:
return "unknown";
}
Expand Down
2 changes: 2 additions & 0 deletions Common/Input/InputState.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ enum {
DEVICE_ID_XINPUT_2 = 22,
DEVICE_ID_XINPUT_3 = 23,
DEVICE_ID_ACCELEROMETER = 30,
DEVICE_ID_XR_CONTROLLER_LEFT = 40,
DEVICE_ID_XR_CONTROLLER_RIGHT = 41,
};

//number of contiguous generic joypad IDs
Expand Down
1 change: 1 addition & 0 deletions Common/System/System.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ enum SystemDeviceType {
DEVICE_TYPE_MOBILE = 0, // phones and pads
DEVICE_TYPE_TV = 1, // Android TV and similar
DEVICE_TYPE_DESKTOP = 2, // Desktop computer
DEVICE_TYPE_VR = 3, // VR headset
};

enum SystemKeyboardLayout {
Expand Down
9 changes: 9 additions & 0 deletions Common/UI/UIScreen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@
#include "Common/Log.h"
#include "Common/StringUtils.h"

#ifdef OPENXR
#include "VR/VRBase.h"
#include "VR/VRRenderer.h"
#endif

static const bool ClickDebug = false;

UIScreen::UIScreen()
Expand Down Expand Up @@ -88,6 +93,10 @@ void UIScreen::preRender() {
draw->BindFramebufferAsRenderTarget(nullptr, { RPAction::CLEAR, RPAction::CLEAR, RPAction::CLEAR, 0xFF000000 }, "UI");
screenManager()->getUIContext()->BeginFrame();

#ifdef OPENXR
VR_BindFramebuffer(VR_GetEngine(), 0);
#endif

Draw::Viewport viewport;
viewport.TopLeftX = 0;
viewport.TopLeftY = 0;
Expand Down
165 changes: 165 additions & 0 deletions Common/VR/VRBase.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
#include "VRBase.h"

#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

static engine_t vr_engine;
int vr_initialized = 0;

const char* const requiredExtensionNames[] = {
XR_KHR_OPENGL_ES_ENABLE_EXTENSION_NAME,
XR_KHR_COMPOSITION_LAYER_CYLINDER_EXTENSION_NAME};
const uint32_t numRequiredExtensions =
sizeof(requiredExtensionNames) / sizeof(requiredExtensionNames[0]);

void VR_Init( ovrJava java ) {
if (vr_initialized)
return;

ovrApp_Clear(&vr_engine.appState);

PFN_xrInitializeLoaderKHR xrInitializeLoaderKHR;
xrGetInstanceProcAddr(
XR_NULL_HANDLE, "xrInitializeLoaderKHR", (PFN_xrVoidFunction*)&xrInitializeLoaderKHR);
if (xrInitializeLoaderKHR != NULL) {
XrLoaderInitInfoAndroidKHR loaderInitializeInfoAndroid;
memset(&loaderInitializeInfoAndroid, 0, sizeof(loaderInitializeInfoAndroid));
loaderInitializeInfoAndroid.type = XR_TYPE_LOADER_INIT_INFO_ANDROID_KHR;
loaderInitializeInfoAndroid.next = NULL;
loaderInitializeInfoAndroid.applicationVM = java.Vm;
loaderInitializeInfoAndroid.applicationContext = java.ActivityObject;
xrInitializeLoaderKHR((XrLoaderInitInfoBaseHeaderKHR*)&loaderInitializeInfoAndroid);
}

// Create the OpenXR instance.
XrApplicationInfo appInfo;
memset(&appInfo, 0, sizeof(appInfo));
strcpy(appInfo.applicationName, java.AppName);
strcpy(appInfo.engineName, java.AppName);
appInfo.applicationVersion = java.AppVersion;
appInfo.engineVersion = java.AppVersion;
appInfo.apiVersion = XR_CURRENT_API_VERSION;

XrInstanceCreateInfo instanceCreateInfo;
memset(&instanceCreateInfo, 0, sizeof(instanceCreateInfo));
instanceCreateInfo.type = XR_TYPE_INSTANCE_CREATE_INFO;
instanceCreateInfo.next = NULL;
instanceCreateInfo.createFlags = 0;
instanceCreateInfo.applicationInfo = appInfo;
instanceCreateInfo.enabledApiLayerCount = 0;
instanceCreateInfo.enabledApiLayerNames = NULL;
instanceCreateInfo.enabledExtensionCount = numRequiredExtensions;
instanceCreateInfo.enabledExtensionNames = requiredExtensionNames;

XrResult initResult;
OXR(initResult = xrCreateInstance(&instanceCreateInfo, &vr_engine.appState.Instance));
if (initResult != XR_SUCCESS) {
ALOGE("Failed to create XR instance: %d.", initResult);
exit(1);
}

XrInstanceProperties instanceInfo;
instanceInfo.type = XR_TYPE_INSTANCE_PROPERTIES;
instanceInfo.next = NULL;
OXR(xrGetInstanceProperties(vr_engine.appState.Instance, &instanceInfo));
ALOGV(
"Runtime %s: Version : %u.%u.%u",
instanceInfo.runtimeName,
XR_VERSION_MAJOR(instanceInfo.runtimeVersion),
XR_VERSION_MINOR(instanceInfo.runtimeVersion),
XR_VERSION_PATCH(instanceInfo.runtimeVersion));

XrSystemGetInfo systemGetInfo;
memset(&systemGetInfo, 0, sizeof(systemGetInfo));
systemGetInfo.type = XR_TYPE_SYSTEM_GET_INFO;
systemGetInfo.next = NULL;
systemGetInfo.formFactor = XR_FORM_FACTOR_HEAD_MOUNTED_DISPLAY;

XrSystemId systemId;
OXR(initResult = xrGetSystem(vr_engine.appState.Instance, &systemGetInfo, &systemId));
if (initResult != XR_SUCCESS) {
ALOGE("Failed to get system.");
exit(1);
}

// Get the graphics requirements.
PFN_xrGetOpenGLESGraphicsRequirementsKHR pfnGetOpenGLESGraphicsRequirementsKHR = NULL;
OXR(xrGetInstanceProcAddr(
vr_engine.appState.Instance,
"xrGetOpenGLESGraphicsRequirementsKHR",
(PFN_xrVoidFunction*)(&pfnGetOpenGLESGraphicsRequirementsKHR)));

XrGraphicsRequirementsOpenGLESKHR graphicsRequirements = {};
graphicsRequirements.type = XR_TYPE_GRAPHICS_REQUIREMENTS_OPENGL_ES_KHR;
OXR(pfnGetOpenGLESGraphicsRequirementsKHR(vr_engine.appState.Instance, systemId, &graphicsRequirements));

vr_engine.appState.MainThreadTid = gettid();
vr_engine.appState.SystemId = systemId;

vr_engine.java = java;
vr_initialized = 1;
}

void VR_Destroy( engine_t* engine ) {
if (engine == &vr_engine) {
xrDestroyInstance(engine->appState.Instance);
ovrApp_Destroy(&engine->appState);
}
}

void VR_EnterVR( engine_t* engine ) {

if (engine->appState.Session) {
ALOGE("VR_EnterVR called with existing session");
return;
}

// Create the OpenXR Session.
XrGraphicsBindingOpenGLESAndroidKHR graphicsBindingAndroidGLES = {};
graphicsBindingAndroidGLES.type = XR_TYPE_GRAPHICS_BINDING_OPENGL_ES_ANDROID_KHR;
graphicsBindingAndroidGLES.next = NULL;
graphicsBindingAndroidGLES.display = eglGetCurrentDisplay();
graphicsBindingAndroidGLES.config = eglGetCurrentSurface(EGL_DRAW);
graphicsBindingAndroidGLES.context = eglGetCurrentContext();

XrSessionCreateInfo sessionCreateInfo = {};
memset(&sessionCreateInfo, 0, sizeof(sessionCreateInfo));
sessionCreateInfo.type = XR_TYPE_SESSION_CREATE_INFO;
sessionCreateInfo.next = &graphicsBindingAndroidGLES;
sessionCreateInfo.createFlags = 0;
sessionCreateInfo.systemId = engine->appState.SystemId;

XrResult initResult;
OXR(initResult = xrCreateSession(engine->appState.Instance, &sessionCreateInfo, &engine->appState.Session));
if (initResult != XR_SUCCESS) {
ALOGE("Failed to create XR session: %d.", initResult);
exit(1);
}

// Create a space to the first path
XrReferenceSpaceCreateInfo spaceCreateInfo = {};
spaceCreateInfo.type = XR_TYPE_REFERENCE_SPACE_CREATE_INFO;
spaceCreateInfo.referenceSpaceType = XR_REFERENCE_SPACE_TYPE_VIEW;
spaceCreateInfo.poseInReferenceSpace.orientation.w = 1.0f;
OXR(xrCreateReferenceSpace(engine->appState.Session, &spaceCreateInfo, &engine->appState.HeadSpace));
}

void VR_LeaveVR( engine_t* engine ) {
if (engine->appState.Session) {
OXR(xrDestroySpace(engine->appState.HeadSpace));
// StageSpace is optional.
if (engine->appState.StageSpace != XR_NULL_HANDLE) {
OXR(xrDestroySpace(engine->appState.StageSpace));
}
OXR(xrDestroySpace(engine->appState.FakeStageSpace));
engine->appState.CurrentSpace = XR_NULL_HANDLE;
OXR(xrDestroySession(engine->appState.Session));
engine->appState.Session = NULL;
}
}

engine_t* VR_GetEngine( void ) {
return &vr_engine;
}
10 changes: 10 additions & 0 deletions Common/VR/VRBase.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#pragma once

#include "VRFramebuffer.h"

void VR_Init( ovrJava java );
void VR_Destroy( engine_t* engine );
void VR_EnterVR( engine_t* engine );
void VR_LeaveVR( engine_t* engine );

engine_t* VR_GetEngine( void );
Loading