mirror of
https://gitlab.freedesktop.org/monado/monado.git
synced 2025-01-01 12:46:12 +00:00
a/bindings: Generate code to verify paths for promoted core paths
Part-of: <https://gitlab.freedesktop.org/monado/monado/-/merge_requests/2194>
This commit is contained in:
parent
7cf457d894
commit
cdbf4ef26a
|
@ -441,7 +441,7 @@ header = '''// Copyright 2020-2022, Collabora, Ltd.
|
||||||
|
|
||||||
func_start = '''
|
func_start = '''
|
||||||
bool
|
bool
|
||||||
{name}(const struct oxr_extension_status *exts, const char *str, size_t length)
|
{name}(const struct oxr_extension_status *exts, XrVersion openxr_version, const char *str, size_t length)
|
||||||
{{
|
{{
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
@ -459,6 +459,21 @@ if_strcmp = '''{exttab}if (strcmp(str, "{check}") == 0) {{
|
||||||
{exttab}\t\t\treturn true;
|
{exttab}\t\t\treturn true;
|
||||||
{exttab}\t\t}} else '''
|
{exttab}\t\t}} else '''
|
||||||
|
|
||||||
|
def check_promoted(openxr_version_promoted):
|
||||||
|
# If required version is 0.0, we can skip checking that the instance uses a more recent version
|
||||||
|
return openxr_version_promoted is not None and openxr_version_promoted["major"] != '0' and openxr_version_promoted["minor"] != '0'
|
||||||
|
|
||||||
|
def write_verify_switch_body(f, dict_of_lists, profile, profile_name, ext_name, tab_char):
|
||||||
|
"""Generate function to check if a string is in a set of strings.
|
||||||
|
Input is a file to write the code into, a dict where keys are length and
|
||||||
|
the values are lists of strings of that length. And a suffix if any."""
|
||||||
|
f.write(f"{tab_char}\tswitch (length) {{\n")
|
||||||
|
for length in dict_of_lists:
|
||||||
|
f.write(f"{tab_char}\tcase {str(length)}:\n\t\t")
|
||||||
|
for path in dict_of_lists[length]:
|
||||||
|
f.write(if_strcmp.format(exttab=tab_char, check=path))
|
||||||
|
f.write(f"{tab_char}{{\n{tab_char}\t\t\tbreak;\n{tab_char}\t\t}}\n")
|
||||||
|
f.write(f"{tab_char}\tdefault: break;\n{tab_char}\t}}\n")
|
||||||
|
|
||||||
def write_verify_func_switch(f, dict_of_lists, profile, profile_name, ext_name):
|
def write_verify_func_switch(f, dict_of_lists, profile, profile_name, ext_name):
|
||||||
"""Generate function to check if a string is in a set of strings.
|
"""Generate function to check if a string is in a set of strings.
|
||||||
|
@ -467,29 +482,30 @@ def write_verify_func_switch(f, dict_of_lists, profile, profile_name, ext_name):
|
||||||
if len(dict_of_lists) == 0:
|
if len(dict_of_lists) == 0:
|
||||||
return
|
return
|
||||||
|
|
||||||
if profile.extension_name is not None:
|
is_ext = ext_name is not None and len(ext_name) > 0
|
||||||
f.write(f'#ifdef OXR_HAVE_{profile.extension_name}\n')
|
is_promoted = check_promoted(profile.openxr_version_promoted)
|
||||||
|
|
||||||
f.write(f"\t// generated from: {profile_name}\n")
|
f.write(f"\t// generated from: {profile_name}\n")
|
||||||
is_ext = ext_name is not None and len(ext_name) > 0
|
|
||||||
ext_tab = ""
|
# Example: pico neo 3 can be enabled by either enabling XR_BD_controller_interaction ext or using OpenXR 1.1+.
|
||||||
|
# Disabling OXR_HAVE_BD_controller_interaction should NOT remove pico neo from OpenXR 1.1+ (it makes "exts->BD_controller_interaction" invalid C code).
|
||||||
|
# Therefore separate code blocks for ext and version checks generated to avoid ifdef hell.
|
||||||
if is_ext:
|
if is_ext:
|
||||||
|
f.write(f'#ifdef OXR_HAVE_{profile.extension_name}\n')
|
||||||
f.write(f"\tif (exts->{ext_name}) {{\n")
|
f.write(f"\tif (exts->{ext_name}) {{\n")
|
||||||
ext_tab = "\t"
|
write_verify_switch_body(f, dict_of_lists, profile, profile_name, ext_name, '\t')
|
||||||
|
f.write("\t}\n")
|
||||||
|
f.write(f'#endif // OXR_HAVE_{profile.extension_name}\n')
|
||||||
|
|
||||||
f.write(f"{ext_tab}\tswitch (length) {{\n")
|
# The split into "is_promoted" and "not is_ext and not is_promoted" cases is not strictly necessary as we could generate the version check for both cases.
|
||||||
for length in dict_of_lists:
|
# For the "not is_ext and not is_promoted" case this would generate "if (openxr_version >= XR_MAKE_VERSION(0, 0, 0))", which we avoid doing here by this split.
|
||||||
f.write(f"{ext_tab}\tcase {str(length)}:\n\t\t")
|
if is_promoted:
|
||||||
for path in dict_of_lists[length]:
|
f.write(f'\tif (openxr_version >= XR_MAKE_VERSION({profile.openxr_version_promoted["major"]}, {profile.openxr_version_promoted["minor"]}, 0)) {{\n')
|
||||||
f.write(if_strcmp.format(exttab=ext_tab, check=path))
|
write_verify_switch_body(f, dict_of_lists, profile, profile_name, ext_name, '\t')
|
||||||
f.write(f"{ext_tab}{{\n{ext_tab}\t\t\tbreak;\n{ext_tab}\t\t}}\n")
|
|
||||||
f.write(f"{ext_tab}\tdefault: break;\n{ext_tab}\t}}\n")
|
|
||||||
|
|
||||||
if is_ext:
|
|
||||||
f.write("\t}\n")
|
f.write("\t}\n")
|
||||||
|
|
||||||
if profile.extension_name is not None:
|
if not is_ext and not is_promoted:
|
||||||
f.write(f'#endif // OXR_HAVE_{profile.extension_name}\n')
|
write_verify_switch_body(f, dict_of_lists, profile, profile_name, ext_name, '')
|
||||||
|
|
||||||
def write_verify_func_body(f, profile, dict_name):
|
def write_verify_func_body(f, profile, dict_name):
|
||||||
if profile is None or dict_name is None or len(dict_name) == 0:
|
if profile is None or dict_name is None or len(dict_name) == 0:
|
||||||
|
@ -516,8 +532,18 @@ def generate_verify_functions(f, profile):
|
||||||
|
|
||||||
f.write(f'''
|
f.write(f'''
|
||||||
void
|
void
|
||||||
oxr_verify_{profile.validation_func_name}_ext(const struct oxr_extension_status *extensions, bool *out_supported, bool *out_enabled)
|
oxr_verify_{profile.validation_func_name}_ext(const struct oxr_extension_status *extensions, XrVersion openxr_version, bool *out_supported, bool *out_enabled)
|
||||||
{{''')
|
{{
|
||||||
|
''')
|
||||||
|
is_promoted = check_promoted(profile.openxr_version_promoted)
|
||||||
|
if is_promoted:
|
||||||
|
f.write(f'\tif (openxr_version >= XR_MAKE_VERSION({profile.openxr_version_promoted["major"]}, {profile.openxr_version_promoted["minor"]}, 0)) {{\n')
|
||||||
|
f.write(f'\t\t*out_supported = true;\n')
|
||||||
|
f.write(f'\t\t*out_enabled = true;\n')
|
||||||
|
f.write(f'\t\treturn;\n')
|
||||||
|
f.write(f'\t}}')
|
||||||
|
|
||||||
|
|
||||||
if profile.extension_name is not None:
|
if profile.extension_name is not None:
|
||||||
f.write(f'''
|
f.write(f'''
|
||||||
#ifdef OXR_HAVE_{profile.extension_name}
|
#ifdef OXR_HAVE_{profile.extension_name}
|
||||||
|
@ -776,6 +802,8 @@ def generate_bindings_h(file, b):
|
||||||
#include "xrt/xrt_defines.h"
|
#include "xrt/xrt_defines.h"
|
||||||
|
|
||||||
typedef uint64_t XrPath; // OpenXR typedef
|
typedef uint64_t XrPath; // OpenXR typedef
|
||||||
|
typedef uint64_t XrVersion; // OpenXR typedef
|
||||||
|
|
||||||
struct oxr_extension_status;
|
struct oxr_extension_status;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -792,8 +820,8 @@ void oxr_get_interaction_profile_path_cache(XrPath **out_path_cache[{len(b.profi
|
||||||
for profile in b.profiles:
|
for profile in b.profiles:
|
||||||
for fn_suffix in fn_prefixes:
|
for fn_suffix in fn_prefixes:
|
||||||
f.write(
|
f.write(
|
||||||
f"\nbool\noxr_verify_{profile.validation_func_name}{fn_suffix}(const struct oxr_extension_status *extensions, const char *str, size_t length);\n")
|
f"\nbool\noxr_verify_{profile.validation_func_name}{fn_suffix}(const struct oxr_extension_status *extensions, XrVersion openxr_major_minor, const char *str, size_t length);\n")
|
||||||
f.write(f'''\nvoid\noxr_verify_{profile.validation_func_name}_ext(const struct oxr_extension_status *extensions, bool *out_supported, bool *out_enabled);\n''')
|
f.write(f'''\nvoid\noxr_verify_{profile.validation_func_name}_ext(const struct oxr_extension_status *extensions, XrVersion openxr_version, bool *out_supported, bool *out_enabled);\n''')
|
||||||
|
|
||||||
f.write(f'''
|
f.write(f'''
|
||||||
#define PATHS_PER_BINDING_TEMPLATE 16
|
#define PATHS_PER_BINDING_TEMPLATE 16
|
||||||
|
@ -826,8 +854,8 @@ struct binding_template
|
||||||
\tenum xrt_output_name output;
|
\tenum xrt_output_name output;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
typedef bool (*path_verify_fn_t)(const struct oxr_extension_status *extensions, const char *, size_t);
|
typedef bool (*path_verify_fn_t)(const struct oxr_extension_status *extensions, XrVersion openxr_version, const char *, size_t);
|
||||||
typedef void (*ext_verify_fn_t)(const struct oxr_extension_status *extensions, bool *out_supported, bool *out_enabled);
|
typedef void (*ext_verify_fn_t)(const struct oxr_extension_status *extensions, XrVersion openxr_version, bool *out_supported, bool *out_enabled);
|
||||||
|
|
||||||
struct profile_template
|
struct profile_template
|
||||||
{{
|
{{
|
||||||
|
|
|
@ -53,7 +53,7 @@ process_dpad(struct oxr_logger *log,
|
||||||
dpad->binding);
|
dpad->binding);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!dpad_emulator_fn(&inst->extensions, str, length)) {
|
if (!dpad_emulator_fn(&inst->extensions, inst->openxr_version.major_minor, str, length)) {
|
||||||
return oxr_error(log, XR_ERROR_PATH_UNSUPPORTED,
|
return oxr_error(log, XR_ERROR_PATH_UNSUPPORTED,
|
||||||
"(%s->binding == \"%s\") is not a valid dpad binding path for profile \"%s\"", prefix,
|
"(%s->binding == \"%s\") is not a valid dpad binding path for profile \"%s\"", prefix,
|
||||||
str, ip_str);
|
str, ip_str);
|
||||||
|
@ -248,7 +248,7 @@ oxr_xrSuggestInteractionProfileBindings(XrInstance instance,
|
||||||
|
|
||||||
bool ext_supported;
|
bool ext_supported;
|
||||||
bool ext_enabled;
|
bool ext_enabled;
|
||||||
ext_verify_fn(&inst->extensions, &ext_supported, &ext_enabled);
|
ext_verify_fn(&inst->extensions, inst->openxr_version.major_minor, &ext_supported, &ext_enabled);
|
||||||
if (!ext_supported) {
|
if (!ext_supported) {
|
||||||
return oxr_error(
|
return oxr_error(
|
||||||
&log, XR_ERROR_PATH_UNSUPPORTED,
|
&log, XR_ERROR_PATH_UNSUPPORTED,
|
||||||
|
@ -286,12 +286,12 @@ oxr_xrSuggestInteractionProfileBindings(XrInstance instance,
|
||||||
i, s->binding);
|
i, s->binding);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (subpath_fn(&inst->extensions, str, length)) {
|
if (subpath_fn(&inst->extensions, inst->openxr_version.major_minor, str, length)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef XR_EXT_dpad_binding
|
#ifdef XR_EXT_dpad_binding
|
||||||
if (dpad_path_fn(&inst->extensions, str, length)) {
|
if (dpad_path_fn(&inst->extensions, inst->openxr_version.major_minor, str, length)) {
|
||||||
if (!has_dpad) {
|
if (!has_dpad) {
|
||||||
return oxr_error(
|
return oxr_error(
|
||||||
&log, XR_ERROR_PATH_UNSUPPORTED,
|
&log, XR_ERROR_PATH_UNSUPPORTED,
|
||||||
|
|
Loading…
Reference in a new issue