OpenXR - Use OpenGL ES 3 and ensure FBO pair calls

This commit is contained in:
Lubos 2022-08-19 16:59:39 +02:00
parent 4603ccdd92
commit 98f726af3b
7 changed files with 48 additions and 28 deletions

View file

@ -5,6 +5,9 @@
#if PPSSPP_PLATFORM(IOS) #if PPSSPP_PLATFORM(IOS)
#include <OpenGLES/ES3/gl.h> #include <OpenGLES/ES3/gl.h>
#include <OpenGLES/ES3/glext.h> #include <OpenGLES/ES3/glext.h>
#elif defined(OPEXR)
#include <GLES3/gl3.h>
#include <GLES3/gl3ext.h>
#elif defined(USING_GLES2) #elif defined(USING_GLES2)
#include <GLES2/gl2.h> #include <GLES2/gl2.h>
#include <GLES2/gl2ext.h> #include <GLES2/gl2ext.h>

View file

@ -203,22 +203,6 @@ bool GLRenderManager::ThreadFrame() {
std::unique_lock<std::mutex> lock(mutex_); std::unique_lock<std::mutex> lock(mutex_);
if (!run_) if (!run_)
return false; return false;
#ifdef OPENXR
VR_BeginFrame(VR_GetEngine());
// Decide if the scene is 3D or not
if (g_Config.bEnableVR && !VR_GetConfig(VR_CONFIG_FORCE_2D) && (VR_GetConfig(VR_CONFIG_3D_GEOMETRY_COUNT) > 15)) {
VR_SetConfig(VR_CONFIG_MODE, g_Config.bEnableStereo ? VR_MODE_STEREO_6DOF : VR_MODE_MONO_6DOF);
} else {
VR_SetConfig(VR_CONFIG_MODE, VR_MODE_FLAT_SCREEN);
}
VR_SetConfig(VR_CONFIG_3D_GEOMETRY_COUNT, VR_GetConfig(VR_CONFIG_3D_GEOMETRY_COUNT) / 2);
// Set customizations
VR_SetConfig(VR_CONFIG_6DOF_ENABLED, g_Config.bEnable6DoF);
VR_SetConfig(VR_CONFIG_CANVAS_DISTANCE, g_Config.iCanvasDistance);
VR_SetConfig(VR_CONFIG_FOV_SCALE, g_Config.iFieldOfViewPercentage);
#endif
// In case of syncs or other partial completion, we keep going until we complete a frame. // In case of syncs or other partial completion, we keep going until we complete a frame.
do { do {
@ -254,12 +238,33 @@ bool GLRenderManager::ThreadFrame() {
INFO_LOG(G3D, "Running first frame (%d)", threadFrame_); INFO_LOG(G3D, "Running first frame (%d)", threadFrame_);
firstFrame = false; firstFrame = false;
} }
#ifdef OPENXR
if (VR_BeginFrame(VR_GetEngine())) {
// Decide if the scene is 3D or not
if (g_Config.bEnableVR && !VR_GetConfig(VR_CONFIG_FORCE_2D) && (VR_GetConfig(VR_CONFIG_3D_GEOMETRY_COUNT) > 15)) {
VR_SetConfig(VR_CONFIG_MODE, g_Config.bEnableStereo ? VR_MODE_STEREO_6DOF : VR_MODE_MONO_6DOF);
} else {
VR_SetConfig(VR_CONFIG_MODE, VR_MODE_FLAT_SCREEN);
}
VR_SetConfig(VR_CONFIG_3D_GEOMETRY_COUNT, VR_GetConfig(VR_CONFIG_3D_GEOMETRY_COUNT) / 2);
// Set customizations
VR_SetConfig(VR_CONFIG_6DOF_ENABLED, g_Config.bEnable6DoF);
VR_SetConfig(VR_CONFIG_CANVAS_DISTANCE, g_Config.iCanvasDistance);
VR_SetConfig(VR_CONFIG_FOV_SCALE, g_Config.iFieldOfViewPercentage);
// Render scene
Run(threadFrame_);
VR_EndFrame(VR_GetEngine());
}
#else
Run(threadFrame_); Run(threadFrame_);
#endif
VLOG("PULL: Finished frame %d", threadFrame_); VLOG("PULL: Finished frame %d", threadFrame_);
} while (!nextFrame); } while (!nextFrame);
#ifdef OPENXR
VR_EndFrame(VR_GetEngine());
#endif
return true; return true;
} }

