Skip to content

Commit dfaffa6

Browse files
committed
queue initialize_texture_memory sends of texture clears now
1 parent ea13a2a commit dfaffa6

File tree

4 files changed

+102
-4
lines changed

4 files changed

+102
-4
lines changed

wgpu-core/src/command/mod.rs

+95
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ mod query;
77
mod render;
88
mod transfer;
99

10+
use std::num::NonZeroU32;
11+
1012
pub use self::bundle::*;
1113
pub use self::compute::*;
1214
pub use self::draw::*;
@@ -15,7 +17,9 @@ pub use self::render::*;
1517
pub use self::transfer::*;
1618

1719
use crate::error::{ErrorFormatter, PrettyError};
20+
use crate::init_tracker::TextureInitRange;
1821
use crate::init_tracker::{BufferInitTrackerAction, MemoryInitKind, TextureInitTrackerAction};
22+
use crate::track::TextureSelector;
1923
use crate::{
2024
hub::{Global, GlobalIdentityHandlerFactory, HalApi, Storage, Token},
2125
id,
@@ -68,9 +72,11 @@ pub struct BakedCommands<A: hal::Api> {
6872
pub(crate) list: Vec<A::CommandBuffer>,
6973
pub(crate) trackers: TrackerSet,
7074
buffer_memory_init_actions: Vec<BufferInitTrackerAction>,
75+
texture_memory_init_actions: Vec<TextureInitTrackerAction>,
7176
}
7277

7378
pub(crate) struct DestroyedBufferError(pub id::BufferId);
79+
pub(crate) struct DestroyedTextureError(pub id::TextureId);
7480

7581
impl<A: hal::Api> BakedCommands<A> {
7682
pub(crate) fn initialize_buffer_memory(
@@ -79,6 +85,7 @@ impl<A: hal::Api> BakedCommands<A> {
7985
buffer_guard: &mut Storage<Buffer<A>, id::BufferId>,
8086
) -> Result<(), DestroyedBufferError> {
8187
let mut ranges = Vec::new();
88+
// TODO: neighboring NeedsInitializedMemory ranges in init_actions are not collapsed!
8289
for buffer_use in self.buffer_memory_init_actions.drain(..) {
8390
let buffer = buffer_guard
8491
.get_mut(buffer_use.id)
@@ -130,7 +137,94 @@ impl<A: hal::Api> BakedCommands<A> {
130137
}
131138
}
132139
}
140+
Ok(())
141+
}
133142

143+
pub(crate) fn initialize_texture_memory(
144+
&mut self,
145+
device_tracker: &mut TrackerSet,
146+
texture_guard: &mut Storage<Texture<A>, id::TextureId>,
147+
) -> Result<(), DestroyedTextureError> {
148+
let mut ranges = Vec::new();
149+
for texture_use in self.texture_memory_init_actions.drain(..) {
150+
let texture = texture_guard
151+
.get_mut(texture_use.id)
152+
.map_err(|_| DestroyedTextureError(texture_use.id))?;
153+
let use_range = texture_use.range;
154+
let affected_mip_trackers = texture
155+
.initialization_status
156+
.mips
157+
.iter_mut()
158+
.enumerate()
159+
.skip(use_range.mip_range.start as usize)
160+
.take((use_range.mip_range.end - use_range.mip_range.start) as usize);
161+
162+
match texture_use.kind {
163+
MemoryInitKind::ImplicitlyInitialized => {
164+
for (_, mip_tracker) in affected_mip_trackers {
165+
mip_tracker
166+
.drain(use_range.layer_range.clone())
167+
.for_each(drop);
168+
}
169+
}
170+
MemoryInitKind::NeedsInitializedMemory => {
171+
ranges.clear();
172+
for (mip_level, mip_tracker) in affected_mip_trackers {
173+
for layer_range in mip_tracker.drain(use_range.layer_range.clone()) {
174+
// TODO: Don't treat every mip_level separately and collapse equal layer ranges!
175+
ranges.push(TextureInitRange {
176+
mip_range: mip_level as u32..(mip_level as u32 + 1),
177+
layer_range,
178+
})
179+
}
180+
}
181+
182+
let raw_texture = texture
183+
.raw
184+
.as_ref()
185+
.ok_or(DestroyedTextureError(texture_use.id))?;
186+
187+
for range in &ranges {
188+
// TODO: D24 formats are not allowed to support COPY_DST!! (and on the rest we don't enforce it)
189+
// -> This would mean we need use clear passes whenever applicable and fall back to copies or even shader writes. Need to figure this out.
190+
// --> Depending on the outcome we may decide to skip all this elaborate range collapsing anyways
191+
192+
// Don't do use_replace since the texture may already no longer have a ref_count.
193+
// However, we *know* that it is currently in use, so the tracker must already know about it.
194+
let transition = device_tracker.textures.change_replace_tracked(
195+
id::Valid(texture_use.id),
196+
TextureSelector {
197+
levels: range.mip_range.clone(),
198+
layers: range.layer_range.clone(),
199+
},
200+
hal::TextureUses::COPY_DST,
201+
);
202+
unsafe {
203+
self.encoder.transition_textures(
204+
transition.map(|pending| pending.into_hal(texture)),
205+
);
206+
self.encoder.clear_texture(
207+
raw_texture,
208+
&ranges
209+
.iter()
210+
.map(|r| wgt::ImageSubresourceRange {
211+
aspect: wgt::TextureAspect::All,
212+
base_mip_level: r.mip_range.start,
213+
mip_level_count: NonZeroU32::new(
214+
r.mip_range.end - r.mip_range.start,
215+
),
216+
base_array_layer: r.layer_range.start,
217+
array_layer_count: NonZeroU32::new(
218+
r.layer_range.end - r.layer_range.start,
219+
),
220+
})
221+
.collect::<Vec<wgt::ImageSubresourceRange>>(),
222+
);
223+
}
224+
}
225+
}
226+
}
227+
}
134228
Ok(())
135229
}
136230
}
@@ -236,6 +330,7 @@ impl<A: hal::Api> CommandBuffer<A> {
236330
list: self.encoder.list,
237331
trackers: self.trackers,
238332
buffer_memory_init_actions: self.buffer_memory_init_actions,
333+
texture_memory_init_actions: self.texture_memory_init_actions,
239334
}
240335
}
241336
}

