From fea9de3c8368d3c293f6b2a1035c9ef7f1df7516 Mon Sep 17 00:00:00 2001 From: Yiwei Zhang Date: Fri, 21 Jun 2024 11:20:21 -0700 Subject: [PATCH] vulkan: properly ignore unsupported feature structs This is inspired from below MR but done in the fixed way: https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26767 The requirements used to look up struct extensions are missing the alias check for those promoted ones. This change fixes it so that the condition now is correct. We can land this now as all drivers have migrated to use the common properties, which has now also been mandated. Signed-off-by: Yiwei Zhang Part-of: --- src/vulkan/util/vk_extensions.py | 17 ++++++++++- .../util/vk_physical_device_features_gen.py | 28 +++++++++++++++++-- 2 files changed, 41 insertions(+), 4 deletions(-) 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()