native: Abstract the binding tracker into a separate module

This commit is contained in:
Dzmitry Malyshau 2019-01-20 15:51:29 -05:00
parent 3ed4620c1f
commit 6699f4bed1
3 changed files with 90 additions and 40 deletions

View File

@ -0,0 +1,76 @@
use crate::registry::{HUB, Items, ConcreteItems};
use crate::{
B, Stored, WeaklyStored,
BindGroup, PipelineLayout,
BindGroupId, BindGroupLayoutId, PipelineLayoutId,
};
use hal;
use parking_lot::RwLockReadGuard;
#[derive(Clone, Default)]
struct BindGroupEntry {
layout: Option<WeaklyStored<BindGroupLayoutId>>,
data: Option<Stored<BindGroupId>>,
}
#[derive(Default)]
pub struct Binder {
pipeline_layout_id: Option<WeaklyStored<PipelineLayoutId>>, //TODO: strongly `Stored`
entries: Vec<BindGroupEntry>,
}
pub struct NewBind<'a, B: hal::Backend> {
pipeline_layout_guard: RwLockReadGuard<'a, ConcreteItems<PipelineLayout<B>>>,
pipeline_layout_id: PipelineLayoutId,
bind_group_guard: RwLockReadGuard<'a, ConcreteItems<BindGroup<B>>>,
bind_group_id: BindGroupId,
}
impl<'a, B: hal::Backend> NewBind<'a, B> {
pub fn pipeline_layout(&self) -> &B::PipelineLayout {
&self.pipeline_layout_guard.get(self.pipeline_layout_id).raw
}
pub fn descriptor_set(&self) -> &B::DescriptorSet {
&self.bind_group_guard.get(self.bind_group_id).raw
}
}
impl Binder {
//Note: `'a` is need to avoid inheriting the lifetime from `self`
pub fn bind_group<'a>(
&mut self, index: u32, bind_group_id: BindGroupId
) -> Option<NewBind<'a, B>> {
let bind_group_guard = HUB.bind_groups.read();
let bind_group = bind_group_guard.get(bind_group_id);
while self.entries.len() <= index as usize {
self.entries.push(BindGroupEntry::default());
}
*self.entries.get_mut(index as usize).unwrap() = BindGroupEntry {
layout: Some(bind_group.layout_id.clone()),
data: Some(Stored {
value: bind_group_id,
ref_count: bind_group.life_guard.ref_count.clone(),
}),
};
if let Some(WeaklyStored(pipeline_layout_id)) = self.pipeline_layout_id {
//TODO: we can cache the group layout ids of the current pipeline in `Binder` itself
let pipeline_layout_guard = HUB.pipeline_layouts.read();
let pipeline_layout = pipeline_layout_guard.get(pipeline_layout_id);
if pipeline_layout.bind_group_layout_ids[index as usize] == bind_group.layout_id {
return Some(NewBind {
pipeline_layout_guard,
pipeline_layout_id,
bind_group_guard,
bind_group_id,
})
}
}
None
}
}

View File

@ -1,9 +1,9 @@
use crate::command::bind::Binder;
use crate::registry::{Items, HUB};
use crate::{
Stored, WeaklyStored,
BindGroupId, CommandBufferId, ComputePassId, ComputePipelineId, PipelineLayoutId,
Stored,
BindGroupId, CommandBufferId, ComputePassId, ComputePipelineId,
};
use super::{BindGroupEntry};
use hal::command::RawCommandBuffer;
@ -13,8 +13,7 @@ use std::iter;
pub struct ComputePass<B: hal::Backend> {
raw: B::CommandBuffer,
cmb_id: Stored<CommandBufferId>,
pipeline_layout_id: Option<WeaklyStored<PipelineLayoutId>>, //TODO: strongly `Stored`
bind_groups: Vec<BindGroupEntry>,
binder: Binder,
}
impl<B: hal::Backend> ComputePass<B> {
@ -22,8 +21,7 @@ impl<B: hal::Backend> ComputePass<B> {
ComputePass {
raw,
cmb_id,
pipeline_layout_id: None,
bind_groups: Vec::new(),
binder: Binder::default(),
}
}
}
@ -48,32 +46,14 @@ pub extern "C" fn wgpu_compute_pass_set_bind_group(
) {
let mut pass_guard = HUB.compute_passes.write();
let pass = pass_guard.get_mut(pass_id);
let bind_group_guard = HUB.bind_groups.read();
let bind_group = bind_group_guard.get(bind_group_id);
let pipeline_layout_guard = HUB.pipeline_layouts.read();
while pass.bind_groups.len() <= index as usize {
pass.bind_groups.push(BindGroupEntry::default());
}
*pass.bind_groups.get_mut(index as usize).unwrap() = BindGroupEntry {
layout: Some(bind_group.layout_id.clone()),
data: Some(Stored {
value: bind_group_id,
ref_count: bind_group.life_guard.ref_count.clone(),
}),
};
if let Some(ref pipeline_layout_id) = pass.pipeline_layout_id {
let pipeline_layout = pipeline_layout_guard.get(pipeline_layout_id.0);
if pipeline_layout.bind_group_layout_ids[index as usize] == bind_group.layout_id {
unsafe {
pass.raw.bind_compute_descriptor_sets(
&pipeline_layout.raw,
index as usize,
iter::once(&bind_group.raw),
&[],
);
}
if let Some(bind) = pass.binder.bind_group(index, bind_group_id) {
unsafe {
pass.raw.bind_compute_descriptor_sets(
bind.pipeline_layout(),
index as usize,
iter::once(bind.descriptor_set()),
&[],
);
}
}
}

View File

@ -1,4 +1,5 @@
mod allocator;
mod bind;
mod compute;
mod render;
@ -13,7 +14,6 @@ use crate::track::{BufferTracker, TextureTracker};
use crate::{conv, resource};
use crate::{
BufferId, CommandBufferId, ComputePassId, DeviceId,
BindGroupId, BindGroupLayoutId,
RenderPassId, TextureId, TextureViewId,
BufferUsageFlags, TextureUsageFlags, Color, Origin3d,
LifeGuard, Stored, WeaklyStored,
@ -30,12 +30,6 @@ use std::slice;
use std::thread::ThreadId;
#[derive(Clone, Default)]
struct BindGroupEntry {
layout: Option<WeaklyStored<BindGroupLayoutId>>,
data: Option<Stored<BindGroupId>>,
}
#[repr(C)]
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
pub enum LoadOp {