wgpu_core/command/
transition_resources.rs1use thiserror::Error;
2use wgt::error::{ErrorType, WebGpuError};
3
4use crate::{
5 command::{CommandEncoder, CommandEncoderError, EncoderStateError},
6 device::DeviceError,
7 global::Global,
8 id::{BufferId, CommandEncoderId, TextureId},
9 resource::{InvalidResourceError, ParentDevice},
10 track::ResourceUsageCompatibilityError,
11};
12
13impl Global {
14 pub fn command_encoder_transition_resources(
15 &self,
16 command_encoder_id: CommandEncoderId,
17 buffer_transitions: impl Iterator<Item = wgt::BufferTransition<BufferId>>,
18 texture_transitions: impl Iterator<Item = wgt::TextureTransition<TextureId>>,
19 ) -> Result<(), EncoderStateError> {
20 profiling::scope!("CommandEncoder::transition_resources");
21
22 let hub = &self.hub;
23
24 let cmd_enc = hub.command_encoders.get(command_encoder_id);
26 let mut cmd_buf_data = cmd_enc.data.lock();
27 cmd_buf_data.record_with(|cmd_buf_data| -> Result<(), CommandEncoderError> {
28 let device = &cmd_enc.device;
30 device.check_is_valid()?;
31 let snatch_guard = &device.snatchable_lock.read();
32
33 let mut usage_scope = device.new_usage_scope();
34 let indices = &device.tracker_indices;
35 usage_scope.buffers.set_size(indices.buffers.size());
36 usage_scope.textures.set_size(indices.textures.size());
37
38 for buffer_transition in buffer_transitions {
40 let buffer = hub.buffers.get(buffer_transition.buffer).get()?;
41 buffer.same_device_as(cmd_enc.as_ref())?;
42
43 usage_scope
44 .buffers
45 .merge_single(&buffer, buffer_transition.state)?;
46 }
47
48 for texture_transition in texture_transitions {
50 let texture = hub.textures.get(texture_transition.texture).get()?;
51 texture.same_device_as(cmd_enc.as_ref())?;
52
53 unsafe {
54 usage_scope.textures.merge_single(
55 &texture,
56 texture_transition.selector,
57 texture_transition.state,
58 )
59 }?;
60 }
61
62 let cmd_buf_raw = cmd_buf_data.encoder.open()?;
64 CommandEncoder::insert_barriers_from_scope(
65 cmd_buf_raw,
66 &mut cmd_buf_data.trackers,
67 &usage_scope,
68 snatch_guard,
69 );
70 Ok(())
71 })
72 }
73}
74
75#[derive(Clone, Debug, Error)]
77#[non_exhaustive]
78pub enum TransitionResourcesError {
79 #[error(transparent)]
80 Device(#[from] DeviceError),
81 #[error(transparent)]
82 EncoderState(#[from] EncoderStateError),
83 #[error(transparent)]
84 InvalidResource(#[from] InvalidResourceError),
85 #[error(transparent)]
86 ResourceUsage(#[from] ResourceUsageCompatibilityError),
87}
88
89impl WebGpuError for TransitionResourcesError {
90 fn webgpu_error_type(&self) -> ErrorType {
91 let e: &dyn WebGpuError = match self {
92 Self::Device(e) => e,
93 Self::EncoderState(e) => e,
94 Self::InvalidResource(e) => e,
95 Self::ResourceUsage(e) => e,
96 };
97 e.webgpu_error_type()
98 }
99}