vulkan/device: Use vk_errorf to report missing features

With a tiny bit more code-gen, we can now not only throw the error but
also log back to the client exactly which feature was missing.

Reviewed-By: Mike Blumenkrantz <michael.blumenkrantz@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13045>
This commit is contained in:
Jason Ekstrand 2021-09-30 11:41:15 -05:00 committed by Marge Bot
parent 5b42f1a374
commit 305b170229

View file

@ -33,20 +33,21 @@ from mako.template import Template
TEMPLATE_C = Template(COPYRIGHT + """
/* This file generated from ${filename}, don't edit directly. */
#include "vk_log.h"
#include "vk_physical_device.h"
#include "vk_util.h"
static VkResult
check_physical_device_features(const VkPhysicalDeviceFeatures *supported,
const VkPhysicalDeviceFeatures *enabled)
check_physical_device_features(struct vk_physical_device *physical_device,
const VkPhysicalDeviceFeatures *supported,
const VkPhysicalDeviceFeatures *enabled,
const char *struct_name)
{
const VkBool32 *supported_feature = (const VkBool32 *) supported;
const VkBool32 *enabled_feature = (const VkBool32 *) enabled;
unsigned num_features = sizeof(VkPhysicalDeviceFeatures) / sizeof(VkBool32);
for (uint32_t i = 0; i < num_features; i++) {
if (enabled_feature[i] && !supported_feature[i])
return VK_ERROR_FEATURE_NOT_PRESENT;
}
% for flag in pdev_features:
if (enabled->${flag} && !supported->${flag})
return vk_errorf(physical_device, VK_ERROR_FEATURE_NOT_PRESENT,
"%s.%s not supported", struct_name, "${flag}");
% endfor
return VK_SUCCESS;
}
@ -96,8 +97,10 @@ vk_physical_device_check_device_features(struct vk_physical_device *physical_dev
if (pCreateInfo->pEnabledFeatures) {
VkResult result =
check_physical_device_features(&supported_features2.features,
pCreateInfo->pEnabledFeatures);
check_physical_device_features(physical_device,
&supported_features2.features,
pCreateInfo->pEnabledFeatures,
"VkPhysicalDeviceFeatures");
if (result != VK_SUCCESS)
return result;
}
@ -109,8 +112,10 @@ vk_physical_device_check_device_features(struct vk_physical_device *physical_dev
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2: {
const VkPhysicalDeviceFeatures2 *features2 = (const void *)feat;
VkResult result =
check_physical_device_features(&supported_features2.features,
&features2->features);
check_physical_device_features(physical_device,
&supported_features2.features,
&features2->features,
"VkPhysicalDeviceFeatures2.features");
if (result != VK_SUCCESS)
return result;
break;
@ -121,7 +126,8 @@ vk_physical_device_check_device_features(struct vk_physical_device *physical_dev
${f.name} *b = (${f.name} *) feat;
% for flag in f.vk_flags:
if (b->${flag} && !a->${flag})
return VK_ERROR_FEATURE_NOT_PRESENT;
return vk_errorf(physical_device, VK_ERROR_FEATURE_NOT_PRESENT,
"%s.%s not supported", "${f.name}", "${flag}");
% endfor
break;
}
@ -137,6 +143,21 @@ vk_physical_device_check_device_features(struct vk_physical_device *physical_dev
Feature = namedtuple('Feature', 'name vk_type vk_flags')
def get_pdev_features(doc):
for _type in doc.findall('./types/type'):
if _type.attrib.get('name') != 'VkPhysicalDeviceFeatures':
continue
flags = []
for p in _type.findall('./member'):
assert p.find('./type').text == 'VkBool32'
flags.append(p.find('./name').text)
return flags
return None
def get_features(doc):
features = OrderedDict()
@ -182,13 +203,16 @@ def get_features(doc):
return features.values()
def get_features_from_xml(xml_files):
pdev_features = None
features = []
for filename in xml_files:
doc = et.parse(filename)
features += get_features(doc)
if not pdev_features:
pdev_features = get_pdev_features(doc)
return features
return pdev_features, features
def main():
@ -199,10 +223,11 @@ def main():
required=True, action='append', dest='xml_files')
args = parser.parse_args()
features = get_features_from_xml(args.xml_files)
pdev_features, features = get_features_from_xml(args.xml_files)
environment = {
'filename': os.path.basename(__file__),
'pdev_features': pdev_features,
'features': features,
}