wgpu_core/indirect_validation/
mod.rs1use crate::{
2 device::DeviceError,
3 pipeline::{CreateComputePipelineError, CreateShaderModuleError},
4};
5use alloc::boxed::Box;
6use thiserror::Error;
7
8mod dispatch;
9mod draw;
10mod utils;
11
12pub(crate) use dispatch::Dispatch;
13pub(crate) use draw::{Draw, DrawBatcher, DrawResources};
14
15#[derive(Clone, Debug, Error)]
16#[non_exhaustive]
17enum CreateIndirectValidationPipelineError {
18 #[error(transparent)]
19 DeviceError(#[from] DeviceError),
20 #[error(transparent)]
21 ShaderModule(#[from] CreateShaderModuleError),
22 #[error(transparent)]
23 ComputePipeline(#[from] CreateComputePipelineError),
24}
25
26pub(crate) struct IndirectValidation {
27 pub(crate) dispatch: Dispatch,
28 pub(crate) draw: Draw,
29}
30
31impl IndirectValidation {
32 pub(crate) fn new(
33 device: &dyn hal::DynDevice,
34 required_limits: &wgt::Limits,
35 required_features: &wgt::Features,
36 instance_flags: wgt::InstanceFlags,
37 backend: wgt::Backend,
38 ) -> Result<Self, DeviceError> {
39 let dispatch = match Dispatch::new(device, instance_flags, required_limits) {
40 Ok(dispatch) => dispatch,
41 Err(e) => {
42 log::error!("indirect-validation error: {e:?}");
43 return Err(DeviceError::Lost);
44 }
45 };
46 let draw = match Draw::new(
47 device,
48 required_features,
49 instance_flags,
50 backend,
51 required_limits,
52 ) {
53 Ok(draw) => draw,
54 Err(e) => {
55 log::error!("indirect-draw-validation error: {e:?}");
56 return Err(DeviceError::Lost);
57 }
58 };
59 Ok(Self { dispatch, draw })
60 }
61
62 pub(crate) fn dispose(self, device: &dyn hal::DynDevice) {
63 let Self { dispatch, draw } = self;
64
65 dispatch.dispose(device);
66 draw.dispose(device);
67 }
68}
69
70#[derive(Debug)]
71pub(crate) struct BindGroups {
72 pub(crate) dispatch: Box<dyn hal::DynBindGroup>,
73 draw: Box<dyn hal::DynBindGroup>,
74}
75
76impl BindGroups {
77 pub(crate) fn new(
79 indirect_validation: &IndirectValidation,
80 device: &crate::device::Device,
81 buffer_size: u64,
82 buffer: &dyn hal::DynBuffer,
83 ) -> Result<Option<Self>, DeviceError> {
84 let dispatch = indirect_validation.dispatch.create_src_bind_group(
85 device.raw(),
86 &device.limits,
87 buffer_size,
88 buffer,
89 device.instance_flags,
90 )?;
91 let draw = indirect_validation.draw.create_src_bind_group(
92 device.raw(),
93 &device.adapter.limits(),
94 buffer_size,
95 buffer,
96 device.instance_flags,
97 )?;
98
99 match (dispatch, draw) {
100 (None, None) => Ok(None),
101 (None, Some(_)) => unreachable!(),
102 (Some(_), None) => unreachable!(),
103 (Some(dispatch), Some(draw)) => Ok(Some(Self { dispatch, draw })),
104 }
105 }
106
107 pub(crate) fn dispose(self, device: &dyn hal::DynDevice) {
108 let Self { dispatch, draw } = self;
109
110 unsafe {
111 device.destroy_bind_group(dispatch);
112 device.destroy_bind_group(draw);
113 }
114 }
115}