vk/util: ignore unsupported feature structs

vk_physical_device_check_device_features should ignore unsupported
feature structs:

  Any component of the implementation (the loader, any enabled layers,
  and drivers) must skip over, without processing (other than reading
  the sType and pNext members) any extending structures in the chain not
  defined by core versions or extensions supported by that component.

Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/10177
Cc: mesa-stable
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26767>
This commit is contained in:
Chia-I Wu 2023-12-19 14:06:16 -08:00 committed by Marge Bot
parent 2816db0182
commit eb5bb5c784

View file

@ -32,7 +32,7 @@ import xml.etree.ElementTree as et
import mako import mako
from mako.template import Template 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): def str_removeprefix(s, prefix):
if s.startswith(prefix): if s.startswith(prefix):
@ -124,10 +124,21 @@ def get_renamed_feature(c_type, feature):
@dataclass @dataclass
class FeatureStruct: class FeatureStruct:
reqs: Requirements
c_type: str c_type: str
s_type: str s_type: str
features: typing.List[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:])
return '(' + ' || '.join(conds) + ')'
TEMPLATE_H = Template(COPYRIGHT + """ TEMPLATE_H = Template(COPYRIGHT + """
/* This file generated from ${filename}, don't edit directly. */ /* This file generated from ${filename}, don't edit directly. */
#ifndef VK_FEATURES_H #ifndef VK_FEATURES_H
@ -203,6 +214,10 @@ vk_physical_device_check_device_features(struct vk_physical_device *physical_dev
switch (features->sType) { switch (features->sType) {
% for f in feature_structs: % for f in feature_structs:
case ${f.s_type}: case ${f.s_type}:
% if f.condition("physical_device"):
if (!${f.condition("physical_device")})
break;
% endif
supported = (VkBaseOutStructure *) &supported_${f.c_type}; supported = (VkBaseOutStructure *) &supported_${f.c_type};
break; break;
% endfor % endfor
@ -252,6 +267,10 @@ vk_physical_device_check_device_features(struct vk_physical_device *physical_dev
} }
% for f in feature_structs: % for f in feature_structs:
case ${f.s_type}: { case ${f.s_type}: {
% if f.condition("physical_device"):
if (!${f.condition("physical_device")})
break;
% endif
const ${f.c_type} *a = &supported_${f.c_type}; const ${f.c_type} *a = &supported_${f.c_type};
const ${f.c_type} *b = (const void *) features; const ${f.c_type} *b = (const void *) features;
% for flag in f.features: % for flag in f.features:
@ -365,8 +384,9 @@ def get_feature_structs(doc, api, beta):
if _type.attrib['name'] not in required: if _type.attrib['name'] not in required:
continue continue
reqs = required[_type.attrib['name']]
# Skip extensions with a define for now # 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 not beta): if guard is not None and (guard != "VK_ENABLE_BETA_EXTENSIONS" or not beta):
continue continue
@ -391,7 +411,7 @@ def get_feature_structs(doc, api, beta):
assert p.find('./type').text == 'VkBool32' assert p.find('./type').text == 'VkBool32'
flags.append(m_name) 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 feature_structs[feature_struct.c_type] = feature_struct
return feature_structs.values() return feature_structs.values()