More robust extension and feature dependency checks (#2434)

This commit is contained in:
Rua 2023-12-28 20:30:51 +01:00 committed by GitHub
parent ac67f927bd
commit 2bbd4eff69
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 125 additions and 25 deletions

View File

@ -179,6 +179,8 @@ fn device_extensions_output(members: &[ExtensionsMember]) -> TokenStream {
requires_all_of,
..
}| {
let name_string = name.to_string();
let requires_all_of_items = requires_all_of
.iter()
.filter(
@ -213,6 +215,14 @@ fn device_extensions_output(members: &[ExtensionsMember]) -> TokenStream {
let base_requirement_item = {
let ident = format_ident!("{}", base_requirement);
quote! {
assert!(
supported.#ident,
"The device extension `{}` is enabled, and it requires \
the `{}` extension to be also enabled, but the device \
does not support the required extension. \
This is a bug in the Vulkan driver for this device.",
#name_string, #base_requirement,
);
self.#ident = true;
}
};
@ -355,6 +365,8 @@ fn instance_extensions_output(members: &[ExtensionsMember]) -> TokenStream {
requires_all_of,
..
}| {
let name_string = name.to_string();
let requires_all_of_items = requires_all_of
.iter()
.filter(
@ -389,6 +401,14 @@ fn instance_extensions_output(members: &[ExtensionsMember]) -> TokenStream {
let base_requirement_item = {
let ident = format_ident!("{}", base_requirement);
quote! {
assert!(
supported.#ident,
"The instance extension `{}` is enabled, and it requires \
the `{}` extension to be also enabled, but the device \
does not support the required extension. \
This is a bug in the Vulkan driver.",
#name_string, #base_requirement,
);
self.#ident = true;
}
};
@ -471,6 +491,18 @@ fn extensions_common_output(struct_name: Ident, members: &[ExtensionsMember]) ->
}
});
let count_items = members.iter().map(|ExtensionsMember { name, .. }| {
quote! {
self.#name as u64
}
});
let is_empty_items = members.iter().map(|ExtensionsMember { name, .. }| {
quote! {
self.#name
}
});
let intersects_items = members.iter().map(|ExtensionsMember { name, .. }| {
quote! {
(self.#name && other.#name)
@ -565,6 +597,18 @@ fn extensions_common_output(struct_name: Ident, members: &[ExtensionsMember]) ->
}
}
/// Returns the number of members set in self.
#[inline]
pub const fn count(self) -> u64 {
#(#count_items)+*
}
/// Returns whether no members are set in `self`.
#[inline]
pub const fn is_empty(self) -> bool {
!(#(#is_empty_items)||*)
}
/// Returns whether any members are set in both `self` and `other`.
#[inline]
pub const fn intersects(&self, other: &Self) -> bool {

View File

@ -230,47 +230,103 @@ impl Device {
create_info.enabled_extensions.khr_portability_subset = true;
}
macro_rules! enable_extension_required_features {
(
$extension:ident,
$feature_to_enable:ident $(,)?
) => {
if create_info.enabled_extensions.$extension {
assert!(
physical_device.supported_features().$feature_to_enable,
"The device extension `{}` is enabled, and it requires the `{}` feature \
to be also enabled, but the device does not support the required feature. \
This is a bug in the Vulkan driver for this device.",
stringify!($extension),
stringify!($feature_to_enable),
);
create_info.enabled_features.$feature_to_enable = true;
}
};
}
if physical_device.api_version() >= Version::V1_1 {
// VUID-VkDeviceCreateInfo-ppEnabledExtensionNames-04476
if create_info.enabled_extensions.khr_shader_draw_parameters {
create_info.enabled_features.shader_draw_parameters = true;
}
enable_extension_required_features!(khr_shader_draw_parameters, shader_draw_parameters);
}
if physical_device.api_version() >= Version::V1_2 {
// VUID-VkDeviceCreateInfo-ppEnabledExtensionNames-02831
if create_info.enabled_extensions.khr_draw_indirect_count {
create_info.enabled_features.draw_indirect_count = true;
}
enable_extension_required_features!(khr_draw_indirect_count, draw_indirect_count);
// VUID-VkDeviceCreateInfo-ppEnabledExtensionNames-02832
if create_info
.enabled_extensions
.khr_sampler_mirror_clamp_to_edge
{
create_info.enabled_features.sampler_mirror_clamp_to_edge = true;
}
enable_extension_required_features!(
khr_sampler_mirror_clamp_to_edge,
sampler_mirror_clamp_to_edge,
);
// VUID-VkDeviceCreateInfo-ppEnabledExtensionNames-02833
if create_info.enabled_extensions.ext_descriptor_indexing {
create_info.enabled_features.descriptor_indexing = true;
}
enable_extension_required_features!(ext_descriptor_indexing, descriptor_indexing);
// VUID-VkDeviceCreateInfo-ppEnabledExtensionNames-02834
if create_info.enabled_extensions.ext_sampler_filter_minmax {
create_info.enabled_features.sampler_filter_minmax = true;
}
enable_extension_required_features!(ext_sampler_filter_minmax, sampler_filter_minmax);
// VUID-VkDeviceCreateInfo-ppEnabledExtensionNames-02835
if create_info
.enabled_extensions
.ext_shader_viewport_index_layer
{
create_info.enabled_features.shader_output_viewport_index = true;
create_info.enabled_features.shader_output_layer = true;
}
enable_extension_required_features!(
ext_shader_viewport_index_layer,
shader_output_layer,
);
enable_extension_required_features!(
ext_shader_viewport_index_layer,
shader_output_layer,
);
}
macro_rules! enable_feature_required_features {
(
$feature:ident,
$feature_to_enable:ident $(,)?
) => {
if create_info.enabled_features.$feature {
assert!(
physical_device.supported_features().$feature_to_enable,
"The device feature `{}` is enabled, and it requires the `{}` feature \
to be also enabled, but the device does not support the required feature. \
This is a bug in the Vulkan driver for this device.",
stringify!($feature),
stringify!($feature_to_enable),
);
create_info.enabled_features.$feature_to_enable = true;
}
};
}
// VUID-VkPhysicalDeviceVariablePointersFeatures-variablePointers-01431
enable_feature_required_features!(variable_pointers, variable_pointers_storage_buffer);
// VUID-VkPhysicalDeviceMultiviewFeatures-multiviewGeometryShader-00580
enable_feature_required_features!(multiview_geometry_shader, multiview);
// VUID-VkPhysicalDeviceMultiviewFeatures-multiviewTessellationShader-00581
enable_feature_required_features!(multiview_tessellation_shader, multiview);
// VUID-VkPhysicalDeviceMeshShaderFeaturesEXT-multiviewMeshShader-07032
enable_feature_required_features!(multiview_mesh_shader, multiview);
// VUID-VkPhysicalDeviceMeshShaderFeaturesEXT-primitiveFragmentShadingRateMeshShader-07033
enable_feature_required_features!(
primitive_fragment_shading_rate_mesh_shader,
primitive_fragment_shading_rate,
);
// VUID-VkPhysicalDeviceRayTracingPipelineFeaturesKHR-rayTracingPipelineShaderGroupHandleCaptureReplayMixed-03575
enable_feature_required_features!(
ray_tracing_pipeline_shader_group_handle_capture_replay_mixed,
ray_tracing_pipeline_shader_group_handle_capture_replay,
);
// VUID-VkPhysicalDeviceRobustness2FeaturesEXT-robustBufferAccess2-04000
enable_feature_required_features!(robust_buffer_access2, robust_buffer_access);
let &DeviceCreateInfo {
ref queue_create_infos,
ref enabled_extensions,