Share use_xxx implementations in the tracker

This commit is contained in:
Dzmitry Malyshau 2018-10-19 10:45:11 -04:00
parent 0fca6930d9
commit f9cd55ed59
3 changed files with 39 additions and 46 deletions

View File

@ -92,7 +92,6 @@ pub extern "C" fn wgpu_command_buffer_begin_render_pass(
let device_guard = HUB.devices.lock(); let device_guard = HUB.devices.lock();
let device = device_guard.get(cmb.device_id.0); let device = device_guard.get(cmb.device_id.0);
let transit_comb = cmb.raw.pop().unwrap();
let current_comb = device.com_allocator.extend(cmb); let current_comb = device.com_allocator.extend(cmb);
//let render_pass = device.create_render_pass(); //let render_pass = device.create_render_pass();
@ -111,7 +110,6 @@ pub extern "C" fn wgpu_command_buffer_begin_render_pass(
.lock() .lock()
.register(RenderPass::new( .register(RenderPass::new(
current_comb, current_comb,
transit_comb,
command_buffer_id, command_buffer_id,
)) ))
} }

View File

@ -13,7 +13,6 @@ use std::iter;
pub struct RenderPass<B: hal::Backend> { pub struct RenderPass<B: hal::Backend> {
raw: B::CommandBuffer, raw: B::CommandBuffer,
parent: B::CommandBuffer,
cmb_id: Stored<CommandBufferId>, cmb_id: Stored<CommandBufferId>,
tracker: Tracker, tracker: Tracker,
} }
@ -21,12 +20,10 @@ pub struct RenderPass<B: hal::Backend> {
impl<B: hal::Backend> RenderPass<B> { impl<B: hal::Backend> RenderPass<B> {
pub fn new( pub fn new(
raw: B::CommandBuffer, raw: B::CommandBuffer,
parent: B::CommandBuffer,
cmb_id: CommandBufferId, cmb_id: CommandBufferId,
) -> Self { ) -> Self {
RenderPass { RenderPass {
raw, raw,
parent,
cmb_id: Stored(cmb_id), cmb_id: Stored(cmb_id),
tracker: Tracker::default(), tracker: Tracker::default(),
} }
@ -42,13 +39,11 @@ pub extern "C" fn wgpu_render_pass_end_pass(
.take(pass_id); .take(pass_id);
pass.raw.end_render_pass(); pass.raw.end_render_pass();
let combs = iter::once(pass.parent)
.chain(iter::once(pass.raw));
HUB.command_buffers HUB.command_buffers
.lock() .lock()
.get_mut(pass.cmb_id.0) .get_mut(pass.cmb_id.0)
.raw .raw
.extend(combs); .push(pass.raw);
pass.cmb_id.0 pass.cmb_id.0
} }

View File

@ -2,7 +2,8 @@ use {Stored, BufferId, TextureId};
use resource::{BufferUsageFlags, TextureUsageFlags}; use resource::{BufferUsageFlags, TextureUsageFlags};
use std::collections::hash_map::{Entry, HashMap}; use std::collections::hash_map::{Entry, HashMap};
use std::ops::Range; use std::hash::Hash;
use std::ops::BitOr;
use std::sync::Mutex; use std::sync::Mutex;
@ -22,33 +23,47 @@ bitflags! {
} }
trait GenericUsage {
fn is_exclusive(&self) -> bool;
}
impl GenericUsage for BufferUsageFlags {
fn is_exclusive(&self) -> bool {
BufferUsageFlags::WRITE_ALL.intersects(*self)
}
}
impl GenericUsage for TextureUsageFlags {
fn is_exclusive(&self) -> bool {
TextureUsageFlags::WRITE_ALL.intersects(*self)
}
}
#[derive(Default)] #[derive(Default)]
pub struct Tracker { pub struct Tracker {
buffers: Mutex<HashMap<Stored<BufferId>, Range<BufferUsageFlags>>>, buffers: Mutex<HashMap<Stored<BufferId>, BufferUsageFlags>>,
textures: Mutex<HashMap<Stored<TextureId>, Range<TextureUsageFlags>>>, textures: Mutex<HashMap<Stored<TextureId>, TextureUsageFlags>>,
} }
impl Tracker { impl Tracker {
pub(crate) fn use_buffer( fn use_impl<I, U>(
&self, id: Stored<BufferId>, usage: BufferUsageFlags, permit: UsePermit, map: &mut HashMap<I, U>, id: I, usage: U, permit: UsePermit
) -> Result<UseAction<BufferUsageFlags>, BufferUsageFlags> { ) -> Result<UseAction<U>, U>
match self.buffers.lock().unwrap().entry(id) { where
I: Hash + Eq,
U: Copy + GenericUsage + BitOr<Output = U> + PartialEq,
{
match map.entry(id) {
Entry::Vacant(e) => { Entry::Vacant(e) => {
e.insert(usage .. usage); e.insert(usage);
Ok(UseAction::Init) Ok(UseAction::Init)
} }
Entry::Occupied(mut e) => { Entry::Occupied(mut e) => {
let old = e.get().end; let old = *e.get();
if usage == old { if usage == old {
Ok(UseAction::Keep) Ok(UseAction::Keep)
} else if permit.contains(UsePermit::EXTEND) && } else if permit.contains(UsePermit::EXTEND) && !(old | usage).is_exclusive() {
!BufferUsageFlags::WRITE_ALL.intersects(old | usage) Ok(UseAction::Extend { old: e.insert(old | usage) })
{
e.get_mut().end |= usage;
Ok(UseAction::Extend { old })
} else if permit.contains(UsePermit::REPLACE) { } else if permit.contains(UsePermit::REPLACE) {
e.get_mut().end = usage; Ok(UseAction::Replace { old: e.insert(usage) })
Ok(UseAction::Replace { old })
} else { } else {
Err(old) Err(old)
} }
@ -56,30 +71,15 @@ impl Tracker {
} }
} }
pub(crate) fn use_buffer(
&self, id: Stored<BufferId>, usage: BufferUsageFlags, permit: UsePermit,
) -> Result<UseAction<BufferUsageFlags>, BufferUsageFlags> {
Self::use_impl(&mut *self.buffers.lock().unwrap(), id, usage, permit)
}
pub(crate) fn use_texture( pub(crate) fn use_texture(
&self, id: Stored<TextureId>, usage: TextureUsageFlags, permit: UsePermit, &self, id: Stored<TextureId>, usage: TextureUsageFlags, permit: UsePermit,
) -> Result<UseAction<TextureUsageFlags>, TextureUsageFlags> { ) -> Result<UseAction<TextureUsageFlags>, TextureUsageFlags> {
match self.textures.lock().unwrap().entry(id) { Self::use_impl(&mut *self.textures.lock().unwrap(), id, usage, permit)
Entry::Vacant(e) => {
e.insert(usage .. usage);
Ok(UseAction::Init)
}
Entry::Occupied(mut e) => {
let old = e.get().end;
if usage == old {
Ok(UseAction::Keep)
} else if permit.contains(UsePermit::EXTEND) &&
!TextureUsageFlags::WRITE_ALL.intersects(old | usage)
{
e.get_mut().end |= usage;
Ok(UseAction::Extend { old })
} else if permit.contains(UsePermit::REPLACE) {
e.get_mut().end = usage;
Ok(UseAction::Replace { old })
} else {
Err(old)
}
}
}
} }
} }