Skip to content

Commit

Permalink
Support writeTexture for surface textures
Browse files Browse the repository at this point in the history
  • Loading branch information
kvark committed Jan 12, 2022
1 parent 6bc896f commit 16edd91
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 34 deletions.
95 changes: 66 additions & 29 deletions wgpu-core/src/device/queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -609,7 +609,6 @@ 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);
// This could be made immutable. It's only mutated for the `has_work` flag.
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);
Expand Down Expand Up @@ -684,34 +683,15 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
*has_work = true;
let ref_count = cmdbuf.trackers.textures.get_ref_count(id);
//TODO: better error handling here?
{
// first, register it in the device tracker with uninitialized,
// if it wasn't used before.
let mut ts = track::TextureState::default();
let _ = ts.change(
id,
texture.full_range.clone(),
hal::TextureUses::UNINITIALIZED,
None,
);
let _ = trackers.textures.init(
id,
ref_count.clone(),
ts.clone(),
);
}
{
// then, register it in the temporary tracker.
let mut ts = track::TextureState::default();
let _ = ts.change(
id,
texture.full_range.clone(),
hal::TextureUses::empty(),
None,
);
let _ =
used_surface_textures.init(id, ref_count.clone(), ts);
}
// register it in the temporary tracker.
let mut ts = track::TextureState::default();
let _ = ts.change(
id,
texture.full_range.clone(),
hal::TextureUses::empty(), //present
None,
);
let _ = used_surface_textures.init(id, ref_count.clone(), ts);
}
}
if !texture.life_guard.use_at(submit_index) {
Expand Down Expand Up @@ -840,6 +820,63 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
ref mut fence,
..
} = *device;

{
//TODO: these blocks have a few organizational issues and should be refactored
// (1) it's similar to the code we have per-command-buffer (at the begin and end)
// Maybe we an merge some?
// (2) it's doing the extra locking unconditionally
// Maybe we can only do so if any surfaces are being written to?

let (_, mut token) = hub.buffers.read(&mut token); // skip token
let (mut texture_guard, _) = hub.textures.write(&mut token);

for &id in pending_writes.dst_textures.iter() {
let texture = texture_guard.get_mut(id).unwrap();
match texture.inner {
TextureInner::Native { raw: None } => {
return Err(QueueSubmitError::DestroyedTexture(id));
}
TextureInner::Native { raw: Some(_) } => {}
TextureInner::Surface {
ref mut has_work, ..
} => {
use track::ResourceState as _;

*has_work = true;
let ref_count = texture.life_guard.add_ref();
//TODO: better error handling here?
// register it in the temporary tracker.
let mut ts = track::TextureState::default();
let _ = ts.change(
id::Valid(id),
texture.full_range.clone(),
hal::TextureUses::empty(), //present
None,
);
let _ = used_surface_textures.init(id::Valid(id), ref_count, ts);
}
}
}

if !used_surface_textures.is_empty() {
let mut trackers = device.trackers.lock();
let texture_barriers = trackers
.textures
.merge_replace(&used_surface_textures)
.map(|pending| {
let tex = &texture_guard[pending.id];
pending.into_hal(tex)
});
unsafe {
pending_writes
.command_encoder
.transition_textures(texture_barriers);
};
used_surface_textures.clear();
}
}

let refs = pending_writes
.pre_submit()
.into_iter()
Expand Down
23 changes: 18 additions & 5 deletions wgpu-core/src/present.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,7 @@ use crate::{
hub::{Global, GlobalIdentityHandlerFactory, HalApi, Input, Token},
id::{DeviceId, SurfaceId, TextureId, Valid},
init_tracker::TextureInitTracker,
resource,
track::TextureSelector,
LifeGuard, Stored,
resource, track, LifeGuard, Stored,
};

use hal::{Queue as _, Surface as _};
Expand Down Expand Up @@ -174,7 +172,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
| wgt::TextureFormatFeatureFlags::MULTISAMPLE_RESOLVE,
},
initialization_status: TextureInitTracker::new(1, 1),
full_range: TextureSelector {
full_range: track::TextureSelector {
layers: 0..1,
levels: 0..1,
},
Expand All @@ -188,7 +186,22 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
let ref_count = texture.life_guard.add_ref();
let id = fid.assign(texture, &mut token);

//suf.acquired_texture = Some(suf_texture);
{
use track::ResourceState as _;
// register it in the device tracker as uninitialized
let mut trackers = device.trackers.lock();
let mut ts = track::TextureState::default();
let _ = ts.change(
id,
track::TextureSelector {
layers: 0..1,
levels: 0..1,
},
hal::TextureUses::UNINITIALIZED,
None,
);
let _ = trackers.textures.init(id, ref_count.clone(), ts);
}

if present.acquired_texture.is_some() {
return Err(SurfaceError::AlreadyAcquired);
Expand Down

0 comments on commit 16edd91

Please sign in to comment.