Skip to content

Commit

Permalink
OpenXR - Stereo without multiview added
Browse files Browse the repository at this point in the history
  • Loading branch information
lvonasek committed Sep 4, 2022
1 parent 5e2ecb5 commit 1df1d79
Show file tree
Hide file tree
Showing 10 changed files with 100 additions and 42 deletions.
40 changes: 28 additions & 12 deletions Common/GPU/OpenGL/GLRenderManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
#include "Common/Thread/ThreadUtil.h"
#include "Common/VR/PPSSPPVR.h"

#include "Core/Config.h"

#include "Common/Log.h"
#include "Common/MemoryUtil.h"
#include "Common/Math/math_util.h"
Expand Down Expand Up @@ -233,15 +235,7 @@ bool GLRenderManager::ThreadFrame() {
INFO_LOG(G3D, "Running first frame (%d)", threadFrame_);
firstFrame = false;
}

if (IsVRBuild()) {
if (PreVRRender()) {
Run(threadFrame_);
PostVRRender();
}
} else {
Run(threadFrame_);
}
Run(threadFrame_);

VLOG("PULL: Finished frame %d", threadFrame_);
} while (!nextFrame);
Expand Down Expand Up @@ -564,8 +558,7 @@ void GLRenderManager::EndSubmitFrame(int frame) {
}

