diff --git a/Common/VR/PPSSPPVR.cpp b/Common/VR/PPSSPPVR.cpp index e9d40b3cbc..f39f1bcc1d 100644 --- a/Common/VR/PPSSPPVR.cpp +++ b/Common/VR/PPSSPPVR.cpp @@ -150,10 +150,11 @@ void InitVROnAndroid(void* vm, void* activity, const char* system, int version, //Set platform flags if (strcmp(vendor, "PICO") == 0) { VR_SetPlatformFLag(VR_PLATFORM_CONTROLLER_PICO, true); - VR_SetPlatformFLag(VR_PLATFORM_INSTANCE_EXT, true); + VR_SetPlatformFLag(VR_PLATFORM_EXTENSION_INSTANCE, true); } else if ((strcmp(vendor, "META") == 0) || (strcmp(vendor, "OCULUS") == 0)) { VR_SetPlatformFLag(VR_PLATFORM_CONTROLLER_QUEST, true); - VR_SetPlatformFLag(VR_PLATFORM_PERFORMANCE_EXT, true); + VR_SetPlatformFLag(VR_PLATFORM_EXTENSION_FOVEATION, true); + VR_SetPlatformFLag(VR_PLATFORM_EXTENSION_PERFORMANCE, true); } VR_SetPlatformFLag(VR_PLATFORM_RENDERER_VULKAN, (GPUBackend)g_Config.iGPUBackend == GPUBackend::VULKAN); diff --git a/Common/VR/VRBase.cpp b/Common/VR/VRBase.cpp index 3ada93d754..715ea6644e 100644 --- a/Common/VR/VRBase.cpp +++ b/Common/VR/VRBase.cpp @@ -49,10 +49,19 @@ void VR_Init( void* system, const char* name, int version ) { } extensions.push_back(XR_KHR_COMPOSITION_LAYER_CYLINDER_EXTENSION_NAME); #ifdef ANDROID - if (VR_GetPlatformFlag(VR_PLATFORM_INSTANCE_EXT)) { + if (VR_GetPlatformFlag(VR_PLATFORM_EXTENSION_FOVEATION)) { + extensions.push_back(XR_FB_SWAPCHAIN_UPDATE_STATE_EXTENSION_NAME); + extensions.push_back(XR_FB_SWAPCHAIN_UPDATE_STATE_OPENGL_ES_EXTENSION_NAME); + extensions.push_back(XR_FB_FOVEATION_EXTENSION_NAME); + extensions.push_back(XR_FB_FOVEATION_CONFIGURATION_EXTENSION_NAME); + if (VR_GetPlatformFlag(VR_PLATFORM_RENDERER_VULKAN)) { + extensions.push_back(XR_FB_SWAPCHAIN_UPDATE_STATE_VULKAN_EXTENSION_NAME); + } + } + if (VR_GetPlatformFlag(VR_PLATFORM_EXTENSION_INSTANCE)) { extensions.push_back(XR_KHR_ANDROID_CREATE_INSTANCE_EXTENSION_NAME); } - if (VR_GetPlatformFlag(VR_PLATFORM_PERFORMANCE_EXT)) { + if (VR_GetPlatformFlag(VR_PLATFORM_EXTENSION_PERFORMANCE)) { extensions.push_back(XR_EXT_PERFORMANCE_SETTINGS_EXTENSION_NAME); extensions.push_back(XR_KHR_ANDROID_THREAD_SETTINGS_EXTENSION_NAME); } @@ -80,7 +89,7 @@ void VR_Init( void* system, const char* name, int version ) { #ifdef ANDROID XrInstanceCreateInfoAndroidKHR instanceCreateInfoAndroid = {XR_TYPE_INSTANCE_CREATE_INFO_ANDROID_KHR}; - if (VR_GetPlatformFlag(VR_PLATFORM_INSTANCE_EXT)) { + if (VR_GetPlatformFlag(VR_PLATFORM_EXTENSION_INSTANCE)) { ovrJava* java = (ovrJava*)system; instanceCreateInfoAndroid.applicationVM = java->Vm; instanceCreateInfoAndroid.applicationActivity = java->ActivityObject; diff --git a/Common/VR/VRBase.h b/Common/VR/VRBase.h index 7ed105c846..2d3405f8a7 100644 --- a/Common/VR/VRBase.h +++ b/Common/VR/VRBase.h @@ -120,8 +120,9 @@ typedef struct { enum VRPlatformFlag { VR_PLATFORM_CONTROLLER_PICO, VR_PLATFORM_CONTROLLER_QUEST, - VR_PLATFORM_INSTANCE_EXT, - VR_PLATFORM_PERFORMANCE_EXT, + VR_PLATFORM_EXTENSION_FOVEATION, + VR_PLATFORM_EXTENSION_INSTANCE, + VR_PLATFORM_EXTENSION_PERFORMANCE, VR_PLATFORM_RENDERER_VULKAN, VR_PLATFORM_TRACKING_FLOOR, VR_PLATFORM_MAX diff --git a/Common/VR/VRFramebuffer.cpp b/Common/VR/VRFramebuffer.cpp index 6d8b94177a..4f53b9eb25 100644 --- a/Common/VR/VRFramebuffer.cpp +++ b/Common/VR/VRFramebuffer.cpp @@ -105,6 +105,15 @@ static bool ovrFramebuffer_CreateGLES(XrSession session, ovrFramebuffer* frameBu swapChainCreateInfo.mipCount = 1; swapChainCreateInfo.arraySize = multiview ? 2 : 1; +#ifdef ANDROID + if (VR_GetPlatformFlag(VR_PLATFORM_EXTENSION_FOVEATION)) { + XrSwapchainCreateInfoFoveationFB swapChainFoveationCreateInfo; + memset(&swapChainFoveationCreateInfo, 0, sizeof(swapChainFoveationCreateInfo)); + swapChainFoveationCreateInfo.type = XR_TYPE_SWAPCHAIN_CREATE_INFO_FOVEATION_FB; + swapChainCreateInfo.next = &swapChainFoveationCreateInfo; + } +#endif + frameBuffer->ColorSwapChain.Width = swapChainCreateInfo.width; frameBuffer->ColorSwapChain.Height = swapChainCreateInfo.height; @@ -198,6 +207,15 @@ static bool ovrFramebuffer_CreateVK(XrSession session, ovrFramebuffer* frameBuff swapChainCreateInfo.mipCount = 1; swapChainCreateInfo.arraySize = multiview ? 2 : 1; +#ifdef ANDROID + if (VR_GetPlatformFlag(VR_PLATFORM_EXTENSION_FOVEATION)) { + XrSwapchainCreateInfoFoveationFB swapChainFoveationCreateInfo; + memset(&swapChainFoveationCreateInfo, 0, sizeof(swapChainFoveationCreateInfo)); + swapChainFoveationCreateInfo.type = XR_TYPE_SWAPCHAIN_CREATE_INFO_FOVEATION_FB; + swapChainCreateInfo.next = &swapChainFoveationCreateInfo; + } +#endif + frameBuffer->ColorSwapChain.Width = swapChainCreateInfo.width; frameBuffer->ColorSwapChain.Height = swapChainCreateInfo.height; @@ -407,6 +425,47 @@ void ovrRenderer_MouseCursor(ovrRenderer* renderer, int x, int y, int sx, int sy } } +#ifdef ANDROID +void ovrRenderer_SetFoveation(XrInstance* instance, XrSession* session, ovrRenderer* renderer, XrFoveationLevelFB level, float verticalOffset, XrFoveationDynamicFB dynamic) { + PFN_xrCreateFoveationProfileFB pfnCreateFoveationProfileFB; + OXR(xrGetInstanceProcAddr(*instance, "xrCreateFoveationProfileFB", (PFN_xrVoidFunction*)(&pfnCreateFoveationProfileFB))); + + PFN_xrDestroyFoveationProfileFB pfnDestroyFoveationProfileFB; + OXR(xrGetInstanceProcAddr(*instance, "xrDestroyFoveationProfileFB", (PFN_xrVoidFunction*)(&pfnDestroyFoveationProfileFB))); + + PFN_xrUpdateSwapchainFB pfnUpdateSwapchainFB; + OXR(xrGetInstanceProcAddr(*instance, "xrUpdateSwapchainFB", (PFN_xrVoidFunction*)(&pfnUpdateSwapchainFB))); + + int instances = renderer->Multiview ? 1 : ovrMaxNumEyes; + for (int eye = 0; eye < instances; eye++) { + XrFoveationLevelProfileCreateInfoFB levelProfileCreateInfo; + memset(&levelProfileCreateInfo, 0, sizeof(levelProfileCreateInfo)); + levelProfileCreateInfo.type = XR_TYPE_FOVEATION_LEVEL_PROFILE_CREATE_INFO_FB; + levelProfileCreateInfo.level = level; + levelProfileCreateInfo.verticalOffset = verticalOffset; + levelProfileCreateInfo.dynamic = dynamic; + + XrFoveationProfileCreateInfoFB profileCreateInfo; + memset(&profileCreateInfo, 0, sizeof(profileCreateInfo)); + profileCreateInfo.type = XR_TYPE_FOVEATION_PROFILE_CREATE_INFO_FB; + profileCreateInfo.next = &levelProfileCreateInfo; + + XrFoveationProfileFB foveationProfile; + + pfnCreateFoveationProfileFB(*session, &profileCreateInfo, &foveationProfile); + + XrSwapchainStateFoveationFB foveationUpdateState; + memset(&foveationUpdateState, 0, sizeof(foveationUpdateState)); + foveationUpdateState.type = XR_TYPE_SWAPCHAIN_STATE_FOVEATION_FB; + foveationUpdateState.profile = foveationProfile; + + pfnUpdateSwapchainFB(renderer->FrameBuffer[eye].ColorSwapChain.Handle, (XrSwapchainStateBaseHeaderFB*)(&foveationUpdateState)); + + pfnDestroyFoveationProfileFB(foveationProfile); + } +} +#endif + /* ================================================================================ @@ -456,7 +515,7 @@ void ovrApp_HandleSessionStateChanges(ovrApp* app, XrSessionState state) { app->SessionActive = (result == XR_SUCCESS); #ifdef ANDROID - if (app->SessionActive && VR_GetPlatformFlag(VR_PLATFORM_PERFORMANCE_EXT)) { + if (app->SessionActive && VR_GetPlatformFlag(VR_PLATFORM_EXTENSION_PERFORMANCE)) { XrPerfSettingsLevelEXT cpuPerfLevel = XR_PERF_SETTINGS_LEVEL_PERFORMANCE_MAX_EXT; XrPerfSettingsLevelEXT gpuPerfLevel = XR_PERF_SETTINGS_LEVEL_PERFORMANCE_MAX_EXT; diff --git a/Common/VR/VRFramebuffer.h b/Common/VR/VRFramebuffer.h index 07a5c19834..49f7484c99 100644 --- a/Common/VR/VRFramebuffer.h +++ b/Common/VR/VRFramebuffer.h @@ -13,3 +13,6 @@ void* ovrFramebuffer_SetCurrent(ovrFramebuffer* frameBuffer); void ovrRenderer_Create(XrSession session, ovrRenderer* renderer, int width, int height, bool multiview, void* vulkanContext); void ovrRenderer_Destroy(ovrRenderer* renderer); void ovrRenderer_MouseCursor(ovrRenderer* renderer, int x, int y, int sx, int sy); +#ifdef ANDROID +void ovrRenderer_SetFoveation(XrInstance* instance, XrSession* session, ovrRenderer* renderer, XrFoveationLevelFB level, float verticalOffset, XrFoveationDynamicFB dynamic); +#endif diff --git a/Common/VR/VRRenderer.cpp b/Common/VR/VRRenderer.cpp index 8a3cc8ef90..5a9a208926 100644 --- a/Common/VR/VRRenderer.cpp +++ b/Common/VR/VRRenderer.cpp @@ -216,6 +216,11 @@ void VR_InitRenderer( engine_t* engine, bool multiview ) { engine->appState.ViewConfigurationView[0].recommendedImageRectWidth, engine->appState.ViewConfigurationView[0].recommendedImageRectHeight, multiview, vulkanContext); +#ifdef ANDROID + if (VR_GetPlatformFlag(VR_PLATFORM_EXTENSION_FOVEATION)) { + ovrRenderer_SetFoveation(&engine->appState.Instance, &engine->appState.Session, &engine->appState.Renderer, XR_FOVEATION_LEVEL_HIGH_TOP_FB, 0, XR_FOVEATION_DYNAMIC_LEVEL_ENABLED_FB); + } +#endif initialized = true; } diff --git a/ext/openxr/openxr.h b/ext/openxr/openxr.h index 2e4dec9fe1..0e38fbc331 100644 --- a/ext/openxr/openxr.h +++ b/ext/openxr/openxr.h @@ -3476,6 +3476,7 @@ typedef enum XrFoveationLevelFB { XR_FOVEATION_LEVEL_LOW_FB = 1, XR_FOVEATION_LEVEL_MEDIUM_FB = 2, XR_FOVEATION_LEVEL_HIGH_FB = 3, + XR_FOVEATION_LEVEL_HIGH_TOP_FB = 4, XR_FOVEATION_LEVEL_MAX_ENUM_FB = 0x7FFFFFFF } XrFoveationLevelFB;