Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OpenXR: Fix updating swapchain for foveation #92137

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,12 @@
Called right before the OpenXR instance is destroyed.
</description>
</method>
<method name="_on_main_swapchains_created" qualifiers="virtual">
<return type="void" />
<description>
Called right after the main swapchains are (re)created.
</description>
</method>
<method name="_on_pre_render" qualifiers="virtual">
<return type="void" />
<description>
Expand Down
1 change: 1 addition & 0 deletions modules/openxr/extensions/openxr_extension_wrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ class OpenXRExtensionWrapper {
// This is when controller data is queried and made available to game logic.
virtual void on_process() {}
virtual void on_pre_render() {} // `on_pre_render` is called right before we start rendering our XR viewports.
virtual void on_main_swapchains_created() {} // `on_main_swapchains_created` is called right after our main swapchains are (re)created.
virtual void on_pre_draw_viewport(RID p_render_target) {} // `on_pre_draw_viewport` is called right before we start rendering this viewport
virtual void on_post_draw_viewport(RID p_render_target) {} // `on_port_draw_viewport` is called right after we start rendering this viewport (note that on Vulkan draw commands may only be queued)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ void OpenXRExtensionWrapperExtension::_bind_methods() {
GDVIRTUAL_BIND(_on_session_created, "session");
GDVIRTUAL_BIND(_on_process);
GDVIRTUAL_BIND(_on_pre_render);
GDVIRTUAL_BIND(_on_main_swapchains_created);
GDVIRTUAL_BIND(_on_session_destroyed);
GDVIRTUAL_BIND(_on_state_idle);
GDVIRTUAL_BIND(_on_state_ready);
Expand Down Expand Up @@ -198,6 +199,10 @@ void OpenXRExtensionWrapperExtension::on_pre_render() {
GDVIRTUAL_CALL(_on_pre_render);
}

void OpenXRExtensionWrapperExtension::on_main_swapchains_created() {
GDVIRTUAL_CALL(_on_main_swapchains_created);
}

void OpenXRExtensionWrapperExtension::on_session_destroyed() {
GDVIRTUAL_CALL(_on_session_destroyed);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ class OpenXRExtensionWrapperExtension : public Object, public OpenXRExtensionWra
virtual void on_session_created(const XrSession p_session) override;
virtual void on_process() override;
virtual void on_pre_render() override;
virtual void on_main_swapchains_created() override;
virtual void on_session_destroyed() override;

GDVIRTUAL0(_on_register_metadata);
Expand All @@ -95,6 +96,7 @@ class OpenXRExtensionWrapperExtension : public Object, public OpenXRExtensionWra
GDVIRTUAL1(_on_session_created, uint64_t);
GDVIRTUAL0(_on_process);
GDVIRTUAL0(_on_pre_render);
GDVIRTUAL0(_on_main_swapchains_created);
GDVIRTUAL0(_on_session_destroyed);

virtual void on_state_idle() override;
Expand Down
37 changes: 26 additions & 11 deletions modules/openxr/extensions/openxr_fb_foveation_extension.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ void *OpenXRFBFoveationExtension::set_swapchain_create_info_and_get_next_pointer
}
}