// Render thread
void GLRenderManager::Run(int frame) {
BeginSubmitFrame(frame);
void GLRenderManager::Render(int frame) {

FrameData &frameData = frameData_[frame];

Expand All @@ -584,15 +577,38 @@ void GLRenderManager::Run(int frame) {
}

queueRunner_.RunSteps(stepsOnThread, skipGLCalls_);

stepsOnThread.clear();

if (!skipGLCalls_) {
for (auto iter : frameData.activePushBuffers) {
iter->MapDevice(bufferStrategy_);
}
}
}

// Render thread
void GLRenderManager::Run(int frame) {
BeginSubmitFrame(frame);

if (IsVRBuild()) {
if (PreVRRender()) {
int passes = 1;
if (!IsMultiviewSupported() && g_Config.bEnableStereo) {
passes = 2;
}
for (int i = 0; i < passes; i++) {
PreVRFrameRender(i);
Render(frame);
PostVRFrameRender();
}
PostVRRender();
}
} else {
Render(frame);
}

switch (frameData.type) {
switch (frameData_[frame].type) {
case GLRRunType::END:
EndSubmitFrame(frame);
break;
Expand Down
1 change: 1 addition & 0 deletions Common/GPU/OpenGL/GLRenderManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,7 @@ class GLRenderManager {
void BeginFrame();
// Can run on a different thread!
void Finish();
void Render(int frame);
void Run(int frame);

// Zaps queued up commands. Use if you know there's a risk you've queued up stuff that has already been deleted. Can happen during in-game shutdown.
Expand Down
14 changes: 13 additions & 1 deletion Common/VR/PPSSPPVR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ bool PreVRRender() {
VR_SetConfig(VR_CONFIG_VIEWPORT_VALID, true);
}

if (VR_BeginFrame(VR_GetEngine())) {
if (VR_InitFrame(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)) {
Expand All @@ -245,9 +245,21 @@ bool PreVRRender() {
}

void PostVRRender() {
VR_FinishFrame(VR_GetEngine());
}

void PreVRFrameRender(int fboIndex) {
VR_BeginFrame(VR_GetEngine(), fboIndex);
}

void PostVRFrameRender() {
VR_EndFrame(VR_GetEngine());
}

int GetVRFBOIndex() {
return VR_GetConfig(VR_CONFIG_CURRENT_FBO);
}

bool IsMultiviewSupported() {
return false;
}
Expand Down
6 changes: 6 additions & 0 deletions Common/VR/PPSSPPVR.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ void UpdateVRScreenKey(const KeyInput &key);
void BindVRFramebuffer();
bool PreVRRender();
void PostVRRender();
void PreVRFrameRender(int fboIndex);
void PostVRFrameRender();
int GetVRFBOIndex();
bool IsMultiviewSupported();
bool IsFlatVRScene();
bool Is2DVRObject(float* projMatrix, bool ortho);
Expand All @@ -37,6 +40,9 @@ inline void UpdateVRScreenKey(const KeyInput &key) {}
inline void BindVRFramebuffer() {}
inline bool PreVRRender() { return false; }
inline void PostVRRender() {}
inline void PreVRFrameRender(int fboIndex) {}
inline void PostVRFrameRender() {}
inline int GetVRFBOIndex() { return 0; }
inline bool IsMultiviewSupported() { return false; }
inline bool IsFlatVRScene() { return true; }
inline bool Is2DVRObject(float* projMatrix, bool ortho) { return false; }
Expand Down
4 changes: 2 additions & 2 deletions Common/VR/VRBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,6 @@ typedef struct {
typedef struct {
int Width;
int Height;
bool Multiview;
uint32_t TextureSwapChainLength;
uint32_t TextureSwapChainIndex;
ovrSwapChain ColorSwapChain;
Expand All @@ -104,7 +103,8 @@ typedef struct {
} ovrFramebuffer;

typedef struct {
ovrFramebuffer FrameBuffer;
bool Multiview;
ovrFramebuffer FrameBuffer[ovrMaxNumEyes];
} ovrRenderer;

typedef struct {
Expand Down
18 changes: 12 additions & 6 deletions Common/VR/VRFramebuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,20 +47,17 @@ bool ovrFramebuffer_Create(XrSession session, ovrFramebuffer* frameBuffer, int w

frameBuffer->Width = width;
frameBuffer->Height = height;
frameBuffer->Multiview = multiview;

if (strstr((const char*)glGetString(GL_EXTENSIONS), "GL_OVR_multiview2") == nullptr)
{
ALOGE("OpenGL implementation does not support GL_OVR_multiview2 extension.\n");
exit(EXIT_FAILURE);
}

typedef void (*PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVR)(GLenum, GLenum, GLuint, GLint, GLint, GLsizei);
auto glFramebufferTextureMultiviewOVR = (PFNGLFRAMEBUFFERTEXTUREMULTIVIEWOVR)eglGetProcAddress ("glFramebufferTextureMultiviewOVR");
if (!glFramebufferTextureMultiviewOVR)
{
ALOGE("Can not get proc address for glFramebufferTextureMultiviewOVR.\n");
exit(EXIT_FAILURE);
}

XrSwapchainCreateInfo swapChainCreateInfo;
Expand Down Expand Up @@ -200,15 +197,24 @@ ovrRenderer
*/

void ovrRenderer_Clear(ovrRenderer* renderer) {
ovrFramebuffer_Clear(&renderer->FrameBuffer);
for (int i = 0; i < ovrMaxNumEyes; i++) {
ovrFramebuffer_Clear(&renderer->FrameBuffer[i]);
}
}

void ovrRenderer_Create(XrSession session, ovrRenderer* renderer, int width, int height, bool multiview) {
ovrFramebuffer_Create(session, &renderer->FrameBuffer, width, height, multiview);
renderer->Multiview = multiview;
int instances = renderer->Multiview ? 1 : ovrMaxNumEyes;
for (int i = 0; i < instances; i++) {
ovrFramebuffer_Create(session, &renderer->FrameBuffer[i], width, height, multiview);
}
}

void ovrRenderer_Destroy(ovrRenderer* renderer) {
ovrFramebuffer_Destroy(&renderer->FrameBuffer);
int instances = renderer->Multiview ? 1 : ovrMaxNumEyes;
for (int i = 0; i < instances; i++) {
ovrFramebuffer_Destroy(&renderer->FrameBuffer[i]);
}
}

/*
Expand Down
43 changes: 29 additions & 14 deletions Common/VR/VRRenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ void VR_ClearFrameBuffer( int width, int height) {
glDisable( GL_SCISSOR_TEST );
}

bool VR_BeginFrame( engine_t* engine ) {
bool VR_InitFrame( engine_t* engine ) {
GLboolean stageBoundsDirty = GL_TRUE;
if (ovrApp_HandleXrEvents(&engine->appState)) {
VR_Recenter(engine);
Expand Down Expand Up @@ -304,16 +304,21 @@ bool VR_BeginFrame( engine_t* engine ) {

engine->appState.LayerCount = 0;
memset(engine->appState.Layers, 0, sizeof(ovrCompositorLayer_Union) * ovrMaxLayerCount);
return true;
}

ovrFramebuffer* frameBuffer = &engine->appState.Renderer.FrameBuffer;
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);
return true;
}

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);
Expand All @@ -322,9 +327,8 @@ void VR_EndFrame( engine_t* engine ) {
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);

// Show mouse cursor
int vrMode = vrConfig[VR_CONFIG_MODE];
int size = vrConfig[VR_CONFIG_MOUSE_SIZE];
if ((vrMode == VR_MODE_FLAT_SCREEN) && (size > 0)) {
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);
Expand All @@ -333,21 +337,27 @@ void VR_EndFrame( engine_t* engine ) {
glDisable(GL_SCISSOR_TEST);
}

ovrFramebuffer* frameBuffer = &engine->appState.Renderer.FrameBuffer;
ovrFramebuffer* frameBuffer = &engine->appState.Renderer.FrameBuffer[fboIndex];
//ovrFramebuffer_Resolve(frameBuffer);
ovrFramebuffer_Release(frameBuffer);
ovrFramebuffer_SetNone();
}

void VR_FinishFrame( engine_t* engine ) {

int vrMode = vrConfig[VR_CONFIG_MODE];
XrCompositionLayerProjectionView projection_layer_elements[2] = {};
if ((vrMode == VR_MODE_MONO_6DOF) || (vrMode == VR_MODE_STEREO_6DOF)) {
vrConfig[VR_CONFIG_MENU_YAW] = (int)hmdorientation.y;

for (int eye = 0; eye < ovrMaxNumEyes; eye++) {
int imageLayer = eye;
int imageLayer = engine->appState.Renderer.Multiview ? eye : 0;
ovrFramebuffer* frameBuffer = &engine->appState.Renderer.FrameBuffer[0];
XrFovf fov = projections[eye].fov;
if (vrMode == VR_MODE_MONO_6DOF) {
fov = projections[0].fov;
imageLayer = 0;
} else if (!engine->appState.Renderer.Multiview) {
frameBuffer = &engine->appState.Renderer.FrameBuffer[eye];
}

memset(&projection_layer_elements[eye], 0, sizeof(XrCompositionLayerProjectionView));
Expand Down Expand Up @@ -376,15 +386,15 @@ void VR_EndFrame( engine_t* engine ) {
} else if (vrMode == VR_MODE_FLAT_SCREEN) {

// Build the cylinder layer
int width = engine->appState.Renderer.FrameBuffer.ColorSwapChain.Width;
int height = engine->appState.Renderer.FrameBuffer.ColorSwapChain.Height;
int width = engine->appState.Renderer.FrameBuffer[0].ColorSwapChain.Width;
int height = engine->appState.Renderer.FrameBuffer[0].ColorSwapChain.Height;
XrCompositionLayerCylinderKHR cylinder_layer = {};
cylinder_layer.type = XR_TYPE_COMPOSITION_LAYER_CYLINDER_KHR;
cylinder_layer.layerFlags = XR_COMPOSITION_LAYER_BLEND_TEXTURE_SOURCE_ALPHA_BIT;
cylinder_layer.space = engine->appState.CurrentSpace;
cylinder_layer.eyeVisibility = XR_EYE_VISIBILITY_BOTH;
memset(&cylinder_layer.subImage, 0, sizeof(XrSwapchainSubImage));
cylinder_layer.subImage.swapchain = engine->appState.Renderer.FrameBuffer.ColorSwapChain.Handle;
cylinder_layer.subImage.swapchain = engine->appState.Renderer.FrameBuffer[0].ColorSwapChain.Handle;
cylinder_layer.subImage.imageRect.offset.x = 0;
cylinder_layer.subImage.imageRect.offset.y = 0;
cylinder_layer.subImage.imageRect.extent.width = width;
Expand Down Expand Up @@ -425,8 +435,12 @@ void VR_EndFrame( engine_t* engine ) {
endFrameInfo.layers = layers;

OXR(xrEndFrame(engine->appState.Session, &endFrameInfo));
frameBuffer->TextureSwapChainIndex++;
frameBuffer->TextureSwapChainIndex %= frameBuffer->TextureSwapChainLength;
int instances = engine->appState.Renderer.Multiview ? 1 : ovrMaxNumEyes;
for (int i = 0; i < instances; i++) {
ovrFramebuffer* frameBuffer = &engine->appState.Renderer.FrameBuffer[instances];
frameBuffer->TextureSwapChainIndex++;
frameBuffer->TextureSwapChainIndex %= frameBuffer->TextureSwapChainLength;
}
}

int VR_GetConfig( VRConfig config ) {
Expand All @@ -439,7 +453,8 @@ void VR_SetConfig( VRConfig config, int value) {

void VR_BindFramebuffer(engine_t *engine) {
if (!initialized) return;
ovrFramebuffer* frameBuffer = &engine->appState.Renderer.FrameBuffer;
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));
Expand Down
6 changes: 5 additions & 1 deletion Common/VR/VRRenderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ enum VRConfig {
VR_CONFIG_MOUSE_SIZE, VR_CONFIG_MOUSE_X, VR_CONFIG_MOUSE_Y,
//viewport setup
VR_CONFIG_VIEWPORT_WIDTH, VR_CONFIG_VIEWPORT_HEIGHT, VR_CONFIG_VIEWPORT_VALID,
//render status
VR_CONFIG_CURRENT_FBO,

//end
VR_CONFIG_MAX
Expand All @@ -41,8 +43,10 @@ void VR_GetResolution( engine_t* engine, int *pWidth, int *pHeight );
void VR_InitRenderer( engine_t* engine, bool multiview );
void VR_DestroyRenderer( engine_t* engine );

bool VR_BeginFrame( engine_t* engine );
bool VR_InitFrame( engine_t* engine );
void VR_BeginFrame( engine_t* engine, int fboIndex );
void VR_EndFrame( engine_t* engine );
void VR_FinishFrame( engine_t* engine );

int VR_GetConfig( VRConfig config );
void VR_SetConfig( VRConfig config, int value);
Expand Down
4 changes: 2 additions & 2 deletions GPU/GLES/ShaderManagerGLES.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,7 @@ void LinkedShader::UpdateUniforms(u32 vertType, const ShaderID &vsid, bool useBu
if (IsMultiviewSupported()) {
render_->SetUniformM4x4Stereo("u_proj", &u_proj, leftEyeMatrix.m, rightEyeMatrix.m);
} else {
render_->SetUniformM4x4(&u_proj, leftEyeMatrix.m);
render_->SetUniformM4x4(&u_proj, GetVRFBOIndex() == 0 ? leftEyeMatrix.m : rightEyeMatrix.m);
}
} else {
Matrix4x4 flippedMatrix;
Expand Down Expand Up @@ -537,7 +537,7 @@ void LinkedShader::UpdateUniforms(u32 vertType, const ShaderID &vsid, bool useBu
if (IsMultiviewSupported()) {
render_->SetUniformM4x4Stereo("u_view", &u_view, leftEyeView, rightEyeView);
} else {
render_->SetUniformM4x4(&u_view, leftEyeView);
render_->SetUniformM4x4(&u_view, GetVRFBOIndex() == 0 ? leftEyeView : rightEyeView);
}
} else {
SetMatrix4x3(render_, &u_view, gstate.viewMatrix);
Expand Down
6 changes: 2 additions & 4 deletions UI/GameSettingsScreen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1120,10 +1120,8 @@ void GameSettingsScreen::CreateViews() {
vrSettings->Add(new CheckBox(&g_Config.bEnableVR, vr->T("Enable virtual reality")));
CheckBox *vr6DoF = vrSettings->Add(new CheckBox(&g_Config.bEnable6DoF, vr->T("Enable 6 degrees of freedom movement")));
vr6DoF->SetEnabledPtr(&g_Config.bEnableVR);
if (IsMultiviewSupported()) {
CheckBox *vrStereo = vrSettings->Add(new CheckBox(&g_Config.bEnableStereo, vr->T("Enable stereoscopic vision")));
vrStereo->SetEnabledPtr(&g_Config.bEnableVR);
}
CheckBox *vrStereo = vrSettings->Add(new CheckBox(&g_Config.bEnableStereo, vr->T("Enable stereoscopic vision")));
vrStereo->SetEnabledPtr(&g_Config.bEnableVR);
PopupSliderChoice *vrFieldOfView = vrSettings->Add(new PopupSliderChoice(&g_Config.iFieldOfViewPercentage, 100, 150, vr->T("Field of view scale", "Headset's field of view scale"), 10, screenManager(), vr->T("% of native FoV")));
vrFieldOfView->SetEnabledPtr(&g_Config.bEnableVR);
vrSettings->Add(new PopupSliderChoice(&g_Config.iCanvasDistance, 1, 10, vr->T("Distance to 2D menus and scenes", "Distance to 2D menus and scenes"), 1, screenManager(), ""));
Expand Down

0 comments on commit 1df1d79

Please sign in to comment.