From e332a6908e971cb72497953b3e8bf940f6f1d7e3 Mon Sep 17 00:00:00 2001 From: Vadym Martsynovskyy Date: Fri, 22 Sep 2023 13:13:34 -0700 Subject: [PATCH] openxr quad layers mode uses stereo Summary: The current quad layers implementation uses a single quad layer with `XR_EYE_VISIBILITY_BOTH`. This works but isn't respecting multiview/stereo. This diff adds proper stereo by adding multiple quads with `XR_EYE_VISIBILITY_LEFT` and `XR_EYE_VISIBILITY_RIGHT`, both pointing at different array layers in the swapchain image. Reviewed By: trivedivivek Differential Revision: D49523415 fbshipit-source-id: 27ab92a36736916251284c39b6f8dddb684dd4ff --- shell/openxr/desktop/XrApp.cpp | 42 ++++++++++++++++++++++------------ shell/openxr/mobile/XrApp.cpp | 42 ++++++++++++++++++++++------------ 2 files changed, 56 insertions(+), 28 deletions(-) diff --git a/shell/openxr/desktop/XrApp.cpp b/shell/openxr/desktop/XrApp.cpp index 83bc9de8dd..8007e1f558 100644 --- a/shell/openxr/desktop/XrApp.cpp +++ b/shell/openxr/desktop/XrApp.cpp @@ -516,15 +516,21 @@ void XrApp::render() { void XrApp::endFrame(XrFrameState frameState) { #ifdef USE_COMPOSITION_LAYER_QUAD - XrCompositionLayerQuad layer{}; - layer.next = nullptr; - layer.type = XR_TYPE_COMPOSITION_LAYER_QUAD; - layer.layerFlags = XR_COMPOSITION_LAYER_BLEND_TEXTURE_SOURCE_ALPHA_BIT; - layer.space = stageSpace_; - layer.eyeVisibility = XR_EYE_VISIBILITY_BOTH; - memset(&layer.subImage, 0, sizeof(XrSwapchainSubImage)); - layer.pose = {{0.f, 0.f, 0.f, 1.f}, {0.f, 0.f, 0.f}}; - layer.size = {1.f, 1.f}; + std::array quadLayers{}; + XrEyeVisibility eye = XR_EYE_VISIBILITY_LEFT; + for (auto& layer : quadLayers) { + layer.next = nullptr; + layer.type = XR_TYPE_COMPOSITION_LAYER_QUAD; + layer.layerFlags = XR_COMPOSITION_LAYER_BLEND_TEXTURE_SOURCE_ALPHA_BIT; + layer.space = stageSpace_; + layer.eyeVisibility = eye; + memset(&layer.subImage, 0, sizeof(XrSwapchainSubImage)); + layer.pose = {{0.f, 0.f, 0.f, 1.f}, {0.f, 0.f, 0.f}}; + layer.size = {1.f, 1.f}; + if (eye == XR_EYE_VISIBILITY_LEFT) { + eye = XR_EYE_VISIBILITY_RIGHT; + } + } #endif std::array projectionViews; @@ -574,25 +580,33 @@ void XrApp::endFrame(XrFrameState frameState) { depthInfos[i].nearZ = appParams.depthParams.nearZ; depthInfos[i].farZ = appParams.depthParams.farZ; #ifdef USE_COMPOSITION_LAYER_QUAD - layer.subImage = projectionViews[0].subImage; + quadLayers[i].subImage = projectionViews[i].subImage; #endif } - const XrCompositionLayerBaseHeader* const layers[] = { #ifdef USE_COMPOSITION_LAYER_QUAD - (const XrCompositionLayerBaseHeader*)&layer + std::array quadLayersBase{}; + for (uint32_t i = 0; i < quadLayers.size(); i++) { + quadLayersBase[i] = (const XrCompositionLayerBaseHeader*)&quadLayers[i]; + } #else - (const XrCompositionLayerBaseHeader*)&projection -#endif + const XrCompositionLayerBaseHeader* const layers[] = { + (const XrCompositionLayerBaseHeader*)&projection, }; +#endif XrFrameEndInfo endFrameInfo = { XR_TYPE_FRAME_END_INFO, nullptr, frameState.predictedDisplayTime, XR_ENVIRONMENT_BLEND_MODE_OPAQUE, +#ifdef USE_COMPOSITION_LAYER_QUAD + quadLayersBase.size(), + quadLayersBase.data(), +#else 1, layers, +#endif }; XR_CHECK(xrEndFrame(session_, &endFrameInfo)); diff --git a/shell/openxr/mobile/XrApp.cpp b/shell/openxr/mobile/XrApp.cpp index 2e990b7e13..93bf42ebfd 100644 --- a/shell/openxr/mobile/XrApp.cpp +++ b/shell/openxr/mobile/XrApp.cpp @@ -541,15 +541,21 @@ void XrApp::render() { void XrApp::endFrame(XrFrameState frameState) { #ifdef USE_COMPOSITION_LAYER_QUAD - XrCompositionLayerQuad layer{}; - layer.next = nullptr; - layer.type = XR_TYPE_COMPOSITION_LAYER_QUAD; - layer.layerFlags = XR_COMPOSITION_LAYER_BLEND_TEXTURE_SOURCE_ALPHA_BIT; - layer.space = stageSpace_; - layer.eyeVisibility = XR_EYE_VISIBILITY_BOTH; - memset(&layer.subImage, 0, sizeof(XrSwapchainSubImage)); - layer.pose = {{0.f, 0.f, 0.f, 1.f}, {0.f, 0.f, 0.f}}; - layer.size = {1.f, 1.f}; + std::array quadLayers{}; + XrEyeVisibility eye = XR_EYE_VISIBILITY_LEFT; + for (auto& layer : quadLayers) { + layer.next = nullptr; + layer.type = XR_TYPE_COMPOSITION_LAYER_QUAD; + layer.layerFlags = XR_COMPOSITION_LAYER_BLEND_TEXTURE_SOURCE_ALPHA_BIT; + layer.space = stageSpace_; + layer.eyeVisibility = eye; + memset(&layer.subImage, 0, sizeof(XrSwapchainSubImage)); + layer.pose = {{0.f, 0.f, 0.f, 1.f}, {0.f, 0.f, 0.f}}; + layer.size = {1.f, 1.f}; + if (eye == XR_EYE_VISIBILITY_LEFT) { + eye = XR_EYE_VISIBILITY_RIGHT; + } + } #endif std::array projectionViews; @@ -599,25 +605,33 @@ void XrApp::endFrame(XrFrameState frameState) { depthInfos[i].nearZ = appParams.depthParams.nearZ; depthInfos[i].farZ = appParams.depthParams.farZ; #ifdef USE_COMPOSITION_LAYER_QUAD - layer.subImage = projectionViews[0].subImage; + quadLayers[i].subImage = projectionViews[i].subImage; #endif } - const XrCompositionLayerBaseHeader* const layers[] = { #ifdef USE_COMPOSITION_LAYER_QUAD - (const XrCompositionLayerBaseHeader*)&layer + std::array quadLayersBase{}; + for (uint32_t i = 0; i < quadLayers.size(); i++) { + quadLayersBase[i] = (const XrCompositionLayerBaseHeader*)&quadLayers[i]; + } #else - (const XrCompositionLayerBaseHeader*)&projection -#endif + const XrCompositionLayerBaseHeader* const layers[] = { + (const XrCompositionLayerBaseHeader*)&projection, }; +#endif XrFrameEndInfo endFrameInfo = { XR_TYPE_FRAME_END_INFO, nullptr, frameState.predictedDisplayTime, XR_ENVIRONMENT_BLEND_MODE_OPAQUE, +#ifdef USE_COMPOSITION_LAYER_QUAD + quadLayersBase.size(), + quadLayersBase.data(), +#else 1, layers, +#endif }; XR_CHECK(xrEndFrame(session_, &endFrameInfo));