mirror of
https://github.com/gfx-rs/wgpu.git
synced 2024-11-25 16:24:24 +00:00
feat(vulkan): enable GPU-based validation for Vulkan backend
If [`VK_LAYER_KHRONOS_validation`] is present, and it supports [`VK_EXT_validation_features`], we can configure it with another instance creation info. element of type [`VkValidationFeaturesEXT`] to enable GPU-based validation. Wire `InstanceFlags::GPU_BASED_VALIDATION` to do this in the Vulkan backend. It's even already finding issues in our `examples` and other tests! But…we'd like to handle those later, since this is so important for users. So, I've broken that out to separate issues. The instances we're aware of: * `water` is running into sync. validation issues: see <https://github.com/gfx-rs/wgpu/issues/5231> * `wgpu_test::shader::struct_layout::uniform_input` is failing to instrument shaders now; see <https://github.com/gfx-rs/wgpu/issues/5245> It is apparent from this and the [DX12 implementation of GPU-based validation] that we will need to communicate clearly to users that `InstanceFlags::GPU_BASED_VALIDATION` implies `InstanceFlags::VALIDATION`. Not all backends enforce this yet; I have [split out this work][follow-up for flag implication]. Note that `VK_EXT_validation_features` has been deprecated in favor of the more general layer configuration mechanism offered by [`VK_EXT_layer_settings`]. [DX12 implementation of GPU-based validation]: https://github.com/gfx-rs/wgpu/pull/5146 [`VK_EXT_layer_settings`]: https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_EXT_layer_settings.html [`VK_EXT_validation_features`]: https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_EXT_validation_features.html [`VK_LAYER_KHRONOS_validation`]:https://vulkan.lunarg.com/doc/sdk/1.3.275.0/linux/khronos_validation_layer.html [`VkValidationFeaturesEXT`]: https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkValidationFeaturesEXT.html [follow-up for flag implication]: https://github.com/gfx-rs/wgpu/pull/5232
This commit is contained in:
parent
6a51f3d82f
commit
31ac63ce3e
@ -89,11 +89,11 @@ Bottom level categories:
|
|||||||
- Eager release of GPU resources comes from device.trackers. By @bradwerth in [#5075](https://github.com/gfx-rs/wgpu/pull/5075)
|
- Eager release of GPU resources comes from device.trackers. By @bradwerth in [#5075](https://github.com/gfx-rs/wgpu/pull/5075)
|
||||||
- `wgpu-types`'s `trace` and `replay` features have been replaced by the `serde` feature. By @KirmesBude in [#5149](https://github.com/gfx-rs/wgpu/pull/5149)
|
- `wgpu-types`'s `trace` and `replay` features have been replaced by the `serde` feature. By @KirmesBude in [#5149](https://github.com/gfx-rs/wgpu/pull/5149)
|
||||||
- `wgpu-core`'s `serial-pass` feature has been removed. Use `serde` instead. By @KirmesBude in [#5149](https://github.com/gfx-rs/wgpu/pull/5149)
|
- `wgpu-core`'s `serial-pass` feature has been removed. Use `serde` instead. By @KirmesBude in [#5149](https://github.com/gfx-rs/wgpu/pull/5149)
|
||||||
- Added `InstanceFlags::GPU_BASED_VALIDATION`, which enables GPU-based validation for shaders. This is currently only supported on the DX12 back end; other platforms ignore this flag, for now.
|
- Added `InstanceFlags::GPU_BASED_VALIDATION`, which enables GPU-based validation for shaders. This is currently only supported on the DX12 and Vulkan backends; other platforms ignore this flag, for now.
|
||||||
- This has been added to the set of flags set by `InstanceFlags::debugging` and `InstanceFlags::from_build_config`. If you notice your graphics workloads running more slowly, this may be the culprit.
|
- This has been added to the set of flags set by `InstanceFlags::debugging` and `InstanceFlags::from_build_config`. If you notice your graphics workloads running more slowly, this may be the culprit.
|
||||||
- As with other instance flags, this flag can be changed in calls to `InstanceFlags::with_env` with the new `WGPU_GPU_BASED_VALIDATION` environment variable.
|
- As with other instance flags, this flag can be changed in calls to `InstanceFlags::with_env` with the new `WGPU_GPU_BASED_VALIDATION` environment variable.
|
||||||
|
|
||||||
By @ErichDonGubler in [#5046](https://github.com/gfx-rs/wgpu/pull/5046).
|
By @ErichDonGubler in [#5146](https://github.com/gfx-rs/wgpu/pull/5146), [#5046](https://github.com/gfx-rs/wgpu/pull/5046).
|
||||||
- `wgpu::Instance` can now report which `wgpu::Backends` are available based on the build configuration. By @wumpf [#5167](https://github.com/gfx-rs/wgpu/pull/5167)
|
- `wgpu::Instance` can now report which `wgpu::Backends` are available based on the build configuration. By @wumpf [#5167](https://github.com/gfx-rs/wgpu/pull/5167)
|
||||||
```diff
|
```diff
|
||||||
-wgpu::Instance::any_backend_feature_enabled()
|
-wgpu::Instance::any_backend_feature_enabled()
|
||||||
|
@ -826,7 +826,25 @@ static TEST: crate::framework::ExampleTestParams = crate::framework::ExampleTest
|
|||||||
height: 768,
|
height: 768,
|
||||||
optional_features: wgpu::Features::default(),
|
optional_features: wgpu::Features::default(),
|
||||||
base_test_parameters: wgpu_test::TestParameters::default()
|
base_test_parameters: wgpu_test::TestParameters::default()
|
||||||
.downlevel_flags(wgpu::DownlevelFlags::READ_ONLY_DEPTH_STENCIL),
|
.downlevel_flags(wgpu::DownlevelFlags::READ_ONLY_DEPTH_STENCIL)
|
||||||
|
// To be fixed in <https://github.com/gfx-rs/wgpu/issues/5231>.
|
||||||
|
.expect_fail(wgpu_test::FailureCase {
|
||||||
|
backends: Some(wgpu::Backends::VULKAN),
|
||||||
|
reasons: vec![
|
||||||
|
wgpu_test::FailureReason::validation_error().with_message(concat!(
|
||||||
|
"vkCmdEndRenderPass: ",
|
||||||
|
"Hazard WRITE_AFTER_READ in subpass 0 for attachment 1 depth aspect ",
|
||||||
|
"during store with storeOp VK_ATTACHMENT_STORE_OP_STORE. ",
|
||||||
|
"Access info (",
|
||||||
|
"usage: SYNC_LATE_FRAGMENT_TESTS_DEPTH_STENCIL_ATTACHMENT_WRITE, ",
|
||||||
|
"prior_usage: SYNC_FRAGMENT_SHADER_SHADER_SAMPLED_READ, ",
|
||||||
|
"read_barriers: VkPipelineStageFlags2(0), ",
|
||||||
|
"command: vkCmdDraw"
|
||||||
|
)),
|
||||||
|
],
|
||||||
|
behavior: wgpu_test::FailureBehavior::AssertFailure,
|
||||||
|
..Default::default()
|
||||||
|
}),
|
||||||
comparisons: &[wgpu_test::ComparisonType::Mean(0.01)],
|
comparisons: &[wgpu_test::ComparisonType::Mean(0.01)],
|
||||||
_phantom: std::marker::PhantomData::<Example>,
|
_phantom: std::marker::PhantomData::<Example>,
|
||||||
};
|
};
|
||||||
|
@ -229,6 +229,11 @@ static UNIFORM_INPUT: GpuTestConfiguration = GpuTestConfiguration::new()
|
|||||||
FailureCase::backend(wgpu::Backends::VULKAN)
|
FailureCase::backend(wgpu::Backends::VULKAN)
|
||||||
.validation_error("a matrix with stride 8 not satisfying alignment to 16"),
|
.validation_error("a matrix with stride 8 not satisfying alignment to 16"),
|
||||||
)
|
)
|
||||||
|
.expect_fail(
|
||||||
|
FailureCase::backend(wgpu::Backends::VULKAN).validation_error(
|
||||||
|
"Failure to instrument shader. Proceeding with non-instrumented shader.",
|
||||||
|
),
|
||||||
|
)
|
||||||
.limits(Limits::downlevel_defaults()),
|
.limits(Limits::downlevel_defaults()),
|
||||||
)
|
)
|
||||||
.run_async(|ctx| {
|
.run_async(|ctx| {
|
||||||
|
@ -653,6 +653,26 @@ impl crate::Instance<super::Api> for super::Instance {
|
|||||||
let validation_layer_name =
|
let validation_layer_name =
|
||||||
CStr::from_bytes_with_nul(b"VK_LAYER_KHRONOS_validation\0").unwrap();
|
CStr::from_bytes_with_nul(b"VK_LAYER_KHRONOS_validation\0").unwrap();
|
||||||
let validation_layer_properties = find_layer(&instance_layers, validation_layer_name);
|
let validation_layer_properties = find_layer(&instance_layers, validation_layer_name);
|
||||||
|
let validation_features_are_enabled = || {
|
||||||
|
validation_layer_properties.is_some().then(|| {
|
||||||
|
let exts = Self::enumerate_instance_extension_properties(
|
||||||
|
&entry,
|
||||||
|
Some(validation_layer_name),
|
||||||
|
)?;
|
||||||
|
let mut ext_names = exts
|
||||||
|
.iter()
|
||||||
|
.filter_map(|ext| cstr_from_bytes_until_nul(&ext.extension_name));
|
||||||
|
let found =
|
||||||
|
ext_names.any(|ext_name| ext_name == vk::ExtValidationFeaturesFn::name());
|
||||||
|
Ok(found)
|
||||||
|
})
|
||||||
|
};
|
||||||
|
let should_enable_gpu_based_validation = desc
|
||||||
|
.flags
|
||||||
|
.intersects(wgt::InstanceFlags::GPU_BASED_VALIDATION)
|
||||||
|
&& validation_features_are_enabled()
|
||||||
|
.transpose()?
|
||||||
|
.unwrap_or(false);
|
||||||
|
|
||||||
let nv_optimus_layer = CStr::from_bytes_with_nul(b"VK_LAYER_NV_optimus\0").unwrap();
|
let nv_optimus_layer = CStr::from_bytes_with_nul(b"VK_LAYER_NV_optimus\0").unwrap();
|
||||||
let has_nv_optimus = find_layer(&instance_layers, nv_optimus_layer).is_some();
|
let has_nv_optimus = find_layer(&instance_layers, nv_optimus_layer).is_some();
|
||||||
@ -664,7 +684,9 @@ impl crate::Instance<super::Api> for super::Instance {
|
|||||||
|
|
||||||
// Request validation layer if asked.
|
// Request validation layer if asked.
|
||||||
let mut debug_utils = None;
|
let mut debug_utils = None;
|
||||||
if desc.flags.intersects(wgt::InstanceFlags::VALIDATION) {
|
if desc.flags.intersects(wgt::InstanceFlags::VALIDATION)
|
||||||
|
|| should_enable_gpu_based_validation
|
||||||
|
{
|
||||||
if let Some(layer_properties) = validation_layer_properties {
|
if let Some(layer_properties) = validation_layer_properties {
|
||||||
layers.push(validation_layer_name);
|
layers.push(validation_layer_name);
|
||||||
|
|
||||||
@ -765,6 +787,16 @@ impl crate::Instance<super::Api> for super::Instance {
|
|||||||
create_info = create_info.push_next(vk_create_info);
|
create_info = create_info.push_next(vk_create_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut gpu_assisted_validation = vk::ValidationFeaturesEXT::builder()
|
||||||
|
.enabled_validation_features(&[
|
||||||
|
vk::ValidationFeatureEnableEXT::GPU_ASSISTED,
|
||||||
|
vk::ValidationFeatureEnableEXT::GPU_ASSISTED_RESERVE_BINDING_SLOT,
|
||||||
|
vk::ValidationFeatureEnableEXT::SYNCHRONIZATION_VALIDATION,
|
||||||
|
]);
|
||||||
|
if should_enable_gpu_based_validation {
|
||||||
|
create_info = create_info.push_next(&mut gpu_assisted_validation);
|
||||||
|
}
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
profiling::scope!("vkCreateInstance");
|
profiling::scope!("vkCreateInstance");
|
||||||
entry.create_instance(&create_info, None)
|
entry.create_instance(&create_info, None)
|
||||||
|
@ -904,13 +904,15 @@ bitflags::bitflags! {
|
|||||||
/// This mainly applies to a Vulkan driver's compliance version. If the major compliance version
|
/// This mainly applies to a Vulkan driver's compliance version. If the major compliance version
|
||||||
/// is `0`, then the driver is ignored. This flag allows that driver to be enabled for testing.
|
/// is `0`, then the driver is ignored. This flag allows that driver to be enabled for testing.
|
||||||
const ALLOW_UNDERLYING_NONCOMPLIANT_ADAPTER = 1 << 3;
|
const ALLOW_UNDERLYING_NONCOMPLIANT_ADAPTER = 1 << 3;
|
||||||
/// Enable GPU-based validation. Currently, this only changes behavior on the DX12
|
/// Enable GPU-based validation. Currently, this only changes behavior on the DX12 and
|
||||||
/// backend.
|
/// Vulkan backends.
|
||||||
///
|
///
|
||||||
/// Supported platforms:
|
/// Supported platforms:
|
||||||
///
|
///
|
||||||
/// - D3D12; called ["GPU-based validation", or
|
/// - D3D12; called ["GPU-based validation", or
|
||||||
/// "GBV"](https://web.archive.org/web/20230206120404/https://learn.microsoft.com/en-us/windows/win32/direct3d12/using-d3d12-debug-layer-gpu-based-validation)
|
/// "GBV"](https://web.archive.org/web/20230206120404/https://learn.microsoft.com/en-us/windows/win32/direct3d12/using-d3d12-debug-layer-gpu-based-validation)
|
||||||
|
/// - Vulkan, via the `VK_LAYER_KHRONOS_validation` layer; called ["GPU-Assisted
|
||||||
|
/// Validation"](https://github.com/KhronosGroup/Vulkan-ValidationLayers/blob/e45aeb85079e0835694cb8f03e6681fd18ae72c9/docs/gpu_validation.md#gpu-assisted-validation)
|
||||||
const GPU_BASED_VALIDATION = 1 << 4;
|
const GPU_BASED_VALIDATION = 1 << 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user