View file

@ -97,6 +97,7 @@ typedef struct {
XrSwapchainImageOpenGLESKHR* ColorSwapChainImage; XrSwapchainImageOpenGLESKHR* ColorSwapChainImage;
XrSwapchainImageOpenGLESKHR* DepthSwapChainImage; XrSwapchainImageOpenGLESKHR* DepthSwapChainImage;
unsigned int* FrameBuffers; unsigned int* FrameBuffers;
bool Acquired;
} ovrFramebuffer; } ovrFramebuffer;
typedef struct { typedef struct {

View file

@ -38,6 +38,7 @@ void ovrFramebuffer_Clear(ovrFramebuffer* frameBuffer) {
frameBuffer->DepthSwapChain.Height = 0; frameBuffer->DepthSwapChain.Height = 0;
frameBuffer->FrameBuffers = NULL; frameBuffer->FrameBuffers = NULL;
frameBuffer->Acquired = false;
} }
bool ovrFramebuffer_Create( bool ovrFramebuffer_Create(
@ -185,11 +186,15 @@ void ovrFramebuffer_Acquire(ovrFramebuffer* frameBuffer) {
i, i,
waitInfo.timeout * (1E-9)); waitInfo.timeout * (1E-9));
} }
frameBuffer->Acquired = res == XR_SUCCESS;
} }
void ovrFramebuffer_Release(ovrFramebuffer* frameBuffer) { void ovrFramebuffer_Release(ovrFramebuffer* frameBuffer) {
XrSwapchainImageReleaseInfo releaseInfo = {XR_TYPE_SWAPCHAIN_IMAGE_RELEASE_INFO, NULL}; if (frameBuffer->Acquired) {
OXR(xrReleaseSwapchainImage(frameBuffer->ColorSwapChain.Handle, &releaseInfo)); XrSwapchainImageReleaseInfo releaseInfo = {XR_TYPE_SWAPCHAIN_IMAGE_RELEASE_INFO, NULL};
OXR(xrReleaseSwapchainImage(frameBuffer->ColorSwapChain.Handle, &releaseInfo));
frameBuffer->Acquired = false;
}
} }
/* /*

View file

@ -232,7 +232,7 @@ void VR_ClearFrameBuffer( int width, int height) {
glEnable( GL_SCISSOR_TEST ); glEnable( GL_SCISSOR_TEST );
glViewport( 0, 0, width, height ); glViewport( 0, 0, width, height );
glClearColor( 0.0f, 0.5f, 1.0f, 1.0f ); glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
glScissor( 0, 0, width, height ); glScissor( 0, 0, width, height );
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
@ -241,13 +241,13 @@ void VR_ClearFrameBuffer( int width, int height) {
glDisable( GL_SCISSOR_TEST ); glDisable( GL_SCISSOR_TEST );
} }
void VR_BeginFrame( engine_t* engine ) { bool VR_BeginFrame( engine_t* engine ) {
GLboolean stageBoundsDirty = GL_TRUE; GLboolean stageBoundsDirty = GL_TRUE;
if (ovrApp_HandleXrEvents(&engine->appState)) { if (ovrApp_HandleXrEvents(&engine->appState)) {
VR_Recenter(engine); VR_Recenter(engine);
} }
if (engine->appState.SessionActive == GL_FALSE) { if (engine->appState.SessionActive == GL_FALSE) {
return; return false;
} }
if (stageBoundsDirty) { if (stageBoundsDirty) {
@ -267,7 +267,7 @@ void VR_BeginFrame( engine_t* engine ) {
OXR(xrWaitFrame(engine->appState.Session, &waitFrameInfo, &frameState)); OXR(xrWaitFrame(engine->appState.Session, &waitFrameInfo, &frameState));
engine->predictedDisplayTime = frameState.predictedDisplayTime; engine->predictedDisplayTime = frameState.predictedDisplayTime;
if (!frameState.shouldRender) { if (!frameState.shouldRender) {
return; return false;
} }
// Get the HMD pose, predicted for the middle of the time period during which // Get the HMD pose, predicted for the middle of the time period during which
@ -315,11 +315,13 @@ void VR_BeginFrame( engine_t* engine ) {
ovrFramebuffer_Acquire(frameBuffer); ovrFramebuffer_Acquire(frameBuffer);
ovrFramebuffer_SetCurrent(frameBuffer); ovrFramebuffer_SetCurrent(frameBuffer);
VR_ClearFrameBuffer(frameBuffer->ColorSwapChain.Width, frameBuffer->ColorSwapChain.Height); VR_ClearFrameBuffer(frameBuffer->ColorSwapChain.Width, frameBuffer->ColorSwapChain.Height);
return true;
} }
void VR_EndFrame( engine_t* engine ) { void VR_EndFrame( engine_t* engine ) {
// Clear the alpha channel, other way OpenXR would not transfer the framebuffer fully // 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); glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
glClearColor(0.0, 0.0, 0.0, 1.0); glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);

View file

@ -38,7 +38,7 @@ void VR_GetResolution( engine_t* engine, int *pWidth, int *pHeight );
void VR_InitRenderer( engine_t* engine ); void VR_InitRenderer( engine_t* engine );
void VR_DestroyRenderer( engine_t* engine ); void VR_DestroyRenderer( engine_t* engine );
void VR_BeginFrame( engine_t* engine ); bool VR_BeginFrame( engine_t* engine );
void VR_EndFrame( engine_t* engine ); void VR_EndFrame( engine_t* engine );
int VR_GetConfig( VRConfig config ); int VR_GetConfig( VRConfig config );

View file

@ -381,7 +381,7 @@ public abstract class NativeActivity extends Activity {
} }
int deviceType = NativeApp.DEVICE_TYPE_MOBILE; int deviceType = NativeApp.DEVICE_TYPE_MOBILE;
if (BuildConfig.FLAVOR.compareTo("quest") == 0) { if (isVRDevice()) {
deviceType = NativeApp.DEVICE_TYPE_VR; deviceType = NativeApp.DEVICE_TYPE_VR;
} }
UiModeManager uiModeManager = (UiModeManager) getSystemService(UI_MODE_SERVICE); UiModeManager uiModeManager = (UiModeManager) getSystemService(UI_MODE_SERVICE);
@ -621,7 +621,7 @@ public abstract class NativeActivity extends Activity {
if (javaGL) { if (javaGL) {
mGLSurfaceView = new NativeGLView(this); mGLSurfaceView = new NativeGLView(this);
nativeRenderer = new NativeRenderer(this); nativeRenderer = new NativeRenderer(this);
mGLSurfaceView.setEGLContextClientVersion(2); mGLSurfaceView.setEGLContextClientVersion(isVRDevice() ? 3 : 2);
sizeManager.setSurfaceView(mGLSurfaceView); sizeManager.setSurfaceView(mGLSurfaceView);
// Setup the GLSurface and ask android for the correct // Setup the GLSurface and ask android for the correct
@ -1545,4 +1545,8 @@ public abstract class NativeActivity extends Activity {
finish(); finish();
} }
} }
private boolean isVRDevice() {
return BuildConfig.FLAVOR.compareTo("quest") == 0;
}
} }