wgpu-core/src/device/queue.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -550,7 +550,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
550550
let (compute_pipe_guard, mut token) = hub.compute_pipelines.read(&mut token);
551551
let (render_pipe_guard, mut token) = hub.render_pipelines.read(&mut token);
552552
let (mut buffer_guard, mut token) = hub.buffers.write(&mut token);
553-
let (texture_guard, mut token) = hub.textures.write(&mut token);
553+
let (mut texture_guard, mut token) = hub.textures.write(&mut token);
554554
let (texture_view_guard, mut token) = hub.texture_views.read(&mut token);
555555
let (sampler_guard, mut token) = hub.samplers.read(&mut token);
556556
let (query_set_guard, _) = hub.query_sets.read(&mut token);
@@ -718,6 +718,9 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
718718
baked
719719
.initialize_buffer_memory(&mut *trackers, &mut *buffer_guard)
720720
.map_err(|err| QueueSubmitError::DestroyedBuffer(err.0))?;
721+
baked
722+
.initialize_texture_memory(&mut *trackers, &mut *texture_guard)
723+
.map_err(|err| QueueSubmitError::DestroyedTexture(err.0))?;
721724
//Note: stateless trackers are not merged:
722725
// device already knows these resources exist.
723726
CommandBuffer::insert_barriers(

wgpu-core/src/init_tracker/texture.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ pub(crate) type TextureLayerInitTracker = InitTracker<u32>;
2929

3030
#[derive(Debug)]
3131
pub(crate) struct TextureInitTracker {
32-
mips: ArrayVec<TextureLayerInitTracker, { hal::MAX_MIP_LEVELS as usize }>,
32+
pub mips: ArrayVec<TextureLayerInitTracker, { hal::MAX_MIP_LEVELS as usize }>,
3333
}
3434

3535
impl TextureInitTracker {

wgpu-hal/src/dx12/command.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -369,8 +369,8 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {
369369

370370
unsafe fn clear_texture(
371371
&mut self,
372-
texture: &super::Texture,
373-
ranges: &[wgt::ImageSubresourceRange],
372+
_texture: &super::Texture,
373+
_ranges: &[wgt::ImageSubresourceRange],
374374
) {
375375
// TODO
376376
}

0 commit comments

Comments
 (0)