From c28466cc21b0a36b85b9c32d703b255238e56a5d Mon Sep 17 00:00:00 2001 From: Erich Gubler Date: Fri, 26 Jan 2024 13:16:34 -0500 Subject: [PATCH] feat: make GPU-based validation opt-in with new `InstanceFlags::GPU_BASED_VALIDATION` --- CHANGELOG.md | 5 +++++ wgpu-hal/src/dx12/instance.rs | 19 +++++++++++++++---- wgpu-types/src/lib.rs | 13 ++++++++++++- 3 files changed, 32 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 58a01f23e..839ae0572 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -89,6 +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) - `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) +- 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. + - 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. + + By @ErichDonGubler in [#5046](https://github.com/gfx-rs/wgpu/pull/5046). ### Bug Fixes diff --git a/wgpu-hal/src/dx12/instance.rs b/wgpu-hal/src/dx12/instance.rs index d7ed76219..020809328 100644 --- a/wgpu-hal/src/dx12/instance.rs +++ b/wgpu-hal/src/dx12/instance.rs @@ -20,14 +20,25 @@ impl crate::Instance for super::Instance { crate::InstanceError::with_source(String::from("failed to load d3d12.dll"), e) })?; - if desc.flags.contains(wgt::InstanceFlags::VALIDATION) { + if desc + .flags + .intersects(wgt::InstanceFlags::VALIDATION | wgt::InstanceFlags::GPU_BASED_VALIDATION) + { // Enable debug layer match lib_main.get_debug_interface() { Ok(pair) => match pair.into_result() { Ok(debug_controller) => { - debug_controller.enable_layer(); - if !debug_controller.enable_gpu_based_validation() { - log::warn!("Failed to enable GPU-based validation"); + if desc.flags.intersects(wgt::InstanceFlags::VALIDATION) { + debug_controller.enable_layer(); + } + if desc + .flags + .intersects(wgt::InstanceFlags::GPU_BASED_VALIDATION) + { + #[allow(clippy::collapsible_if)] + if !debug_controller.enable_gpu_based_validation() { + log::warn!("Failed to enable GPU-based validation"); + } } } Err(err) => { diff --git a/wgpu-types/src/lib.rs b/wgpu-types/src/lib.rs index 7c39c32e0..6cd8c54d0 100644 --- a/wgpu-types/src/lib.rs +++ b/wgpu-types/src/lib.rs @@ -895,6 +895,14 @@ bitflags::bitflags! { /// 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. const ALLOW_UNDERLYING_NONCOMPLIANT_ADAPTER = 1 << 3; + /// Enable GPU-based validation. Currently, this only changes behavior on DX12 and Vulkan + /// back ends. + /// + /// Supported platforms: + /// + /// - 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) + const GPU_BASED_VALIDATION = 1 << 4; } } @@ -907,7 +915,7 @@ impl Default for InstanceFlags { impl InstanceFlags { /// Enable debugging and validation flags. pub fn debugging() -> Self { - InstanceFlags::DEBUG | InstanceFlags::VALIDATION + InstanceFlags::DEBUG | InstanceFlags::VALIDATION | InstanceFlags::GPU_BASED_VALIDATION } /// Infer good defaults from the build type @@ -950,6 +958,9 @@ impl InstanceFlags { if let Some(bit) = env("WGPU_ALLOW_UNDERLYING_NONCOMPLIANT_ADAPTER") { self.set(Self::ALLOW_UNDERLYING_NONCOMPLIANT_ADAPTER, bit); } + if let Some(bit) = env("WGPU_GPU_BASED_VALIDATION") { + self.set(Self::GPU_BASED_VALIDATION, bit); + } self }