wgpu_core/command/
transition_resources.rs1use thiserror::Error;
2use wgt::error::{ErrorType, WebGpuError};
3
4use crate::{
5 command::{CommandBuffer, 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_buf = hub
26 .command_buffers
27 .get(command_encoder_id.into_command_buffer_id());
28 let mut cmd_buf_data = cmd_buf.data.lock();
29 cmd_buf_data.record_with(|cmd_buf_data| -> Result<(), CommandEncoderError> {
30 let device = &cmd_buf.device;
32 device.check_is_valid()?;
33 let snatch_guard = &device.snatchable_lock.read();
34
35 let mut usage_scope = device.new_usage_scope();
36 let indices = &device.tracker_indices;
37 usage_scope.buffers.set_size(indices.buffers.size());
38 usage_scope.textures.set_size(indices.textures.size());
39
40 for buffer_transition in buffer_transitions {
42 let buffer = hub.buffers.get(buffer_transition.buffer).get()?;
43 buffer.same_device_as(cmd_buf.as_ref())?;
44
45 usage_scope
46 .buffers
47 .merge_single(&buffer, buffer_transition.state)?;
48 }
49
50 for texture_transition in texture_transitions {
52 let texture = hub.textures.get(texture_transition.texture).get()?;
53 texture.same_device_as(cmd_buf.as_ref())?;
54
55 unsafe {
56 usage_scope.textures.merge_single(
57 &texture,
58 texture_transition.selector,
59 texture_transition.state,
60 )
61 }?;
62 }
63
64 let cmd_buf_raw = cmd_buf_data.encoder.open()?;
66 CommandBuffer::insert_barriers_from_scope(
67 cmd_buf_raw,
68 &mut cmd_buf_data.trackers,
69 &usage_scope,
70 snatch_guard,
71 );
72 Ok(())
73 })
74 }
75}
76
77#[derive(Clone, Debug, Error)]
79#[non_exhaustive]
80pub enum TransitionResourcesError {
81 #[error(transparent)]
82 Device(#[from] DeviceError),
83 #[error(transparent)]
84 EncoderState(#[from] EncoderStateError),
85 #[error(transparent)]
86 InvalidResource(#[from] InvalidResourceError),
87 #[error(transparent)]
88 ResourceUsage(#[from] ResourceUsageCompatibilityError),
89}
90
91impl WebGpuError for TransitionResourcesError {
92 fn webgpu_error_type(&self) -> ErrorType {
93 let e: &dyn WebGpuError = match self {
94 Self::Device(e) => e,
95 Self::EncoderState(e) => e,
96 Self::InvalidResource(e) => e,
97 Self::ResourceUsage(e) => e,
98 };
99 e.webgpu_error_type()
100 }
101}