From 60990f6b7229a51626590ee204128e5a071fa374 Mon Sep 17 00:00:00 2001 From: Jeroen Bakker Date: Tue, 20 May 2025 14:04:45 +0200 Subject: [PATCH] Refactor: OpenXR: Add begin and end submit swapchain handler Graphics bindings would be able to share resources more easily. Extracted from !139140 Pull Request: https://projects.blender.org/blender/blender/pulls/139155 --- .../ghost/intern/GHOST_IXrGraphicsBinding.hh | 2 ++ .../ghost/intern/GHOST_XrGraphicsBinding.cc | 2 ++ .../intern/GHOST_XrGraphicsBindingD3D.hh | 3 ++ .../intern/GHOST_XrGraphicsBindingVulkan.cc | 2 ++ .../intern/GHOST_XrGraphicsBindingVulkan.hh | 2 ++ intern/ghost/intern/GHOST_XrSession.cc | 29 ++++++++++++++----- intern/ghost/intern/GHOST_XrSession.hh | 1 + 7 files changed, 34 insertions(+), 7 deletions(-) diff --git a/intern/ghost/intern/GHOST_IXrGraphicsBinding.hh b/intern/ghost/intern/GHOST_IXrGraphicsBinding.hh index 5ad6ca73b60..279f2bbb1a9 100644 --- a/intern/ghost/intern/GHOST_IXrGraphicsBinding.hh +++ b/intern/ghost/intern/GHOST_IXrGraphicsBinding.hh @@ -54,8 +54,10 @@ class GHOST_IXrGraphicsBinding { bool &r_is_rgb_format) const = 0; virtual std::vector createSwapchainImages( uint32_t image_count) = 0; + virtual void submitToSwapchainBegin() = 0; virtual void submitToSwapchainImage(XrSwapchainImageBaseHeader &swapchain_image, const GHOST_XrDrawViewInfo &draw_info) = 0; + virtual void submitToSwapchainEnd() = 0; virtual bool needsUpsideDownDrawing(GHOST_Context &ghost_ctx) const = 0; protected: diff --git a/intern/ghost/intern/GHOST_XrGraphicsBinding.cc b/intern/ghost/intern/GHOST_XrGraphicsBinding.cc index 4ab48511c1e..c335c80292b 100644 --- a/intern/ghost/intern/GHOST_XrGraphicsBinding.cc +++ b/intern/ghost/intern/GHOST_XrGraphicsBinding.cc @@ -269,6 +269,7 @@ class GHOST_XrGraphicsBindingOpenGL : public GHOST_IXrGraphicsBinding { return base_images; } + void submitToSwapchainBegin() override {} void submitToSwapchainImage(XrSwapchainImageBaseHeader &swapchain_image, const GHOST_XrDrawViewInfo &draw_info) override { @@ -293,6 +294,7 @@ class GHOST_XrGraphicsBindingOpenGL : public GHOST_IXrGraphicsBinding { glBindFramebuffer(GL_FRAMEBUFFER, 0); } + void submitToSwapchainEnd() override {} bool needsUpsideDownDrawing(GHOST_Context &ghost_ctx) const override { diff --git a/intern/ghost/intern/GHOST_XrGraphicsBindingD3D.hh b/intern/ghost/intern/GHOST_XrGraphicsBindingD3D.hh index 77d91916164..f9ffbe376f5 100644 --- a/intern/ghost/intern/GHOST_XrGraphicsBindingD3D.hh +++ b/intern/ghost/intern/GHOST_XrGraphicsBindingD3D.hh @@ -44,6 +44,9 @@ class GHOST_XrGraphicsBindingD3D : public GHOST_IXrGraphicsBinding { bool &r_is_srgb_format) const override; std::vector createSwapchainImages(uint32_t image_count) override; + void submitToSwapchainBegin() override {} + void submitToSwapchainEnd() override {} + bool needsUpsideDownDrawing(GHOST_Context &ghost_ctx) const override; protected: diff --git a/intern/ghost/intern/GHOST_XrGraphicsBindingVulkan.cc b/intern/ghost/intern/GHOST_XrGraphicsBindingVulkan.cc index 920e446f3d0..819c7fcf94e 100644 --- a/intern/ghost/intern/GHOST_XrGraphicsBindingVulkan.cc +++ b/intern/ghost/intern/GHOST_XrGraphicsBindingVulkan.cc @@ -423,6 +423,7 @@ std::vector GHOST_XrGraphicsBindingVulkan::createS return base_images; } +void GHOST_XrGraphicsBindingVulkan::submitToSwapchainBegin() {} void GHOST_XrGraphicsBindingVulkan::submitToSwapchainImage( XrSwapchainImageBaseHeader &swapchain_image, const GHOST_XrDrawViewInfo &draw_info) { @@ -440,6 +441,7 @@ void GHOST_XrGraphicsBindingVulkan::submitToSwapchainImage( break; } } +void GHOST_XrGraphicsBindingVulkan::submitToSwapchainEnd() {} /* -------------------------------------------------------------------- */ /** \name Data transfer CPU diff --git a/intern/ghost/intern/GHOST_XrGraphicsBindingVulkan.hh b/intern/ghost/intern/GHOST_XrGraphicsBindingVulkan.hh index 5e6921f9820..3e8b79c97c5 100644 --- a/intern/ghost/intern/GHOST_XrGraphicsBindingVulkan.hh +++ b/intern/ghost/intern/GHOST_XrGraphicsBindingVulkan.hh @@ -38,8 +38,10 @@ class GHOST_XrGraphicsBindingVulkan : public GHOST_IXrGraphicsBinding { bool &r_is_srgb_format) const override; std::vector createSwapchainImages(uint32_t image_count) override; + void submitToSwapchainBegin() override; void submitToSwapchainImage(XrSwapchainImageBaseHeader &swapchain_image, const GHOST_XrDrawViewInfo &draw_info) override; + void submitToSwapchainEnd() override; bool needsUpsideDownDrawing(GHOST_Context &ghost_ctx) const override; diff --git a/intern/ghost/intern/GHOST_XrSession.cc b/intern/ghost/intern/GHOST_XrSession.cc index b4640b597e3..65fbef46f08 100644 --- a/intern/ghost/intern/GHOST_XrSession.cc +++ b/intern/ghost/intern/GHOST_XrSession.cc @@ -493,21 +493,20 @@ static void ghost_xr_draw_view_info_from_view(const XrView &view, GHOST_XrDrawVi } void GHOST_XrSession::drawView(GHOST_XrSwapchain &swapchain, + XrSwapchainImageBaseHeader &swapchain_image, XrCompositionLayerProjectionView &r_proj_layer_view, const XrSpaceLocation &view_location, const XrView &view, uint32_t view_idx, void *draw_customdata) { - XrSwapchainImageBaseHeader *swapchain_image = swapchain.acquireDrawableSwapchainImage(); - GHOST_XrDrawViewInfo draw_view_info = {}; - r_proj_layer_view.type = XR_TYPE_COMPOSITION_LAYER_PROJECTION_VIEW; r_proj_layer_view.pose = view.pose; r_proj_layer_view.fov = view.fov; swapchain.updateCompositionLayerProjectViewSubImage(r_proj_layer_view.subImage); assert(view_idx < 256); + GHOST_XrDrawViewInfo draw_view_info = {}; draw_view_info.view_idx = char(view_idx); draw_view_info.swapchain_format = swapchain.getFormat(); draw_view_info.expects_srgb_buffer = swapchain.isBufferSRGB(); @@ -520,9 +519,7 @@ void GHOST_XrSession::drawView(GHOST_XrSwapchain &swapchain, /* Draw! */ m_context->getCustomFuncs().draw_view_fn(&draw_view_info, draw_customdata); - m_gpu_binding->submitToSwapchainImage(*swapchain_image, draw_view_info); - - swapchain.releaseImage(); + m_gpu_binding->submitToSwapchainImage(swapchain_image, draw_view_info); } XrCompositionLayerProjection GHOST_XrSession::drawLayer( @@ -560,15 +557,33 @@ XrCompositionLayerProjection GHOST_XrSession::drawLayer( "Failed to query frame view space"); r_proj_layer_views.resize(view_count); + std::vector swapchain_images; + swapchain_images.resize(view_count); for (uint32_t view_idx = 0; view_idx < view_count; view_idx++) { - drawView(m_oxr->swapchains[view_idx], + GHOST_XrSwapchain &swapchain = m_oxr->swapchains[view_idx]; + swapchain_images[view_idx] = swapchain.acquireDrawableSwapchainImage(); + } + + m_gpu_binding->submitToSwapchainBegin(); + for (uint32_t view_idx = 0; view_idx < view_count; view_idx++) { + GHOST_XrSwapchain &swapchain = m_oxr->swapchains[view_idx]; + XrSwapchainImageBaseHeader &swapchain_image = *swapchain_images[view_idx]; + drawView(swapchain, + swapchain_image, r_proj_layer_views[view_idx], view_location, m_oxr->views[view_idx], view_idx, draw_customdata); } + m_gpu_binding->submitToSwapchainEnd(); + + for (uint32_t view_idx = 0; view_idx < view_count; view_idx++) { + GHOST_XrSwapchain &swapchain = m_oxr->swapchains[view_idx]; + swapchain.releaseImage(); + swapchain_images[view_idx] = nullptr; + } layer.space = m_oxr->reference_space; layer.viewCount = r_proj_layer_views.size(); diff --git a/intern/ghost/intern/GHOST_XrSession.hh b/intern/ghost/intern/GHOST_XrSession.hh index cce0daf7316..c6fcaafe7b9 100644 --- a/intern/ghost/intern/GHOST_XrSession.hh +++ b/intern/ghost/intern/GHOST_XrSession.hh @@ -108,6 +108,7 @@ class GHOST_XrSession { XrCompositionLayerProjection drawLayer( std::vector &r_proj_layer_views, void *draw_customdata); void drawView(GHOST_XrSwapchain &swapchain, + XrSwapchainImageBaseHeader &swapchain_image, XrCompositionLayerProjectionView &r_proj_layer_view, const XrSpaceLocation &view_location, const XrView &view,