From 774b3d23a54fb6449261d3d9a7c1bcd8232aa428 Mon Sep 17 00:00:00 2001 From: huanchen <huanchen@qti.qualcomm.com> Date: Wed, 23 Aug 2023 16:17:40 +0800 Subject: [PATCH] st/oxr: Implement XR_EXT_performance_settings --- CMakeLists.txt | 4 ++ scripts/generate_oxr_ext_support.py | 1 + src/xrt/state_trackers/oxr/oxr_api_session.c | 23 ++++++-- src/xrt/state_trackers/oxr/oxr_conversions.h | 54 +++++++++++++++++++ src/xrt/state_trackers/oxr/oxr_event.c | 30 +++++++++++ .../oxr/oxr_extension_support.h | 12 +++++ src/xrt/state_trackers/oxr/oxr_objects.h | 17 ++++++ src/xrt/state_trackers/oxr/oxr_session.c | 27 ++++++++++ 8 files changed, 163 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 43da82e07..fb2b170d9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -381,6 +381,9 @@ endif() if(NOT DEFINED XRT_FEATURE_OPENXR_VISIBILITY_MASK) set(XRT_FEATURE_OPENXR_VISIBILITY_MASK ON) endif() +if(NOT DEFINED XRT_FEATURE_OPENXR_PERFORMANCE_SETTINGS) + set(XRT_FEATURE_OPENXR_PERFORMANCE_SETTINGS OFF) +endif() option( XRT_FEATURE_OPENXR_VULKAN_SWAPCHAIN_FORMAT_LIST "Enable support for the XR_KHR_vulkan_swapchain_format_list extension" ON @@ -656,6 +659,7 @@ message(STATUS "# FEATURE_OPENXR_LAYER_FB_ALPHA_BLEND: ${XRT_FEATURE message(STATUS "# FEATURE_OPENXR_LAYER_FB_IMAGE_LAYOUT ${XRT_FEATURE_OPENXR_LAYER_FB_IMAGE_LAYOUT}") message(STATUS "# FEATURE_OPENXR_LAYER_FB_SETTINGS: ${XRT_FEATURE_OPENXR_LAYER_FB_SETTINGS}") message(STATUS "# FEATURE_OPENXR_OVERLAY: ${XRT_FEATURE_OPENXR_OVERLAY}") +message(STATUS "# FEATURE_OPENXR_PERFORMANCE_SETTINGS: ${XRT_FEATURE_OPENXR_PERFORMANCE_SETTINGS}") message(STATUS "# FEATURE_OPENXR_SPACE_LOCAL_FLOOR: ${XRT_FEATURE_OPENXR_SPACE_LOCAL_FLOOR}") message(STATUS "# FEATURE_OPENXR_SPACE_UNBOUNDED: ${XRT_FEATURE_OPENXR_SPACE_UNBOUNDED}") message(STATUS "# FEATURE_OPENXR_VISIBILITY_MASK ${XRT_FEATURE_OPENXR_VISIBILITY_MASK}") diff --git a/scripts/generate_oxr_ext_support.py b/scripts/generate_oxr_ext_support.py index 712548771..eff136fff 100755 --- a/scripts/generate_oxr_ext_support.py +++ b/scripts/generate_oxr_ext_support.py @@ -63,6 +63,7 @@ EXTENSIONS = ( ['XR_EXT_hp_mixed_reality_controller', 'XRT_FEATURE_OPENXR_INTERACTION_WINMR'], ['XR_EXT_local_floor', 'XRT_FEATURE_OPENXR_SPACE_LOCAL_FLOOR'], ['XR_EXT_palm_pose', 'XRT_FEATURE_OPENXR_INTERACTION_EXT_PALM_POSE'], + ['XR_EXT_performance_settings', 'XRT_FEATURE_OPENXR_PERFORMANCE_SETTINGS'], ['XR_EXT_samsung_odyssey_controller', 'XRT_FEATURE_OPENXR_INTERACTION_WINMR'], ['XR_FB_composition_layer_alpha_blend', 'XRT_FEATURE_OPENXR_LAYER_FB_ALPHA_BLEND'], ['XR_FB_composition_layer_image_layout', 'XRT_FEATURE_OPENXR_LAYER_FB_IMAGE_LAYOUT'], diff --git a/src/xrt/state_trackers/oxr/oxr_api_session.c b/src/xrt/state_trackers/oxr/oxr_api_session.c index 0b02f919b..0242b77e2 100644 --- a/src/xrt/state_trackers/oxr/oxr_api_session.c +++ b/src/xrt/state_trackers/oxr/oxr_api_session.c @@ -307,14 +307,14 @@ oxr_xrGetVisibilityMaskKHR(XrSession session, } #endif // OXR_HAVE_KHR_visibility_mask + /* * * XR_EXT_performance_settings * */ -#ifdef XR_EXT_performance_settings - +#ifdef OXR_HAVE_EXT_performance_settings XRAPI_ATTR XrResult XRAPI_CALL oxr_xrPerfSettingsSetPerformanceLevelEXT(XrSession session, XrPerfSettingsDomainEXT domain, @@ -326,11 +326,24 @@ oxr_xrPerfSettingsSetPerformanceLevelEXT(XrSession session, struct oxr_logger log; OXR_VERIFY_SESSION_AND_INIT_LOG(&log, session, sess, "xrPerfSettingsSetPerformanceLevelEXT"); OXR_VERIFY_SESSION_NOT_LOST(&log, sess); + OXR_VERIFY_EXTENSION(&log, sess->sys->inst, EXT_performance_settings); + // check parameters + if (domain != XR_PERF_SETTINGS_DOMAIN_CPU_EXT && domain != XR_PERF_SETTINGS_DOMAIN_GPU_EXT) { + return oxr_error(&log, XR_ERROR_VALIDATION_FAILURE, "Invalid domain %d, must be 1(CPU) or 2(GPU)", + domain); + } - return oxr_error(&log, XR_ERROR_HANDLE_INVALID, "Not implemented"); + if (level != XR_PERF_SETTINGS_LEVEL_POWER_SAVINGS_EXT && level != XR_PERF_SETTINGS_LEVEL_SUSTAINED_LOW_EXT && + level != XR_PERF_SETTINGS_LEVEL_SUSTAINED_HIGH_EXT && level != XR_PERF_SETTINGS_LEVEL_BOOST_EXT) { + return oxr_error( + &log, XR_ERROR_VALIDATION_FAILURE, + "Invalid level %d, must be 0(POWER SAVE), 25(SUSTAINED LOW), 50(SUSTAINED_HIGH) or 75(BOOST)", + level); + } + + return oxr_session_set_perf_level(&log, sess, domain, level); } - -#endif +#endif // OXR_HAVE_EXT_performance_settings /* diff --git a/src/xrt/state_trackers/oxr/oxr_conversions.h b/src/xrt/state_trackers/oxr/oxr_conversions.h index 466e4784c..9fd0c95db 100644 --- a/src/xrt/state_trackers/oxr/oxr_conversions.h +++ b/src/xrt/state_trackers/oxr/oxr_conversions.h @@ -158,3 +158,57 @@ xrt_input_type_to_str(enum xrt_input_type type) } // clang-format on } + +static inline enum xrt_perf_set_level +xr_perf_level_to_xrt(XrPerfSettingsLevelEXT level) +{ + switch (level) { + case XR_PERF_SETTINGS_LEVEL_POWER_SAVINGS_EXT: return XRT_PERF_SET_LEVEL_POWER_SAVINGS; + case XR_PERF_SETTINGS_LEVEL_SUSTAINED_LOW_EXT: return XRT_PERF_SET_LEVEL_SUSTAINED_LOW; + case XR_PERF_SETTINGS_LEVEL_SUSTAINED_HIGH_EXT: return XRT_PERF_SET_LEVEL_SUSTAINED_HIGH; + case XR_PERF_SETTINGS_LEVEL_BOOST_EXT: return XRT_PERF_SET_LEVEL_BOOST; + default: assert(false); return 0; + } +} + +static inline enum xrt_perf_domain +xr_perf_domain_to_xrt(XrPerfSettingsDomainEXT domain) +{ + switch (domain) { + case XR_PERF_SETTINGS_DOMAIN_CPU_EXT: return XRT_PERF_DOMAIN_CPU; + case XR_PERF_SETTINGS_DOMAIN_GPU_EXT: return XRT_PERF_DOMAIN_GPU; + default: assert(false); return 0; + } +} + +static inline XrPerfSettingsDomainEXT +xrt_perf_domain_to_xr(enum xrt_perf_domain domain) +{ + switch (domain) { + case XRT_PERF_DOMAIN_CPU: return XR_PERF_SETTINGS_DOMAIN_CPU_EXT; + case XRT_PERF_DOMAIN_GPU: return XR_PERF_SETTINGS_DOMAIN_GPU_EXT; + default: assert(false); return 0; + } +} + +static inline XrPerfSettingsSubDomainEXT +xrt_perf_sub_domain_to_xr(enum xrt_perf_sub_domain subDomain) +{ + switch (subDomain) { + case XRT_PERF_SUB_DOMAIN_COMPOSITING: return XR_PERF_SETTINGS_SUB_DOMAIN_COMPOSITING_EXT; + case XRT_PERF_SUB_DOMAIN_RENDERING: return XR_PERF_SETTINGS_SUB_DOMAIN_RENDERING_EXT; + case XRT_PERF_SUB_DOMAIN_THERMAL: return XR_PERF_SETTINGS_SUB_DOMAIN_THERMAL_EXT; + default: assert(false); return 0; + } +} + +static inline XrPerfSettingsNotificationLevelEXT +xrt_perf_notify_level_to_xr(enum xrt_perf_notify_level level) +{ + switch (level) { + case XRT_PERF_NOTIFY_LEVEL_NORMAL: return XR_PERF_SETTINGS_NOTIF_LEVEL_NORMAL_EXT; + case XRT_PERF_NOTIFY_LEVEL_WARNING: return XR_PERF_SETTINGS_NOTIF_LEVEL_WARNING_EXT; + case XRT_PERF_NOTIFY_LEVEL_IMPAIRED: return XR_PERF_SETTINGS_NOTIF_LEVEL_IMPAIRED_EXT; + default: assert(false); return 0; + } +} diff --git a/src/xrt/state_trackers/oxr/oxr_event.c b/src/xrt/state_trackers/oxr/oxr_event.c index 114c0c496..9943e7a97 100644 --- a/src/xrt/state_trackers/oxr/oxr_event.c +++ b/src/xrt/state_trackers/oxr/oxr_event.c @@ -13,6 +13,7 @@ #include "oxr_objects.h" #include "oxr_logger.h" +#include "oxr_conversions.h" #include <stdio.h> #include <string.h> @@ -266,6 +267,35 @@ oxr_event_push_XrEventDataMainSessionVisibilityChangedEXTX(struct oxr_logger *lo } #endif // OXR_HAVE_EXTX_overlay + +#ifdef OXR_HAVE_EXT_performance_settings +XrResult +oxr_event_push_XrEventDataPerfSettingsEXTX(struct oxr_logger *log, + struct oxr_session *sess, + enum xrt_perf_domain domain, + enum xrt_perf_sub_domain subDomain, + enum xrt_perf_notify_level fromLevel, + enum xrt_perf_notify_level toLevel) +{ + struct oxr_instance *inst = sess->sys->inst; + XrEventDataPerfSettingsEXT *changed; + struct oxr_event *event = NULL; + + ALLOC(log, inst, &event, &changed); + changed->type = XR_TYPE_EVENT_DATA_PERF_SETTINGS_EXT; + changed->domain = xrt_perf_domain_to_xr(domain); + changed->subDomain = xrt_perf_sub_domain_to_xr(subDomain); + changed->fromLevel = xrt_perf_notify_level_to_xr(fromLevel); + changed->toLevel = xrt_perf_notify_level_to_xr(toLevel); + event->result = XR_SUCCESS; + lock(inst); + push(inst, event); + unlock(inst); + + return XR_SUCCESS; +} +#endif // OXR_HAVE_EXT_performance_settings + XrResult oxr_event_remove_session_events(struct oxr_logger *log, struct oxr_session *sess) { diff --git a/src/xrt/state_trackers/oxr/oxr_extension_support.h b/src/xrt/state_trackers/oxr/oxr_extension_support.h index 95e4a643d..acd619f81 100644 --- a/src/xrt/state_trackers/oxr/oxr_extension_support.h +++ b/src/xrt/state_trackers/oxr/oxr_extension_support.h @@ -360,6 +360,17 @@ #endif +/* + * XR_EXT_performance_settings + */ +#if defined(XR_EXT_performance_settings) && defined(XRT_FEATURE_OPENXR_PERFORMANCE_SETTINGS) +#define OXR_HAVE_EXT_performance_settings +#define OXR_EXTENSION_SUPPORT_EXT_performance_settings(_) _(EXT_performance_settings, EXT_PERFORMANCE_SETTINGS) +#else +#define OXR_EXTENSION_SUPPORT_EXT_performance_settings(_) +#endif + + /* * XR_EXT_samsung_odyssey_controller */ @@ -620,6 +631,7 @@ OXR_EXTENSION_SUPPORT_EXT_hp_mixed_reality_controller(_) \ OXR_EXTENSION_SUPPORT_EXT_local_floor(_) \ OXR_EXTENSION_SUPPORT_EXT_palm_pose(_) \ + OXR_EXTENSION_SUPPORT_EXT_performance_settings(_) \ OXR_EXTENSION_SUPPORT_EXT_samsung_odyssey_controller(_) \ OXR_EXTENSION_SUPPORT_FB_composition_layer_alpha_blend(_) \ OXR_EXTENSION_SUPPORT_FB_composition_layer_image_layout(_) \ diff --git a/src/xrt/state_trackers/oxr/oxr_objects.h b/src/xrt/state_trackers/oxr/oxr_objects.h index 3cebd91e6..539feaf88 100644 --- a/src/xrt/state_trackers/oxr/oxr_objects.h +++ b/src/xrt/state_trackers/oxr/oxr_objects.h @@ -771,6 +771,14 @@ oxr_session_get_visibility_mask(struct oxr_logger *log, XrVisibilityMaskKHR *visibilityMask); #endif // OXR_HAVE_KHR_visibility_mask +#ifdef OXR_HAVE_EXT_performance_settings +XrResult +oxr_session_set_perf_level(struct oxr_logger *log, + struct oxr_session *sess, + XrPerfSettingsDomainEXT domain, + XrPerfSettingsLevelEXT level); +#endif // OXR_HAVE_EXT_performance_settings + /* * * oxr_space.c @@ -968,6 +976,15 @@ oxr_event_push_XrEventDataMainSessionVisibilityChangedEXTX(struct oxr_logger *lo bool visible); #endif // OXR_HAVE_EXTX_overlay +#ifdef OXR_HAVE_EXT_performance_settings +XrResult +oxr_event_push_XrEventDataPerfSettingsEXTX(struct oxr_logger *log, + struct oxr_session *sess, + enum xrt_perf_domain domain, + enum xrt_perf_sub_domain subDomain, + enum xrt_perf_notify_level fromLevel, + enum xrt_perf_notify_level toLevel); +#endif // OXR_HAVE_EXT_performance_settings /*! * This clears all pending events refers to the given session. */ diff --git a/src/xrt/state_trackers/oxr/oxr_session.c b/src/xrt/state_trackers/oxr/oxr_session.c index b68ee3c26..3972da9e6 100644 --- a/src/xrt/state_trackers/oxr/oxr_session.c +++ b/src/xrt/state_trackers/oxr/oxr_session.c @@ -363,6 +363,13 @@ oxr_session_poll(struct oxr_logger *log, struct oxr_session *sess) case XRT_SESSION_EVENT_REFERENCE_SPACE_CHANGE_PENDING: handle_reference_space_change_pending(log, sess, &xse.ref_change); break; + case XRT_SESSION_EVENT_PERFORMANCE_CHANGE: +#ifdef OXR_HAVE_EXT_performance_settings + oxr_event_push_XrEventDataPerfSettingsEXTX( + log, sess, xse.performance.domain, xse.performance.sub_domain, xse.performance.from_level, + xse.performance.to_level); +#endif // OXR_HAVE_EXT_performance_settings + break; default: U_LOG_W("unhandled event type! %d", xse.type); break; } } @@ -1394,3 +1401,23 @@ oxr_session_request_display_refresh_rate(struct oxr_logger *log, struct oxr_sess return XR_SUCCESS; } #endif // OXR_HAVE_FB_display_refresh_rate + +#ifdef OXR_HAVE_EXT_performance_settings +XrResult +oxr_session_set_perf_level(struct oxr_logger *log, + struct oxr_session *sess, + XrPerfSettingsDomainEXT domain, + XrPerfSettingsLevelEXT level) +{ + struct xrt_compositor *xc = &sess->xcn->base; + + if (xc->set_performance_level == NULL) { + return XR_ERROR_FUNCTION_UNSUPPORTED; + } + enum xrt_perf_domain oxr_domain = xr_perf_domain_to_xrt(domain); + enum xrt_perf_set_level oxr_level = xr_perf_level_to_xrt(level); + xrt_comp_set_performance_level(xc, oxr_domain, oxr_level); + + return XR_SUCCESS; +} +#endif // OXR_HAVE_EXT_performance_settings