mirror of
https://github.com/gfx-rs/wgpu.git
synced 2024-11-25 00:03:29 +00:00
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.
# Conflicts:
# CHANGELOG.md
This commit is contained in:
parent
24aeee2d15
commit
e3b5c1a33f
@ -39,6 +39,12 @@ Bottom level categories:
|
||||
|
||||
## Unreleased
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
#### General
|
||||
|
||||
- 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)
|
||||
|
||||
### Overview
|
||||
|
@ -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 {
|
||||
|
@ -71,7 +71,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
|
||||
|
@ -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())
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user