diff --git a/src/vulkan/util/vk_extensions.py b/src/vulkan/util/vk_extensions.py index 5372edadb47..f58b04f71cb 100644 --- a/src/vulkan/util/vk_extensions.py +++ b/src/vulkan/util/vk_extensions.py @@ -175,8 +175,23 @@ def filter_api(elem, api): return api in elem.attrib['api'].split(',') +def get_alias(aliases, name): + if name in aliases: + # in case the spec registry adds an alias chain later + return get_alias(aliases, aliases[name]) + return name + def get_all_required(xml, thing, api, beta): things = {} + aliases = {} + for struct in xml.findall('./types/type[@category="struct"][@alias]'): + if not filter_api(struct, api): + continue + + name = struct.attrib['name'] + alias = struct.attrib['alias'] + aliases[name] = alias + for feature in xml.findall('./feature'): if not filter_api(feature, api): continue @@ -200,7 +215,7 @@ def get_all_required(xml, thing, api, beta): continue for t in require.findall('./' + thing): - name = t.attrib['name'] + name = get_alias(aliases, t.attrib['name']) r = things.setdefault(name, Requirements()) r.add_extension(ext) diff --git a/src/vulkan/util/vk_physical_device_features_gen.py b/src/vulkan/util/vk_physical_device_features_gen.py index 27673ca3c0c..47cee1af52a 100644 --- a/src/vulkan/util/vk_physical_device_features_gen.py +++ b/src/vulkan/util/vk_physical_device_features_gen.py @@ -32,7 +32,7 @@ import xml.etree.ElementTree as et import mako from mako.template import Template -from vk_extensions import get_all_required, filter_api +from vk_extensions import Requirements, get_all_required, filter_api def str_removeprefix(s, prefix): if s.startswith(prefix): @@ -124,10 +124,23 @@ def get_renamed_feature(c_type, feature): @dataclass class FeatureStruct: + reqs: Requirements c_type: str s_type: str features: typing.List[str] + def condition(self, physical_dev): + conds = [] + if self.reqs.core_version: + conds.append(physical_dev + '->properties.apiVersion >= ' + + self.reqs.core_version.c_vk_version()) + for ext in self.reqs.extensions: + conds.append(physical_dev + '->supported_extensions.' + + ext.name[3:]) + if not conds: + return None + return '(' + ' || '.join(conds) + ')' + TEMPLATE_H = Template(COPYRIGHT + """ /* This file generated from ${filename}, don't edit directly. */ #ifndef VK_FEATURES_H @@ -203,6 +216,10 @@ vk_physical_device_check_device_features(struct vk_physical_device *physical_dev switch (features->sType) { % for f in feature_structs: case ${f.s_type}: +% if f.condition("physical_device") is not None: + if (!${f.condition("physical_device")}) + break; +% endif supported = (VkBaseOutStructure *) &supported_${f.c_type}; break; % endfor @@ -252,6 +269,10 @@ vk_physical_device_check_device_features(struct vk_physical_device *physical_dev } % for f in feature_structs: case ${f.s_type}: { +% if f.condition("physical_device") is not None: + if (!${f.condition("physical_device")}) + break; +% endif const ${f.c_type} *a = &supported_${f.c_type}; const ${f.c_type} *b = (const void *) features; % for flag in f.features: @@ -365,8 +386,9 @@ def get_feature_structs(doc, api, beta): if _type.attrib['name'] not in required: continue + reqs = required[_type.attrib['name']] # Skip extensions with a define for now - guard = required[_type.attrib['name']].guard + guard = reqs.guard if guard is not None and (guard != "VK_ENABLE_BETA_EXTENSIONS" or beta != "true"): continue @@ -391,7 +413,7 @@ def get_feature_structs(doc, api, beta): assert p.find('./type').text == 'VkBool32' flags.append(m_name) - feature_struct = FeatureStruct(c_type=_type.attrib.get('name'), s_type=s_type, features=flags) + feature_struct = FeatureStruct(reqs=reqs, c_type=_type.attrib.get('name'), s_type=s_type, features=flags) feature_structs[feature_struct.c_type] = feature_struct return feature_structs.values()