From 745bebcbb5063200b7905279d43947bb1daa9140 Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Thu, 13 Jun 2019 11:22:54 -0400 Subject: [PATCH] Move buffer state tracking into a module, add unit tests --- wgpu-native/src/track/buffer.rs | 99 +++++++++++++++++++++++++++++++++ wgpu-native/src/track/mod.rs | 78 +------------------------- 2 files changed, 102 insertions(+), 75 deletions(-) create mode 100644 wgpu-native/src/track/buffer.rs diff --git a/wgpu-native/src/track/buffer.rs b/wgpu-native/src/track/buffer.rs new file mode 100644 index 0000000000..f22a371e37 --- /dev/null +++ b/wgpu-native/src/track/buffer.rs @@ -0,0 +1,99 @@ +use crate::{ + conv, + resource::BufferUsage, + BufferId, +}; +use super::{PendingTransition, ResourceState, Stitch, Unit}; +use std::ops::Range; + +//TODO: store `hal::buffer::State` here to avoid extra conversions +pub type BufferState = Unit; + +impl PendingTransition { + pub fn to_states(&self) -> Range { + conv::map_buffer_state(self.usage.start) .. + conv::map_buffer_state(self.usage.end) + } +} + +impl Default for BufferState { + fn default() -> Self { + BufferState { + init: BufferUsage::empty(), + last: BufferUsage::empty(), + } + } +} + +impl ResourceState for BufferState { + type Id = BufferId; + type Selector = (); + type Usage = BufferUsage; + + fn query( + &self, + _selector: Self::Selector, + ) -> Option { + Some(self.last) + } + + fn change( + &mut self, + id: Self::Id, + _selector: Self::Selector, + usage: Self::Usage, + output: Option<&mut Vec>>, + ) -> Result<(), PendingTransition> { + let old = self.last; + if usage != old { + let pending = PendingTransition { + id, + selector: (), + usage: old .. usage, + }; + self.last = match output { + Some(transitions) => { + transitions.push(pending); + usage + } + None => { + if !old.is_empty() && BufferUsage::WRITE_ALL.intersects(old | usage) { + return Err(pending); + } + old | usage + } + }; + } + Ok(()) + } + + fn merge( + &mut self, + id: Self::Id, + other: &Self, + stitch: Stitch, + output: Option<&mut Vec>>, + ) -> Result<(), PendingTransition> { + let usage = other.select(stitch); + self.change(id, (), usage, output) + } +} + +#[cfg(test)] +mod test { + use crate::TypedId; + use super::*; + + #[test] + fn change() { + let mut bs = Unit { + init: BufferUsage::INDEX, + last: BufferUsage::STORAGE, + }; + let id = TypedId::new(0, 0); + assert!(bs.change(id, (), BufferUsage::VERTEX, None).is_err()); + bs.change(id, (), BufferUsage::VERTEX, Some(&mut Vec::new())).unwrap(); + bs.change(id, (), BufferUsage::INDEX, None).unwrap(); + assert_eq!(bs.last, BufferUsage::VERTEX | BufferUsage::INDEX); + } +} diff --git a/wgpu-native/src/track/mod.rs b/wgpu-native/src/track/mod.rs index 9acbcca85e..842fef8104 100644 --- a/wgpu-native/src/track/mod.rs +++ b/wgpu-native/src/track/mod.rs @@ -1,11 +1,11 @@ +mod buffer; mod range; use crate::{ conv, device::MAX_MIP_LEVELS, hub::Storage, - resource::{BufferUsage, TextureUsage}, - BufferId, + resource::{TextureUsage}, Epoch, Index, RefCount, @@ -26,6 +26,7 @@ use std::{ vec::Drain, }; +use buffer::BufferState; use range::RangedStates; @@ -289,79 +290,6 @@ impl ResourceTracker { } } -//TODO: store `hal::buffer::State` here to avoid extra conversions -pub type BufferState = Unit; - -impl PendingTransition { - pub fn to_states(&self) -> Range { - conv::map_buffer_state(self.usage.start) .. - conv::map_buffer_state(self.usage.end) - } -} - -impl Default for BufferState { - fn default() -> Self { - BufferState { - init: BufferUsage::empty(), - last: BufferUsage::empty(), - } - } -} - -impl ResourceState for BufferState { - type Id = BufferId; - type Selector = (); - type Usage = BufferUsage; - - fn query( - &self, - _selector: Self::Selector, - ) -> Option { - Some(self.last) - } - - fn change( - &mut self, - id: Self::Id, - _selector: Self::Selector, - usage: Self::Usage, - output: Option<&mut Vec>>, - ) -> Result<(), PendingTransition> { - let old = self.last; - if usage != old { - let pending = PendingTransition { - id, - selector: (), - usage: old .. usage, - }; - self.last = match output { - Some(transitions) => { - transitions.push(pending); - usage - } - None => { - if !old.is_empty() && BufferUsage::WRITE_ALL.intersects(old | usage) { - return Err(pending); - } - old | usage - } - }; - } - Ok(()) - } - - fn merge( - &mut self, - id: Self::Id, - other: &Self, - stitch: Stitch, - output: Option<&mut Vec>>, - ) -> Result<(), PendingTransition> { - let usage = other.select(stitch); - self.change(id, (), usage, output) - } -} - type PlaneStates = RangedStates;