From 553363a5b51f94fb6fe12a816979cbc97638ed2b Mon Sep 17 00:00:00 2001 From: Lubos Date: Fri, 15 Jul 2022 15:41:21 +0200 Subject: [PATCH] OpenXR - Rendering into VR framebuffer works --- Common/GPU/OpenGL/GLQueueRunner.cpp | 10 ++++++++++ Common/GPU/OpenGL/GLRenderManager.cpp | 12 ++++++++++++ VR/VRFramebuffer.cpp | 12 ++++-------- VR/VRRenderer.cpp | 23 ++++++++++++++++------- VR/VRRenderer.h | 2 ++ android/jni/app-android.cpp | 3 --- 6 files changed, 44 insertions(+), 18 deletions(-) diff --git a/Common/GPU/OpenGL/GLQueueRunner.cpp b/Common/GPU/OpenGL/GLQueueRunner.cpp index 328605d1e2..9e916aba25 100644 --- a/Common/GPU/OpenGL/GLQueueRunner.cpp +++ b/Common/GPU/OpenGL/GLQueueRunner.cpp @@ -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 @@ -1653,6 +1658,11 @@ void GLQueueRunner::fbo_unbind() { bindDefaultFBO(); #endif +#ifdef OPENXR + GLuint fbo = VR_Framebuffer(VR_GetEngine(), 0); + glBindFramebuffer(GL_FRAMEBUFFER, fbo); +#endif + currentDrawHandle_ = 0; currentReadHandle_ = 0; CHECK_GL_ERROR_IF_DEBUG(); diff --git a/Common/GPU/OpenGL/GLRenderManager.cpp b/Common/GPU/OpenGL/GLRenderManager.cpp index 1475d8d5ff..8315fc3052 100644 --- a/Common/GPU/OpenGL/GLRenderManager.cpp +++ b/Common/GPU/OpenGL/GLRenderManager.cpp @@ -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 @@ -202,6 +207,9 @@ bool GLRenderManager::ThreadFrame() { std::unique_lock 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 { @@ -240,6 +248,9 @@ bool GLRenderManager::ThreadFrame() { Run(threadFrame_); VLOG("PULL: Finished frame %d", threadFrame_); } while (!nextFrame); +#ifdef OPENXR + VR_DrawFrame(VR_GetEngine()); +#endif return true; } @@ -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) { diff --git a/VR/VRFramebuffer.cpp b/VR/VRFramebuffer.cpp index 934c092405..c225e3b8f7 100644 --- a/VR/VRFramebuffer.cpp +++ b/VR/VRFramebuffer.cpp @@ -105,19 +105,15 @@ bool ovrFramebuffer_Create( // Create depth buffer. GL(glGenRenderbuffers(1, &frameBuffer->DepthBuffers[i])); GL(glBindRenderbuffer(GL_RENDERBUFFER, frameBuffer->DepthBuffers[i])); - GL(glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, width, height)); + GL(glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height)); GL(glBindRenderbuffer(GL_RENDERBUFFER, 0)); // Create the frame buffer. GL(glGenFramebuffers(1, &frameBuffer->FrameBuffers[i])); GL(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, frameBuffer->FrameBuffers[i])); - GL(glFramebufferRenderbuffer( - GL_DRAW_FRAMEBUFFER, - GL_DEPTH_ATTACHMENT, - GL_RENDERBUFFER, - frameBuffer->DepthBuffers[i])); - GL(glFramebufferTexture2D( - GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture, 0)); + GL(glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, frameBuffer->DepthBuffers[i])); + GL(glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, frameBuffer->DepthBuffers[i])); + GL(glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture, 0)); GL(GLenum renderFramebufferStatus = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER)); GL(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0)); if (renderFramebufferStatus != GL_FRAMEBUFFER_COMPLETE) { diff --git a/VR/VRRenderer.cpp b/VR/VRRenderer.cpp index de5e1571a4..810a467953 100644 --- a/VR/VRRenderer.cpp +++ b/VR/VRRenderer.cpp @@ -8,7 +8,10 @@ #include #include +XrFovf fov = {}; XrView* projections; +XrPosef invViewTransform[2]; +XrFrameState frameState = {}; GLboolean stageSupported = GL_FALSE; float menuYaw = 0; @@ -225,7 +228,7 @@ void VR_ClearFrameBuffer( int width, int height) glEnable( GL_SCISSOR_TEST ); 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 ); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); @@ -234,8 +237,8 @@ void VR_ClearFrameBuffer( int width, int height) glDisable( GL_SCISSOR_TEST ); } -void VR_DrawFrame( engine_t* engine ) { - +void VR_BeginFrame( engine_t* engine ) +{ GLboolean stageBoundsDirty = GL_TRUE; if (ovrApp_HandleXrEvents(&engine->appState)) { VR_Recenter(engine); @@ -255,7 +258,6 @@ void VR_DrawFrame( engine_t* engine ) { waitFrameInfo.type = XR_TYPE_FRAME_WAIT_INFO; waitFrameInfo.next = NULL; - XrFrameState frameState = {}; frameState.type = XR_TYPE_FRAME_STATE; frameState.next = NULL; @@ -294,8 +296,6 @@ void VR_DrawFrame( engine_t* engine ) { projections)); // - XrFovf fov = {}; - XrPosef invViewTransform[2]; for (int eye = 0; eye < ovrMaxNumEyes; eye++) { invViewTransform[eye] = projections[eye].pose; @@ -331,8 +331,9 @@ void VR_DrawFrame( engine_t* engine ) { ovrFramebuffer_SetCurrent(frameBuffer); VR_ClearFrameBuffer(frameBuffer->ColorSwapChain.Width, frameBuffer->ColorSwapChain.Height); } +} - //TODO:Com_Frame(); +void VR_DrawFrame( engine_t* engine ) { for (int eye = 0; eye < ovrMaxNumEyes; eye++) { @@ -432,3 +433,11 @@ void VR_DrawFrame( engine_t* engine ) { frameBuffer->TextureSwapChainIndex %= frameBuffer->TextureSwapChainLength; } } + +unsigned int VR_Framebuffer( engine_t* engine, int eye ) +{ + ovrFramebuffer* frameBuffer = &engine->appState.Renderer.FrameBuffer[eye]; + int swapchainIndex = frameBuffer->TextureSwapChainIndex; + int glFramebuffer = frameBuffer->FrameBuffers[swapchainIndex]; + return glFramebuffer; +} diff --git a/VR/VRRenderer.h b/VR/VRRenderer.h index fc96d06d10..333d503288 100644 --- a/VR/VRRenderer.h +++ b/VR/VRRenderer.h @@ -6,7 +6,9 @@ void VR_GetResolution( engine_t* engine, int *pWidth, int *pHeight ); void VR_InitRenderer( engine_t* engine ); void VR_DestroyRenderer( engine_t* engine ); +void VR_BeginFrame( engine_t* engine ); void VR_DrawFrame( engine_t* engine ); void VR_ReInitRenderer(); +unsigned int VR_Framebuffer( engine_t* engine, int eye ); #endif diff --git a/android/jni/app-android.cpp b/android/jni/app-android.cpp index 103a063bb0..99cea829a6 100644 --- a/android/jni/app-android.cpp +++ b/android/jni/app-android.cpp @@ -1063,9 +1063,6 @@ extern "C" void Java_org_ppsspp_ppsspp_NativeRenderer_displayRender(JNIEnv *env, } else { UpdateRunLoopAndroid(env); } -#ifdef OPENXR - VR_DrawFrame(VR_GetEngine()); -#endif } void System_AskForPermission(SystemPermission permission) {