Skip to content

Commit

Permalink
queue initialize_texture_memory sends of texture clears now
Browse files Browse the repository at this point in the history
  • Loading branch information
Wumpf committed Aug 21, 2021
1 parent 8dda966 commit e4cd399
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 6 deletions.
95 changes: 95 additions & 0 deletions wgpu-core/src/command/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ mod query;
mod render;
mod transfer;

use std::num::NonZeroU32;

pub use self::bundle::*;
pub use self::compute::*;
pub use self::draw::*;
Expand All @@ -15,7 +17,9 @@ pub use self::render::*;
pub use self::transfer::*;

use crate::error::{ErrorFormatter, PrettyError};
use crate::init_tracker::TextureInitRange;
use crate::init_tracker::{BufferInitTrackerAction, MemoryInitKind, TextureInitTrackerAction};
use crate::track::TextureSelector;
use crate::{
hub::{Global, GlobalIdentityHandlerFactory, HalApi, Storage, Token},
id,
Expand Down Expand Up @@ -69,9 +73,11 @@ pub struct BakedCommands<A: hal::Api> {
pub(crate) list: Vec<A::CommandBuffer>,
pub(crate) trackers: TrackerSet,
buffer_memory_init_actions: Vec<BufferInitTrackerAction>,
texture_memory_init_actions: Vec<TextureInitTrackerAction>,
}

pub(crate) struct DestroyedBufferError(pub id::BufferId);
pub(crate) struct DestroyedTextureError(pub id::TextureId);

impl<A: hal::Api> BakedCommands<A> {
pub(crate) fn initialize_buffer_memory(
Expand All @@ -80,6 +86,7 @@ impl<A: hal::Api> BakedCommands<A> {
buffer_guard: &mut Storage<Buffer<A>, id::BufferId>,
) -> Result<(), DestroyedBufferError> {
let mut ranges = Vec::new();
// TODO: neighboring NeedsInitializedMemory ranges in init_actions are not collapsed!
for buffer_use in self.buffer_memory_init_actions.drain(..) {
let buffer = buffer_guard
.get_mut(buffer_use.id)
Expand Down Expand Up @@ -131,7 +138,94 @@ impl<A: hal::Api> BakedCommands<A> {
}
}
}
Ok(())
}

pub(crate) fn initialize_texture_memory(
&mut self,
device_tracker: &mut TrackerSet,
texture_guard: &mut Storage<Texture<A>, id::TextureId>,
) -> Result<(), DestroyedTextureError> {
let mut ranges = Vec::new();
for texture_use in self.texture_memory_init_actions.drain(..) {
let texture = texture_guard
.get_mut(texture_use.id)
.map_err(|_| DestroyedTextureError(texture_use.id))?;
let use_range = texture_use.range;
let affected_mip_trackers = texture
.initialization_status
.mips
.iter_mut()
.enumerate()
.skip(use_range.mip_range.start as usize)
.take((use_range.mip_range.end - use_range.mip_range.start) as usize);

match texture_use.kind {
MemoryInitKind::ImplicitlyInitialized => {
for (_, mip_tracker) in affected_mip_trackers {
mip_tracker
.drain(use_range.layer_range.clone())
.for_each(drop);
}
}
MemoryInitKind::NeedsInitializedMemory => {
ranges.clear();
for (mip_level, mip_tracker) in affected_mip_trackers {
for layer_range in mip_tracker.drain(use_range.layer_range.clone()) {
// TODO: Don't treat every mip_level separately and collapse equal layer ranges!
ranges.push(TextureInitRange {
mip_range: mip_level as u32..(mip_level as u32 + 1),
layer_range,
})
}
}

let raw_texture = texture
.raw
.as_ref()
.ok_or(DestroyedTextureError(texture_use.id))?;

for range in &ranges {
// TODO: D24 formats are not allowed to support COPY_DST!! (and on the rest we don't enforce it)
// -> This would mean we need use clear passes whenever applicable and fall back to copies or even shader writes. Need to figure this out.
// --> Depending on the outcome we may decide to skip all this elaborate range collapsing anyways

// Don't do use_replace since the texture may already no longer have a ref_count.
// However, we *know* that it is currently in use, so the tracker must already know about it.
let transition = device_tracker.textures.change_replace_tracked(
id::Valid(texture_use.id),
TextureSelector {
levels: range.mip_range.clone(),
layers: range.layer_range.clone(),
},
hal::TextureUses::COPY_DST,
);
unsafe {
self.encoder.transition_textures(
transition.map(|pending| pending.into_hal(texture)),
);
self.encoder.clear_texture(
raw_texture,
&ranges
.iter()
.map(|r| wgt::ImageSubresourceRange {
aspect: wgt::TextureAspect::All,
base_mip_level: r.mip_range.start,
mip_level_count: NonZeroU32::new(
r.mip_range.end - r.mip_range.start,
),
base_array_layer: r.layer_range.start,
array_layer_count: NonZeroU32::new(
r.layer_range.end - r.layer_range.start,
),
})
.collect::<Vec<wgt::ImageSubresourceRange>>(),
);
}
}
}
}
}
Ok(())
}
}
Expand Down Expand Up @@ -239,6 +333,7 @@ impl<A: hal::Api> CommandBuffer<A> {
list: self.encoder.list,
trackers: self.trackers,
buffer_memory_init_actions: self.buffer_memory_init_actions,
texture_memory_init_actions: self.texture_memory_init_actions,
}
}
}
Expand Down
5 changes: 4 additions & 1 deletion wgpu-core/src/device/queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -533,7 +533,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
let (compute_pipe_guard, mut token) = hub.compute_pipelines.read(&mut token);
let (render_pipe_guard, mut token) = hub.render_pipelines.read(&mut token);
let (mut buffer_guard, mut token) = hub.buffers.write(&mut token);
let (texture_guard, mut token) = hub.textures.write(&mut token);
let (mut texture_guard, mut token) = hub.textures.write(&mut token);
let (texture_view_guard, mut token) = hub.texture_views.read(&mut token);
let (sampler_guard, mut token) = hub.samplers.read(&mut token);
let (query_set_guard, _) = hub.query_sets.read(&mut token);
Expand Down Expand Up @@ -678,6 +678,9 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
baked
.initialize_buffer_memory(&mut *trackers, &mut *buffer_guard)
.map_err(|err| QueueSubmitError::DestroyedBuffer(err.0))?;
baked
.initialize_texture_memory(&mut *trackers, &mut *texture_guard)
.map_err(|err| QueueSubmitError::DestroyedTexture(err.0))?;
//Note: stateless trackers are not merged:
// device already knows these resources exist.
CommandBuffer::insert_barriers(
Expand Down
6 changes: 3 additions & 3 deletions wgpu-core/src/init_tracker/texture.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ pub(crate) type TextureLayerInitTracker = InitTracker<u32>;

#[derive(Debug)]
pub(crate) struct TextureInitTracker {
mips: ArrayVec<TextureLayerInitTracker, { hal::MAX_MIP_LEVELS as usize }>,
pub mips: ArrayVec<TextureLayerInitTracker, { hal::MAX_MIP_LEVELS as usize }>,
}

impl TextureInitTracker {
Expand Down Expand Up @@ -73,8 +73,8 @@ impl TextureInitTracker {
Some(TextureInitTrackerAction {
id: action.id,
range: TextureInitRange {
mip_range: mip_range_start as u32..mip_range_end as u32,
layer_range: layer_range_start..layer_range_end,
mip_range: mip_range_start as u32..mip_range_end as u32,
layer_range: layer_range_start..layer_range_end,
},
kind: action.kind,
})
Expand Down
4 changes: 2 additions & 2 deletions wgpu-hal/src/dx12/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -331,8 +331,8 @@ impl crate::CommandEncoder<super::Api> for super::CommandEncoder {

unsafe fn clear_texture(
&mut self,
texture: &super::Texture,
ranges: &[wgt::ImageSubresourceRange],
_texture: &super::Texture,
_ranges: &[wgt::ImageSubresourceRange],
) {
// TODO
}
Expand Down

0 comments on commit e4cd399

Please sign in to comment.