From 8a56046c1db954c3bbe0c7ca8b71fb0c264d8fab Mon Sep 17 00:00:00 2001 From: Ryan Pavlik Date: Tue, 9 Nov 2021 10:51:35 -0600 Subject: [PATCH] a/vk: Also generate the extension list/checking --- scripts/generate_vk_helpers.py | 115 ++++++++++++++++++++++++------ src/xrt/auxiliary/vk/vk_helpers.c | 18 ++++- src/xrt/auxiliary/vk/vk_helpers.h | 3 + 3 files changed, 113 insertions(+), 23 deletions(-) diff --git a/scripts/generate_vk_helpers.py b/scripts/generate_vk_helpers.py index 1b9cd74d6..58ce68092 100755 --- a/scripts/generate_vk_helpers.py +++ b/scripts/generate_vk_helpers.py @@ -4,9 +4,10 @@ """Simple script to update vk_helpers.{c,h}.""" from pathlib import Path -from typing import List, Tuple +from typing import List, Optional, Tuple -# Each tuple is a function name, followed optionally by one or more conditions to test in the preprocessor, which will be wrapped in "defined()" +# Each tuple is a function name, followed optionally by one or more conditions +# to test in the preprocessor, which will be wrapped in "defined()" # if they aren't already. Empty tuples insert a blank line. DEVICE_FUNCTIONS = [ @@ -180,9 +181,9 @@ INSTANCE_FUNCTIONS = [ ] EXTENSIONS_TO_CHECK = [ -"GOOGLE_display_timing", -"EXT_global_priority", -"EXT_robustness2", + "VK_GOOGLE_display_timing", + "VK_EXT_global_priority", + "VK_EXT_robustness2", ] ROOT = Path(__file__).resolve().parent.parent @@ -206,31 +207,52 @@ def compute_condition(pp_conditions): return " && ".join(wrap_condition(x) for x in pp_conditions) +class ConditionalGenerator: + """Keep track of conditions to avoid unneeded repetition of ifdefs.""" + + def __init__(self): + self.current_condition = None + + def process_condition(self, new_condition: Optional[str]) -> Optional[str]: + """Return a line (or lines) to yield if required based on the new condition state.""" + lines = [] + if self.current_condition and new_condition != self.current_condition: + # Close current condition if required. + lines.append("#endif // {}".format(self.current_condition)) + # empty line + lines.append("") + self.current_condition = None + + if new_condition != self.current_condition: + # Open new condition if required + lines.append("#if {}".format(new_condition)) + self.current_condition = new_condition + + if lines: + return "\n".join(lines) + + def finish(self) -> Optional[str]: + """Return a line (or lines) to yield if required at the end of the loop.""" + return self.process_condition(None) + + def generate_per_function(functions: List[Tuple[str, ...]], per_function_handler): - current_condition = None + conditional = ConditionalGenerator() for data in functions: if not data: # empty line yield "" continue - new_condition = compute_condition(data[1:]) - if current_condition and new_condition != current_condition: - # Close current condition if required. - yield "#endif // {}".format(current_condition) - # empty line - yield "" - current_condition = None - - if new_condition != current_condition: - # Open new condition if required - yield "#if {}".format(new_condition) - current_condition = new_condition + condition_line = conditional.process_condition(compute_condition(data[1:])) + if condition_line: + yield condition_line yield per_function_handler(data[0]) # close any trailing conditions - if current_condition: - yield "#endif // {}".format(current_condition) + condition_line = conditional.finish() + if condition_line: + yield condition_line def generate_structure_members(functions: List[Tuple[str, ...]]): @@ -254,6 +276,46 @@ def generate_dev_proc(functions: List[Tuple[str, ...]]): return generate_per_function(functions, per_function) +def make_ext_member_name(ext: str): + return "has_{}".format(ext[3:]) + + +def make_ext_name_define(ext: str): + return "{}_EXTENSION_NAME".format(ext.upper()).replace("2", "_2") + + +def generate_ext_members(): + for ext in EXTENSIONS_TO_CHECK: + yield "\tbool {};".format(make_ext_member_name(ext)) + + +def generate_ext_check(): + yield "\t// Reset before filling out." + + for ext in EXTENSIONS_TO_CHECK: + yield "\tvk->{} = false;".format(make_ext_member_name(ext)) + + yield "" + yield "\tfor (uint32_t i = 0; i < device_extension_count; i++) {" + yield "\t\tconst char *ext = device_extensions[i];" + yield "" + + conditional = ConditionalGenerator() + for ext in EXTENSIONS_TO_CHECK: + condition_line = conditional.process_condition(compute_condition((ext,))) + if condition_line: + yield condition_line + yield "\t\tif (strcmp(ext, {}) == 0) {{".format(make_ext_name_define(ext)) + yield "\t\t\tvk->{} = true;".format(make_ext_member_name(ext)) + yield "\t\t\tcontinue;" + yield "\t\t}" + # close any trailing conditions + condition_line = conditional.finish() + if condition_line: + yield condition_line + yield "\t}" + + def replace_middle( lines: List[str], start_sentinel: str, end_sentinel: str, new_middle: List[str] ) -> List[str]: @@ -293,6 +355,12 @@ def process_header(): DEVICE_TEMPLATES["END"], list(generate_structure_members(DEVICE_FUNCTIONS)), ) + lines = replace_middle( + lines, + EXT_TEMPLATES["BEGIN"], + EXT_TEMPLATES["END"], + list(generate_ext_members()), + ) with open(str(HEADER_FN), "w", encoding="utf-8") as fp: fp.write("\n".join(lines)) @@ -317,6 +385,13 @@ def process_impl(): list(generate_dev_proc(DEVICE_FUNCTIONS)), ) + lines = replace_middle( + lines, + EXT_TEMPLATES["BEGIN"], + EXT_TEMPLATES["END"], + list(generate_ext_check()), + ) + with open(str(IMPL_FN), "w", encoding="utf-8") as fp: fp.write("\n".join(lines)) fp.write("\n") diff --git a/src/xrt/auxiliary/vk/vk_helpers.c b/src/xrt/auxiliary/vk/vk_helpers.c index 4ee036d09..a4c0d427e 100644 --- a/src/xrt/auxiliary/vk/vk_helpers.c +++ b/src/xrt/auxiliary/vk/vk_helpers.c @@ -884,7 +884,8 @@ vk_get_instance_functions(struct vk_bundle *vk) #if defined(VK_USE_PLATFORM_WIN32_KHR) vk->vkCreateWin32SurfaceKHR = GET_INS_PROC(vk, vkCreateWin32SurfaceKHR); #endif // defined(VK_USE_PLATFORM_WIN32_KHR) - // end of GENERATED instance loader code - do not modify - used by scripts + + // end of GENERATED instance loader code - do not modify - used by scripts return VK_SUCCESS; } @@ -1220,6 +1221,7 @@ vk_check_extension(struct vk_bundle *vk, VkExtensionProperties *props, uint32_t static void fill_in_has_extensions(struct vk_bundle *vk, const char **device_extensions, uint32_t num_device_extensions) { + // beginning of GENERATED extension code - do not modify - used by scripts // Reset before filling out. vk->has_GOOGLE_display_timing = false; vk->has_EXT_global_priority = false; @@ -1228,18 +1230,28 @@ fill_in_has_extensions(struct vk_bundle *vk, const char **device_extensions, uin for (uint32_t i = 0; i < num_device_extensions; i++) { const char *ext = device_extensions[i]; +#if defined(VK_GOOGLE_display_timing) if (strcmp(ext, VK_GOOGLE_DISPLAY_TIMING_EXTENSION_NAME) == 0) { vk->has_GOOGLE_display_timing = true; + continue; } +#endif // defined(VK_GOOGLE_display_timing) + +#if defined(VK_EXT_global_priority) if (strcmp(ext, VK_EXT_GLOBAL_PRIORITY_EXTENSION_NAME) == 0) { vk->has_EXT_global_priority = true; + continue; } -#ifdef VK_EXT_robustness2 +#endif // defined(VK_EXT_global_priority) + +#if defined(VK_EXT_robustness2) if (strcmp(ext, VK_EXT_ROBUSTNESS_2_EXTENSION_NAME) == 0) { vk->has_EXT_robustness2 = true; + continue; } -#endif +#endif // defined(VK_EXT_robustness2) } + // end of GENERATED extension code - do not modify - used by scripts } static VkResult diff --git a/src/xrt/auxiliary/vk/vk_helpers.h b/src/xrt/auxiliary/vk/vk_helpers.h index 8e02feb79..6bd5b604f 100644 --- a/src/xrt/auxiliary/vk/vk_helpers.h +++ b/src/xrt/auxiliary/vk/vk_helpers.h @@ -48,9 +48,11 @@ struct vk_bundle struct os_mutex queue_mutex; + // beginning of GENERATED extension code - do not modify - used by scripts bool has_GOOGLE_display_timing; bool has_EXT_global_priority; bool has_EXT_robustness2; + // end of GENERATED extension code - do not modify - used by scripts bool is_tegra; @@ -129,6 +131,7 @@ struct vk_bundle #if defined(VK_USE_PLATFORM_WIN32_KHR) PFN_vkCreateWin32SurfaceKHR vkCreateWin32SurfaceKHR; #endif // defined(VK_USE_PLATFORM_WIN32_KHR) + // end of GENERATED instance loader code - do not modify - used by scripts // beginning of GENERATED device loader code - do not modify - used by scripts