Remove the old tracking code, update local feature and the headers

This commit is contained in:
Dzmitry Malyshau
2019-06-12 12:15:22 -04:00
parent bc7b842f12
commit d92b623bd8
4 changed files with 11 additions and 353 deletions

View File

@@ -19,8 +19,6 @@ typedef struct WGPUClientFactory WGPUClientFactory;
typedef struct WGPUServer WGPUServer;
typedef struct WGPUTrackPermit WGPUTrackPermit;
typedef uint32_t WGPUIndex;
typedef uint32_t WGPUEpoch;
@@ -57,10 +55,6 @@ typedef struct {
const uint8_t *error;
} WGPUInfrastructure;
WGPUDeviceId wgpu_client_adapter_create_device(const WGPUClient *client,
WGPUAdapterId adapter_id,
const WGPUDeviceDescriptor *desc);

View File

@@ -11,6 +11,8 @@
#define WGPUMAX_COLOR_TARGETS 4
#define WGPUMAX_MIP_LEVELS 16
#define WGPUMAX_VERTEX_BUFFERS 8
typedef enum {
@@ -230,8 +232,6 @@ typedef enum {
WGPUVertexFormat_Int4 = 48,
} WGPUVertexFormat;
typedef struct WGPUTrackPermit WGPUTrackPermit;
typedef uint32_t WGPUIndex;
typedef uint32_t WGPUEpoch;
@@ -615,10 +615,6 @@ typedef struct {
uint32_t array_count;
} WGPUTextureViewDescriptor;
#if defined(WGPU_LOCAL)
WGPUDeviceId wgpu_adapter_request_device(WGPUAdapterId adapter_id,
const WGPUDeviceDescriptor *desc);

View File

@@ -764,7 +764,7 @@ pub extern "C" fn wgpu_device_create_texture(
) -> TextureId {
let texture = device_create_texture(device_id, desc);
let ref_count = texture.life_guard.ref_count.clone();
let range = texture.full_range;
let range = texture.full_range.clone();
let id = HUB.textures.register_local(texture);
device_track_texture(device_id, id, ref_count, range);
id
@@ -1797,6 +1797,7 @@ pub fn swap_chain_populate_textures(
for (i, mut texture) in textures.into_iter().enumerate() {
let format = texture.format;
let kind = texture.kind;
let range = texture.full_range.clone();
let view_raw = unsafe {
device
@@ -1806,7 +1807,7 @@ pub fn swap_chain_populate_textures(
hal::image::ViewKind::D2,
conv::map_texture_format(format),
hal::format::Swizzle::NO,
texture.full_range.clone(),
range.clone(),
)
.unwrap()
};
@@ -1819,9 +1820,10 @@ pub fn swap_chain_populate_textures(
ref_count: texture.life_guard.ref_count.clone(),
value: HUB.textures.register_local(texture),
};
trackers.textures.query(
trackers.textures.init(
texture_id.value,
&texture_id.ref_count,
range.clone(),
resource::TextureUsage::UNINITIALIZED,
);
@@ -1831,6 +1833,7 @@ pub fn swap_chain_populate_textures(
format,
extent: kind.extent(),
samples: kind.num_samples(),
range,
is_owned_by_swap_chain: true,
life_guard: LifeGuard::new(),
};
@@ -1840,7 +1843,7 @@ pub fn swap_chain_populate_textures(
};
trackers
.views
.query(view_id.value, &view_id.ref_count, DummyUsage);
.init(view_id.value, &view_id.ref_count, (), ());
swap_chain.frames.alloc().init(swap_chain::Frame {
texture_id,

View File

@@ -14,86 +14,19 @@ use crate::{
};
use arrayvec::ArrayVec;
use bitflags::bitflags;
use hal::backend::FastHashMap;
use std::{
borrow::Borrow,
cmp::Ordering,
collections::hash_map::{Entry, Iter},
collections::hash_map::Entry,
iter::Peekable,
marker::PhantomData,
mem,
ops::{BitOr, Range},
ops::Range,
slice,
vec::Drain,
};
#[derive(Clone, Debug, PartialEq)]
#[allow(unused)]
pub enum Tracktion<T> {
Init,
Keep,
Extend { old: T },
Replace { old: T },
}
impl<T> Tracktion<T> {
pub fn into_source(self) -> Option<T> {
match self {
Tracktion::Init | Tracktion::Keep => None,
Tracktion::Extend { old } | Tracktion::Replace { old } => Some(old),
}
}
}
#[derive(Clone, Debug, PartialEq)]
pub struct Query<T> {
pub usage: T,
pub initialized: bool,
}
bitflags! {
pub struct TrackPermit: u32 {
/// Allow extension of the current usage. This is useful during render pass
/// recording, where the usage has to stay constant, but we can defer the
/// decision on what it is until the end of the pass.
const EXTEND = 1;
/// Allow replacing the current usage with the new one. This is useful when
/// recording a command buffer live, and the current usage is already been set.
const REPLACE = 2;
}
}
pub trait GenericUsage {
fn is_exclusive(&self) -> bool;
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct DummyUsage;
impl BitOr for DummyUsage {
type Output = Self;
fn bitor(self, other: Self) -> Self {
other
}
}
impl GenericUsage for BufferUsage {
fn is_exclusive(&self) -> bool {
BufferUsage::WRITE_ALL.intersects(*self)
}
}
impl GenericUsage for TextureUsage {
fn is_exclusive(&self) -> bool {
TextureUsage::WRITE_ALL.intersects(*self)
}
}
impl GenericUsage for DummyUsage {
fn is_exclusive(&self) -> bool {
false
}
}
/// A single unit of state tracking.
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct Unit<U> {
@@ -117,32 +50,6 @@ impl<U: Copy> Unit<U> {
}
}
impl<U: Copy + BitOr<Output=U> + PartialEq + GenericUsage> Unit<U> {
fn transit(&mut self, usage: U, permit: TrackPermit) -> Result<Tracktion<U>, U> {
let old = self.last;
if usage == old {
Ok(Tracktion::Keep)
} else if permit.contains(TrackPermit::EXTEND) && !(old | usage).is_exclusive() {
self.last = old | usage;
Ok(Tracktion::Extend { old })
} else if permit.contains(TrackPermit::REPLACE) {
self.last = usage;
Ok(Tracktion::Replace { old })
} else {
Err(old)
}
}
}
//TODO: consider having `I` as an associated type of `S`?
#[derive(Debug)]
pub struct Tracker<I, S> {
/// An association of known resource indices with their tracked states.
map: FastHashMap<Index, Resource<S>>,
_phantom: PhantomData<I>,
}
//TODO: make this a generic parameter.
/// Mode of stitching to states together.
#[derive(Clone, Copy, Debug)]
pub enum Stitch {
@@ -152,248 +59,6 @@ pub enum Stitch {
Last,
}
//TODO: consider rewriting this without any iterators that have side effects.
#[derive(Debug)]
pub struct ConsumeIterator<'a, I: TypedId, U: Copy + PartialEq> {
src: Iter<'a, Index, Resource<Unit<U>>>,
dst: &'a mut FastHashMap<Index, Resource<Unit<U>>>,
stitch: Stitch,
_marker: PhantomData<I>,
}
impl<'a, I: TypedId, U: Copy + PartialEq> Iterator for ConsumeIterator<'a, I, U> {
type Item = (I, Range<U>);
fn next(&mut self) -> Option<Self::Item> {
loop {
let (&index, new) = self.src.next()?;
match self.dst.entry(index) {
Entry::Vacant(e) => {
e.insert(new.clone());
}
Entry::Occupied(mut e) => {
assert_eq!(e.get().epoch, new.epoch);
let old = mem::replace(&mut e.get_mut().state.last, new.state.last);
if old != new.state.init {
let states = old .. new.state.select(self.stitch);
return Some((I::new(index, new.epoch), states))
}
}
}
}
}
}
// Make sure to finish all side effects on drop
impl<'a, I: TypedId, U: Copy + PartialEq> Drop for ConsumeIterator<'a, I, U> {
fn drop(&mut self) {
self.for_each(drop)
}
}
impl<I: TypedId, S> Tracker<I, S> {
pub fn new() -> Self {
Tracker {
map: FastHashMap::default(),
_phantom: PhantomData,
}
}
/// Remove an id from the tracked map.
pub fn remove(&mut self, id: I) -> bool {
match self.map.remove(&id.index()) {
Some(resource) => {
assert_eq!(resource.epoch, id.epoch());
true
}
None => false,
}
}
/// Return an iterator over used resources keys.
pub fn used<'a>(&'a self) -> impl 'a + Iterator<Item = I> {
self.map
.iter()
.map(|(&index, resource)| I::new(index, resource.epoch))
}
fn clear(&mut self) {
self.map.clear();
}
}
impl<I: Copy + TypedId, U: Copy + GenericUsage + BitOr<Output = U> + PartialEq> Tracker<I, Unit<U>> {
/// Get the last usage on a resource.
pub(crate) fn query(&mut self, id: I, ref_count: &RefCount, default: U) -> Query<U> {
match self.map.entry(id.index()) {
Entry::Vacant(e) => {
e.insert(Resource {
ref_count: ref_count.clone(),
state: Unit::new(default),
epoch: id.epoch(),
});
Query {
usage: default,
initialized: true,
}
}
Entry::Occupied(e) => {
assert_eq!(e.get().epoch, id.epoch());
Query {
usage: e.get().state.last,
initialized: false,
}
}
}
}
/// Transit a specified resource into a different usage.
pub(crate) fn transit(
&mut self,
id: I,
ref_count: &RefCount,
usage: U,
permit: TrackPermit,
) -> Result<Tracktion<U>, U> {
match self.map.entry(id.index()) {
Entry::Vacant(e) => {
e.insert(Resource {
ref_count: ref_count.clone(),
state: Unit::new(usage),
epoch: id.epoch(),
});
Ok(Tracktion::Init)
}
Entry::Occupied(mut e) => {
assert_eq!(e.get().epoch, id.epoch());
e.get_mut().state.transit(usage, permit)
}
}
}
/// Consume another tacker, adding it's transitions to `self`.
/// Transitions the current usage to the new one.
pub fn consume_by_replace<'a>(
&'a mut self,
other: &'a Self,
stitch: Stitch,
) -> ConsumeIterator<'a, I, U> {
ConsumeIterator {
src: other.map.iter(),
dst: &mut self.map,
stitch,
_marker: PhantomData,
}
}
/// Consume another tacker, adding it's transitions to `self`.
/// Extends the current usage without doing any transitions.
pub fn consume_by_extend<'a>(&'a mut self, other: &'a Self) -> Result<(), (I, Range<U>)> {
for (&index, new) in other.map.iter() {
match self.map.entry(index) {
Entry::Vacant(e) => {
e.insert(new.clone());
}
Entry::Occupied(mut e) => {
assert_eq!(e.get().epoch, new.epoch);
let old = e.get().state.last;
if old != new.state.last {
let extended = old | new.state.last;
if extended.is_exclusive() {
let id = I::new(index, new.epoch);
return Err((id, old .. new.state.last));
}
e.get_mut().state.last = extended;
}
}
}
}
Ok(())
}
fn _get_with_usage<'a, T: 'a + Borrow<RefCount>>(
&mut self,
storage: &'a Storage<T, I>,
id: I,
usage: U,
permit: TrackPermit,
) -> Result<(&'a T, Tracktion<U>), U> {
let item = &storage[id];
self.transit(id, item.borrow(), usage, permit)
.map(|tracktion| (item, tracktion))
}
pub(crate) fn get_with_extended_usage<'a, T: 'a + Borrow<RefCount>>(
&mut self,
storage: &'a Storage<T, I>,
id: I,
usage: U,
) -> Result<&'a T, U> {
let item = &storage[id];
self.transit(id, item.borrow(), usage, TrackPermit::EXTEND)
.map(|_tracktion| item)
}
pub(crate) fn get_with_replaced_usage<'a, T: 'a + Borrow<RefCount>>(
&mut self,
storage: &'a Storage<T, I>,
id: I,
usage: U,
) -> Result<(&'a T, Option<U>), U> {
let item = &storage[id];
self.transit(id, item.borrow(), usage, TrackPermit::REPLACE)
.map(|tracktion| {
(
item,
match tracktion {
Tracktion::Init | Tracktion::Keep => None,
Tracktion::Extend { .. } => unreachable!(),
Tracktion::Replace { old } => Some(old),
},
)
})
}
}
pub type BufferTracker = Tracker<BufferId, Unit<BufferUsage>>;
pub type TextureTracker = Tracker<TextureId, Unit<TextureUsage>>;
pub type TextureViewTracker = Tracker<TextureViewId, Unit<DummyUsage>>;
pub type BindGroupTracker = Tracker<BindGroupId, Unit<DummyUsage>>;
#[derive(Debug)]
pub struct TrackerSetOld {
pub buffers: BufferTracker,
pub textures: TextureTracker,
pub views: TextureViewTracker,
pub bind_groups: BindGroupTracker,
//TODO: samplers
}
impl TrackerSetOld {
pub fn new() -> Self {
TrackerSetOld {
buffers: BufferTracker::new(),
textures: TextureTracker::new(),
views: TextureViewTracker::new(),
bind_groups: BindGroupTracker::new(),
}
}
pub fn clear(&mut self) {
self.buffers.clear();
self.textures.clear();
self.views.clear();
self.bind_groups.clear();
}
pub fn consume_by_extend(&mut self, other: &Self) {
self.buffers.consume_by_extend(&other.buffers).unwrap();
self.textures.consume_by_extend(&other.textures).unwrap();
self.views.consume_by_extend(&other.views).unwrap();
self.bind_groups.consume_by_extend(&other.bind_groups).unwrap();
}
}
pub trait ResourceState: Clone + Default {
type Id: Copy + TypedId;
type Selector;