The open source OpenXR runtime
1#!/usr/bin/env python3
2# Copyright 2019, Collabora, Ltd.
3# SPDX-License-Identifier: BSL-1.0
4"""Simple script to update oxr_extension_support.h."""
5
6from pathlib import Path
7
8# Each extension that we implement gets an entry in this tuple.
9# Each entry should be a list of defines that are checked for an extension:
10# the first one must be the name of the extension itself.
11# Keep sorted.
12EXTENSIONS = (
13 ['XR_KHR_android_create_instance', 'XR_USE_PLATFORM_ANDROID'],
14 ['XR_KHR_convert_timespec_time', 'XR_USE_TIMESPEC'],
15 ['XR_KHR_opengl_enable', 'XR_USE_GRAPHICS_API_OPENGL'],
16 ['XR_KHR_opengl_es_enable', 'XR_USE_GRAPHICS_API_OPENGL_ES'],
17 ['XR_KHR_vulkan_enable', 'XR_USE_GRAPHICS_API_VULKAN'],
18 ['XR_KHR_vulkan_enable2', 'XR_USE_GRAPHICS_API_VULKAN'],
19 ['XR_KHR_composition_layer_depth', 'XRT_FEATURE_OPENXR_LAYER_DEPTH'],
20 ['XR_KHR_composition_layer_cube', 'XRT_FEATURE_OPENXR_LAYER_CUBE'],
21 ['XR_KHR_composition_layer_cylinder', 'XRT_FEATURE_OPENXR_LAYER_CYLINDER'],
22 ['XR_KHR_composition_layer_equirect', 'XRT_FEATURE_OPENXR_LAYER_EQUIRECT1'],
23 ['XR_KHR_composition_layer_equirect2', 'XRT_FEATURE_OPENXR_LAYER_EQUIRECT2'],
24 ['XR_EXT_debug_utils'],
25 ['XR_MND_headless'],
26 ['XR_MND_swapchain_usage_input_attachment_bit'],
27 ['XR_EXTX_overlay'],
28 ['XR_MNDX_egl_enable', 'XR_USE_PLATFORM_EGL', 'XR_USE_GRAPHICS_API_OPENGL'],
29 ['XR_MNDX_ball_on_a_stick_controller'],
30 ['XR_EXT_hand_tracking']
31)
32
33ROOT = Path(__file__).resolve().parent.parent
34FN = ROOT / 'src' / 'xrt'/'state_trackers' / 'oxr' / 'oxr_extension_support.h'
35
36INVOCATION_PREFIX = 'OXR_EXTENSION_SUPPORT'
37BEGIN_OF_PER_EXTENSION = '// beginning of GENERATED defines - do not modify - used by scripts'
38END_OF_PER_EXTENSION = '// end of GENERATED per-extension defines - do not modify - used by scripts'
39CLANG_FORMAT_OFF = '// clang-format off'
40CLANG_FORMAT_ON = '// clang-format on'
41
42
43def trim_ext_name(name):
44 return name[3:]
45
46
47def generate_first_chunk():
48 parts = []
49 for data in EXTENSIONS:
50 ext_name = data[0]
51 trimmed_name = trim_ext_name(ext_name)
52 upper_name = trimmed_name.upper()
53 condition = " && ".join("defined({})".format(x) for x in data)
54
55 parts.append(f"""
56/*
57* {ext_name}
58*/
59#if {condition}
60#define OXR_HAVE_{trimmed_name}
61#define {INVOCATION_PREFIX}_{trimmed_name}(_) \\
62 _({trimmed_name}, {upper_name})
63#else
64#define {INVOCATION_PREFIX}_{trimmed_name}(_)
65#endif
66""")
67 return '\n'.join(parts)
68
69
70def generate_second_chunk():
71 trimmed_names = [trim_ext_name(data[0]) for data in EXTENSIONS]
72 invocations = ('{}_{}(_)'.format(INVOCATION_PREFIX, name)
73 for name in trimmed_names)
74
75 macro_lines = ['#define OXR_EXTENSION_SUPPORT_GENERATE(_)']
76 macro_lines.extend(invocations)
77
78 lines = [CLANG_FORMAT_OFF]
79 lines.append(' \\\n '.join(macro_lines))
80 lines.append(CLANG_FORMAT_ON)
81 return '\n'.join(lines)
82
83
84if __name__ == "__main__":
85 with open(str(FN), 'r', encoding='utf-8') as fp:
86 orig = [line.rstrip() for line in fp.readlines()]
87 beginning = orig[:orig.index(BEGIN_OF_PER_EXTENSION)+1]
88 middle_start = orig.index(END_OF_PER_EXTENSION)
89 middle_end = orig.index(CLANG_FORMAT_OFF)
90 middle = orig[middle_start:middle_end]
91
92 new_contents = beginning
93 new_contents.append(generate_first_chunk())
94 new_contents.extend(middle)
95 new_contents.append(generate_second_chunk())
96
97 with open(str(FN), 'w', encoding='utf-8') as fp:
98 fp.write('\n'.join(new_contents))
99 fp.write('\n')