diff --git a/CMakeLists.txt b/CMakeLists.txt index 6dcea5c466..378c004bac 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1084,6 +1084,8 @@ if(ANDROID) if (OPENXR) set(nativeExtra ${nativeExtra} + Common/VR/PPSSPPVR.cpp + Common/VR/PPSSPPVR.h Common/VR/VRBase.cpp Common/VR/VRBase.h Common/VR/VRFramebuffer.cpp diff --git a/Common/GPU/OpenGL/GLQueueRunner.cpp b/Common/GPU/OpenGL/GLQueueRunner.cpp index 90162f8de4..872f618a63 100644 --- a/Common/GPU/OpenGL/GLQueueRunner.cpp +++ b/Common/GPU/OpenGL/GLQueueRunner.cpp @@ -6,6 +6,7 @@ #include "Common/GPU/OpenGL/GLFeatures.h" #include "Common/GPU/OpenGL/DataFormatGL.h" #include "Common/Math/math_util.h" +#include "Common/VR/PPSSPPVR.h" #include "Common/Log.h" #include "Common/MemoryUtil.h" @@ -30,11 +31,6 @@ 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 @@ -276,25 +272,27 @@ void GLQueueRunner::RunInitSteps(const std::vector &steps, bool ski for (size_t j = 0; j < program->queries_.size(); j++) { auto &query = program->queries_[j]; _dbg_assert_(query.name); -#ifdef OPENXR - int location = -1; - int index = GetStereoBufferIndex(query.name); - if (index >= 0) { - std::string layout = GetStereoBufferLayout(query.name); - glUniformBlockBinding(program->program, glGetUniformBlockIndex(program->program, layout.c_str()), index); - GLuint buffer = 0; - glGenBuffers(1, &buffer); - glBindBuffer(GL_UNIFORM_BUFFER, buffer); - glBufferData(GL_UNIFORM_BUFFER,2 * 16 * sizeof(float),NULL, GL_STATIC_DRAW); - glBindBuffer(GL_UNIFORM_BUFFER, 0); - location = buffer; + int location = -1; + if (IsVRBuild()) { + int index = GetStereoBufferIndex(query.name); + if (index >= 0) { + std::string layout = GetStereoBufferLayout(query.name); + glUniformBlockBinding(program->program, glGetUniformBlockIndex(program->program, layout.c_str()), index); + + GLuint buffer = 0; + glGenBuffers(1, &buffer); + glBindBuffer(GL_UNIFORM_BUFFER, buffer); + glBufferData(GL_UNIFORM_BUFFER,2 * 16 * sizeof(float),NULL, GL_STATIC_DRAW); + glBindBuffer(GL_UNIFORM_BUFFER, 0); + location = buffer; + } else { + location = glGetUniformLocation(program->program, query.name); + } } else { location = glGetUniformLocation(program->program, query.name); } -#else - int location = glGetUniformLocation(program->program, query.name); -#endif + if (location < 0 && query.required) { WARN_LOG(G3D, "Required uniform query for '%s' failed", query.name); } @@ -1026,7 +1024,6 @@ void GLQueueRunner::PerformRenderPass(const GLRStep &step, bool first, bool last CHECK_GL_ERROR_IF_DEBUG(); break; } -#ifdef OPENXR case GLRRenderCommand::UNIFORMSTEREOMATRIX: { _dbg_assert_(curProgram); @@ -1043,7 +1040,6 @@ void GLQueueRunner::PerformRenderPass(const GLRStep &step, bool first, bool last CHECK_GL_ERROR_IF_DEBUG(); break; } -#endif case GLRRenderCommand::UNIFORMMATRIX: { _dbg_assert_(curProgram); @@ -1714,9 +1710,9 @@ void GLQueueRunner::fbo_unbind() { bindDefaultFBO(); #endif -#ifdef OPENXR - VR_BindFramebuffer(VR_GetEngine()); -#endif + if (IsVRBuild()) { + BindVRFramebuffer(); + } currentDrawHandle_ = 0; currentReadHandle_ = 0; diff --git a/Common/GPU/OpenGL/GLRenderManager.cpp b/Common/GPU/OpenGL/GLRenderManager.cpp index 3cc61d2137..b9173c2beb 100644 --- a/Common/GPU/OpenGL/GLRenderManager.cpp +++ b/Common/GPU/OpenGL/GLRenderManager.cpp @@ -3,17 +3,12 @@ #include "Common/GPU/OpenGL/GLFeatures.h" #include "Common/GPU/thin3d.h" #include "Common/Thread/ThreadUtil.h" +#include "Common/VR/PPSSPPVR.h" #include "Common/Log.h" #include "Common/MemoryUtil.h" #include "Common/Math/math_util.h" -#ifdef OPENXR -#include "Core/Config.h" -#include "VR/VRBase.h" -#include "VR/VRRenderer.h" -#endif - #if 0 // def _DEBUG #define VLOG(...) INFO_LOG(G3D, __VA_ARGS__) #else @@ -239,29 +234,15 @@ bool GLRenderManager::ThreadFrame() { 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); + if (IsVRBuild()) { + if (PreVRRender()) { + Run(threadFrame_); + PostVRRender(); } - 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 - GL(Run(threadFrame_)); - VR_EndFrame(VR_GetEngine()); + } else { + Run(threadFrame_); } -#else - Run(threadFrame_); -#endif + VLOG("PULL: Finished frame %d", threadFrame_); } while (!nextFrame); diff --git a/Common/GPU/OpenGL/GLRenderManager.h b/Common/GPU/OpenGL/GLRenderManager.h index ed8d4e99cc..5423262c98 100644 --- a/Common/GPU/OpenGL/GLRenderManager.h +++ b/Common/GPU/OpenGL/GLRenderManager.h @@ -743,7 +743,6 @@ public: curRenderStep_->commands.push_back(data); } -#ifdef OPENXR void SetUniformM4x4Stereo(const char *name, const GLint *loc, const float *left, const float *right) { _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); #ifdef _DEBUG @@ -756,7 +755,6 @@ public: memcpy(&data.uniformMatrix4.m[16], right, sizeof(float) * 16); curRenderStep_->commands.push_back(data); } -#endif void SetUniformM4x4(const char *name, const float *udata) { _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == GLRStepType::RENDER); diff --git a/Common/GPU/Vulkan/VulkanLoader.cpp b/Common/GPU/Vulkan/VulkanLoader.cpp index 929ef9c501..75462aace1 100644 --- a/Common/GPU/Vulkan/VulkanLoader.cpp +++ b/Common/GPU/Vulkan/VulkanLoader.cpp @@ -23,6 +23,7 @@ #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 @@ -306,10 +307,10 @@ void VulkanSetAvailable(bool available) { bool VulkanMayBeAvailable() { -#ifdef OPENXR - //unsupported at the moment - return false; -#endif + //unsupported in VR at the moment + if (IsVRBuild()) { + return false; + } if (g_vulkanAvailabilityChecked) { return g_vulkanMayBeAvailable; diff --git a/Common/UI/UIScreen.cpp b/Common/UI/UIScreen.cpp index 9421e0612b..8026de37bc 100644 --- a/Common/UI/UIScreen.cpp +++ b/Common/UI/UIScreen.cpp @@ -12,15 +12,11 @@ #include "Common/UI/Root.h" #include "Common/Data/Text/I18n.h" #include "Common/Render/DrawBuffer.h" +#include "Common/VR/PPSSPPVR.h" #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() @@ -93,9 +89,9 @@ void UIScreen::preRender() { draw->BindFramebufferAsRenderTarget(nullptr, { RPAction::CLEAR, RPAction::CLEAR, RPAction::CLEAR, 0xFF000000 }, "UI"); screenManager()->getUIContext()->BeginFrame(); -#ifdef OPENXR - VR_BindFramebuffer(VR_GetEngine()); -#endif + if (IsVRBuild()) { + BindVRFramebuffer(); + } Draw::Viewport viewport; viewport.TopLeftX = 0; diff --git a/Common/VR/PPSSPPVR.cpp b/Common/VR/PPSSPPVR.cpp new file mode 100644 index 0000000000..de82514151 --- /dev/null +++ b/Common/VR/PPSSPPVR.cpp @@ -0,0 +1,202 @@ +#include "Common/VR/PPSSPPVR.h" +#include "Common/VR/VRBase.h" +#include "Common/VR/VRInput.h" +#include "Common/VR/VRRenderer.h" +#include "Common/VR/VRTweaks.h" + +#include "Core/HLE/sceDisplay.h" +#include "Core/Config.h" +#include "Core/KeyMap.h" + + +/* +================================================================================ + +VR button mapping + +================================================================================ +*/ + +struct ButtonMapping { + ovrButton ovr; + int keycode; + bool pressed; + int repeat; + + ButtonMapping(int keycode, ovrButton ovr) { + this->keycode = keycode; + this->ovr = ovr; + pressed = false; + repeat = 0; + } +}; + +static std::vector leftControllerMapping = { + ButtonMapping(NKCODE_BUTTON_X, ovrButton_X), + ButtonMapping(NKCODE_BUTTON_Y, ovrButton_Y), + ButtonMapping(NKCODE_ALT_LEFT, ovrButton_GripTrigger), + ButtonMapping(NKCODE_DPAD_UP, ovrButton_Up), + ButtonMapping(NKCODE_DPAD_DOWN, ovrButton_Down), + ButtonMapping(NKCODE_DPAD_LEFT, ovrButton_Left), + ButtonMapping(NKCODE_DPAD_RIGHT, ovrButton_Right), + ButtonMapping(NKCODE_BUTTON_THUMBL, ovrButton_LThumb), + ButtonMapping(NKCODE_ENTER, ovrButton_Trigger), + ButtonMapping(NKCODE_BACK, ovrButton_Enter), +}; + +static std::vector rightControllerMapping = { + ButtonMapping(NKCODE_BUTTON_A, ovrButton_A), + ButtonMapping(NKCODE_BUTTON_B, ovrButton_B), + ButtonMapping(NKCODE_ALT_RIGHT, ovrButton_GripTrigger), + ButtonMapping(NKCODE_DPAD_UP, ovrButton_Up), + ButtonMapping(NKCODE_DPAD_DOWN, ovrButton_Down), + ButtonMapping(NKCODE_DPAD_LEFT, ovrButton_Left), + ButtonMapping(NKCODE_DPAD_RIGHT, ovrButton_Right), + ButtonMapping(NKCODE_BUTTON_THUMBR, ovrButton_RThumb), + ButtonMapping(NKCODE_ENTER, ovrButton_Trigger), +}; + +static const int controllerIds[] = {DEVICE_ID_XR_CONTROLLER_LEFT, DEVICE_ID_XR_CONTROLLER_RIGHT}; +static std::vector controllerMapping[2] = { + leftControllerMapping, + rightControllerMapping +}; + +/* +================================================================================ + +VR app flow integration + +================================================================================ +*/ + +bool IsVRBuild() { + return true; +} + +void InitVROnAndroid(void* vm, void* activity, int version, char* name) { + ovrJava java; + java.Vm = (JavaVM*)vm; + java.ActivityObject = (jobject)activity; + java.AppVersion = version; + strcpy(java.AppName, name); + VR_Init(java); + + __DisplaySetFramerate(72); +} + +void EnterVR(bool firstStart) { + if (firstStart) { + VR_EnterVR(VR_GetEngine()); + IN_VRInit(VR_GetEngine()); + } + VR_InitRenderer(VR_GetEngine()); +} + +void GetVRResolutionPerEye(int* width, int* height) { + if (VR_GetEngine()->appState.Instance) { + VR_GetResolution(VR_GetEngine(), width, height); + } +} + +void UpdateVRInput(bool(*NativeKey)(const KeyInput &key), bool haptics) { + KeyInput keyInput = {}; + for (int j = 0; j < 2; j++) { + int status = IN_VRGetButtonState(j); + for (ButtonMapping& m : controllerMapping[j]) { + bool pressed = status & m.ovr; + keyInput.flags = pressed ? KEY_DOWN : KEY_UP; + keyInput.keyCode = m.keycode; + keyInput.deviceId = controllerIds[j]; + + if (m.pressed != pressed) { + if (pressed && haptics) { + INVR_Vibrate(100, j, 1000); + } + NativeKey(keyInput); + m.pressed = pressed; + m.repeat = 0; + } else if (pressed && (m.repeat > 30)) { + keyInput.flags |= KEY_IS_REPEAT; + NativeKey(keyInput); + m.repeat = 0; + } else { + m.repeat++; + } + } + } +} + +void UpdateVRScreenKey(const KeyInput &key) { + std::vector nativeKeys; + if (KeyMap::KeyToPspButton(key.deviceId, key.keyCode, &nativeKeys)) { + for (int& nativeKey : nativeKeys) { + if (nativeKey == CTRL_SCREEN) { + VR_SetConfig(VR_CONFIG_FORCE_2D, key.flags & KEY_DOWN); + } + } + } +} + +/* +================================================================================ + +VR rendering integration + +================================================================================ +*/ + +void BindVRFramebuffer() { + VR_BindFramebuffer(VR_GetEngine()); +} + +bool PreVRRender() { + 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); + return true; + } + return false; +} + +void PostVRRender() { + VR_EndFrame(VR_GetEngine()); +} + +bool IsFlatVRScene() { + return VR_GetConfig(VR_CONFIG_MODE) == VR_MODE_FLAT_SCREEN; +} + +bool Is2DVRObject(float* projMatrix, bool ortho) { + bool is2D = VR_TweakIsMatrixBigScale(projMatrix) || + VR_TweakIsMatrixIdentity(projMatrix) || + VR_TweakIsMatrixOneOrtho(projMatrix) || + VR_TweakIsMatrixOneScale(projMatrix) || + VR_TweakIsMatrixOneTransform(projMatrix); + if (!is2D && !ortho) { + VR_SetConfig(VR_CONFIG_3D_GEOMETRY_COUNT, VR_GetConfig(VR_CONFIG_3D_GEOMETRY_COUNT) + 1); + } + return is2D; +} + +void UpdateVRProjection(float* projMatrix, float* leftEye, float* rightEye) { + VR_TweakProjection(projMatrix, leftEye, VR_PROJECTION_MATRIX_LEFT_EYE); + VR_TweakProjection(projMatrix, rightEye, VR_PROJECTION_MATRIX_RIGHT_EYE); + VR_TweakMirroring(projMatrix); +} + +void UpdateVRView(float* projMatrix, float* leftEye, float* rightEye) { + VR_TweakView(leftEye, projMatrix, VR_VIEW_MATRIX_LEFT_EYE); + VR_TweakView(rightEye, projMatrix, VR_VIEW_MATRIX_RIGHT_EYE); +} diff --git a/Common/VR/PPSSPPVR.h b/Common/VR/PPSSPPVR.h new file mode 100644 index 0000000000..da751f68cd --- /dev/null +++ b/Common/VR/PPSSPPVR.h @@ -0,0 +1,44 @@ +#pragma once + +#include "Common/Input/InputState.h" +#include "Common/Input/KeyCodes.h" + +#ifdef OPENXR + +// VR app flow integration +bool IsVRBuild(); +void InitVROnAndroid(void* vm, void* activity, int version, char* name); +void EnterVR(bool firstStart); +void GetVRResolutionPerEye(int* width, int* height); +void UpdateVRInput(bool(*NativeKey)(const KeyInput &key), bool haptics); +void UpdateVRScreenKey(const KeyInput &key); + +// VR rendering integration +void BindVRFramebuffer(); +bool PreVRRender(); +void PostVRRender(); +bool IsFlatVRScene(); +bool Is2DVRObject(float* projMatrix, bool ortho); +void UpdateVRProjection(float* projMatrix, float* leftEye, float* rightEye); +void UpdateVRView(float* projMatrix, float* leftEye, float* rightEye); + +#else //dummy integration + +// VR app flow integration +bool IsVRBuild() { return false; } +void InitVROnAndroid(void* vm, void* activity, int version, char* name) {} +void EnterVR(bool firstTime) {} +void GetVRResolutionPerEye(int* width, int* height) {} +void UpdateVRInput(bool(*NativeKey)(const KeyInput &key), bool haptics) {} +void UpdateVRScreenKey(const KeyInput &key) {} + +// VR rendering integration +void BindVRFramebuffer() {} +bool PreVRRender() { return false; } +void PostVRRender() {} +bool IsFlatVRScene() { return true; } +bool Is2DVRObject(float* projMatrix, bool ortho) { return false; } +void UpdateVRProjection(float* projMatrix, float* leftEye, float* rightEye) {} +void UpdateVRView(float* projMatrix, float* leftEye, float* rightEye) {} + +#endif diff --git a/Core/Config.cpp b/Core/Config.cpp index dd191593cb..3c24061088 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -44,6 +44,7 @@ #include "Common/System/System.h" #include "Common/StringUtils.h" #include "Common/GPU/Vulkan/VulkanLoader.h" +#include "Common/VR/PPSSPPVR.h" #include "Core/Config.h" #include "Core/ConfigValues.h" #include "Core/Loaders.h" @@ -695,9 +696,9 @@ const char * const vulkanDefaultBlacklist[] = { }; static int DefaultGPUBackend() { -#ifdef OPENXR - return (int)GPUBackend::OPENGL; -#endif + if (IsVRBuild()) { + return (int)GPUBackend::OPENGL; + } #if PPSSPP_PLATFORM(WINDOWS) // If no Vulkan, use Direct3D 11 on Windows 8+ (most importantly 10.) diff --git a/Core/KeyMap.cpp b/Core/KeyMap.cpp index 2a4cf3f458..b0a3b69c7e 100644 --- a/Core/KeyMap.cpp +++ b/Core/KeyMap.cpp @@ -25,6 +25,7 @@ #include "Common/System/System.h" #include "Common/Data/Format/IniFile.h" #include "Common/Input/InputState.h" +#include "Common/VR/PPSSPPVR.h" #include "Common/Log.h" #include "Common/StringUtils.h" #include "Core/HLE/sceUtility.h" @@ -654,10 +655,11 @@ void SetAxisMapping(int btn, int deviceId, int axisId, int direction, bool repla void RestoreDefault() { g_controllerMap.clear(); g_controllerMapGeneration++; -#ifdef OPENXR - SetDefaultKeyMap(DEFAULT_MAPPING_VR_HEADSET, false); - return; -#endif + + if (IsVRBuild()) { + SetDefaultKeyMap(DEFAULT_MAPPING_VR_HEADSET, false); + return; + } #if PPSSPP_PLATFORM(WINDOWS) SetDefaultKeyMap(DEFAULT_MAPPING_KEYBOARD, true); diff --git a/GPU/Common/PresentationCommon.cpp b/GPU/Common/PresentationCommon.cpp index 1603234ad0..552e62a0c5 100644 --- a/GPU/Common/PresentationCommon.cpp +++ b/GPU/Common/PresentationCommon.cpp @@ -24,6 +24,7 @@ #include "Common/System/Display.h" #include "Common/System/System.h" #include "Common/File/VFS/VFS.h" +#include "Common/VR/PPSSPPVR.h" #include "Common/Log.h" #include "Common/TimeUtil.h" #include "Core/Config.h" @@ -35,10 +36,6 @@ #include "GPU/Common/PresentationCommon.h" #include "Common/GPU/ShaderTranslation.h" -#ifdef OPENXR -#include "VR/VRRenderer.h" -#endif - struct Vertex { float x, y, z; float u, v; @@ -77,13 +74,13 @@ void CenterDisplayOutputRect(FRect *rc, float origW, float origH, const FRect &f bool rotated = rotation == ROTATION_LOCKED_VERTICAL || rotation == ROTATION_LOCKED_VERTICAL180; -#ifdef OPENXR - if (VR_GetConfig(VR_CONFIG_MODE) == VR_MODE_FLAT_SCREEN) { - g_Config.iSmallDisplayZoomType = (int)SmallDisplayZoom::AUTO; - } else { - g_Config.iSmallDisplayZoomType = (int)SmallDisplayZoom::STRETCH; + if (IsVRBuild()) { + if (IsFlatVRScene()) { + g_Config.iSmallDisplayZoomType = (int)SmallDisplayZoom::AUTO; + } else { + g_Config.iSmallDisplayZoomType = (int)SmallDisplayZoom::STRETCH; + } } -#endif if (g_Config.iSmallDisplayZoomType == (int)SmallDisplayZoom::STRETCH) { outW = frame.w; diff --git a/GPU/Common/VertexShaderGenerator.cpp b/GPU/Common/VertexShaderGenerator.cpp index ca33596519..aee415cbb0 100644 --- a/GPU/Common/VertexShaderGenerator.cpp +++ b/GPU/Common/VertexShaderGenerator.cpp @@ -23,6 +23,7 @@ #include "Common/GPU/OpenGL/GLFeatures.h" #include "Common/GPU/ShaderWriter.h" #include "Common/GPU/thin3d.h" +#include "Common/VR/PPSSPPVR.h" #include "Core/Config.h" #include "GPU/ge_constants.h" #include "GPU/GPUState.h" @@ -151,9 +152,9 @@ bool GenerateVertexShader(const VShaderID &id, char *buffer, const ShaderLanguag gl_exts.push_back("#extension GL_ARB_cull_distance : enable"); } } -#ifdef OPENXR - gl_exts.push_back("#extension GL_OVR_multiview2 : enable\nlayout(num_views=2) in;"); -#endif + if (IsVRBuild()) { + gl_exts.push_back("#extension GL_OVR_multiview2 : enable\nlayout(num_views=2) in;"); + } ShaderWriter p(buffer, compat, ShaderStage::Vertex, gl_exts.data(), gl_exts.size()); bool isModeThrough = id.Bit(VS_BIT_IS_THROUGH); @@ -472,11 +473,11 @@ bool GenerateVertexShader(const VShaderID &id, char *buffer, const ShaderLanguag WRITE(p, "uniform mat4 u_proj_through;\n"); *uniformMask |= DIRTY_PROJTHROUGHMATRIX; } else if (useHWTransform) { -#ifdef OPENXR - WRITE(p, "layout(shared) uniform ProjectionMatrix { uniform mat4 u_proj[2]; };\n"); -#else - WRITE(p, "uniform mat4 u_proj;\n"); -#endif + if (IsVRBuild()) { + WRITE(p, "layout(shared) uniform ProjectionMatrix { uniform mat4 u_proj[2]; };\n"); + } else { + WRITE(p, "uniform mat4 u_proj;\n"); + } *uniformMask |= DIRTY_PROJMATRIX; } @@ -484,11 +485,11 @@ bool GenerateVertexShader(const VShaderID &id, char *buffer, const ShaderLanguag // When transforming by hardware, we need a great deal more uniforms... // TODO: Use 4x3 matrices where possible. Though probably doesn't matter much. WRITE(p, "uniform mat4 u_world;\n"); -#ifdef OPENXR - WRITE(p, "layout(shared) uniform ViewMatrices { uniform mat4 u_view[2]; };\n"); -#else - WRITE(p, "uniform mat4 u_view;\n"); -#endif + if (IsVRBuild()) { + WRITE(p, "layout(shared) uniform ViewMatrices { uniform mat4 u_view[2]; };\n"); + } else { + WRITE(p, "uniform mat4 u_view;\n"); + } *uniformMask |= DIRTY_WORLDMATRIX | DIRTY_VIEWMATRIX; if (doTextureTransform) { WRITE(p, "uniform mediump mat4 u_texmtx;\n"); @@ -545,10 +546,10 @@ bool GenerateVertexShader(const VShaderID &id, char *buffer, const ShaderLanguag WRITE(p, "uniform lowp float u_rotation;\n"); } -#ifdef OPENXR - WRITE(p, "uniform lowp float u_scaleX;\n"); - WRITE(p, "uniform lowp float u_scaleY;\n"); -#endif + if (IsVRBuild()) { + WRITE(p, "uniform lowp float u_scaleX;\n"); + WRITE(p, "uniform lowp float u_scaleY;\n"); + } if (useHWTransform || !hasColor) { WRITE(p, "uniform lowp vec4 u_matambientalpha;\n"); // matambient + matalpha @@ -912,9 +913,9 @@ bool GenerateVertexShader(const VShaderID &id, char *buffer, const ShaderLanguag } std::string matrixPostfix; -#ifdef OPENXR - matrixPostfix = "[gl_ViewID_OVR]"; -#endif + if (IsVRBuild()) { + matrixPostfix = "[gl_ViewID_OVR]"; + } WRITE(p, " vec4 viewPos = vec4(mul(vec4(worldpos, 1.0), u_view%s).xyz, 1.0);\n", matrixPostfix.c_str()); @@ -1204,12 +1205,13 @@ bool GenerateVertexShader(const VShaderID &id, char *buffer, const ShaderLanguag WRITE(p, " if (%sgl_Position.z == %sgl_Position.w) %sgl_Position.z *= 0.999999;\n", compat.vsOutPrefix, compat.vsOutPrefix, compat.vsOutPrefix); } -#ifdef OPENXR - WRITE(p, " if ((u_scaleX < 0.99) || (u_scaleY < 0.99)) {\n"); - WRITE(p, " %sgl_Position.x *= u_scaleX;\n", compat.vsOutPrefix); - WRITE(p, " %sgl_Position.y *= u_scaleY;\n", compat.vsOutPrefix); - WRITE(p, " }\n"); -#endif + + if (IsVRBuild()) { + WRITE(p, " if ((u_scaleX < 0.99) || (u_scaleY < 0.99)) {\n"); + WRITE(p, " %sgl_Position.x *= u_scaleX;\n", compat.vsOutPrefix); + WRITE(p, " %sgl_Position.y *= u_scaleY;\n", compat.vsOutPrefix); + WRITE(p, " }\n"); + } if (compat.shaderLanguage == HLSL_D3D11 || compat.shaderLanguage == HLSL_D3D9) { WRITE(p, " return Out;\n"); diff --git a/GPU/GLES/ShaderManagerGLES.cpp b/GPU/GLES/ShaderManagerGLES.cpp index 8fbf0770f4..f4cbc27aab 100644 --- a/GPU/GLES/ShaderManagerGLES.cpp +++ b/GPU/GLES/ShaderManagerGLES.cpp @@ -34,6 +34,7 @@ #include "Common/GPU/thin3d.h" #include "Common/GPU/OpenGL/GLRenderManager.h" #include "Common/System/Display.h" +#include "Common/VR/PPSSPPVR.h" #include "Common/Log.h" #include "Common/File/FileUtil.h" @@ -50,12 +51,6 @@ #include "GPU/GLES/DrawEngineGLES.h" #include "GPU/GLES/FramebufferManagerGLES.h" -#ifdef OPENXR -#include "VR/VRBase.h" -#include "VR/VRRenderer.h" -#include "VR/VRTweaks.h" -#endif - using namespace Lin; Shader::Shader(GLRenderManager *render, const char *code, const std::string &desc, const ShaderDescGLES ¶ms) @@ -132,10 +127,11 @@ LinkedShader::LinkedShader(GLRenderManager *render, VShaderID VSID, Shader *vs, queries.push_back({ &u_cullRangeMin, "u_cullRangeMin" }); queries.push_back({ &u_cullRangeMax, "u_cullRangeMax" }); queries.push_back({ &u_rotation, "u_rotation" }); -#ifdef OPENXR - queries.push_back({ &u_scaleX, "u_scaleX" }); - queries.push_back({ &u_scaleY, "u_scaleY" }); -#endif + + if (IsVRBuild()) { + queries.push_back({ &u_scaleX, "u_scaleX" }); + queries.push_back({ &u_scaleY, "u_scaleY" }); + } #ifdef USE_BONE_ARRAY queries.push_back({ &u_bone, "u_bone" }); @@ -354,9 +350,10 @@ void LinkedShader::use(const ShaderID &VSID) { void LinkedShader::UpdateUniforms(u32 vertType, const ShaderID &vsid, bool useBufferedRendering) { u64 dirty = dirtyUniforms & availableUniforms; dirtyUniforms = 0; -#ifdef OPENXR - dirty |= DIRTY_VIEWMATRIX; -#endif + + if (IsVRBuild()) { + dirty |= DIRTY_VIEWMATRIX; + } if (!dirty) return; @@ -371,63 +368,55 @@ void LinkedShader::UpdateUniforms(u32 vertType, const ShaderID &vsid, bool useBu render_->SetUniformUI1(&u_depal_mask_shift_off_fmt, val); } -#ifdef OPENXR - // Count 3D instances - bool is2D = VR_TweakIsMatrixBigScale(gstate.projMatrix) || - VR_TweakIsMatrixIdentity(gstate.projMatrix) || - VR_TweakIsMatrixOneOrtho(gstate.projMatrix) || - VR_TweakIsMatrixOneScale(gstate.projMatrix) || - VR_TweakIsMatrixOneTransform(gstate.projMatrix); - if (!is2D && !gstate.isModeThrough()) { - VR_SetConfig(VR_CONFIG_3D_GEOMETRY_COUNT, VR_GetConfig(VR_CONFIG_3D_GEOMETRY_COUNT) + 1); - } + bool is2D, flatScreen; + if (IsVRBuild()) { + // Analyze scene + is2D = Is2DVRObject(gstate.projMatrix, gstate.isModeThrough()); + flatScreen = IsFlatVRScene(); - // Set HUD mode - bool is3D = gstate.isDepthWriteEnabled(); - bool flatScreen = VR_GetConfig(VR_CONFIG_MODE) == VR_MODE_FLAT_SCREEN; - bool hud = is2D && !is3D && !flatScreen && - gstate.isModeThrough() && //2D content requires orthographic projection - gstate.isAlphaBlendEnabled() && //2D content has to be blended - !gstate.isLightingEnabled() && //2D content cannot be rendered with lights on - !gstate.isFogEnabled(); //2D content cannot be rendered with fog on - if (hud) { - float scale = 0.5f; - render_->SetUniformF1(&u_scaleX, scale); - render_->SetUniformF1(&u_scaleY, scale / 480.0f * 272.0f); - } else { - render_->SetUniformF1(&u_scaleX, 1.0f); - render_->SetUniformF1(&u_scaleY, 1.0f); + // Set HUD mode + bool is3D = gstate.isDepthWriteEnabled(); + bool hud = is2D && !is3D && !flatScreen && + gstate.isModeThrough() && //2D content requires orthographic projection + gstate.isAlphaBlendEnabled() && //2D content has to be blended + !gstate.isLightingEnabled() && //2D content cannot be rendered with lights on + !gstate.isFogEnabled(); //2D content cannot be rendered with fog on + if (hud) { + float scale = 0.5f; + render_->SetUniformF1(&u_scaleX, scale); + render_->SetUniformF1(&u_scaleY, scale / 480.0f * 272.0f); + } else { + render_->SetUniformF1(&u_scaleX, 1.0f); + render_->SetUniformF1(&u_scaleY, 1.0f); + } } -#endif // Update any dirty uniforms before we draw if (dirty & DIRTY_PROJMATRIX) { -#ifdef OPENXR - Matrix4x4 leftEyeMatrix, rightEyeMatrix; - if (flatScreen || is2D) { - memcpy(&leftEyeMatrix, gstate.projMatrix, 16 * sizeof(float)); - memcpy(&rightEyeMatrix, gstate.projMatrix, 16 * sizeof(float)); + if (IsVRBuild()) { + Matrix4x4 leftEyeMatrix, rightEyeMatrix; + if (flatScreen || is2D) { + memcpy(&leftEyeMatrix, gstate.projMatrix, 16 * sizeof(float)); + memcpy(&rightEyeMatrix, gstate.projMatrix, 16 * sizeof(float)); + } else { + UpdateVRProjection(gstate.projMatrix, leftEyeMatrix.m, rightEyeMatrix.m); + } + + FlipProjMatrix(leftEyeMatrix, useBufferedRendering); + FlipProjMatrix(rightEyeMatrix, useBufferedRendering); + ScaleProjMatrix(leftEyeMatrix, useBufferedRendering); + ScaleProjMatrix(rightEyeMatrix, useBufferedRendering); + + render_->SetUniformM4x4Stereo("u_proj", &u_proj, leftEyeMatrix.m, rightEyeMatrix.m); } else { - VR_TweakProjection(gstate.projMatrix, leftEyeMatrix.m, VR_PROJECTION_MATRIX_LEFT_EYE); - VR_TweakProjection(gstate.projMatrix, rightEyeMatrix.m, VR_PROJECTION_MATRIX_RIGHT_EYE); - VR_TweakMirroring(gstate.projMatrix); + Matrix4x4 flippedMatrix; + memcpy(&flippedMatrix, gstate.projMatrix, 16 * sizeof(float)); + + FlipProjMatrix(flippedMatrix, useBufferedRendering); + ScaleProjMatrix(flippedMatrix, useBufferedRendering); + + render_->SetUniformM4x4(&u_proj, flippedMatrix.m); } - - FlipProjMatrix(leftEyeMatrix, useBufferedRendering); - FlipProjMatrix(rightEyeMatrix, useBufferedRendering); - ScaleProjMatrix(leftEyeMatrix, useBufferedRendering); - ScaleProjMatrix(rightEyeMatrix, useBufferedRendering); - - render_->SetUniformM4x4Stereo("u_proj", &u_proj, leftEyeMatrix.m, rightEyeMatrix.m); -#else - Matrix4x4 flippedMatrix; - memcpy(&flippedMatrix, gstate.projMatrix, 16 * sizeof(float)); - - FlipProjMatrix(flippedMatrix, useBufferedRendering); - ScaleProjMatrix(flippedMatrix, useBufferedRendering); - - render_->SetUniformM4x4(&u_proj, flippedMatrix.m); -#endif render_->SetUniformF1(&u_rotation, useBufferedRendering ? 0 : (float)g_display_rotation); } if (dirty & DIRTY_PROJTHROUGHMATRIX) @@ -533,19 +522,18 @@ void LinkedShader::UpdateUniforms(u32 vertType, const ShaderID &vsid, bool useBu SetMatrix4x3(render_, &u_world, gstate.worldMatrix); } if (dirty & DIRTY_VIEWMATRIX) { -#ifdef OPENXR - float leftEyeView[16]; - float rightEyeView[16]; - ConvertMatrix4x3To4x4Transposed(leftEyeView, gstate.viewMatrix); - ConvertMatrix4x3To4x4Transposed(rightEyeView, gstate.viewMatrix); - if (!flatScreen && !is2D) { - VR_TweakView(leftEyeView, gstate.projMatrix, VR_VIEW_MATRIX_LEFT_EYE); - VR_TweakView(rightEyeView, gstate.projMatrix, VR_VIEW_MATRIX_RIGHT_EYE); + if (IsVRBuild()) { + float leftEyeView[16]; + float rightEyeView[16]; + ConvertMatrix4x3To4x4Transposed(leftEyeView, gstate.viewMatrix); + ConvertMatrix4x3To4x4Transposed(rightEyeView, gstate.viewMatrix); + if (!flatScreen && !is2D) { + UpdateVRView(gstate.projMatrix, leftEyeView, rightEyeView); + } + render_->SetUniformM4x4Stereo("u_view", &u_view, leftEyeView, rightEyeView); + } else { + SetMatrix4x3(render_, &u_view, gstate.viewMatrix); } - render_->SetUniformM4x4Stereo("u_view", &u_view, leftEyeView, rightEyeView); -#else - SetMatrix4x3(render_, &u_view, gstate.viewMatrix); -#endif } if (dirty & DIRTY_TEXMATRIX) { SetMatrix4x3(render_, &u_texmtx, gstate.tgenMatrix); diff --git a/UI/NativeApp.cpp b/UI/NativeApp.cpp index d740c323bc..82c380ebca 100644 --- a/UI/NativeApp.cpp +++ b/UI/NativeApp.cpp @@ -78,6 +78,7 @@ #include "Common/GraphicsContext.h" #include "Common/OSVersion.h" #include "Common/GPU/ShaderTranslation.h" +#include "Common/VR/PPSSPPVR.h" #include "Core/ControlMapper.h" #include "Core/Config.h" @@ -142,10 +143,6 @@ #include #endif -#ifdef OPENXR -#include "VR/VRRenderer.h" -#endif - ScreenManager *screenManager; std::string config_filename; @@ -1302,17 +1299,10 @@ bool NativeTouch(const TouchInput &touch) { bool NativeKey(const KeyInput &key) { - // Hack to quick enable 2D mode in VR game mode. -#ifdef OPENXR - std::vector nativeKeys; - if (KeyMap::KeyToPspButton(key.deviceId, key.keyCode, &nativeKeys)) { - for (int& nativeKey : nativeKeys) { - if (nativeKey == CTRL_SCREEN) { - VR_SetConfig(VR_CONFIG_FORCE_2D, key.flags & KEY_DOWN); - } - } + // Hack to quickly enable 2D mode in VR game mode. + if (IsVRBuild()) { + UpdateVRScreenKey(key); } -#endif // INFO_LOG(SYSTEM, "Key code: %i flags: %i", key.keyCode, key.flags); #if !defined(MOBILE_DEVICE) diff --git a/android/jni/AndroidEGLContext.cpp b/android/jni/AndroidEGLContext.cpp index 937ce727b9..9507c217e6 100644 --- a/android/jni/AndroidEGLContext.cpp +++ b/android/jni/AndroidEGLContext.cpp @@ -3,6 +3,7 @@ #include "Common/Log.h" #include "Common/System/System.h" +#include "Common/VR/PPSSPPVR.h" #include "AndroidEGLContext.h" #include "GL/GLInterface/EGLAndroid.h" #include "Core/Config.h" @@ -46,11 +47,7 @@ bool AndroidEGLGraphicsContext::InitFromRenderThread(ANativeWindow *wnd, int des } gl->MakeCurrent(); if (gl->GetMode() == GLInterfaceMode::MODE_OPENGL) -#ifdef OPENXR - SetGLCoreContext(false); -#else - SetGLCoreContext(true); -#endif + SetGLCoreContext(!IsVRBuild()); CheckGLExtensions(); draw_ = Draw::T3DCreateGLContext(); SetGPUBackend(GPUBackend::OPENGL); diff --git a/android/jni/app-android.cpp b/android/jni/app-android.cpp index f913e62489..6cc3ea0885 100644 --- a/android/jni/app-android.cpp +++ b/android/jni/app-android.cpp @@ -70,6 +70,7 @@ struct JNIEnv {}; #include "Common/Profiler/Profiler.h" #include "Common/Math/math_util.h" #include "Common/Data/Text/Parsers.h" +#include "Common/VR/PPSSPPVR.h" #include "Common/Log.h" #include "Common/GraphicsContext.h" @@ -93,58 +94,6 @@ struct JNIEnv {}; #include "Common/Log.h" #include "UI/GameInfoCache.h" -#ifdef OPENXR -#include "Core/HLE/sceDisplay.h" -#include "VR/VRBase.h" -#include "VR/VRInput.h" -#include "VR/VRRenderer.h" - -struct ButtonMapping { - ovrButton ovr; - int keycode; - bool pressed; - int repeat; - - ButtonMapping(int keycode, ovrButton ovr) { - this->keycode = keycode; - this->ovr = ovr; - pressed = false; - repeat = 0; - } -}; - -static std::vector leftControllerMapping = { - ButtonMapping(NKCODE_BUTTON_X, ovrButton_X), - ButtonMapping(NKCODE_BUTTON_Y, ovrButton_Y), - ButtonMapping(NKCODE_ALT_LEFT, ovrButton_GripTrigger), - ButtonMapping(NKCODE_DPAD_UP, ovrButton_Up), - ButtonMapping(NKCODE_DPAD_DOWN, ovrButton_Down), - ButtonMapping(NKCODE_DPAD_LEFT, ovrButton_Left), - ButtonMapping(NKCODE_DPAD_RIGHT, ovrButton_Right), - ButtonMapping(NKCODE_BUTTON_THUMBL, ovrButton_LThumb), - ButtonMapping(NKCODE_ENTER, ovrButton_Trigger), - ButtonMapping(NKCODE_BACK, ovrButton_Enter), -}; - -static std::vector rightControllerMapping = { - ButtonMapping(NKCODE_BUTTON_A, ovrButton_A), - ButtonMapping(NKCODE_BUTTON_B, ovrButton_B), - ButtonMapping(NKCODE_ALT_RIGHT, ovrButton_GripTrigger), - ButtonMapping(NKCODE_DPAD_UP, ovrButton_Up), - ButtonMapping(NKCODE_DPAD_DOWN, ovrButton_Down), - ButtonMapping(NKCODE_DPAD_LEFT, ovrButton_Left), - ButtonMapping(NKCODE_DPAD_RIGHT, ovrButton_Right), - ButtonMapping(NKCODE_BUTTON_THUMBR, ovrButton_RThumb), - ButtonMapping(NKCODE_ENTER, ovrButton_Trigger), -}; - -static const int controllerIds[] = {DEVICE_ID_XR_CONTROLLER_LEFT, DEVICE_ID_XR_CONTROLLER_RIGHT}; -static std::vector controllerMapping[2] = { - leftControllerMapping, - rightControllerMapping -}; -#endif - #include "app-android.h" bool useCPUThread = true; @@ -808,17 +757,10 @@ retry: EmuThreadStart(); } -#ifdef OPENXR - Version gitVer(PPSSPP_GIT_VERSION); - ovrJava java; - java.Vm = gJvm; - java.ActivityObject = nativeActivity; - java.AppVersion = gitVer.ToInteger(); - strcpy(java.AppName, "PPSSPP"); - VR_Init(java); - - __DisplaySetFramerate(72); -#endif + if (IsVRBuild()) { + Version gitVer(PPSSPP_GIT_VERSION); + InitVROnAndroid(gJvm, nativeActivity, gitVer.ToInteger(), "PPSSPP"); + } } extern "C" void Java_org_ppsspp_ppsspp_NativeApp_audioInit(JNIEnv *, jclass) { @@ -997,13 +939,9 @@ extern "C" bool Java_org_ppsspp_ppsspp_NativeRenderer_displayInit(JNIEnv * env, } NativeMessageReceived("recreateviews", ""); -#ifdef OPENXR - if (firstStart) { - VR_EnterVR(VR_GetEngine()); - IN_VRInit(VR_GetEngine()); + if (IsVRBuild()) { + EnterVR(firstStart); } - VR_InitRenderer(VR_GetEngine()); -#endif return true; } @@ -1043,11 +981,10 @@ extern "C" void JNICALL Java_org_ppsspp_ppsspp_NativeApp_backbufferResize(JNIEnv pixel_xres = bufw; pixel_yres = bufh; backbuffer_format = format; -#ifdef OPENXR - if (VR_GetEngine()->appState.Instance) { - VR_GetResolution(VR_GetEngine(), &pixel_xres, &pixel_yres); + + if (IsVRBuild()) { + GetVRResolutionPerEye(&pixel_xres, &pixel_yres); } -#endif recalculateDpi(); @@ -1128,33 +1065,9 @@ extern "C" void Java_org_ppsspp_ppsspp_NativeRenderer_displayRender(JNIEnv *env, UpdateRunLoopAndroid(env); } -#ifdef OPENXR - KeyInput keyInput = {}; - for (int j = 0; j < 2; j++) { - int status = IN_VRGetButtonState(j); - for (ButtonMapping& m : controllerMapping[j]) { - bool pressed = status & m.ovr; - keyInput.flags = pressed ? KEY_DOWN : KEY_UP; - keyInput.keyCode = m.keycode; - keyInput.deviceId = controllerIds[j]; - - if (m.pressed != pressed) { - if (pressed && g_Config.bHapticFeedback) { - INVR_Vibrate(100, j, 1000); - } - NativeKey(keyInput); - m.pressed = pressed; - m.repeat = 0; - } else if (pressed && (m.repeat > 30)) { - keyInput.flags |= KEY_IS_REPEAT; - NativeKey(keyInput); - m.repeat = 0; - } else { - m.repeat++; - } - } + if (IsVRBuild()) { + UpdateVRInput(NativeKey, g_Config.bHapticFeedback); } -#endif } void System_AskForPermission(SystemPermission permission) { @@ -1373,15 +1286,14 @@ void getDesiredBackbufferSize(int &sz_x, int &sz_y) { extern "C" void JNICALL Java_org_ppsspp_ppsspp_NativeApp_setDisplayParameters(JNIEnv *, jclass, jint xres, jint yres, jint dpi, jfloat refreshRate) { INFO_LOG(G3D, "NativeApp.setDisplayParameters(%d x %d, dpi=%d, refresh=%0.2f)", xres, yres, dpi, refreshRate); -#ifdef OPENXR - if (VR_GetEngine()->appState.Instance) { + + if (IsVRBuild()) { int width, height; - VR_GetResolution(VR_GetEngine(), &width, &height); + GetVRResolutionPerEye(&width, &height); xres = width; yres = height; dpi = 320; } -#endif bool changed = false; changed = changed || display_xres != xres || display_yres != yres;