mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-23 13:30:02 +00:00
OpenXR - Initial work on Vulkan support
This commit is contained in:
parent
c6ff56d4a3
commit
fea2ace548
@ -23,7 +23,6 @@
|
||||
#include "Common/GPU/Vulkan/VulkanLoader.h"
|
||||
#include "Common/Log.h"
|
||||
#include "Common/System/System.h"
|
||||
#include "Common/VR/PPSSPPVR.h"
|
||||
|
||||
#if !PPSSPP_PLATFORM(WINDOWS) && !PPSSPP_PLATFORM(SWITCH)
|
||||
#include <dlfcn.h>
|
||||
@ -309,11 +308,6 @@ void VulkanSetAvailable(bool available) {
|
||||
|
||||
bool VulkanMayBeAvailable() {
|
||||
|
||||
//unsupported in VR at the moment
|
||||
if (IsVRBuild()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (g_vulkanAvailabilityChecked) {
|
||||
return g_vulkanMayBeAvailable;
|
||||
}
|
||||
|
@ -97,12 +97,14 @@ bool IsVRBuild() {
|
||||
}
|
||||
|
||||
void InitVROnAndroid(void* vm, void* activity, int version, const char* name) {
|
||||
bool useVulkan = (GPUBackend)g_Config.iGPUBackend == GPUBackend::VULKAN;
|
||||
|
||||
ovrJava java;
|
||||
java.Vm = (JavaVM*)vm;
|
||||
java.ActivityObject = (jobject)activity;
|
||||
java.AppVersion = version;
|
||||
strcpy(java.AppName, name);
|
||||
VR_Init(java);
|
||||
VR_Init(java, useVulkan);
|
||||
|
||||
__DisplaySetFramerate(72);
|
||||
}
|
||||
|
@ -4,21 +4,12 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <vector>
|
||||
|
||||
static engine_t vr_engine;
|
||||
int vr_initialized = 0;
|
||||
|
||||
const char* const requiredExtensionNames[] = {
|
||||
XR_KHR_OPENGL_ES_ENABLE_EXTENSION_NAME,
|
||||
#ifdef OPENXR_HAS_PERFORMANCE_EXTENSION
|
||||
XR_EXT_PERFORMANCE_SETTINGS_EXTENSION_NAME,
|
||||
XR_KHR_ANDROID_THREAD_SETTINGS_EXTENSION_NAME,
|
||||
#endif
|
||||
XR_KHR_COMPOSITION_LAYER_CYLINDER_EXTENSION_NAME};
|
||||
const uint32_t numRequiredExtensions =
|
||||
sizeof(requiredExtensionNames) / sizeof(requiredExtensionNames[0]);
|
||||
|
||||
void VR_Init( ovrJava java ) {
|
||||
void VR_Init( ovrJava java, bool useVulkan ) {
|
||||
if (vr_initialized)
|
||||
return;
|
||||
|
||||
@ -37,6 +28,18 @@ void VR_Init( ovrJava java ) {
|
||||
xrInitializeLoaderKHR((XrLoaderInitInfoBaseHeaderKHR*)&loaderInitializeInfoAndroid);
|
||||
}
|
||||
|
||||
std::vector<char*> extensions;
|
||||
if (useVulkan) {
|
||||
extensions.push_back(XR_KHR_VULKAN_ENABLE_EXTENSION_NAME);
|
||||
} else {
|
||||
extensions.push_back(XR_KHR_OPENGL_ES_ENABLE_EXTENSION_NAME);
|
||||
}
|
||||
extensions.push_back(XR_KHR_COMPOSITION_LAYER_CYLINDER_EXTENSION_NAME);
|
||||
#ifdef OPENXR_HAS_PERFORMANCE_EXTENSION
|
||||
extensions.push_back(XR_EXT_PERFORMANCE_SETTINGS_EXTENSION_NAME);
|
||||
extensions.push_back(XR_KHR_ANDROID_THREAD_SETTINGS_EXTENSION_NAME);
|
||||
#endif
|
||||
|
||||
// Create the OpenXR instance.
|
||||
XrApplicationInfo appInfo;
|
||||
memset(&appInfo, 0, sizeof(appInfo));
|
||||
@ -54,8 +57,8 @@ void VR_Init( ovrJava java ) {
|
||||
instanceCreateInfo.applicationInfo = appInfo;
|
||||
instanceCreateInfo.enabledApiLayerCount = 0;
|
||||
instanceCreateInfo.enabledApiLayerNames = NULL;
|
||||
instanceCreateInfo.enabledExtensionCount = numRequiredExtensions;
|
||||
instanceCreateInfo.enabledExtensionNames = requiredExtensionNames;
|
||||
instanceCreateInfo.enabledExtensionCount = extensions.size();
|
||||
instanceCreateInfo.enabledExtensionNames = extensions.data();
|
||||
|
||||
XrResult initResult;
|
||||
OXR(initResult = xrCreateInstance(&instanceCreateInfo, &vr_engine.appState.Instance));
|
||||
@ -89,15 +92,27 @@ void VR_Init( ovrJava java ) {
|
||||
}
|
||||
|
||||
// Get the graphics requirements.
|
||||
PFN_xrGetOpenGLESGraphicsRequirementsKHR pfnGetOpenGLESGraphicsRequirementsKHR = NULL;
|
||||
OXR(xrGetInstanceProcAddr(
|
||||
vr_engine.appState.Instance,
|
||||
"xrGetOpenGLESGraphicsRequirementsKHR",
|
||||
(PFN_xrVoidFunction*)(&pfnGetOpenGLESGraphicsRequirementsKHR)));
|
||||
if (useVulkan) {
|
||||
PFN_xrGetVulkanGraphicsRequirementsKHR pfnGetVulkanGraphicsRequirementsKHR = NULL;
|
||||
OXR(xrGetInstanceProcAddr(
|
||||
vr_engine.appState.Instance,
|
||||
"xrGetVulkanGraphicsRequirementsKHR",
|
||||
(PFN_xrVoidFunction*)(&pfnGetVulkanGraphicsRequirementsKHR)));
|
||||
|
||||
XrGraphicsRequirementsOpenGLESKHR graphicsRequirements = {};
|
||||
graphicsRequirements.type = XR_TYPE_GRAPHICS_REQUIREMENTS_OPENGL_ES_KHR;
|
||||
OXR(pfnGetOpenGLESGraphicsRequirementsKHR(vr_engine.appState.Instance, systemId, &graphicsRequirements));
|
||||
XrGraphicsRequirementsVulkanKHR graphicsRequirements = {};
|
||||
graphicsRequirements.type = XR_TYPE_GRAPHICS_REQUIREMENTS_VULKAN_KHR;
|
||||
OXR(pfnGetVulkanGraphicsRequirementsKHR(vr_engine.appState.Instance, systemId, &graphicsRequirements));
|
||||
} else {
|
||||
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;
|
||||
|
@ -12,10 +12,12 @@
|
||||
//OpenXR
|
||||
#define XR_USE_PLATFORM_ANDROID 1
|
||||
#define XR_USE_GRAPHICS_API_OPENGL_ES 1
|
||||
#define XR_USE_GRAPHICS_API_VULKAN 1
|
||||
#include <EGL/egl.h>
|
||||
#include <EGL/eglext.h>
|
||||
#include <jni.h>
|
||||
#include <math.h>
|
||||
#include <vulkan/vulkan.h>
|
||||
#include <openxr.h>
|
||||
#include <openxr_platform.h>
|
||||
#include <GLES3/gl3.h>
|
||||
@ -146,7 +148,7 @@ typedef struct {
|
||||
float predictedDisplayTime;
|
||||
} engine_t;
|
||||
|
||||
void VR_Init( ovrJava java );
|
||||
void VR_Init( ovrJava java, bool useVulkan );
|
||||
void VR_Destroy( engine_t* engine );
|
||||
void VR_EnterVR( engine_t* engine );
|
||||
void VR_LeaveVR( engine_t* engine );
|
||||
|
@ -9,8 +9,6 @@
|
||||
#include <pthread.h>
|
||||
#include <sys/prctl.h>
|
||||
#include <assert.h>
|
||||
#include <GLES3/gl3.h>
|
||||
#include <GLES3/gl3ext.h>
|
||||
|
||||
double FromXrTime(const XrTime time) {
|
||||
return (time * 1e-9);
|
||||
@ -178,6 +176,15 @@ void ovrFramebuffer_Acquire(ovrFramebuffer* frameBuffer) {
|
||||
waitInfo.timeout * (1E-9));
|
||||
}
|
||||
frameBuffer->Acquired = res == XR_SUCCESS;
|
||||
|
||||
ovrFramebuffer_SetCurrent(frameBuffer);
|
||||
GL(glEnable( GL_SCISSOR_TEST ));
|
||||
GL(glViewport( 0, 0, frameBuffer->Width, frameBuffer->Height ));
|
||||
GL(glClearColor( 0.0f, 0.0f, 0.0f, 1.0f ));
|
||||
GL(glScissor( 0, 0, frameBuffer->Width, frameBuffer->Height ));
|
||||
GL(glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ));
|
||||
GL(glScissor( 0, 0, 0, 0 ));
|
||||
GL(glDisable( GL_SCISSOR_TEST ));
|
||||
}
|
||||
|
||||
void ovrFramebuffer_Release(ovrFramebuffer* frameBuffer) {
|
||||
@ -185,6 +192,12 @@ void ovrFramebuffer_Release(ovrFramebuffer* frameBuffer) {
|
||||
XrSwapchainImageReleaseInfo releaseInfo = {XR_TYPE_SWAPCHAIN_IMAGE_RELEASE_INFO, NULL};
|
||||
OXR(xrReleaseSwapchainImage(frameBuffer->ColorSwapChain.Handle, &releaseInfo));
|
||||
frameBuffer->Acquired = false;
|
||||
|
||||
// Clear the alpha channel, other way OpenXR would not transfer the framebuffer fully
|
||||
GL(glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE));
|
||||
GL(glClearColor(0.0f, 0.0f, 0.0f, 1.0f));
|
||||
GL(glClear(GL_COLOR_BUFFER_BIT));
|
||||
GL(glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE));
|
||||
}
|
||||
}
|
||||
|
||||
@ -217,6 +230,15 @@ void ovrRenderer_Destroy(ovrRenderer* renderer) {
|
||||
}
|
||||
}
|
||||
|
||||
void ovrRenderer_MouseCursor(ovrRenderer* renderer, int x, int y, int size) {
|
||||
GL(glEnable(GL_SCISSOR_TEST));
|
||||
GL(glScissor(x, y, size, size));
|
||||
GL(glViewport(x, y, size, size));
|
||||
GL(glClearColor(1.0f, 1.0f, 1.0f, 1.0f));
|
||||
GL(glClear(GL_COLOR_BUFFER_BIT));
|
||||
GL(glDisable(GL_SCISSOR_TEST));
|
||||
}
|
||||
|
||||
/*
|
||||
================================================================================
|
||||
|
||||
|
@ -14,3 +14,4 @@ void ovrFramebuffer_SetNone();
|
||||
|
||||
void ovrRenderer_Create(XrSession session, ovrRenderer* renderer, int width, int height, bool multiview);
|
||||
void ovrRenderer_Destroy(ovrRenderer* renderer);
|
||||
void ovrRenderer_MouseCursor(ovrRenderer* renderer, int x, int y, int size);
|
||||
|
@ -6,14 +6,11 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <GLES3/gl3.h>
|
||||
#include <GLES3/gl3ext.h>
|
||||
|
||||
XrView* projections;
|
||||
XrPosef invViewTransform[2];
|
||||
XrFrameState frameState = {};
|
||||
GLboolean initialized = GL_FALSE;
|
||||
GLboolean stageSupported = GL_FALSE;
|
||||
bool initialized = false;
|
||||
bool stageSupported = false;
|
||||
int vrConfig[VR_CONFIG_MAX] = {};
|
||||
|
||||
XrVector3f hmdorientation;
|
||||
@ -194,7 +191,7 @@ void VR_InitRenderer( engine_t* engine, bool multiview ) {
|
||||
|
||||
for (uint32_t i = 0; i < numOutputSpaces; i++) {
|
||||
if (referenceSpaces[i] == XR_REFERENCE_SPACE_TYPE_STAGE) {
|
||||
stageSupported = GL_TRUE;
|
||||
stageSupported = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -213,40 +210,27 @@ void VR_InitRenderer( engine_t* engine, bool multiview ) {
|
||||
engine->appState.ViewConfigurationView[0].recommendedImageRectWidth,
|
||||
engine->appState.ViewConfigurationView[0].recommendedImageRectHeight,
|
||||
multiview);
|
||||
initialized = GL_TRUE;
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
void VR_DestroyRenderer( engine_t* engine ) {
|
||||
ovrRenderer_Destroy(&engine->appState.Renderer);
|
||||
free(projections);
|
||||
initialized = GL_FALSE;
|
||||
}
|
||||
|
||||
void VR_ClearFrameBuffer( int width, int height) {
|
||||
glEnable( GL_SCISSOR_TEST );
|
||||
glViewport( 0, 0, width, height );
|
||||
|
||||
glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
|
||||
|
||||
glScissor( 0, 0, width, height );
|
||||
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
|
||||
|
||||
glScissor( 0, 0, 0, 0 );
|
||||
glDisable( GL_SCISSOR_TEST );
|
||||
initialized = false;
|
||||
}
|
||||
|
||||
bool VR_InitFrame( engine_t* engine ) {
|
||||
GLboolean stageBoundsDirty = GL_TRUE;
|
||||
bool stageBoundsDirty = true;
|
||||
if (ovrApp_HandleXrEvents(&engine->appState)) {
|
||||
VR_Recenter(engine);
|
||||
}
|
||||
if (engine->appState.SessionActive == GL_FALSE) {
|
||||
if (engine->appState.SessionActive == false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (stageBoundsDirty) {
|
||||
VR_UpdateStageBounds(&engine->appState);
|
||||
stageBoundsDirty = GL_FALSE;
|
||||
stageBoundsDirty = false;
|
||||
}
|
||||
|
||||
// NOTE: OpenXR does not use the concept of frame indices. Instead,
|
||||
@ -309,32 +293,19 @@ bool VR_InitFrame( engine_t* engine ) {
|
||||
|
||||
void VR_BeginFrame( engine_t* engine, int fboIndex ) {
|
||||
vrConfig[VR_CONFIG_CURRENT_FBO] = fboIndex;
|
||||
ovrFramebuffer* frameBuffer = &engine->appState.Renderer.FrameBuffer[fboIndex];
|
||||
ovrFramebuffer_Acquire(frameBuffer);
|
||||
ovrFramebuffer_SetCurrent(frameBuffer);
|
||||
VR_ClearFrameBuffer(frameBuffer->ColorSwapChain.Width, frameBuffer->ColorSwapChain.Height);
|
||||
ovrFramebuffer_Acquire(&engine->appState.Renderer.FrameBuffer[fboIndex]);
|
||||
}
|
||||
|
||||
void VR_EndFrame( engine_t* engine ) {
|
||||
|
||||
int fboIndex = vrConfig[VR_CONFIG_CURRENT_FBO];
|
||||
|
||||
// Clear the alpha channel, other way OpenXR would not transfer the framebuffer fully
|
||||
VR_BindFramebuffer(engine);
|
||||
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
|
||||
glClearColor(0.0, 0.0, 0.0, 1.0);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
|
||||
// Show mouse cursor
|
||||
int size = vrConfig[VR_CONFIG_MOUSE_SIZE];
|
||||
if ((vrConfig[VR_CONFIG_MODE] == VR_MODE_FLAT_SCREEN) && (size > 0)) {
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
glScissor(vrConfig[VR_CONFIG_MOUSE_X], vrConfig[VR_CONFIG_MOUSE_Y], size, size);
|
||||
glViewport(vrConfig[VR_CONFIG_MOUSE_X], vrConfig[VR_CONFIG_MOUSE_Y], size, size);
|
||||
glClearColor(1, 1, 1, 1);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
int x = vrConfig[VR_CONFIG_MOUSE_X];
|
||||
int y = vrConfig[VR_CONFIG_MOUSE_Y];
|
||||
ovrRenderer_MouseCursor(&engine->appState.Renderer, x, y, size);
|
||||
}
|
||||
|
||||
ovrFramebuffer* frameBuffer = &engine->appState.Renderer.FrameBuffer[fboIndex];
|
||||
@ -454,10 +425,7 @@ void VR_SetConfig( VRConfig config, int value) {
|
||||
void VR_BindFramebuffer(engine_t *engine) {
|
||||
if (!initialized) return;
|
||||
int fboIndex = vrConfig[VR_CONFIG_CURRENT_FBO];
|
||||
ovrFramebuffer* frameBuffer = &engine->appState.Renderer.FrameBuffer[fboIndex];
|
||||
unsigned int swapchainIndex = frameBuffer->TextureSwapChainIndex;
|
||||
unsigned int glFramebuffer = frameBuffer->FrameBuffers[swapchainIndex];
|
||||
GL(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, glFramebuffer));
|
||||
ovrFramebuffer_SetCurrent(&engine->appState.Renderer.FrameBuffer[fboIndex]);
|
||||
}
|
||||
|
||||
ovrMatrix4f VR_GetMatrix( VRMatrix matrix ) {
|
||||
|
Loading…
Reference in New Issue
Block a user