diff --git a/src/vulkan/Android.mk b/src/vulkan/Android.mk index 4b1695abc65..57342ce6e22 100644 --- a/src/vulkan/Android.mk +++ b/src/vulkan/Android.mk @@ -38,7 +38,8 @@ intermediates := $(call local-generated-sources-dir) LOCAL_C_INCLUDES := \ $(MESA_TOP)/include/vulkan \ $(MESA_TOP)/src/vulkan/util \ - $(MESA_TOP)/src/gallium/include + $(MESA_TOP)/src/gallium/include \ + $(intermediates)/util \ ifeq ($(shell test $(PLATFORM_SDK_VERSION) -ge 27; echo $$?), 0) LOCAL_C_INCLUDES += \ @@ -55,7 +56,7 @@ LOCAL_SRC_FILES := $(VULKAN_UTIL_FILES) $(VULKAN_WSI_FILES) vulkan_api_xml = $(MESA_TOP)/src/vulkan/registry/vk.xml -$(firstword $(LOCAL_GENERATED_SOURCES)): $(MESA_TOP)/src/vulkan/util/gen_enum_to_str.py \ +$(intermediates)/util/vk_enum_to_str.c: $(MESA_TOP)/src/vulkan/util/gen_enum_to_str.py \ $(vulkan_api_xml) @echo "target Generated: $(PRIVATE_MODULE) <= $(notdir $(@))" @mkdir -p $(dir $@) @@ -63,7 +64,23 @@ $(firstword $(LOCAL_GENERATED_SOURCES)): $(MESA_TOP)/src/vulkan/util/gen_enum_to --xml $(vulkan_api_xml) \ --outdir $(dir $@) -$(lastword $(LOCAL_GENERATED_SOURCES)): $(firstword $(LOCAL_GENERATED_SOURCES)) +$(intermediates)/util/vk_enum_to_str.h: $(intermediates)/util/vk_enum_to_str.c + +$(intermediates)/util/vk_extensions.c: $(MESA_TOP)/src/vulkan/util/vk_extensions_gen.py \ + $(vulkan_api_xml) + @echo "target Generated: $(PRIVATE_MODULE) <= $(notdir $(@))" + @mkdir -p $(dir $@) + $(hide) $(MESA_PYTHON2) $< \ + --xml $(vulkan_api_xml) \ + --out-c $@ + +$(intermediates)/util/vk_extensions.h: $(MESA_TOP)/src/vulkan/util/vk_extensions_gen.py \ + $(vulkan_api_xml) + @echo "target Generated: $(PRIVATE_MODULE) <= $(notdir $(@))" + @mkdir -p $(dir $@) + $(hide) $(MESA_PYTHON2) $< \ + --xml $(vulkan_api_xml) \ + --out-h $@ LOCAL_EXPORT_C_INCLUDE_DIRS := $(intermediates)/util diff --git a/src/vulkan/Makefile.sources b/src/vulkan/Makefile.sources index e17a043ac01..9c684e8f56b 100644 --- a/src/vulkan/Makefile.sources +++ b/src/vulkan/Makefile.sources @@ -39,4 +39,6 @@ VULKAN_UTIL_FILES := \ VULKAN_UTIL_GENERATED_FILES := \ util/vk_enum_to_str.c \ - util/vk_enum_to_str.h + util/vk_enum_to_str.h \ + util/vk_extensions.c \ + util/vk_extensions.h diff --git a/src/vulkan/util/meson.build b/src/vulkan/util/meson.build index f0078c90258..5545ac00234 100644 --- a/src/vulkan/util/meson.build +++ b/src/vulkan/util/meson.build @@ -45,9 +45,20 @@ vk_enum_to_str = custom_target( ], ) +vk_extensions = custom_target( + 'vk_extensions', + input : ['vk_extensions_gen.py', vk_api_xml], + output : ['vk_extensions.c', 'vk_extensions.h'], + command : [ + prog_python, '@INPUT0@', '--xml', '@INPUT1@', + '--out-c', '@OUTPUT0@', '--out-h', '@OUTPUT1@' + ], + dependencies : ['vk_extensions.py'], +) + libvulkan_util = static_library( 'vulkan_util', - [files_vulkan_util, vk_enum_to_str], + [files_vulkan_util, vk_enum_to_str, vk_extensions], include_directories : [inc_include, inc_src, inc_gallium], dependencies : [vulkan_wsi_deps, idep_mesautil], c_args : [vulkan_wsi_args], @@ -56,7 +67,7 @@ libvulkan_util = static_library( ) idep_vulkan_util_headers = declare_dependency( - sources : vk_enum_to_str[1], + sources : [vk_enum_to_str[1], vk_extensions[1]], include_directories : include_directories('.') ) diff --git a/src/vulkan/util/vk_extensions.py b/src/vulkan/util/vk_extensions.py index 07217a6586b..9a0329ca10a 100644 --- a/src/vulkan/util/vk_extensions.py +++ b/src/vulkan/util/vk_extensions.py @@ -63,6 +63,43 @@ class VkVersion: return self.__int_ver() > other.__int_ver() +# Sort the extension list the way we expect: KHR, then EXT, then vendors +# alphabetically. For digits, read them as a whole number sort that. +# eg.: VK_KHR_8bit_storage < VK_KHR_16bit_storage < VK_EXT_acquire_xlib_display +def extension_order(ext): + order = [] + for substring in re.split('(KHR|EXT|[0-9]+)', ext.name): + if substring == 'KHR': + order.append(1) + if substring == 'EXT': + order.append(2) + elif substring.isdigit(): + order.append(int(substring)) + else: + order.append(substring) + return order + +def get_all_exts_from_xml(xml): + """ Get a list of all Vulkan extensions. """ + + xml = et.parse(xml) + + extensions = [] + for ext_elem in xml.findall('.extensions/extension'): + supported = ext_elem.attrib['supported'] == 'vulkan' + name = ext_elem.attrib['name'] + if not supported and name != 'VK_ANDROID_native_buffer': + continue + version = None + for enum_elem in ext_elem.findall('.require/enum'): + if enum_elem.attrib['name'].endswith('_SPEC_VERSION'): + assert version is None + version = int(enum_elem.attrib['value']) + ext = Extension(name, version, True) + extensions.append(Extension(name, version, True)) + + return sorted(extensions, key=extension_order) + def init_exts_from_xml(xml, extensions, platform_defines): """ Walk the Vulkan XML and fill out extra extension information. """ diff --git a/src/vulkan/util/vk_extensions_gen.py b/src/vulkan/util/vk_extensions_gen.py index bbfb60b3d81..4c74b45485c 100644 --- a/src/vulkan/util/vk_extensions_gen.py +++ b/src/vulkan/util/vk_extensions_gen.py @@ -35,10 +35,15 @@ _TEMPLATE_H = Template(COPYRIGHT + """ #ifndef ${driver.upper()}_EXTENSIONS_H #define ${driver.upper()}_EXTENSIONS_H +#include + %for include in includes: #include "${include}" %endfor +%if type_prefix == 'vk' and driver != 'vk': +#include "vk_extensions.h" +%else: #define ${driver.upper()}_INSTANCE_EXTENSION_COUNT ${len(instance_extensions)} extern const VkExtensionProperties ${driver}_instance_extensions[]; @@ -54,8 +59,6 @@ struct ${driver}_instance_extension_table { }; }; -extern const struct ${driver}_instance_extension_table ${driver}_instance_extensions_supported; - #define ${driver.upper()}_DEVICE_EXTENSION_COUNT ${len(device_extensions)} @@ -71,19 +74,45 @@ struct ${driver}_device_extension_table { }; }; }; +%endif struct ${driver}_physical_device; +%if driver != 'vk': +extern const struct ${type_prefix}_instance_extension_table ${driver}_instance_extensions_supported; + void ${driver}_physical_device_get_supported_extensions(const struct ${driver}_physical_device *device, - struct ${driver}_device_extension_table *extensions); + struct ${type_prefix}_device_extension_table *extensions); +%endif #endif /* ${driver.upper()}_EXTENSIONS_H */ """) _TEMPLATE_C = Template(COPYRIGHT + """ +%if driver == 'vk': +#include "vk_object.h" +%else: #include "${driver}_private.h" +%endif +#include "${driver}_extensions.h" + +%if type_prefix != 'vk' or driver == 'vk': +const VkExtensionProperties ${driver}_instance_extensions[${driver.upper()}_INSTANCE_EXTENSION_COUNT] = { +%for ext in instance_extensions: + {"${ext.name}", ${ext.ext_version}}, +%endfor +}; + +const VkExtensionProperties ${driver}_device_extensions[${driver.upper()}_DEVICE_EXTENSION_COUNT] = { +%for ext in device_extensions: + {"${ext.name}", ${ext.ext_version}}, +%endfor +}; +%endif + +%if driver != 'vk': #include "vk_util.h" /* Convert the VK_USE_PLATFORM_* defines to booleans */ @@ -119,13 +148,7 @@ VkResult ${driver}_EnumerateInstanceVersion( return VK_SUCCESS; } -const VkExtensionProperties ${driver}_instance_extensions[${driver.upper()}_INSTANCE_EXTENSION_COUNT] = { -%for ext in instance_extensions: - {"${ext.name}", ${ext.ext_version}}, -%endfor -}; - -const struct ${driver}_instance_extension_table ${driver}_instance_extensions_supported = { +const struct ${type_prefix}_instance_extension_table ${driver}_instance_extensions_supported = { %for ext in instance_extensions: .${ext.name[3:]} = ${get_extension_condition(ext.name, ext.enable)}, %endfor @@ -149,25 +172,21 @@ ${driver}_physical_device_api_version(struct ${driver}_physical_device *device) return version; } -const VkExtensionProperties ${driver}_device_extensions[${driver.upper()}_DEVICE_EXTENSION_COUNT] = { -%for ext in device_extensions: - {"${ext.name}", ${ext.ext_version}}, -%endfor -}; - void ${driver}_physical_device_get_supported_extensions(const struct ${driver}_physical_device *device, - struct ${driver}_device_extension_table *extensions) + struct ${type_prefix}_device_extension_table *extensions) { - *extensions = (struct ${driver}_device_extension_table) { + *extensions = (struct ${type_prefix}_device_extension_table) { %for ext in device_extensions: .${ext.name[3:]} = ${get_extension_condition(ext.name, ext.enable)}, %endfor }; } +%endif """) -def gen_extensions(driver, xml_files, api_versions, max_api_version, extensions, out_c, out_h, includes = []): +def gen_extensions(driver, xml_files, api_versions, max_api_version, + extensions, out_c, out_h, includes = [], type_prefix = None): platform_defines = [] for filename in xml_files: init_exts_from_xml(filename, extensions, platform_defines) @@ -175,8 +194,12 @@ def gen_extensions(driver, xml_files, api_versions, max_api_version, extensions, for ext in extensions: assert ext.type == 'instance' or ext.type == 'device' + if type_prefix is None: + type_prefix = driver + template_env = { 'driver': driver, + 'type_prefix': type_prefix, 'API_VERSIONS': api_versions, 'MAX_API_VERSION': max_api_version, 'instance_extensions': [e for e in extensions if e.type == 'instance'], @@ -193,3 +216,22 @@ def gen_extensions(driver, xml_files, api_versions, max_api_version, extensions, if out_c: with open(out_c, 'w') as f: f.write(_TEMPLATE_C.render(**template_env)) + + +if __name__ == '__main__': + parser = argparse.ArgumentParser() + parser.add_argument('--out-c', help='Output C file.') + parser.add_argument('--out-h', help='Output H file.') + parser.add_argument('--xml', + help='Vulkan API XML file.', + required=True, + action='append', + dest='xml_files') + args = parser.parse_args() + + extensions = [] + for filename in args.xml_files: + extensions += get_all_exts_from_xml(filename) + + gen_extensions('vk', args.xml_files, None, None, + extensions, args.out_c, args.out_h, [])