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

View File

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

View File

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