Error instead of panic in check bind (#6012)

Removed zipping of binding entries introduced in 4a19ac279c (to make sure binding numbers actually match) and add unknown error for fallback.
This commit is contained in:
Samson 2024-07-24 17:50:18 +02:00 committed by GitHub
parent 4f02057359
commit 2897fb58db
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 36 additions and 89 deletions

View File

@ -53,6 +53,7 @@ Bottom level categories:
- As a workaround for [issue #4905](https://github.com/gfx-rs/wgpu/issues/4905), `wgpu-core` is undocumented unless `--cfg wgpu_core_doc` feature is enabled. By @kpreid in [#5987](https://github.com/gfx-rs/wgpu/pull/5987)
- Bump MSRV for `d3d12`/`naga`/`wgpu-core`/`wgpu-hal`/`wgpu-types`' to 1.76. By @wumpf in [#6003](https://github.com/gfx-rs/wgpu/pull/6003)
- Print requested and supported usages on `UnsupportedUsage` error. By @VladasZ in [#6007](https://github.com/gfx-rs/wgpu/pull/6007)
- Fix function for checking bind compatibility to error instead of panic. By @sagudev [#6012](https://github.com/gfx-rs/wgpu/pull/6012)
## 22.0.0 (2024-07-17)

View File

@ -142,49 +142,50 @@ mod compat {
let mut errors = Vec::new();
let mut expected_bgl_entries = expected_bgl.entries.iter();
let mut assigned_bgl_entries = assigned_bgl.entries.iter();
let zipped = crate::utils::ZipWithProperAdvance::new(
&mut expected_bgl_entries,
&mut assigned_bgl_entries,
);
for ((&binding, expected_entry), (_, assigned_entry)) in zipped {
if assigned_entry.visibility != expected_entry.visibility {
errors.push(EntryError::Visibility {
binding,
expected: expected_entry.visibility,
assigned: assigned_entry.visibility,
});
}
if assigned_entry.ty != expected_entry.ty {
errors.push(EntryError::Type {
binding,
expected: expected_entry.ty,
assigned: assigned_entry.ty,
});
}
if assigned_entry.count != expected_entry.count {
errors.push(EntryError::Count {
binding,
expected: expected_entry.count,
assigned: assigned_entry.count,
});
for (&binding, expected_entry) in expected_bgl.entries.iter() {
if let Some(assigned_entry) = assigned_bgl.entries.get(binding) {
if assigned_entry.visibility != expected_entry.visibility {
errors.push(EntryError::Visibility {
binding,
expected: expected_entry.visibility,
assigned: assigned_entry.visibility,
});
}
if assigned_entry.ty != expected_entry.ty {
errors.push(EntryError::Type {
binding,
expected: expected_entry.ty,
assigned: assigned_entry.ty,
});
}
if assigned_entry.count != expected_entry.count {
errors.push(EntryError::Count {
binding,
expected: expected_entry.count,
assigned: assigned_entry.count,
});
}
} else {
errors.push(EntryError::ExtraExpected { binding });
}
}
for (&binding, _) in expected_bgl_entries {
errors.push(EntryError::ExtraExpected { binding });
for (&binding, _) in assigned_bgl.entries.iter() {
if !expected_bgl.entries.contains_key(binding) {
errors.push(EntryError::ExtraAssigned { binding });
}
}
for (&binding, _) in assigned_bgl_entries {
errors.push(EntryError::ExtraAssigned { binding });
}
#[derive(Clone, Debug, Error)]
#[error("Unknown reason")]
struct Unknown();
Err(Error::Incompatible {
expected_bgl: expected_bgl.error_ident(),
assigned_bgl: assigned_bgl.error_ident(),
inner: MultiError::new(errors.drain(..)).unwrap(),
inner: MultiError::new(errors.drain(..)).unwrap_or_else(|| {
MultiError::new(core::iter::once(Unknown())).unwrap()
}),
})
}
} else {

View File

@ -85,7 +85,6 @@ pub mod resource;
mod snatch;
pub mod storage;
mod track;
mod utils;
// This is public for users who pre-compile shaders while still wanting to
// preserve all run-time checks that `wgpu-core` does.
// See <https://github.com/gfx-rs/wgpu/issues/3103>, after which this can be

View File

@ -1,54 +0,0 @@
/// If the first iterator is longer than the second, the zip implementation
/// in the standard library will still advance the the first iterator before
/// realizing that the second iterator has finished.
///
/// This implementation will advance the shorter iterator first avoiding
/// the issue above.
///
/// If you can guarantee that the first iterator is always shorter than the
/// second, you should use the zip impl in stdlib.
pub(crate) struct ZipWithProperAdvance<
A: ExactSizeIterator<Item = IA>,
B: ExactSizeIterator<Item = IB>,
IA,
IB,
> {
a: A,
b: B,
iter_a_first: bool,
}
impl<A: ExactSizeIterator<Item = IA>, B: ExactSizeIterator<Item = IB>, IA, IB>
ZipWithProperAdvance<A, B, IA, IB>
{
pub(crate) fn new(a: A, b: B) -> Self {
let iter_a_first = a.len() <= b.len();
Self { a, b, iter_a_first }
}
}
impl<A: ExactSizeIterator<Item = IA>, B: ExactSizeIterator<Item = IB>, IA, IB> Iterator
for ZipWithProperAdvance<A, B, IA, IB>
{
type Item = (IA, IB);
fn next(&mut self) -> Option<Self::Item> {
if self.iter_a_first {
let a = self.a.next()?;
let b = self.b.next()?;
Some((a, b))
} else {
let b = self.b.next()?;
let a = self.a.next()?;
Some((a, b))
}
}
}
impl<A: ExactSizeIterator<Item = IA>, B: ExactSizeIterator<Item = IB>, IA, IB> ExactSizeIterator
for ZipWithProperAdvance<A, B, IA, IB>
{
fn len(&self) -> usize {
self.a.len().min(self.b.len())
}
}