void OpenXRFBFoveationExtension::on_state_ready() {
void OpenXRFBFoveationExtension::on_main_swapchains_created() {
update_profile();
}

Expand All @@ -127,42 +127,57 @@ void OpenXRFBFoveationExtension::set_foveation_dynamic(XrFoveationDynamicFB p_fo
update_profile();
}

void OpenXRFBFoveationExtension::update_profile() {
if (!is_enabled()) {
void OpenXRFBFoveationExtension::_update_profile() {
// Must be called from rendering thread!
ERR_NOT_ON_RENDER_THREAD;

OpenXRFBFoveationExtension *fov_ext = OpenXRFBFoveationExtension::get_singleton();
ERR_FAIL_NULL(fov_ext);

if (!fov_ext->is_enabled()) {
return;
}

OpenXRAPI *openxr_api = OpenXRAPI::get_singleton();
ERR_FAIL_NULL(openxr_api);

XrSwapchain main_color_swapchain = openxr_api->get_color_swapchain();
if (main_color_swapchain == XR_NULL_HANDLE) {
// Our swapchain hasn't been created yet, we'll call this again once it has.
return;
}

XrFoveationLevelProfileCreateInfoFB level_profile_create_info;
level_profile_create_info.type = XR_TYPE_FOVEATION_LEVEL_PROFILE_CREATE_INFO_FB;
level_profile_create_info.next = nullptr;
level_profile_create_info.level = foveation_level;
level_profile_create_info.level = fov_ext->foveation_level;
level_profile_create_info.verticalOffset = 0.0f;
level_profile_create_info.dynamic = foveation_dynamic;
level_profile_create_info.dynamic = fov_ext->foveation_dynamic;

XrFoveationProfileCreateInfoFB profile_create_info;
profile_create_info.type = XR_TYPE_FOVEATION_PROFILE_CREATE_INFO_FB;
profile_create_info.next = &level_profile_create_info;

XrFoveationProfileFB foveation_profile;
XrResult result = xrCreateFoveationProfileFB(OpenXRAPI::get_singleton()->get_session(), &profile_create_info, &foveation_profile);
XrResult result = fov_ext->xrCreateFoveationProfileFB(openxr_api->get_session(), &profile_create_info, &foveation_profile);
if (XR_FAILED(result)) {
print_line("OpenXR: Unable to create the foveation profile [", OpenXRAPI::get_singleton()->get_error_string(result), "]");
print_line("OpenXR: Unable to create the foveation profile [", openxr_api->get_error_string(result), "]");
return;
}

XrSwapchainStateFoveationFB foveation_update_state;
foveation_update_state.type = XR_TYPE_SWAPCHAIN_STATE_FOVEATION_FB;
foveation_update_state.profile = foveation_profile;

result = swapchain_update_state_ext->xrUpdateSwapchainFB(OpenXRAPI::get_singleton()->get_color_swapchain(), (XrSwapchainStateBaseHeaderFB *)&foveation_update_state);
result = fov_ext->swapchain_update_state_ext->xrUpdateSwapchainFB(main_color_swapchain, (XrSwapchainStateBaseHeaderFB *)&foveation_update_state);
if (XR_FAILED(result)) {
print_line("OpenXR: Unable to update the swapchain [", OpenXRAPI::get_singleton()->get_error_string(result), "]");
print_line("OpenXR: Unable to update the swapchain [", openxr_api->get_error_string(result), "]");

// We still want to destroy our profile so keep going...
}

result = xrDestroyFoveationProfileFB(foveation_profile);
result = fov_ext->xrDestroyFoveationProfileFB(foveation_profile);
if (XR_FAILED(result)) {
print_line("OpenXR: Unable to destroy the foveation profile [", OpenXRAPI::get_singleton()->get_error_string(result), "]");
print_line("OpenXR: Unable to destroy the foveation profile [", openxr_api->get_error_string(result), "]");
}
}
12 changes: 10 additions & 2 deletions modules/openxr/extensions/openxr_fb_foveation_extension.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ class OpenXRFBFoveationExtension : public OpenXRExtensionWrapper {

virtual void *set_swapchain_create_info_and_get_next_pointer(void *p_next_pointer) override;

virtual void on_state_ready() override;
virtual void on_main_swapchains_created() override;

bool is_enabled() const;

Expand All @@ -82,7 +82,15 @@ class OpenXRFBFoveationExtension : public OpenXRExtensionWrapper {
XrFoveationLevelFB foveation_level = XR_FOVEATION_LEVEL_NONE_FB;
XrFoveationDynamicFB foveation_dynamic = XR_FOVEATION_DYNAMIC_DISABLED_FB;

void update_profile();
static void _update_profile();

void update_profile() {
// If we're rendering on a separate thread, we may still be processing the last frame, don't communicate this till we're ready...
RenderingServer *rendering_server = RenderingServer::get_singleton();
ERR_FAIL_NULL(rendering_server);

rendering_server->call_on_render_thread(callable_mp_static(&OpenXRFBFoveationExtension::_update_profile));
}

// Enable foveation on this swapchain
XrSwapchainCreateInfoFoveationFB swapchain_create_info_foveation_fb;
Expand Down
4 changes: 4 additions & 0 deletions modules/openxr/openxr_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1220,6 +1220,10 @@ bool OpenXRAPI::create_main_swapchains(Size2i p_size) {
}
};

for (OpenXRExtensionWrapper *wrapper : registered_extension_wrappers) {
wrapper->on_main_swapchains_created();
}

return true;
};

Expand Down
Loading