Skip to content

Commit 159ac9e

Browse files
authored
validation: More detailed on incompatible BGL (#4826)
1 parent ba56dd2 commit 159ac9e

File tree

4 files changed

+105
-13
lines changed

4 files changed

+105
-13
lines changed

wgpu-core/src/command/bind.rs

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,79 @@ mod compat {
5353
fn is_incompatible(&self) -> bool {
5454
self.expected.is_none() || !self.is_valid()
5555
}
56+
57+
// Describe how bind group layouts are incompatible, for validation
58+
// error message.
59+
fn bgl_diff(&self) -> Vec<String> {
60+
let mut diff = Vec::new();
61+
62+
if let Some(expected_bgl) = self.expected.as_ref() {
63+
diff.push(format!(
64+
"Should be compatible with bind group layout with label = `{}`",
65+
expected_bgl.label()
66+
));
67+
if let Some(assigned_bgl) = self.assigned.as_ref() {
68+
diff.push(format!(
69+
"Assigned bind group layout with label = `{}`",
70+
assigned_bgl.label()
71+
));
72+
for (id, e_entry) in &expected_bgl.entries {
73+
if let Some(a_entry) = assigned_bgl.entries.get(id) {
74+
if a_entry.binding != e_entry.binding {
75+
diff.push(format!(
76+
"Entry {id} binding expected {}, got {}",
77+
e_entry.binding, a_entry.binding
78+
));
79+
}
80+
if a_entry.count != e_entry.count {
81+
diff.push(format!(
82+
"Entry {id} count expected {:?}, got {:?}",
83+
e_entry.count, a_entry.count
84+
));
85+
}
86+
if a_entry.ty != e_entry.ty {
87+
diff.push(format!(
88+
"Entry {id} type expected {:?}, got {:?}",
89+
e_entry.ty, a_entry.ty
90+
));
91+
}
92+
if a_entry.visibility != e_entry.visibility {
93+
diff.push(format!(
94+
"Entry {id} visibility expected {:?}, got {:?}",
95+
e_entry.visibility, a_entry.visibility
96+
));
97+
}
98+
} else {
99+
diff.push(format!("Entry {id} not found in assigned bindgroup layout"))
100+
}
101+
}
102+
103+
assigned_bgl.entries.iter().for_each(|(id, _e_entry)| {
104+
if !expected_bgl.entries.contains_key(id) {
105+
diff.push(format!("Entry {id} not found in expected bindgroup layout"))
106+
}
107+
});
108+
} else {
109+
diff.push(
110+
"Assigned bindgroup layout is implicit, expected explicit".to_owned(),
111+
);
112+
}
113+
} else if let Some(assigned_bgl) = self.assigned.as_ref() {
114+
diff.push(format!(
115+
"Assigned bind group layout = `{}`",
116+
assigned_bgl.label()
117+
));
118+
diff.push(
119+
"Assigned bindgroup layout is not implicit, expected implicit".to_owned(),
120+
);
121+
}
122+
123+
if diff.is_empty() {
124+
diff.push("But no differences found? (internal error)".to_owned())
125+
}
126+
127+
diff
128+
}
56129
}
57130

58131
#[derive(Debug, Default)]
@@ -121,6 +194,15 @@ mod compat {
121194
}
122195
})
123196
}
197+
198+
pub fn bgl_diff(&self) -> Vec<String> {
199+
for e in &self.entries {
200+
if !e.is_valid() {
201+
return e.bgl_diff();
202+
}
203+
}
204+
vec![String::from("No differences detected? (internal error)")]
205+
}
124206
}
125207
}
126208

@@ -274,6 +356,10 @@ impl<A: HalApi> Binder<A> {
274356
self.manager.invalid_mask()
275357
}
276358

