1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
use std::sync::Arc;

/// Wgpu device error scope for all filters that auto closes when exiting the scope unless it was already closed.
///
/// The expectation is that the scope is manually closed, but this construct is useful to not accidentally
/// leave the scope open when returning early from a function.
/// Opens scopes for all error types.
pub struct WgpuErrorScope {
    open: bool,
    device: Arc<wgpu::Device>,
}

impl WgpuErrorScope {
    pub fn start(device: &Arc<wgpu::Device>) -> Self {
        device.push_error_scope(wgpu::ErrorFilter::Validation);
        device.push_error_scope(wgpu::ErrorFilter::OutOfMemory);
        // TODO(gfx-rs/wgpu#4866): Internal is missing!
        Self {
            device: device.clone(),
            open: true,
        }
    }

    pub fn end(
        mut self,
    ) -> [impl std::future::Future<Output = Option<wgpu::Error>> + Send + 'static; 2] {
        self.open = false;
        [self.device.pop_error_scope(), self.device.pop_error_scope()]
    }
}

impl Drop for WgpuErrorScope {
    fn drop(&mut self) {
        if self.open {
            drop(self.device.pop_error_scope());
            drop(self.device.pop_error_scope());
        }
    }
}