mirror of
https://github.com/gfx-rs/wgpu.git
synced 2024-11-25 16:24:24 +00:00
Split the tracker into stateful/stateless to reduce the overhead
This commit is contained in:
parent
f62d0d5edc
commit
7b7e72b1c2
@ -214,7 +214,7 @@ impl RenderBundleEncoder {
|
||||
state.set_bind_group(index, bind_group_id, bind_group.layout_id, offsets);
|
||||
state
|
||||
.trackers
|
||||
.merge_extend(&bind_group.used)
|
||||
.merge_extend_all(&bind_group.used)
|
||||
.map_pass_err(scope)?;
|
||||
}
|
||||
RenderCommand::SetPipeline(pipeline_id) => {
|
||||
|
@ -12,7 +12,7 @@ use crate::{
|
||||
id,
|
||||
memory_init_tracker::{MemoryInitKind, MemoryInitTrackerAction},
|
||||
resource::{Buffer, BufferUse, Texture},
|
||||
track::{TrackerSet, UsageConflict},
|
||||
track::{StatefulTrackerSubset, TrackerSet, UsageConflict},
|
||||
validation::{check_buffer_usage, MissingBufferUsageError},
|
||||
Label, DOWNLEVEL_ERROR_WARNING_MESSAGE,
|
||||
};
|
||||
@ -193,7 +193,7 @@ where
|
||||
struct State {
|
||||
binder: Binder,
|
||||
pipeline: StateChange<id::ComputePipelineId>,
|
||||
trackers: TrackerSet,
|
||||
trackers: StatefulTrackerSubset,
|
||||
debug_scope_depth: u32,
|
||||
}
|
||||
|
||||
@ -223,6 +223,7 @@ impl State {
|
||||
) -> Result<(), UsageConflict> {
|
||||
for id in self.binder.list_active() {
|
||||
self.trackers.merge_extend(&bind_group_guard[id].used)?;
|
||||
base_trackers.merge_extend_stateless(&bind_group_guard[id].used);
|
||||
}
|
||||
|
||||
log::trace!("Encoding dispatch barriers");
|
||||
@ -230,7 +231,8 @@ impl State {
|
||||
CommandBuffer::insert_barriers(
|
||||
raw_cmd_buf,
|
||||
base_trackers,
|
||||
&self.trackers,
|
||||
&self.trackers.buffers,
|
||||
&self.trackers.textures,
|
||||
buffer_guard,
|
||||
texture_guard,
|
||||
);
|
||||
@ -303,7 +305,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
let mut state = State {
|
||||
binder: Binder::new(),
|
||||
pipeline: StateChange::new(),
|
||||
trackers: TrackerSet::new(B::VARIANT),
|
||||
trackers: StatefulTrackerSubset::new(B::VARIANT),
|
||||
debug_scope_depth: 0,
|
||||
};
|
||||
let mut temp_offsets = Vec::new();
|
||||
|
@ -27,7 +27,7 @@ use crate::{
|
||||
id,
|
||||
memory_init_tracker::MemoryInitTrackerAction,
|
||||
resource::{Buffer, Texture},
|
||||
track::TrackerSet,
|
||||
track::{BufferState, ResourceTracker, TextureState, TrackerSet},
|
||||
Label, PrivateFeatures, Stored,
|
||||
};
|
||||
|
||||
@ -74,7 +74,8 @@ impl<B: GfxBackend> CommandBuffer<B> {
|
||||
pub(crate) fn insert_barriers(
|
||||
raw: &mut B::CommandBuffer,
|
||||
base: &mut TrackerSet,
|
||||
head: &TrackerSet,
|
||||
head_buffers: &ResourceTracker<BufferState>,
|
||||
head_textures: &ResourceTracker<TextureState>,
|
||||
buffer_guard: &Storage<Buffer<B>, id::BufferId>,
|
||||
texture_guard: &Storage<Texture<B>, id::TextureId>,
|
||||
) {
|
||||
@ -82,25 +83,17 @@ impl<B: GfxBackend> CommandBuffer<B> {
|
||||
|
||||
profiling::scope!("insert_barriers");
|
||||
debug_assert_eq!(B::VARIANT, base.backend());
|
||||
debug_assert_eq!(B::VARIANT, head.backend());
|
||||
|
||||
let buffer_barriers = base.buffers.merge_replace(&head.buffers).map(|pending| {
|
||||
let buffer_barriers = base.buffers.merge_replace(head_buffers).map(|pending| {
|
||||
let buf = &buffer_guard[pending.id];
|
||||
pending.into_hal(buf)
|
||||
});
|
||||
let texture_barriers = base.textures.merge_replace(&head.textures).map(|pending| {
|
||||
let texture_barriers = base.textures.merge_replace(head_textures).map(|pending| {
|
||||
let tex = &texture_guard[pending.id];
|
||||
pending.into_hal(tex)
|
||||
});
|
||||
base.views.merge_extend(&head.views).unwrap();
|
||||
base.bind_groups.merge_extend(&head.bind_groups).unwrap();
|
||||
base.samplers.merge_extend(&head.samplers).unwrap();
|
||||
base.compute_pipes
|
||||
.merge_extend(&head.compute_pipes)
|
||||
.unwrap();
|
||||
base.render_pipes.merge_extend(&head.render_pipes).unwrap();
|
||||
base.bundles.merge_extend(&head.bundles).unwrap();
|
||||
|
||||
//TODO: be more deliberate about the stages
|
||||
let stages = all_buffer_stages() | all_image_stages();
|
||||
unsafe {
|
||||
raw.pipeline_barrier(
|
||||
|
@ -19,7 +19,7 @@ use crate::{
|
||||
memory_init_tracker::{MemoryInitKind, MemoryInitTrackerAction},
|
||||
pipeline::PipelineFlags,
|
||||
resource::{BufferUse, Texture, TextureUse, TextureView, TextureViewInner},
|
||||
track::{TextureSelector, TrackerSet, UsageConflict},
|
||||
track::{StatefulTrackerSubset, TextureSelector, UsageConflict},
|
||||
validation::{
|
||||
check_buffer_usage, check_texture_usage, MissingBufferUsageError, MissingTextureUsageError,
|
||||
},
|
||||
@ -504,7 +504,7 @@ struct RenderAttachment<'a> {
|
||||
|
||||
struct RenderPassInfo<'a, B: hal::Backend> {
|
||||
context: RenderPassContext,
|
||||
trackers: TrackerSet,
|
||||
trackers: StatefulTrackerSubset,
|
||||
render_attachments: AttachmentDataVec<RenderAttachment<'a>>,
|
||||
used_swap_chain: Option<Stored<id::SwapChainId>>,
|
||||
is_ds_read_only: bool,
|
||||
@ -517,7 +517,7 @@ impl<'a, B: GfxBackend> RenderPassInfo<'a, B> {
|
||||
raw: &mut B::CommandBuffer,
|
||||
color_attachments: &[RenderPassColorAttachment],
|
||||
depth_stencil_attachment: Option<&RenderPassDepthStencilAttachment>,
|
||||
cmd_buf: &CommandBuffer<B>,
|
||||
cmd_buf: &mut CommandBuffer<B>,
|
||||
device: &Device<B>,
|
||||
view_guard: &'a Storage<TextureView<B>, id::TextureViewId>,
|
||||
) -> Result<Self, RenderPassErrorInner> {
|
||||
@ -536,7 +536,6 @@ impl<'a, B: GfxBackend> RenderPassInfo<'a, B> {
|
||||
let mut sample_count = 0;
|
||||
let mut depth_stencil_aspects = hal::format::Aspects::empty();
|
||||
let mut used_swap_chain = None::<Stored<id::SwapChainId>>;
|
||||
let mut trackers = TrackerSet::new(B::VARIANT);
|
||||
|
||||
let mut add_view = |view: &TextureView<B>, type_name| {
|
||||
if let Some(ex) = extent {
|
||||
@ -564,7 +563,8 @@ impl<'a, B: GfxBackend> RenderPassInfo<'a, B> {
|
||||
let rp_key = {
|
||||
let depth_stencil = match depth_stencil_attachment {
|
||||
Some(at) => {
|
||||
let view = trackers
|
||||
let view = cmd_buf
|
||||
.trackers
|
||||
.views
|
||||
.use_extend(&*view_guard, at.view, (), ())
|
||||
.map_err(|_| RenderPassErrorInner::InvalidAttachment(at.view))?;
|
||||
@ -627,7 +627,8 @@ impl<'a, B: GfxBackend> RenderPassInfo<'a, B> {
|
||||
let mut resolves = ArrayVec::new();
|
||||
|
||||
for at in color_attachments {
|
||||
let view = trackers
|
||||
let view = cmd_buf
|
||||
.trackers
|
||||
.views
|
||||
.use_extend(&*view_guard, at.view, (), ())
|
||||
.map_err(|_| RenderPassErrorInner::InvalidAttachment(at.view))?;
|
||||
@ -690,7 +691,8 @@ impl<'a, B: GfxBackend> RenderPassInfo<'a, B> {
|
||||
}
|
||||
|
||||
for resolve_target in color_attachments.iter().flat_map(|at| at.resolve_target) {
|
||||
let view = trackers
|
||||
let view = cmd_buf
|
||||
.trackers
|
||||
.views
|
||||
.use_extend(&*view_guard, resolve_target, (), ())
|
||||
.map_err(|_| RenderPassErrorInner::InvalidAttachment(resolve_target))?;
|
||||
@ -961,7 +963,7 @@ impl<'a, B: GfxBackend> RenderPassInfo<'a, B> {
|
||||
|
||||
Ok(Self {
|
||||
context,
|
||||
trackers,
|
||||
trackers: StatefulTrackerSubset::new(B::VARIANT),
|
||||
render_attachments,
|
||||
used_swap_chain,
|
||||
is_ds_read_only,
|
||||
@ -973,7 +975,8 @@ impl<'a, B: GfxBackend> RenderPassInfo<'a, B> {
|
||||
fn finish(
|
||||
mut self,
|
||||
texture_guard: &Storage<Texture<B>, id::TextureId>,
|
||||
) -> Result<(TrackerSet, Option<Stored<id::SwapChainId>>), RenderPassErrorInner> {
|
||||
) -> Result<(StatefulTrackerSubset, Option<Stored<id::SwapChainId>>), RenderPassErrorInner>
|
||||
{
|
||||
profiling::scope!("finish", "RenderPassInfo");
|
||||
|
||||
for ra in self.render_attachments {
|
||||
@ -1122,7 +1125,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
);
|
||||
dynamic_offset_count += num_dynamic_offsets as usize;
|
||||
|
||||
let bind_group = info
|
||||
let bind_group = cmd_buf
|
||||
.trackers
|
||||
.bind_groups
|
||||
.use_extend(&*bind_group_guard, bind_group_id, (), ())
|
||||
@ -1132,9 +1135,11 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
.validate_dynamic_bindings(&temp_offsets)
|
||||
.map_pass_err(scope)?;
|
||||
|
||||
// merge the resource tracker in
|
||||
info.trackers
|
||||
.merge_extend(&bind_group.used)
|
||||
.map_pass_err(scope)?;
|
||||
cmd_buf.trackers.merge_extend_stateless(&bind_group.used);
|
||||
|
||||
cmd_buf.buffer_memory_init_actions.extend(
|
||||
bind_group.used_buffer_ranges.iter().filter_map(|action| {
|
||||
@ -1184,7 +1189,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
continue;
|
||||
}
|
||||
|
||||
let pipeline = info
|
||||
let pipeline = cmd_buf
|
||||
.trackers
|
||||
.render_pipes
|
||||
.use_extend(&*pipeline_guard, pipeline_id, (), ())
|
||||
@ -1826,7 +1831,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
} => {
|
||||
let scope = PassErrorScope::WriteTimestamp;
|
||||
|
||||
let query_set = info
|
||||
let query_set = cmd_buf
|
||||
.trackers
|
||||
.query_sets
|
||||
.use_extend(&*query_set_guard, query_set_id, (), ())
|
||||
@ -1853,7 +1858,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
} => {
|
||||
let scope = PassErrorScope::BeginPipelineStatisticsQuery;
|
||||
|
||||
let query_set = info
|
||||
let query_set = cmd_buf
|
||||
.trackers
|
||||
.query_sets
|
||||
.use_extend(&*query_set_guard, query_set_id, (), ())
|
||||
@ -1887,7 +1892,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
}
|
||||
RenderCommand::ExecuteBundle(bundle_id) => {
|
||||
let scope = PassErrorScope::ExecuteBundle;
|
||||
let bundle = info
|
||||
let bundle = cmd_buf
|
||||
.trackers
|
||||
.bundles
|
||||
.use_extend(&*bundle_guard, bundle_id, (), ())
|
||||
@ -1984,7 +1989,8 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
super::CommandBuffer::insert_barriers(
|
||||
last_cmd_buf,
|
||||
&mut cmd_buf.trackers,
|
||||
&trackers,
|
||||
&trackers.buffers,
|
||||
&trackers.textures,
|
||||
&*buffer_guard,
|
||||
&*texture_guard,
|
||||
);
|
||||
|
@ -760,10 +760,12 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
|
||||
.begin_primary(hal::command::CommandBufferFlags::ONE_TIME_SUBMIT);
|
||||
}
|
||||
log::trace!("Stitching command buffer {:?} before submission", cmb_id);
|
||||
trackers.merge_extend_stateless(&cmdbuf.trackers);
|
||||
CommandBuffer::insert_barriers(
|
||||
&mut transit,
|
||||
&mut *trackers,
|
||||
&cmdbuf.trackers,
|
||||
&cmdbuf.trackers.buffers,
|
||||
&cmdbuf.trackers.textures,
|
||||
&*buffer_guard,
|
||||
&*texture_guard,
|
||||
);
|
||||
|
@ -625,10 +625,17 @@ impl TrackerSet {
|
||||
}
|
||||
|
||||
/// Merge all the trackers of another instance by extending
|
||||
/// the usage. Panics on a conflict.
|
||||
pub fn merge_extend(&mut self, other: &Self) -> Result<(), UsageConflict> {
|
||||
/// the usage. Panics on a stateless conflict, returns a conflict otherwise.
|
||||
pub fn merge_extend_all(&mut self, other: &Self) -> Result<(), UsageConflict> {
|
||||
self.buffers.merge_extend(&other.buffers)?;
|
||||
self.textures.merge_extend(&other.textures)?;
|
||||
self.merge_extend_stateless(other);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Merge all the stateless trackers of another instance by extending
|
||||
/// the usage. Panics on a conflict.
|
||||
pub fn merge_extend_stateless(&mut self, other: &Self) {
|
||||
self.views.merge_extend(&other.views).unwrap();
|
||||
self.bind_groups.merge_extend(&other.bind_groups).unwrap();
|
||||
self.samplers.merge_extend(&other.samplers).unwrap();
|
||||
@ -638,10 +645,38 @@ impl TrackerSet {
|
||||
self.render_pipes.merge_extend(&other.render_pipes).unwrap();
|
||||
self.bundles.merge_extend(&other.bundles).unwrap();
|
||||
self.query_sets.merge_extend(&other.query_sets).unwrap();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn backend(&self) -> wgt::Backend {
|
||||
self.buffers.backend
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct StatefulTrackerSubset {
|
||||
pub buffers: ResourceTracker<BufferState>,
|
||||
pub textures: ResourceTracker<TextureState>,
|
||||
}
|
||||
|
||||
impl StatefulTrackerSubset {
|
||||
/// Create an empty set.
|
||||
pub fn new(backend: wgt::Backend) -> Self {
|
||||
Self {
|
||||
buffers: ResourceTracker::new(backend),
|
||||
textures: ResourceTracker::new(backend),
|
||||
}
|
||||
}
|
||||
|
||||
/// Clear all the trackers.
|
||||
pub fn clear(&mut self) {
|
||||
self.buffers.clear();
|
||||
self.textures.clear();
|
||||
}
|
||||
|
||||
/// Merge all the trackers of another tracker the usage.
|
||||
pub fn merge_extend(&mut self, other: &TrackerSet) -> Result<(), UsageConflict> {
|
||||
self.buffers.merge_extend(&other.buffers)?;
|
||||
self.textures.merge_extend(&other.textures)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user