mirror of
https://github.com/gfx-rs/wgpu.git
synced 2026-04-22 03:02:01 -04:00
Remove the old tracking code, update local feature and the headers
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user