359+
pub(super) fn bgl_diff(&self) -> Vec<String> {
360+
self.manager.bgl_diff()
361+
}
362+
277363
/// Scan active buffer bindings corresponding to layouts without `min_binding_size` specified.
278364
pub(super) fn check_late_buffer_bindings(
279365
&self,

wgpu-core/src/command/compute.rs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -173,12 +173,8 @@ pub struct ComputePassDescriptor<'a> {
173173
pub enum DispatchError {
174174
#[error("Compute pipeline must be set")]
175175
MissingPipeline,
176-
#[error("The pipeline layout, associated with the current compute pipeline, contains a bind group layout at index {index} which is incompatible with the bind group layout associated with the bind group at {index}")]
177-
IncompatibleBindGroup {
178-
index: u32,
179-
//expected: BindGroupLayoutId,
180-
//provided: Option<(BindGroupLayoutId, BindGroupId)>,
181-
},
176+
#[error("Incompatible bind group at index {index} in the current compute pipeline")]
177+
IncompatibleBindGroup { index: u32, diff: Vec<String> },
182178
#[error(
183179
"Each current dispatch group size dimension ({current:?}) must be less or equal to {limit}"
184180
)]
@@ -245,6 +241,11 @@ impl PrettyError for ComputePassErrorInner {
245241
Self::InvalidIndirectBuffer(id) => {
246242
fmt.buffer_label(&id);
247243
}
244+
Self::Dispatch(DispatchError::IncompatibleBindGroup { ref diff, .. }) => {
245+
for d in diff {
246+
fmt.note(&d);
247+
}
248+
}
248249
_ => {}
249250
};
250251
}
@@ -291,8 +292,11 @@ impl<A: HalApi> State<A> {
291292
let bind_mask = self.binder.invalid_mask();
292293
if bind_mask != 0 {
293294
//let (expected, provided) = self.binder.entries[index as usize].info();
295+
let index = bind_mask.trailing_zeros();
296+
294297
return Err(DispatchError::IncompatibleBindGroup {
295-
index: bind_mask.trailing_zeros(),
298+
index,
299+
diff: self.binder.bgl_diff(),
296300
});
297301
}
298302
if self.pipeline.is_none() {

wgpu-core/src/command/draw.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,8 @@ pub enum DrawError {
2525
MissingVertexBuffer { index: u32 },
2626
#[error("Index buffer must be set")]
2727
MissingIndexBuffer,
28-
#[error("The pipeline layout, associated with the current render pipeline, contains a bind group layout at index {index} which is incompatible with the bind group layout associated with the bind group at {index}")]
29-
IncompatibleBindGroup {
30-
index: u32,
31-
//expected: BindGroupLayoutId,
32-
//provided: Option<(BindGroupLayoutId, BindGroupId)>,
33-
},
28+
#[error("Incompatible bind group at index {index} in the current render pipeline")]
29+
IncompatibleBindGroup { index: u32, diff: Vec<String> },
3430
#[error("Vertex {last_vertex} extends beyond limit {vertex_limit} imposed by the buffer in slot {slot}. Did you bind the correct `Vertex` step-rate vertex buffer?")]
3531
VertexBeyondLimit {
3632
last_vertex: u32,

wgpu-core/src/command/render.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -441,6 +441,7 @@ impl<A: HalApi> State<A> {
441441
//let (expected, provided) = self.binder.entries[index as usize].info();
442442
return Err(DrawError::IncompatibleBindGroup {
443443
index: bind_mask.trailing_zeros(),
444+
diff: self.binder.bgl_diff(),
444445
});
445446
}
446447
if self.pipeline.is_none() {
@@ -643,6 +644,11 @@ impl PrettyError for RenderPassErrorInner {
643644
if let Self::InvalidAttachment(id) = *self {
644645
fmt.texture_view_label_with_key(&id, "attachment");
645646
};
647+
if let Self::Draw(DrawError::IncompatibleBindGroup { diff, .. }) = self {
648+
for d in diff {
649+
fmt.note(&d);
650+
}
651+
};
646652
}
647653
}
648654

0 commit comments

Comments
 (0)