Skip to content

Commit ef79a92

Browse files
hal/vulkan: With internal_error_panic, panic on Vulkan validation errors (gfx-rs#9879)
1 parent 59209f2 commit ef79a92

5 files changed

Lines changed: 82 additions & 4 deletions

File tree

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cts_runner/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ log.workspace = true
2424
pico-args.workspace = true
2525
tokio = { workspace = true, features = ["full"] }
2626
termcolor.workspace = true
27+
wgpu-hal = { workspace = true, features = ["internal_error_panic"] }
2728

2829
[dev-dependencies]
2930
tempfile.workspace = true

wgpu-hal/Cargo.toml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -186,10 +186,11 @@ portable-atomic = ["dep:portable-atomic", "dep:portable-atomic-util"]
186186
# Panic when running into a device lost error (for debugging purposes).
187187
# Only affects the d3d12 and vulkan backends.
188188
device_lost_panic = []
189-
# Panic when running into an internal error other than out-of-memory and device lost
190-
# (for debugging purposes).
191-
#
192-
# Only affects the d3d12 and vulkan backends.
189+
# Panic on unexpected errors (does _not_ include out-of-memory errors or device
190+
# loss) from platform APIs, for debugging purposes. Such errors likely indicate
191+
# bug(s) in wgpu, platform components, or drivers. Despite the name, this is not
192+
# related to the spec's `GPUInternalError`. Only affects the d3d12 and vulkan
193+
# backends.
193194
internal_error_panic = []
194195
# Tracks validation errors in a `VALIDATION_CANARY` static.
195196
validation_canary = ["dep:parking_lot"]

wgpu-hal/src/vulkan/instance.rs

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,9 +158,80 @@ unsafe extern "system" fn debug_utils_messenger_callback(
158158
crate::VALIDATION_CANARY.add(message.to_string());
159159
}
160160

161+
#[cfg(all(debug_assertions, feature = "internal_error_panic"))]
162+
if level == log::Level::Error
163+
&& message_type.contains(vk::DebugUtilsMessageTypeFlagsEXT::VALIDATION)
164+
&& !error_is_waived(cd.message_id_number)
165+
&& !cts_error_is_waived(cd.message_id_number)
166+
{
167+
use alloc::string::ToString as _;
168+
panic!("{}", message.to_string());
169+
}
170+
161171
vk::FALSE
162172
}
163173

174+
/// Validation errors known to fire, not just in the CTS.
175+
///
176+
/// These never panic.
177+
#[cfg(feature = "internal_error_panic")]
178+
fn error_is_waived(message_id_number: i32) -> bool {
179+
const WAIVED_MESSAGE_IDS: &[i32] = &[
180+
// SYNC-HAZARD-WRITE-AFTER-WRITE
181+
// e.g. webgpu:api,operation,memory_sync,texture,readonly_depth_stencil:sampling_while_testing:*
182+
// https://github.com/gfx-rs/wgpu/issues/5231
183+
// https://github.com/gfx-rs/wgpu/issues/8705
184+
0x5c0ec5d6_u32 as i32,
185+
];
186+
187+
WAIVED_MESSAGE_IDS.contains(&message_id_number)
188+
}
189+
190+
/// Validation errors known to fire when running the CTS.
191+
///
192+
/// These waivers are keyed off the `WGPU_CTS_XTASK` environment variable, which
193+
/// is set in `xtask/src/cts.rs`.
194+
#[cfg(feature = "internal_error_panic")]
195+
fn cts_error_is_waived(message_id_number: i32) -> bool {
196+
use std::sync::LazyLock;
197+
198+
static WGPU_CTS_XTASK: LazyLock<bool> =
199+
LazyLock::new(|| std::env::var_os("WGPU_CTS_XTASK").is_some());
200+
201+
if !*WGPU_CTS_XTASK {
202+
return false;
203+
}
204+
205+
const WAIVED_MESSAGE_IDS: &[i32] = &[
206+
// VUID-vkCmdPushConstants-offset-01795
207+
// e.g. webgpu:api,operation,command_buffer,programmable,immediate:*
208+
0x27bc88c6_u32 as i32,
209+
// VUID-SampleMask-SampleMask-04359
210+
// e.g. webgpu:api,validation,render_pipeline,inter_stage:max_variables_count,*
211+
0x34d444b2_u32 as i32,
212+
// VUID-vkCmdCopyImage-srcImage-01728
213+
// e.g. webgpu:api,validation,encoding,cmds,copyTextureToTexture:*
214+
0x6b654496_u32 as i32,
215+
// VUID-StandaloneSpirv-OpImageQuerySizeLod-04659
216+
// e.g. webgpu:shader,execution,expression,call,builtin,textureNumLayers:*
217+
0x82396078_u32 as i32,
218+
// VUID-RuntimeSpirv-Location-06272
219+
// e.g. webgpu:api,validation,render_pipeline,inter_stage:max_variables_count,*
220+
0xa3614f8b_u32 as i32,
221+
// VUID-VkViewport-width-01770
222+
// e.g. webgpu:api,validation,encoding,cmds,render,dynamic_state:*
223+
0xa4164ba5_u32 as i32,
224+
// VUID-VkImageViewCreateInfo-image-04441
225+
// e.g. webgpu:api,validation,createView:texture_view_usage:*
226+
0xb75da543_u32 as i32,
227+
// VUID-VkBufferCreateInfo-None-09500
228+
// e.g. webgpu:api,validation,buffer,create:usage,*
229+
0xf6d454db_u32 as i32,
230+
];
231+
232+
WAIVED_MESSAGE_IDS.contains(&message_id_number)
233+
}
234+
164235
impl super::DebugUtilsCreateInfo {
165236
fn to_vk_create_info(&self) -> vk::DebugUtilsMessengerCreateInfoEXT<'_> {
166237
let user_data_ptr: *const super::DebugUtilsMessengerUserData = &*self.callback_data;

xtask/src/cts.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,10 @@ pub fn run_cts(
7272
let llvm_cov = args.contains("--llvm-cov");
7373
let release = args.contains("--release");
7474

75+
// This is used in the Vulkan hal to waive pre-existing validation
76+
// errors in the CTS, until they can be fixed.
77+
shell.set_var("WGPU_CTS_XTASK", "1");
78+
7579
let output_filter = args
7680
.opt_value_from_str::<_, String>("--print-output-when")?
7781
.map(|f| {

0 commit comments

Comments
 (0)