The open source OpenXR runtime
at main 8.8 kB view raw
1#!/usr/bin/env python3 2# Copyright 2019-2024, Collabora, Ltd. 3# SPDX-License-Identifier: BSL-1.0 4"""Simple script to update oxr_extension_support.h.""" 5 6from pathlib import Path 7 8def _add_defined(s): 9 if "defined" in s: 10 return s 11 return "defined({})".format(s) 12 13def or_(*args): 14 """ 15 Create an "OR" in the definition condition list. 16 17 Takes any number of strings directly or through e.g. "not_". 18 """ 19 return "({})".format(" || ".join(_add_defined(s) for s in args)) 20 21 22def not_(s): 23 """ 24 Create a "NOT" in the condition list. 25 26 Takes a single string, directly or through e.g. "or_". 27 """ 28 return "(!{})".format(_add_defined(s)) 29 30# Each extension that we implement gets an entry in this tuple. 31# Each entry should be a list of defines that are checked for an extension: 32# the first one must be the name of the extension itself. 33# The second and later items might be modified using or_() and not_(). 34# Keep sorted, KHR, EXT, Vendor, experimental (same order). 35EXTENSIONS = ( 36 # Khronos extensions, sorted alphabetically. 37 ['XR_KHR_android_create_instance', 'XR_USE_PLATFORM_ANDROID'], 38 ['XR_KHR_android_thread_settings', 'XR_USE_PLATFORM_ANDROID'], 39 ['XR_KHR_binding_modification'], 40 ['XR_KHR_composition_layer_color_scale_bias', 'XRT_FEATURE_OPENXR_LAYER_COLOR_SCALE_BIAS'], 41 ['XR_KHR_composition_layer_cube', 'XRT_FEATURE_OPENXR_LAYER_CUBE'], 42 ['XR_KHR_composition_layer_cylinder', 'XRT_FEATURE_OPENXR_LAYER_CYLINDER'], 43 ['XR_KHR_composition_layer_depth', 'XRT_FEATURE_OPENXR_LAYER_DEPTH'], 44 ['XR_KHR_composition_layer_equirect', 'XRT_FEATURE_OPENXR_LAYER_EQUIRECT1'], 45 ['XR_KHR_composition_layer_equirect2', 'XRT_FEATURE_OPENXR_LAYER_EQUIRECT2'], 46 ['XR_KHR_convert_timespec_time', 'XR_USE_TIMESPEC', not_('XR_USE_PLATFORM_WIN32')], 47 ['XR_KHR_D3D11_enable', 'XR_USE_GRAPHICS_API_D3D11'], 48 ['XR_KHR_D3D12_enable', 'XR_USE_GRAPHICS_API_D3D12'], 49 ['XR_KHR_extended_struct_name_lengths'], 50 ['XR_KHR_loader_init', 'XR_USE_PLATFORM_ANDROID'], 51 ['XR_KHR_loader_init_android', 'OXR_HAVE_KHR_loader_init', 'XR_USE_PLATFORM_ANDROID'], 52 ['XR_KHR_locate_spaces'], 53 ['XR_KHR_maintenance1'], 54 ['XR_KHR_opengl_enable', 'XR_USE_GRAPHICS_API_OPENGL'], 55 ['XR_KHR_opengl_es_enable', 'XR_USE_GRAPHICS_API_OPENGL_ES'], 56 ['XR_KHR_swapchain_usage_input_attachment_bit'], 57 ['XR_KHR_visibility_mask', 'XRT_FEATURE_OPENXR_VISIBILITY_MASK'], 58 ['XR_KHR_vulkan_enable', 'XR_USE_GRAPHICS_API_VULKAN'], 59 ['XR_KHR_vulkan_enable2', 'XR_USE_GRAPHICS_API_VULKAN'], 60 ['XR_KHR_vulkan_swapchain_format_list', 'XR_USE_GRAPHICS_API_VULKAN', 'XRT_FEATURE_OPENXR_VULKAN_SWAPCHAIN_FORMAT_LIST'], 61 ['XR_KHR_win32_convert_performance_counter_time', 'XR_USE_PLATFORM_WIN32'], 62 # EXT extensions, sorted alphabetically. 63 ['XR_EXT_active_action_set_priority', 'XRT_FEATURE_OPENXR_ACTIVE_ACTION_SET_PRIORITY'], 64 ['XR_EXT_debug_utils', 'XRT_FEATURE_OPENXR_DEBUG_UTILS'], 65 ['XR_EXT_dpad_binding'], 66 ['XR_EXT_eye_gaze_interaction', 'XRT_FEATURE_OPENXR_INTERACTION_EXT_EYE_GAZE'], 67 ['XR_EXT_future', 'XRT_FEATURE_OPENXR_FUTURE_EXT'], 68 ['XR_EXT_hand_interaction', 'XRT_FEATURE_OPENXR_INTERACTION_EXT_HAND'], 69 ['XR_EXT_hand_tracking', 'XRT_FEATURE_OPENXR_HAND_TRACKING_EXT'], 70 ['XR_EXT_hand_tracking_data_source', 'XRT_FEATURE_OPENXR_HAND_TRACKING_DATA_SOURCE_EXT'], 71 ['XR_EXT_hp_mixed_reality_controller', 'XRT_FEATURE_OPENXR_INTERACTION_WINMR'], 72 ['XR_EXT_local_floor', 'XRT_FEATURE_OPENXR_SPACE_LOCAL_FLOOR'], 73 ['XR_EXT_palm_pose', 'XRT_FEATURE_OPENXR_INTERACTION_EXT_PALM_POSE'], 74 ['XR_EXT_performance_settings', 'XRT_FEATURE_OPENXR_PERFORMANCE_SETTINGS'], 75 ['XR_EXT_plane_detection', 'XRT_FEATURE_OPENXR_PLANE_DETECTION'], 76 ['XR_EXT_samsung_odyssey_controller', 'XRT_FEATURE_OPENXR_INTERACTION_WINMR'], 77 ['XR_EXT_user_presence', 'XRT_FEATURE_OPENXR_USER_PRESENCE'], 78 # Vendor extensions, sorted alphabetically. 79 ['XR_ANDROID_face_tracking', 'XRT_FEATURE_OPENXR_FACE_TRACKING_ANDROID'], 80 ['XR_BD_controller_interaction', 'XRT_FEATURE_OPENXR_INTERACTION_BYTEDANCE'], 81 ['XR_FB_body_tracking', 'XRT_FEATURE_OPENXR_BODY_TRACKING_FB'], 82 ['XR_FB_composition_layer_alpha_blend', 'XRT_FEATURE_OPENXR_LAYER_FB_ALPHA_BLEND'], 83 ['XR_FB_composition_layer_depth_test', 'XRT_FEATURE_OPENXR_LAYER_FB_DEPTH_TEST'], 84 ['XR_FB_composition_layer_image_layout', 'XRT_FEATURE_OPENXR_LAYER_FB_IMAGE_LAYOUT'], 85 ['XR_FB_composition_layer_settings', 'XRT_FEATURE_OPENXR_LAYER_FB_SETTINGS'], 86 ['XR_FB_display_refresh_rate', 'XRT_FEATURE_OPENXR_DISPLAY_REFRESH_RATE'], 87 ['XR_FB_face_tracking2', 'XRT_FEATURE_OPENXR_FACE_TRACKING2_FB'], 88 ['XR_FB_haptic_pcm', 'XRT_FEATURE_OPENXR_HAPTIC_PCM'], 89 ['XR_FB_passthrough', 'XRT_FEATURE_OPENXR_LAYER_FB_PASSTHROUGH'], 90 ['XR_FB_touch_controller_pro', 'XRT_FEATURE_OPENXR_INTERACTION_TOUCH_PRO'], 91 ['XR_FB_touch_controller_proximity', 'XRT_FEATURE_OPENXR_INTERACTION_FB_PROXIMITY'], 92 ['XR_HTC_facial_tracking', 'XRT_FEATURE_OPENXR_FACIAL_TRACKING_HTC'], 93 ['XR_HTC_vive_cosmos_controller_interaction', 'XRT_FEATURE_OPENXR_INTERACTION_VIVE_COSMOS'], 94 ['XR_HTC_vive_focus3_controller_interaction', 'XRT_FEATURE_OPENXR_INTERACTION_VIVE_FOCUS3'], 95 ['XR_META_body_tracking_calibration', 'XRT_FEATURE_OPENXR_BODY_TRACKING_CALIBRATION_META'], 96 ['XR_META_body_tracking_full_body', 'XRT_FEATURE_OPENXR_BODY_TRACKING_FULL_BODY_META'], 97 ['XR_META_touch_controller_plus', 'XRT_FEATURE_OPENXR_INTERACTION_TOUCH_PLUS'], 98 ['XR_ML_ml2_controller_interaction', 'XRT_FEATURE_OPENXR_INTERACTION_ML2'], 99 ['XR_MND_headless', 'XRT_FEATURE_OPENXR_HEADLESS'], 100 ['XR_MND_swapchain_usage_input_attachment_bit'], 101 ['XR_MSFT_hand_interaction', 'XRT_FEATURE_OPENXR_INTERACTION_MSFT_HAND'], 102 ['XR_MSFT_unbounded_reference_space', 'XRT_FEATURE_OPENXR_SPACE_UNBOUNDED'], 103 ['XR_OPPO_controller_interaction', 'XRT_FEATURE_OPENXR_INTERACTION_OPPO'], 104 # Experimental extensions, sorted alphabetically. 105 ['XR_EXTX_overlay', 'XRT_FEATURE_OPENXR_OVERLAY'], 106 ['XR_HTCX_vive_tracker_interaction', 'ALWAYS_DISABLED'], 107 ['XR_MNDX_ball_on_a_stick_controller', 'XRT_FEATURE_OPENXR_INTERACTION_MNDX'], 108 ['XR_MNDX_blubur_s1', 'XRT_FEATURE_OPENXR_INTERACTION_MNDX'], 109 ['XR_MNDX_egl_enable', 'XR_USE_PLATFORM_EGL'], 110 ['XR_MNDX_force_feedback_curl', 'XRT_FEATURE_OPENXR_FORCE_FEEDBACK_CURL'], 111 ['XR_MNDX_hydra', 'XRT_FEATURE_OPENXR_INTERACTION_MNDX'], 112 ['XR_MNDX_oculus_remote', 'XRT_FEATURE_OPENXR_INTERACTION_MNDX'], 113 ['XR_MNDX_psvr2_interaction', 'XRT_FEATURE_OPENXR_INTERACTION_MNDX'], 114 ['XR_MNDX_system_buttons', 'XRT_FEATURE_OPENXR_INTERACTION_MNDX'], 115 ['XR_MNDX_xdev_space', 'XRT_FEATURE_OPENXR_XDEV_SPACE'], 116) 117 118 119ROOT = Path(__file__).resolve().parent.parent 120FN = ROOT / 'src' / 'xrt'/'state_trackers' / 'oxr' / 'oxr_extension_support.h' 121 122INVOCATION_PREFIX = 'OXR_EXTENSION_SUPPORT' 123BEGIN_OF_PER_EXTENSION = '// beginning of GENERATED defines - do not modify - used by scripts' 124END_OF_PER_EXTENSION = '// end of GENERATED per-extension defines - do not modify - used by scripts' 125CLANG_FORMAT_OFF = '// clang-format off' 126CLANG_FORMAT_ON = '// clang-format on' 127 128 129def trim_ext_name(name): 130 return name[3:] 131 132 133def generate_first_chunk(): 134 parts = [] 135 for data in EXTENSIONS: 136 ext_name = data[0] 137 trimmed_name = trim_ext_name(ext_name) 138 upper_name = trimmed_name.upper() 139 condition = " && ".join(_add_defined(x) for x in data) 140 141 parts.append(f""" 142/* 143 * {ext_name} 144 */ 145#if {condition} 146#define OXR_HAVE_{trimmed_name} 147#define {INVOCATION_PREFIX}_{trimmed_name}(_) \\ 148 _({trimmed_name}, {upper_name}) 149#else 150#define {INVOCATION_PREFIX}_{trimmed_name}(_) 151#endif 152""") 153 return '\n'.join(parts) 154 155 156def generate_second_chunk(): 157 trimmed_names = [trim_ext_name(data[0]) for data in EXTENSIONS] 158 invocations = ('{}_{}(_)'.format(INVOCATION_PREFIX, name) 159 for name in trimmed_names) 160 161 macro_lines = ['#define OXR_EXTENSION_SUPPORT_GENERATE(_)'] 162 macro_lines.extend(invocations) 163 164 lines = [CLANG_FORMAT_OFF] 165 lines.append(' \\\n '.join(macro_lines)) 166 lines.append(CLANG_FORMAT_ON) 167 return '\n'.join(lines) 168 169 170if __name__ == "__main__": 171 with open(str(FN), 'r', encoding='utf-8') as fp: 172 orig = [line.rstrip() for line in fp.readlines()] 173 beginning = orig[:orig.index(BEGIN_OF_PER_EXTENSION)+1] 174 middle_start = orig.index(END_OF_PER_EXTENSION) 175 middle_end = orig.index(CLANG_FORMAT_OFF) 176 middle = orig[middle_start:middle_end] 177 178 new_contents = beginning 179 new_contents.append(generate_first_chunk()) 180 new_contents.extend(middle) 181 new_contents.append(generate_second_chunk()) 182 183 with open(str(FN), 'w', encoding='utf-8') as fp: 184 fp.write('\n'.join(new_contents)) 185 fp.write('\n')