mirror of
https://github.com/gfx-rs/wgpu.git
synced 2025-02-21 19:32:49 +00:00
Refactored tracking, now includes the views
This commit is contained in:
parent
7386a05a0d
commit
c21420399a
@ -18,6 +18,7 @@ crate-type = ["lib", "cdylib", "staticlib"]
|
||||
[features]
|
||||
default = []
|
||||
local = ["winit", "gfx-backend-empty/winit"]
|
||||
metal-auto-capture = ["gfx-backend-metal/auto-capture"]
|
||||
|
||||
[dependencies]
|
||||
bitflags = "1.0"
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::track::{BufferTracker, TextureTracker};
|
||||
use crate::track::TrackerSet;
|
||||
use crate::{
|
||||
LifeGuard, WeaklyStored,
|
||||
BindGroupLayoutId, BufferId, SamplerId, TextureViewId,
|
||||
@ -84,6 +84,5 @@ pub struct BindGroup<B: hal::Backend> {
|
||||
pub(crate) raw: B::DescriptorSet,
|
||||
pub(crate) layout_id: WeaklyStored<BindGroupLayoutId>,
|
||||
pub(crate) life_guard: LifeGuard,
|
||||
pub(crate) used_buffers: BufferTracker,
|
||||
pub(crate) used_textures: TextureTracker,
|
||||
pub(crate) used: TrackerSet,
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
use super::CommandBuffer;
|
||||
use crate::track::Tracker;
|
||||
use crate::track::TrackerSet;
|
||||
use crate::{DeviceId, LifeGuard, Stored, SubmissionIndex};
|
||||
|
||||
use hal::command::RawCommandBuffer;
|
||||
@ -86,8 +86,7 @@ impl<B: hal::Backend> CommandAllocator<B> {
|
||||
recorded_thread_id: thread_id,
|
||||
device_id,
|
||||
life_guard: LifeGuard::new(),
|
||||
buffer_tracker: Tracker::new(),
|
||||
texture_tracker: Tracker::new(),
|
||||
trackers: TrackerSet::new(),
|
||||
swap_chain_links: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::command::bind::{Binder};
|
||||
use crate::hub::HUB;
|
||||
use crate::track::{BufferTracker, TextureTracker};
|
||||
use crate::track::TrackerSet;
|
||||
use crate::{
|
||||
Stored, CommandBuffer,
|
||||
BindGroupId, CommandBufferId, ComputePassId, ComputePipelineId,
|
||||
@ -16,8 +16,7 @@ pub struct ComputePass<B: hal::Backend> {
|
||||
raw: B::CommandBuffer,
|
||||
cmb_id: Stored<CommandBufferId>,
|
||||
binder: Binder,
|
||||
buffer_tracker: BufferTracker,
|
||||
texture_tracker: TextureTracker,
|
||||
trackers: TrackerSet,
|
||||
}
|
||||
|
||||
impl<B: hal::Backend> ComputePass<B> {
|
||||
@ -26,8 +25,7 @@ impl<B: hal::Backend> ComputePass<B> {
|
||||
raw,
|
||||
cmb_id,
|
||||
binder: Binder::default(),
|
||||
buffer_tracker: BufferTracker::new(),
|
||||
texture_tracker: TextureTracker::new(),
|
||||
trackers: TrackerSet::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -36,6 +34,8 @@ impl<B: hal::Backend> ComputePass<B> {
|
||||
pub extern "C" fn wgpu_compute_pass_end_pass(pass_id: ComputePassId) -> CommandBufferId {
|
||||
let pass = HUB.compute_passes.unregister(pass_id);
|
||||
|
||||
//TODO: transitions?
|
||||
|
||||
HUB.command_buffers
|
||||
.write()
|
||||
.get_mut(pass.cmb_id.value)
|
||||
@ -69,13 +69,15 @@ pub extern "C" fn wgpu_compute_pass_set_bind_group(
|
||||
//Note: currently, WebGPU compute passes have synchronization defined
|
||||
// at a dispatch granularity, so we insert the necessary barriers here.
|
||||
|
||||
//TODO: have `TrackerSet::consume()` ?
|
||||
CommandBuffer::insert_barriers(
|
||||
&mut pass.raw,
|
||||
pass.buffer_tracker.consume_by_replace(&bind_group.used_buffers),
|
||||
pass.texture_tracker.consume_by_replace(&bind_group.used_textures),
|
||||
pass.trackers.buffers.consume_by_replace(&bind_group.used.buffers),
|
||||
pass.trackers.textures.consume_by_replace(&bind_group.used.textures),
|
||||
&*HUB.buffers.read(),
|
||||
&*HUB.textures.read(),
|
||||
);
|
||||
pass.trackers.views.consume(&bind_group.used.views);
|
||||
|
||||
if let Some(pipeline_layout_id) = pass.binder.provide_entry(index as usize, bind_group_id, bind_group) {
|
||||
let pipeline_layout_guard = HUB.pipeline_layouts.read();
|
||||
|
@ -15,7 +15,7 @@ use crate::device::{
|
||||
};
|
||||
use crate::hub::{HUB, Storage};
|
||||
use crate::swap_chain::{SwapChainLink, SwapImageEpoch};
|
||||
use crate::track::{BufferTracker, TextureTracker};
|
||||
use crate::track::TrackerSet;
|
||||
use crate::conv;
|
||||
use crate::{
|
||||
BufferHandle, TextureHandle,
|
||||
@ -85,8 +85,7 @@ pub struct CommandBuffer<B: hal::Backend> {
|
||||
recorded_thread_id: ThreadId,
|
||||
device_id: Stored<DeviceId>,
|
||||
pub(crate) life_guard: LifeGuard,
|
||||
pub(crate) buffer_tracker: BufferTracker,
|
||||
pub(crate) texture_tracker: TextureTracker,
|
||||
pub(crate) trackers: TrackerSet,
|
||||
pub(crate) swap_chain_links: Vec<SwapChainLink<SwapImageEpoch>>,
|
||||
}
|
||||
|
||||
@ -184,7 +183,7 @@ pub fn command_encoder_begin_render_pass(
|
||||
};
|
||||
|
||||
let rp_key = {
|
||||
let tracker = &mut cmb.texture_tracker;
|
||||
let trackers = &mut cmb.trackers;
|
||||
let swap_chain_links = &mut cmb.swap_chain_links;
|
||||
|
||||
let depth_stencil_key = depth_stencil_attachment.map(|at| {
|
||||
@ -194,7 +193,12 @@ pub fn command_encoder_begin_render_pass(
|
||||
} else {
|
||||
extent = Some(view.extent);
|
||||
}
|
||||
let query = tracker.query(&view.texture_id, TextureUsageFlags::empty());
|
||||
trackers.views.query(at.attachment, &view.life_guard.ref_count);
|
||||
let query = trackers.textures.query(
|
||||
view.texture_id.value,
|
||||
&view.texture_id.ref_count,
|
||||
TextureUsageFlags::empty(),
|
||||
);
|
||||
let (_, layout) = conv::map_texture_state(
|
||||
query.usage,
|
||||
hal::format::Aspects::DEPTH | hal::format::Aspects::STENCIL,
|
||||
@ -232,7 +236,12 @@ pub fn command_encoder_begin_render_pass(
|
||||
} else {
|
||||
extent = Some(view.extent);
|
||||
}
|
||||
let query = tracker.query(&view.texture_id, TextureUsageFlags::empty());
|
||||
trackers.views.query(at.attachment, &view.life_guard.ref_count);
|
||||
let query = trackers.textures.query(
|
||||
view.texture_id.value,
|
||||
&view.texture_id.ref_count,
|
||||
TextureUsageFlags::empty(),
|
||||
);
|
||||
let (_, layout) = conv::map_texture_state(query.usage, hal::format::Aspects::COLOR);
|
||||
hal::pass::Attachment {
|
||||
format: Some(conv::map_texture_format(view.format)),
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::command::bind::Binder;
|
||||
use crate::hub::HUB;
|
||||
use crate::resource::BufferUsageFlags;
|
||||
use crate::track::{BufferTracker, TextureTracker};
|
||||
use crate::track::TrackerSet;
|
||||
use crate::{
|
||||
CommandBuffer, Stored,
|
||||
BindGroupId, BufferId, CommandBufferId, RenderPassId, RenderPipelineId,
|
||||
@ -16,8 +16,7 @@ pub struct RenderPass<B: hal::Backend> {
|
||||
raw: B::CommandBuffer,
|
||||
cmb_id: Stored<CommandBufferId>,
|
||||
binder: Binder,
|
||||
buffer_tracker: BufferTracker,
|
||||
texture_tracker: TextureTracker,
|
||||
trackers: TrackerSet,
|
||||
}
|
||||
|
||||
impl<B: hal::Backend> RenderPass<B> {
|
||||
@ -26,8 +25,7 @@ impl<B: hal::Backend> RenderPass<B> {
|
||||
raw,
|
||||
cmb_id,
|
||||
binder: Binder::default(),
|
||||
buffer_tracker: BufferTracker::new(),
|
||||
texture_tracker: TextureTracker::new(),
|
||||
trackers: TrackerSet::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -42,16 +40,27 @@ pub extern "C" fn wgpu_render_pass_end_pass(pass_id: RenderPassId) -> CommandBuf
|
||||
let mut cmb_guard = HUB.command_buffers.write();
|
||||
let cmb = cmb_guard.get_mut(pass.cmb_id.value);
|
||||
|
||||
if let Some(ref mut last) = cmb.raw.last_mut() {
|
||||
CommandBuffer::insert_barriers(
|
||||
last,
|
||||
cmb.buffer_tracker.consume_by_replace(&pass.buffer_tracker),
|
||||
cmb.texture_tracker.consume_by_replace(&pass.texture_tracker),
|
||||
&*HUB.buffers.read(),
|
||||
&*HUB.textures.read(),
|
||||
);
|
||||
unsafe { last.finish() };
|
||||
match cmb.raw.last_mut() {
|
||||
Some(ref mut last) => {
|
||||
CommandBuffer::insert_barriers(
|
||||
last,
|
||||
cmb.trackers.buffers.consume_by_replace(&pass.trackers.buffers),
|
||||
cmb.trackers.textures.consume_by_replace(&pass.trackers.textures),
|
||||
&*HUB.buffers.read(),
|
||||
&*HUB.textures.read(),
|
||||
);
|
||||
unsafe { last.finish() };
|
||||
}
|
||||
None => {
|
||||
cmb.trackers.buffers
|
||||
.consume_by_extend(&pass.trackers.buffers)
|
||||
.unwrap();
|
||||
cmb.trackers.textures
|
||||
.consume_by_extend(&pass.trackers.textures)
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
cmb.trackers.views.consume(&pass.trackers.views);
|
||||
|
||||
cmb.raw.push(pass.raw);
|
||||
pass.cmb_id.value
|
||||
@ -65,7 +74,7 @@ pub extern "C" fn wgpu_render_pass_set_index_buffer(
|
||||
let buffer_guard = HUB.buffers.read();
|
||||
|
||||
let pass = pass_guard.get_mut(pass_id);
|
||||
let buffer = pass.buffer_tracker
|
||||
let buffer = pass.trackers.buffers
|
||||
.get_with_extended_usage(
|
||||
&*buffer_guard,
|
||||
buffer_id,
|
||||
@ -102,7 +111,7 @@ pub extern "C" fn wgpu_render_pass_set_vertex_buffers(
|
||||
|
||||
let pass = pass_guard.get_mut(pass_id);
|
||||
for &id in buffers {
|
||||
pass.buffer_tracker
|
||||
pass.trackers.buffers
|
||||
.get_with_extended_usage(
|
||||
&*buffer_guard,
|
||||
id,
|
||||
@ -174,12 +183,13 @@ pub extern "C" fn wgpu_render_pass_set_bind_group(
|
||||
let bind_group_guard = HUB.bind_groups.read();
|
||||
let bind_group = bind_group_guard.get(bind_group_id);
|
||||
|
||||
pass.buffer_tracker
|
||||
.consume_by_extend(&bind_group.used_buffers)
|
||||
pass.trackers.buffers
|
||||
.consume_by_extend(&bind_group.used.buffers)
|
||||
.unwrap();
|
||||
pass.texture_tracker
|
||||
.consume_by_extend(&bind_group.used_textures)
|
||||
pass.trackers.textures
|
||||
.consume_by_extend(&bind_group.used.textures)
|
||||
.unwrap();
|
||||
pass.trackers.views.consume(&bind_group.used.views);
|
||||
|
||||
if let Some(pipeline_layout_id) = pass.binder.provide_entry(index as usize, bind_group_id, bind_group) {
|
||||
let pipeline_layout_guard = HUB.pipeline_layouts.read();
|
||||
|
@ -45,7 +45,7 @@ pub extern "C" fn wgpu_command_buffer_copy_buffer_to_buffer(
|
||||
let cmb = cmb_guard.get_mut(command_buffer_id);
|
||||
let buffer_guard = HUB.buffers.read();
|
||||
|
||||
let (src_buffer, src_usage) = cmb.buffer_tracker
|
||||
let (src_buffer, src_usage) = cmb.trackers.buffers
|
||||
.get_with_replaced_usage(
|
||||
&*buffer_guard,
|
||||
src,
|
||||
@ -59,7 +59,7 @@ pub extern "C" fn wgpu_command_buffer_copy_buffer_to_buffer(
|
||||
range: None .. None,
|
||||
});
|
||||
|
||||
let (dst_buffer, dst_usage) = cmb.buffer_tracker
|
||||
let (dst_buffer, dst_usage) = cmb.trackers.buffers
|
||||
.get_with_replaced_usage(
|
||||
&*buffer_guard,
|
||||
dst,
|
||||
@ -105,7 +105,7 @@ pub extern "C" fn wgpu_command_buffer_copy_buffer_to_texture(
|
||||
let buffer_guard = HUB.buffers.read();
|
||||
let texture_guard = HUB.textures.read();
|
||||
|
||||
let (src_buffer, src_usage) = cmb.buffer_tracker
|
||||
let (src_buffer, src_usage) = cmb.trackers.buffers
|
||||
.get_with_replaced_usage(
|
||||
&*buffer_guard,
|
||||
source.buffer,
|
||||
@ -119,7 +119,7 @@ pub extern "C" fn wgpu_command_buffer_copy_buffer_to_texture(
|
||||
range: None .. None,
|
||||
});
|
||||
|
||||
let (dst_texture, dst_usage) = cmb.texture_tracker
|
||||
let (dst_texture, dst_usage) = cmb.trackers.textures
|
||||
.get_with_replaced_usage(
|
||||
&*texture_guard,
|
||||
destination.texture,
|
||||
@ -188,7 +188,7 @@ pub extern "C" fn wgpu_command_buffer_copy_texture_to_buffer(
|
||||
let buffer_guard = HUB.buffers.read();
|
||||
let texture_guard = HUB.textures.read();
|
||||
|
||||
let (src_texture, src_usage) = cmb.texture_tracker
|
||||
let (src_texture, src_usage) = cmb.trackers.textures
|
||||
.get_with_replaced_usage(
|
||||
&*texture_guard,
|
||||
source.texture,
|
||||
@ -205,7 +205,7 @@ pub extern "C" fn wgpu_command_buffer_copy_texture_to_buffer(
|
||||
});
|
||||
assert!(src_texture.swap_chain_link.is_none()); //TODO
|
||||
|
||||
let (dst_buffer, dst_usage) = cmb.buffer_tracker
|
||||
let (dst_buffer, dst_usage) = cmb.trackers.buffers
|
||||
.get_with_replaced_usage(
|
||||
&*buffer_guard,
|
||||
destination.buffer,
|
||||
@ -263,14 +263,14 @@ pub extern "C" fn wgpu_command_buffer_copy_texture_to_texture(
|
||||
let cmb = cmb_guard.get_mut(command_buffer_id);
|
||||
let texture_guard = HUB.textures.read();
|
||||
|
||||
let (src_texture, src_usage) = cmb.texture_tracker
|
||||
let (src_texture, src_usage) = cmb.trackers.textures
|
||||
.get_with_replaced_usage(
|
||||
&*texture_guard,
|
||||
source.texture,
|
||||
TextureUsageFlags::TRANSFER_SRC,
|
||||
)
|
||||
.unwrap();
|
||||
let (dst_texture, dst_usage) = cmb.texture_tracker
|
||||
let (dst_texture, dst_usage) = cmb.trackers.textures
|
||||
.get_with_replaced_usage(
|
||||
&*texture_guard,
|
||||
destination.texture,
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::{binding_model, command, conv, pipeline, resource, swap_chain};
|
||||
use crate::hub::HUB;
|
||||
use crate::track::{BufferTracker, TextureTracker, TrackPermit};
|
||||
use crate::track::{TrackerSet, TrackPermit};
|
||||
use crate::{
|
||||
LifeGuard, RefCount, Stored, SubmissionIndex, WeaklyStored,
|
||||
};
|
||||
@ -64,6 +64,7 @@ pub(crate) struct FramebufferKey {
|
||||
}
|
||||
impl Eq for FramebufferKey {}
|
||||
|
||||
#[derive(Debug)]
|
||||
enum ResourceId {
|
||||
Buffer(BufferId),
|
||||
Texture(TextureId),
|
||||
@ -140,29 +141,32 @@ impl<B: hal::Backend> DestroyedResources<B> {
|
||||
impl DestroyedResources<back::Backend> {
|
||||
fn triage_referenced(
|
||||
&mut self,
|
||||
buffer_tracker: &mut BufferTracker,
|
||||
texture_tracker: &mut TextureTracker,
|
||||
trackers: &mut TrackerSet,
|
||||
) {
|
||||
for i in (0..self.referenced.len()).rev() {
|
||||
// one in resource itself, and one here in this list
|
||||
let num_refs = self.referenced[i].1.load();
|
||||
if num_refs <= 2 {
|
||||
assert_eq!(num_refs, 2);
|
||||
// Before destruction, a resource is expected to have the following strong refs:
|
||||
// 1. in resource itself
|
||||
// 2. in the device tracker
|
||||
// 3. in this list
|
||||
if num_refs <= 3 {
|
||||
let resource_id = self.referenced.swap_remove(i).0;
|
||||
assert_eq!(num_refs, 3, "Resource {:?} misses some references", resource_id);
|
||||
let (submit_index, resource) = match resource_id {
|
||||
ResourceId::Buffer(id) => {
|
||||
buffer_tracker.remove(id);
|
||||
trackers.buffers.remove(id);
|
||||
let buf = HUB.buffers.unregister(id);
|
||||
let si = buf.life_guard.submission_index.load(Ordering::Acquire);
|
||||
(si, Resource::Buffer(buf))
|
||||
}
|
||||
ResourceId::Texture(id) => {
|
||||
texture_tracker.remove(id);
|
||||
trackers.textures.remove(id);
|
||||
let tex = HUB.textures.unregister(id);
|
||||
let si = tex.life_guard.submission_index.load(Ordering::Acquire);
|
||||
(si, Resource::Texture(tex))
|
||||
}
|
||||
ResourceId::TextureView(id) => {
|
||||
trackers.views.remove(id);
|
||||
let view = HUB.texture_views.unregister(id);
|
||||
let si = view.life_guard.submission_index.load(Ordering::Acquire);
|
||||
(si, Resource::TextureView(view))
|
||||
@ -189,8 +193,7 @@ pub struct Device<B: hal::Backend> {
|
||||
//mem_allocator: Heaps<B::Memory>,
|
||||
pub(crate) com_allocator: command::CommandAllocator<B>,
|
||||
life_guard: LifeGuard,
|
||||
buffer_tracker: Mutex<BufferTracker>,
|
||||
pub(crate) texture_tracker: Mutex<TextureTracker>,
|
||||
pub(crate) trackers: Mutex<TrackerSet>,
|
||||
mem_props: hal::MemoryProperties,
|
||||
pub(crate) render_passes: Mutex<HashMap<RenderPassKey, B::RenderPass>>,
|
||||
pub(crate) framebuffers: Mutex<HashMap<FramebufferKey, B::Framebuffer>>,
|
||||
@ -264,8 +267,7 @@ impl<B: hal::Backend> Device<B> {
|
||||
com_allocator: command::CommandAllocator::new(queue_group.family()),
|
||||
queue_group,
|
||||
life_guard,
|
||||
buffer_tracker: Mutex::new(BufferTracker::new()),
|
||||
texture_tracker: Mutex::new(TextureTracker::new()),
|
||||
trackers: Mutex::new(TrackerSet::new()),
|
||||
mem_props,
|
||||
render_passes: Mutex::new(HashMap::new()),
|
||||
framebuffers: Mutex::new(HashMap::new()),
|
||||
@ -343,12 +345,10 @@ pub fn device_track_buffer(
|
||||
let query = HUB.devices
|
||||
.read()
|
||||
.get(device_id)
|
||||
.buffer_tracker
|
||||
.trackers
|
||||
.lock()
|
||||
.query(
|
||||
&Stored { value: buffer_id, ref_count },
|
||||
resource::BufferUsageFlags::empty(),
|
||||
);
|
||||
.buffers
|
||||
.query(buffer_id, &ref_count, resource::BufferUsageFlags::empty());
|
||||
assert!(query.initialized);
|
||||
}
|
||||
|
||||
@ -458,12 +458,10 @@ pub fn device_track_texture(
|
||||
let query = HUB.devices
|
||||
.read()
|
||||
.get(device_id)
|
||||
.texture_tracker
|
||||
.trackers
|
||||
.lock()
|
||||
.query(
|
||||
&Stored { value: texture_id, ref_count },
|
||||
resource::TextureUsageFlags::UNINITIALIZED,
|
||||
);
|
||||
.textures
|
||||
.query(texture_id, &ref_count, resource::TextureUsageFlags::UNINITIALIZED);
|
||||
assert!(query.initialized);
|
||||
}
|
||||
|
||||
@ -520,6 +518,26 @@ pub fn texture_create_view(
|
||||
}
|
||||
}
|
||||
|
||||
pub fn device_track_view(
|
||||
texture_id: TextureId,
|
||||
view_id: BufferId,
|
||||
ref_count: RefCount,
|
||||
) {
|
||||
let device_id = HUB.textures
|
||||
.read()
|
||||
.get(texture_id)
|
||||
.device_id
|
||||
.value;
|
||||
let initialized = HUB.devices
|
||||
.read()
|
||||
.get(device_id)
|
||||
.trackers
|
||||
.lock()
|
||||
.views
|
||||
.query(view_id, &ref_count);
|
||||
assert!(initialized);
|
||||
}
|
||||
|
||||
#[cfg(feature = "local")]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn wgpu_texture_create_view(
|
||||
@ -527,7 +545,11 @@ pub extern "C" fn wgpu_texture_create_view(
|
||||
desc: &resource::TextureViewDescriptor,
|
||||
) -> TextureViewId {
|
||||
let view = texture_create_view(texture_id, desc);
|
||||
HUB.texture_views.register(view)
|
||||
let texture_id = view.texture_id.value;
|
||||
let ref_count = view.life_guard.ref_count.clone();
|
||||
let id = HUB.texture_views.register(view);
|
||||
device_track_view(texture_id, id, ref_count);
|
||||
id
|
||||
}
|
||||
|
||||
pub fn texture_create_default_view(
|
||||
@ -537,8 +559,10 @@ pub fn texture_create_default_view(
|
||||
let texture = texture_guard.get(texture_id);
|
||||
|
||||
let view_kind = match texture.kind {
|
||||
hal::image::Kind::D1(..) => hal::image::ViewKind::D1,
|
||||
hal::image::Kind::D2(..) => hal::image::ViewKind::D2, //TODO: array
|
||||
hal::image::Kind::D1(_, 1) => hal::image::ViewKind::D1,
|
||||
hal::image::Kind::D1(..) => hal::image::ViewKind::D1Array,
|
||||
hal::image::Kind::D2(_, _, 1, _) => hal::image::ViewKind::D2,
|
||||
hal::image::Kind::D2(..) => hal::image::ViewKind::D2Array,
|
||||
hal::image::Kind::D3(..) => hal::image::ViewKind::D3,
|
||||
};
|
||||
|
||||
@ -575,7 +599,11 @@ pub fn texture_create_default_view(
|
||||
#[no_mangle]
|
||||
pub extern "C" fn wgpu_texture_create_default_view(texture_id: TextureId) -> TextureViewId {
|
||||
let view = texture_create_default_view(texture_id);
|
||||
HUB.texture_views.register(view)
|
||||
let texture_id = view.texture_id.value;
|
||||
let ref_count = view.life_guard.ref_count.clone();
|
||||
let id = HUB.texture_views.register(view);
|
||||
device_track_view(texture_id, id, ref_count);
|
||||
id
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
@ -679,7 +707,7 @@ pub fn device_create_bind_group_layout(
|
||||
hal::pso::DescriptorSetLayoutBinding {
|
||||
binding: binding.binding,
|
||||
ty: conv::map_binding_type(binding.ty),
|
||||
count: bindings.len(),
|
||||
count: 1, //TODO: consolidate
|
||||
stage_flags: conv::map_shader_stage_flags(binding.visibility),
|
||||
immutable_samplers: false, // TODO
|
||||
}
|
||||
@ -771,12 +799,11 @@ pub fn device_create_bind_group(
|
||||
|
||||
//TODO: group writes into contiguous sections
|
||||
let mut writes = Vec::new();
|
||||
let mut used_buffers = BufferTracker::new();
|
||||
let mut used_textures = TextureTracker::new();
|
||||
let mut used = TrackerSet::new();
|
||||
for b in bindings {
|
||||
let descriptor = match b.resource {
|
||||
binding_model::BindingResource::Buffer(ref bb) => {
|
||||
let buffer = used_buffers
|
||||
let buffer = used.buffers
|
||||
.get_with_extended_usage(
|
||||
&*buffer_guard,
|
||||
bb.buffer,
|
||||
@ -792,7 +819,8 @@ pub fn device_create_bind_group(
|
||||
}
|
||||
binding_model::BindingResource::TextureView(id) => {
|
||||
let view = texture_view_guard.get(id);
|
||||
used_textures
|
||||
used.views.query(id, &view.life_guard.ref_count);
|
||||
used.textures
|
||||
.transit(
|
||||
view.texture_id.value,
|
||||
&view.texture_id.ref_count,
|
||||
@ -820,8 +848,7 @@ pub fn device_create_bind_group(
|
||||
raw: desc_set,
|
||||
layout_id: WeaklyStored(desc.layout),
|
||||
life_guard: LifeGuard::new(),
|
||||
used_buffers,
|
||||
used_textures,
|
||||
used,
|
||||
}
|
||||
}
|
||||
|
||||
@ -916,8 +943,7 @@ pub extern "C" fn wgpu_queue_submit(
|
||||
.life_guard
|
||||
.submission_index
|
||||
.fetch_add(1, Ordering::Relaxed);
|
||||
let mut buffer_tracker = device.buffer_tracker.lock();
|
||||
let mut texture_tracker = device.texture_tracker.lock();
|
||||
let mut trackers = device.trackers.lock();
|
||||
|
||||
//TODO: if multiple command buffers are submitted, we can re-use the last
|
||||
// native command buffer of the previous chain instead of always creating
|
||||
@ -934,14 +960,14 @@ pub extern "C" fn wgpu_queue_submit(
|
||||
// update submission IDs
|
||||
comb.life_guard.submission_index
|
||||
.store(old_submit_index, Ordering::Release);
|
||||
for id in comb.buffer_tracker.used() {
|
||||
for id in comb.trackers.buffers.used() {
|
||||
buffer_guard
|
||||
.get(id)
|
||||
.life_guard
|
||||
.submission_index
|
||||
.store(old_submit_index, Ordering::Release);
|
||||
}
|
||||
for id in comb.texture_tracker.used() {
|
||||
for id in comb.trackers.textures.used() {
|
||||
texture_guard
|
||||
.get(id)
|
||||
.life_guard
|
||||
@ -958,13 +984,15 @@ pub extern "C" fn wgpu_queue_submit(
|
||||
);
|
||||
}
|
||||
//TODO: fix the consume
|
||||
let TrackerSet { ref mut buffers, ref mut textures, ref mut views } = *trackers;
|
||||
command::CommandBuffer::insert_barriers(
|
||||
&mut transit,
|
||||
buffer_tracker.consume_by_replace(&comb.buffer_tracker),
|
||||
texture_tracker.consume_by_replace(&comb.texture_tracker),
|
||||
buffers.consume_by_replace(&comb.trackers.buffers),
|
||||
textures.consume_by_replace(&comb.trackers.textures),
|
||||
&*buffer_guard,
|
||||
&*texture_guard,
|
||||
);
|
||||
views.consume(&comb.trackers.views);
|
||||
unsafe {
|
||||
transit.finish();
|
||||
}
|
||||
@ -1014,7 +1042,7 @@ pub extern "C" fn wgpu_queue_submit(
|
||||
|
||||
let last_done = {
|
||||
let mut destroyed = device.destroyed.lock();
|
||||
destroyed.triage_referenced(&mut *buffer_tracker, &mut *texture_tracker);
|
||||
destroyed.triage_referenced(&mut *trackers);
|
||||
let last_done = destroyed.cleanup(&device.raw);
|
||||
|
||||
destroyed.active.push(ActiveSubmission {
|
||||
@ -1435,6 +1463,7 @@ fn swap_chain_populate_textures(
|
||||
.unwrap();
|
||||
let device_guard = HUB.devices.read();
|
||||
let device = device_guard.get(swap_chain.device_id.value);
|
||||
let mut trackers = device.trackers.lock();
|
||||
|
||||
for (i, mut texture) in textures.into_iter().enumerate() {
|
||||
let format = texture.format;
|
||||
@ -1460,9 +1489,11 @@ fn swap_chain_populate_textures(
|
||||
ref_count: texture.life_guard.ref_count.clone(),
|
||||
value: HUB.textures.register(texture),
|
||||
};
|
||||
device.texture_tracker
|
||||
.lock()
|
||||
.query(&texture_id, resource::TextureUsageFlags::UNINITIALIZED);
|
||||
trackers.textures.query(
|
||||
texture_id.value,
|
||||
&texture_id.ref_count,
|
||||
resource::TextureUsageFlags::UNINITIALIZED,
|
||||
);
|
||||
|
||||
let view = resource::TextureView {
|
||||
raw: view_raw,
|
||||
@ -1473,12 +1504,18 @@ fn swap_chain_populate_textures(
|
||||
is_owned_by_swap_chain: true,
|
||||
life_guard: LifeGuard::new(),
|
||||
};
|
||||
let view_id = Stored {
|
||||
ref_count: view.life_guard.ref_count.clone(),
|
||||
value: HUB.texture_views.register(view),
|
||||
};
|
||||
trackers.views.query(
|
||||
view_id.value,
|
||||
&view_id.ref_count,
|
||||
);
|
||||
|
||||
swap_chain.frames.push(swap_chain::Frame {
|
||||
texture_id,
|
||||
view_id: Stored {
|
||||
ref_count: view.life_guard.ref_count.clone(),
|
||||
value: HUB.texture_views.register(view),
|
||||
},
|
||||
view_id,
|
||||
fence: device.raw.create_fence(true).unwrap(),
|
||||
sem_available: device.raw.create_semaphore().unwrap(),
|
||||
sem_present: device.raw.create_semaphore().unwrap(),
|
||||
@ -1507,6 +1544,8 @@ pub extern "C" fn wgpu_device_create_swap_chain(
|
||||
ref_count: outdated_view.life_guard.ref_count.clone(),
|
||||
value: HUB.texture_views.register(outdated_view),
|
||||
};
|
||||
device_track_view(texture_id.value, view_id.value, view_id.ref_count.clone());
|
||||
|
||||
swap_chain::OutdatedFrame {
|
||||
texture_id,
|
||||
view_id,
|
||||
@ -1532,8 +1571,9 @@ pub extern "C" fn wgpu_buffer_set_sub_data(
|
||||
//Note: this is just doing `update_buffer`, which is limited to 64KB
|
||||
|
||||
trace!("transit {:?} to transfer dst", buffer_id);
|
||||
let barrier = device.buffer_tracker
|
||||
let barrier = device.trackers
|
||||
.lock()
|
||||
.buffers
|
||||
.transit(
|
||||
buffer_id,
|
||||
&buffer.life_guard.ref_count,
|
||||
@ -1581,3 +1621,8 @@ pub extern "C" fn wgpu_buffer_set_sub_data(
|
||||
|
||||
device.com_allocator.after_submit(comb);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn wgpu_device_destroy(device_id: BufferId) {
|
||||
HUB.devices.unregister(device_id);
|
||||
}
|
@ -51,6 +51,10 @@ type SubmissionIndex = usize;
|
||||
#[derive(Debug)]
|
||||
pub struct RefCount(ptr::NonNull<AtomicUsize>);
|
||||
|
||||
unsafe impl Send for RefCount {}
|
||||
unsafe impl Sync for RefCount {}
|
||||
|
||||
|
||||
impl RefCount {
|
||||
const MAX: usize = 1 << 24;
|
||||
|
||||
@ -80,10 +84,6 @@ struct LifeGuard {
|
||||
submission_index: AtomicUsize,
|
||||
}
|
||||
|
||||
//TODO: reconsider this
|
||||
unsafe impl Send for LifeGuard {}
|
||||
unsafe impl Sync for LifeGuard {}
|
||||
|
||||
impl LifeGuard {
|
||||
fn new() -> Self {
|
||||
let bx = Box::new(AtomicUsize::new(1));
|
||||
@ -100,9 +100,6 @@ struct Stored<T> {
|
||||
ref_count: RefCount,
|
||||
}
|
||||
|
||||
unsafe impl<T> Send for Stored<T> {}
|
||||
unsafe impl<T> Sync for Stored<T> {}
|
||||
|
||||
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
|
||||
struct WeaklyStored<T>(T);
|
||||
|
||||
|
@ -138,12 +138,13 @@ pub struct TextureViewDescriptor {
|
||||
pub struct TextureView<B: hal::Backend> {
|
||||
pub(crate) raw: B::ImageView,
|
||||
pub(crate) texture_id: Stored<TextureId>,
|
||||
//TODO: store device_id for quick access?
|
||||
pub(crate) format: TextureFormat,
|
||||
pub(crate) extent: hal::image::Extent,
|
||||
pub(crate) samples: hal::image::NumSamples,
|
||||
pub(crate) is_owned_by_swap_chain: bool,
|
||||
#[cfg_attr(not(feature = "local"), allow(dead_code))]
|
||||
pub(crate) life_guard: LifeGuard, //TODO: use
|
||||
pub(crate) life_guard: LifeGuard,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
|
@ -179,8 +179,9 @@ pub extern "C" fn wgpu_swap_chain_present(
|
||||
//TODO: support for swapchain being sampled or read by the shader?
|
||||
|
||||
trace!("transit {:?} to present", frame.texture_id.value);
|
||||
let barrier = device.texture_tracker
|
||||
let barrier = device.trackers
|
||||
.lock()
|
||||
.textures
|
||||
.transit(
|
||||
frame.texture_id.value,
|
||||
&texture.life_guard.ref_count,
|
||||
|
@ -1,14 +1,18 @@
|
||||
use crate::hub::{Id, Storage};
|
||||
use crate::resource::{BufferUsageFlags, TextureUsageFlags};
|
||||
use crate::{BufferId, RefCount, Stored, TextureId, WeaklyStored};
|
||||
use crate::{
|
||||
RefCount, WeaklyStored,
|
||||
BufferId, TextureId, TextureViewId,
|
||||
};
|
||||
|
||||
use std::borrow::Borrow;
|
||||
use std::collections::hash_map::{Entry, HashMap};
|
||||
use std::collections::hash_map::Entry;
|
||||
use std::hash::Hash;
|
||||
use std::mem;
|
||||
use std::ops::{BitOr, Range};
|
||||
|
||||
use bitflags::bitflags;
|
||||
use hal::backend::FastHashMap;
|
||||
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
@ -70,20 +74,38 @@ struct Track<U> {
|
||||
last: U,
|
||||
}
|
||||
|
||||
unsafe impl<U> Send for Track<U> {}
|
||||
unsafe impl<U> Sync for Track<U> {}
|
||||
|
||||
//TODO: consider having `I` as an associated type of `U`?
|
||||
pub struct Tracker<I, U> {
|
||||
map: HashMap<WeaklyStored<I>, Track<U>>,
|
||||
map: FastHashMap<WeaklyStored<I>, Track<U>>,
|
||||
}
|
||||
pub type BufferTracker = Tracker<BufferId, BufferUsageFlags>;
|
||||
pub type TextureTracker = Tracker<TextureId, TextureUsageFlags>;
|
||||
pub struct DummyTracker<I> {
|
||||
map: FastHashMap<WeaklyStored<I>, RefCount>,
|
||||
}
|
||||
pub type TextureViewTracker = DummyTracker<TextureViewId>;
|
||||
|
||||
impl<I: Clone + Hash + Eq, U: Copy + GenericUsage + BitOr<Output = U> + PartialEq> Tracker<I, U> {
|
||||
pub struct TrackerSet {
|
||||
pub buffers: BufferTracker,
|
||||
pub textures: TextureTracker,
|
||||
pub views: TextureViewTracker,
|
||||
//TODO: samplers
|
||||
}
|
||||
|
||||
impl TrackerSet {
|
||||
pub fn new() -> Self {
|
||||
Tracker {
|
||||
map: HashMap::new(),
|
||||
TrackerSet {
|
||||
buffers: BufferTracker::new(),
|
||||
textures: TextureTracker::new(),
|
||||
views: TextureViewTracker::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<I: Clone + Hash + Eq> DummyTracker<I> {
|
||||
pub fn new() -> Self {
|
||||
DummyTracker {
|
||||
map: FastHashMap::default(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -93,11 +115,42 @@ impl<I: Clone + Hash + Eq, U: Copy + GenericUsage + BitOr<Output = U> + PartialE
|
||||
}
|
||||
|
||||
/// Get the last usage on a resource.
|
||||
pub(crate) fn query(&mut self, stored: &Stored<I>, default: U) -> Query<U> {
|
||||
match self.map.entry(WeaklyStored(stored.value.clone())) {
|
||||
pub(crate) fn query(&mut self, id: I, ref_count: &RefCount) -> bool {
|
||||
match self.map.entry(WeaklyStored(id)) {
|
||||
Entry::Vacant(e) => {
|
||||
e.insert(ref_count.clone());
|
||||
true
|
||||
}
|
||||
Entry::Occupied(_) => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Consume another tacker.
|
||||
pub fn consume(&mut self, other: &Self) {
|
||||
for (id, ref_count) in &other.map {
|
||||
self.query(id.0.clone(), ref_count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<I: Clone + Hash + Eq, U: Copy + GenericUsage + BitOr<Output = U> + PartialEq> Tracker<I, U> {
|
||||
pub fn new() -> Self {
|
||||
Tracker {
|
||||
map: FastHashMap::default(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Remove an id from the tracked map.
|
||||
pub(crate) fn remove(&mut self, id: I) -> bool {
|
||||
self.map.remove(&WeaklyStored(id)).is_some()
|
||||
}
|
||||
|
||||
/// 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(WeaklyStored(id)) {
|
||||
Entry::Vacant(e) => {
|
||||
e.insert(Track {
|
||||
ref_count: stored.ref_count.clone(),
|
||||
ref_count: ref_count.clone(),
|
||||
init: default,
|
||||
last: default,
|
||||
});
|
||||
|
@ -16,6 +16,7 @@ license = "MPL-2.0"
|
||||
|
||||
[features]
|
||||
default = []
|
||||
metal-auto-capture = ["wgpu-native/metal-auto-capture"]
|
||||
metal = ["wgpu-native/gfx-backend-metal"]
|
||||
dx11 = ["wgpu-native/gfx-backend-dx11"]
|
||||
dx12 = ["wgpu-native/gfx-backend-dx12"]
|
||||
|
@ -443,6 +443,14 @@ impl Device {
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Device {
|
||||
fn drop(&mut self) {
|
||||
//TODO: make this work in general
|
||||
#[cfg(feature = "metal-auto-capture")]
|
||||
wgn::wgpu_device_destroy(self.id);
|
||||
}
|
||||
}
|
||||
|
||||
impl Buffer {
|
||||
pub fn set_sub_data(&self, offset: u32, data: &[u8]) {
|
||||
wgn::wgpu_buffer_set_sub_data(self.id, offset, data.len() as u32, data.as_ptr());
|
||||
|
Loading…
Reference in New Issue
Block a user