Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tracking Optimization and Rewrite #2662

Merged
merged 39 commits into from
May 24, 2022
Merged
Show file tree
Hide file tree
Changes from 36 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
3eb599a
Texture state full is dead code
cwfitzgerald Apr 28, 2022
aaff782
temp
cwfitzgerald May 2, 2022
5d5298d
temp2 - next is lifetime only
cwfitzgerald May 2, 2022
4fc1ea4
temp3 - all trackers in place
cwfitzgerald May 3, 2022
97e5653
temp4 - continue muddling along
cwfitzgerald May 3, 2022
26c3c7b
temp5 - doodle doodle
cwfitzgerald May 3, 2022
c0deee9
temp6 - continuous progress is continuous
cwfitzgerald May 4, 2022
5235991
temp7 - pro-gress
cwfitzgerald May 4, 2022
483002a
temp8 - Add refcounts to trackers
cwfitzgerald May 5, 2022
f94a451
temp9 - Soundness, generics, refcounts, and epochs
cwfitzgerald May 7, 2022
a65b60e
temp10 - Compiling?!1?!1?!1
cwfitzgerald May 7, 2022
dfb10f7
temp11 - Add bind group state optimization
cwfitzgerald May 7, 2022
22d16b3
temp12 - Safety and adding size setting
cwfitzgerald May 8, 2022
643c264
temp13 - unsafe
cwfitzgerald May 8, 2022
27a4e40
temp14 - Abstract all the state transitions
cwfitzgerald May 9, 2022
db41d9b
temp15 - It verks! kinda...
cwfitzgerald May 9, 2022
79736f5
temp16 - it more verks!
cwfitzgerald May 12, 2022
9015fbb
temp17 - debugging and unit tests
cwfitzgerald May 12, 2022
de84108
temp18 - fixing unfixed things
cwfitzgerald May 12, 2022
a0c3494
temp19 - hmmm
cwfitzgerald May 13, 2022
9fa9e3c
temp20 - curious about line deltas
cwfitzgerald May 14, 2022
ad627e4
temp21 - working texture trackers
cwfitzgerald May 14, 2022
64cc463
temp22 - write merge/update/barrier for buffers
cwfitzgerald May 15, 2022
426e8e2
temp23 - cleanup and buffers
cwfitzgerald May 15, 2022
a7c309d
temp24 - clippy cleanup
cwfitzgerald May 15, 2022
0ff3df0
Merge remote-tracking branch 'origin/master' into tracking-optimization
cwfitzgerald May 15, 2022
dbe615a
temp25 - Add inline markers on buffer functions
cwfitzgerald May 15, 2022
1bbff99
temp26 - Fix buffer trackers
cwfitzgerald May 16, 2022
71035d0
Merge remote-tracking branch 'origin/master' into tracking-optimization
cwfitzgerald May 16, 2022
aa85535
temp27 - fixed texture insert to handle both sides
cwfitzgerald May 16, 2022
6519241
temp28 - document tracker and usages
cwfitzgerald May 17, 2022
0b8ce17
temp29 - document track/mod.rs
cwfitzgerald May 17, 2022
e79eb4b
temp30 - convert STORAGE_WRITE to STORAGE_READ_WRITE
cwfitzgerald May 18, 2022
c7539e6
temp31 - Add some debug asserts to make sure we can't insert invalid …
cwfitzgerald May 18, 2022
24dad75
Merge remote-tracking branch 'origin/master' into tracking-optimization
cwfitzgerald May 18, 2022
1b060b8
temp32 - clippy is opinionated sometimes
cwfitzgerald May 18, 2022
fb58fb9
temp33 - renaming and documentation
cwfitzgerald May 24, 2022
f5d8e5d
temp34 - logging
cwfitzgerald May 24, 2022
17a37a6
Merge remote-tracking branch 'origin/master' into tracking-optimization
cwfitzgerald May 24, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions wgpu-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ vulkan-portability = ["hal/vulkan"]
[dependencies]
arrayvec = "0.7"
bitflags = "1.0"
bit-vec = "0.6"
codespan-reporting = "0.11"
copyless = "0.1"
fxhash = "0.2"
Expand Down
28 changes: 10 additions & 18 deletions wgpu-core/src/binding_model.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use crate::{
device::{DeviceError, MissingDownlevelFlags, MissingFeatures, SHADER_STAGE_COUNT},
error::{ErrorFormatter, PrettyError},
hub::Resource,
id::{BindGroupLayoutId, BufferId, DeviceId, SamplerId, TextureViewId, Valid},
hub::{HalApi, Resource},
id::{BindGroupLayoutId, BufferId, DeviceId, SamplerId, TextureId, TextureViewId, Valid},
init_tracker::{BufferInitTrackerAction, TextureInitTrackerAction},
track::{TrackerSet, UsageConflict, DUMMY_SELECTOR},
track::{BindGroupStates, UsageConflict},
validation::{MissingBufferUsageError, MissingTextureUsageError},
FastHashMap, Label, LifeGuard, MultiRefCount, Stored,
};
Expand All @@ -16,10 +16,7 @@ use serde::Deserialize;
#[cfg(feature = "trace")]
use serde::Serialize;

use std::{
borrow::{Borrow, Cow},
ops::Range,
};
use std::{borrow::Cow, ops::Range};

use thiserror::Error;

Expand Down Expand Up @@ -63,6 +60,8 @@ pub enum CreateBindGroupError {
InvalidBuffer(BufferId),
#[error("texture view {0:?} is invalid")]
InvalidTextureView(TextureViewId),
#[error("texture {0:?} is invalid")]
InvalidTexture(TextureId),
#[error("sampler {0:?} is invalid")]
InvalidSampler(SamplerId),
#[error(
Expand Down Expand Up @@ -709,13 +708,12 @@ pub(crate) fn buffer_binding_type_alignment(
}
}

#[derive(Debug)]
pub struct BindGroup<A: hal::Api> {
pub struct BindGroup<A: HalApi> {
pub(crate) raw: A::BindGroup,
pub(crate) device_id: Stored<DeviceId>,
pub(crate) layout_id: Valid<BindGroupLayoutId>,
pub(crate) life_guard: LifeGuard,
pub(crate) used: TrackerSet,
pub(crate) used: BindGroupStates<A>,
pub(crate) used_buffer_ranges: Vec<BufferInitTrackerAction>,
pub(crate) used_texture_ranges: Vec<TextureInitTrackerAction>,
pub(crate) dynamic_binding_info: Vec<BindGroupDynamicBindingData>,
Expand All @@ -724,7 +722,7 @@ pub struct BindGroup<A: hal::Api> {
pub(crate) late_buffer_binding_sizes: Vec<wgt::BufferSize>,
}

impl<A: hal::Api> BindGroup<A> {
impl<A: HalApi> BindGroup<A> {
pub(crate) fn validate_dynamic_bindings(
&self,
offsets: &[wgt::DynamicOffset],
Expand Down Expand Up @@ -766,13 +764,7 @@ impl<A: hal::Api> BindGroup<A> {
}
}

impl<A: hal::Api> Borrow<()> for BindGroup<A> {
fn borrow(&self) -> &() {
&DUMMY_SELECTOR
}
}

impl<A: hal::Api> Resource for BindGroup<A> {
impl<A: HalApi> Resource for BindGroup<A> {
const TYPE: &'static str = "BindGroup";

fn life_guard(&self) -> &LifeGuard {
Expand Down
96 changes: 51 additions & 45 deletions wgpu-core/src/command/bundle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ invalidations or index format changes.
#![allow(clippy::reversed_empty_ranges)]

use crate::{
binding_model::buffer_binding_type_alignment,
binding_model::{self, buffer_binding_type_alignment},
command::{
BasePass, BindGroupStateChange, DrawError, MapPassErr, PassErrorScope, RenderCommand,
RenderCommandError, StateChange,
Expand All @@ -48,8 +48,9 @@ use crate::{
hub::{GlobalIdentityHandlerFactory, HalApi, Hub, Resource, Storage, Token},
id,
init_tracker::{BufferInitTrackerAction, MemoryInitKind, TextureInitTrackerAction},
pipeline::PipelineFlags,
track::{TrackerSet, UsageConflict},
pipeline::{self, PipelineFlags},
resource,
track::RenderBundleScope,
validation::check_buffer_usage,
Label, LabelHelpers, LifeGuard, Stored,
};
Expand Down Expand Up @@ -117,7 +118,7 @@ impl RenderBundleEncoder {
},
sample_count: {
let sc = desc.sample_count;
if sc == 0 || sc > 32 || !conv::is_power_of_two(sc) {
if sc == 0 || sc > 32 || !conv::is_power_of_two_u32(sc) {
return Err(CreateRenderBundleError::InvalidSampleCount(sc));
}
sc
Expand Down Expand Up @@ -167,20 +168,28 @@ impl RenderBundleEncoder {
self.parent_id
}

pub(crate) fn finish<A: hal::Api, G: GlobalIdentityHandlerFactory>(
pub(crate) fn finish<A: HalApi, G: GlobalIdentityHandlerFactory>(
self,
desc: &RenderBundleDescriptor,
device: &Device<A>,
hub: &Hub<A, G>,
token: &mut Token<Device<A>>,
) -> Result<RenderBundle, RenderBundleError> {
) -> Result<RenderBundle<A>, RenderBundleError> {
let (pipeline_layout_guard, mut token) = hub.pipeline_layouts.read(token);
let (bind_group_guard, mut token) = hub.bind_groups.read(&mut token);
let (pipeline_guard, mut token) = hub.render_pipelines.read(&mut token);
let (buffer_guard, _) = hub.buffers.read(&mut token);
let (query_set_guard, mut token) = hub.query_sets.read(&mut token);
let (buffer_guard, mut token) = hub.buffers.read(&mut token);
let (texture_guard, _) = hub.textures.read(&mut token);

let mut state = State {
trackers: TrackerSet::new(self.parent_id.backend()),
trackers: RenderBundleScope::new(
&*buffer_guard,
&*texture_guard,
&*bind_group_guard,
&*pipeline_guard,
&*query_set_guard,
),
index: IndexState::new(),
vertex: (0..hal::MAX_VERTEX_BUFFERS)
.map(|_| VertexState::new())
Expand Down Expand Up @@ -221,11 +230,11 @@ impl RenderBundleEncoder {
let offsets = &base.dynamic_offsets[..num_dynamic_offsets as usize];
base.dynamic_offsets = &base.dynamic_offsets[num_dynamic_offsets as usize..];

let bind_group = state
let bind_group: &binding_model::BindGroup<A> = state
.trackers
.bind_groups
.use_extend(&*bind_group_guard, bind_group_id, (), ())
.map_err(|_| RenderCommandError::InvalidBindGroup(bind_group_id))
.extend(&*bind_group_guard, bind_group_id)
.ok_or(RenderCommandError::InvalidBindGroup(bind_group_id))
.map_pass_err(scope)?;
if bind_group.dynamic_binding_info.len() != offsets.len() {
return Err(RenderCommandError::InvalidDynamicOffsetCount {
Expand Down Expand Up @@ -255,10 +264,12 @@ impl RenderBundleEncoder {
texture_memory_init_actions.extend_from_slice(&bind_group.used_texture_ranges);

state.set_bind_group(index, bind_group_id, bind_group.layout_id, offsets);
state
.trackers
.merge_extend_stateful(&bind_group.used)
.map_pass_err(scope)?;
unsafe {
state
.trackers
.extend_from_bind_group(&*texture_guard, &bind_group.used)
.map_pass_err(scope)?
};
//Note: stateless trackers are not merged: the lifetime reference
// is held to the bind group itself.
}
Expand All @@ -267,11 +278,11 @@ impl RenderBundleEncoder {

state.pipeline = Some(pipeline_id);

let pipeline = state
let pipeline: &pipeline::RenderPipeline<A> = state
.trackers
.render_pipes
.use_extend(&*pipeline_guard, pipeline_id, (), ())
.map_err(|_| RenderCommandError::InvalidPipeline(pipeline_id))
.render_pipelines
.extend(&*pipeline_guard, pipeline_id)
.ok_or(RenderCommandError::InvalidPipeline(pipeline_id))
.map_pass_err(scope)?;

self.context
Expand Down Expand Up @@ -307,11 +318,11 @@ impl RenderBundleEncoder {
size,
} => {
let scope = PassErrorScope::SetIndexBuffer(buffer_id);
let buffer = state
let buffer: &resource::Buffer<A> = state
.trackers
.buffers
.use_extend(&*buffer_guard, buffer_id, (), hal::BufferUses::INDEX)
.unwrap();
.extend(&*buffer_guard, buffer_id, hal::BufferUses::INDEX)
.map_pass_err(scope)?;
check_buffer_usage(buffer.usage, wgt::BufferUsages::INDEX)
.map_pass_err(scope)?;

Expand All @@ -334,11 +345,11 @@ impl RenderBundleEncoder {
size,
} => {
let scope = PassErrorScope::SetVertexBuffer(buffer_id);
let buffer = state
let buffer: &resource::Buffer<A> = state
.trackers
.buffers
.use_extend(&*buffer_guard, buffer_id, (), hal::BufferUses::VERTEX)
.unwrap();
.extend(&*buffer_guard, buffer_id, hal::BufferUses::VERTEX)
.map_pass_err(scope)?;
check_buffer_usage(buffer.usage, wgt::BufferUsages::VERTEX)
.map_pass_err(scope)?;

Expand Down Expand Up @@ -459,11 +470,11 @@ impl RenderBundleEncoder {
.require_downlevel_flags(wgt::DownlevelFlags::INDIRECT_EXECUTION)
.map_pass_err(scope)?;

let buffer = state
let buffer: &resource::Buffer<A> = state
.trackers
.buffers
.use_extend(&*buffer_guard, buffer_id, (), hal::BufferUses::INDIRECT)
.unwrap();
.extend(&*buffer_guard, buffer_id, hal::BufferUses::INDIRECT)
.map_pass_err(scope)?;
check_buffer_usage(buffer.usage, wgt::BufferUsages::INDIRECT)
.map_pass_err(scope)?;

Expand Down Expand Up @@ -492,11 +503,10 @@ impl RenderBundleEncoder {
.require_downlevel_flags(wgt::DownlevelFlags::INDIRECT_EXECUTION)
.map_pass_err(scope)?;

let buffer = state
let buffer: &resource::Buffer<A> = state
.trackers
.buffers
.use_extend(&*buffer_guard, buffer_id, (), hal::BufferUses::INDIRECT)
.map_err(|err| RenderCommandError::Buffer(buffer_id, err))
.extend(&*buffer_guard, buffer_id, hal::BufferUses::INDIRECT)
.map_pass_err(scope)?;
check_buffer_usage(buffer.usage, wgt::BufferUsages::INDIRECT)
.map_pass_err(scope)?;
Expand Down Expand Up @@ -599,24 +609,23 @@ pub type RenderBundleDescriptor<'a> = wgt::RenderBundleDescriptor<Label<'a>>;
//Note: here, `RenderBundle` is just wrapping a raw stream of render commands.
// The plan is to back it by an actual Vulkan secondary buffer, D3D12 Bundle,
// or Metal indirect command buffer.
#[derive(Debug)]
pub struct RenderBundle {
pub struct RenderBundle<A: HalApi> {
// Normalized command stream. It can be executed verbatim,
// without re-binding anything on the pipeline change.
base: BasePass<RenderCommand>,
pub(super) is_ds_read_only: bool,
pub(crate) device_id: Stored<id::DeviceId>,
pub(crate) used: TrackerSet,
pub(crate) used: RenderBundleScope<A>,
pub(super) buffer_memory_init_actions: Vec<BufferInitTrackerAction>,
pub(super) texture_memory_init_actions: Vec<TextureInitTrackerAction>,
pub(super) context: RenderPassContext,
pub(crate) life_guard: LifeGuard,
}

unsafe impl Send for RenderBundle {}
unsafe impl Sync for RenderBundle {}
unsafe impl<A: HalApi> Send for RenderBundle<A> {}
unsafe impl<A: HalApi> Sync for RenderBundle<A> {}

impl RenderBundle {
impl<A: HalApi> RenderBundle<A> {
/// Actually encode the contents into a native command buffer.
///
/// This is partially duplicating the logic of `command_encoder_run_render_pass`.
Expand All @@ -626,7 +635,7 @@ impl RenderBundle {
/// Note that the function isn't expected to fail, generally.
/// All the validation has already been done by this point.
/// The only failure condition is if some of the used buffers are destroyed.
pub(super) unsafe fn execute<A: HalApi>(
pub(super) unsafe fn execute(
&self,
raw: &mut A::CommandEncoder,
pipeline_layout_guard: &Storage<
Expand Down Expand Up @@ -815,7 +824,7 @@ impl RenderBundle {
}
}

impl Resource for RenderBundle {
impl<A: HalApi> Resource for RenderBundle<A> {
const TYPE: &'static str = "RenderBundle";

fn life_guard(&self) -> &LifeGuard {
Expand Down Expand Up @@ -992,9 +1001,8 @@ struct VertexLimitState {
instance_limit_slot: u32,
}

#[derive(Debug)]
struct State {
trackers: TrackerSet,
struct State<A: HalApi> {
trackers: RenderBundleScope<A>,
index: IndexState,
vertex: ArrayVec<VertexState, { hal::MAX_VERTEX_BUFFERS }>,
bind: ArrayVec<BindState, { hal::MAX_BIND_GROUPS }>,
Expand All @@ -1005,7 +1013,7 @@ struct State {
pipeline: Option<id::RenderPipelineId>,
}

impl State {
impl<A: HalApi> State<A> {
fn vertex_limits(&self) -> VertexLimitState {
let mut vert_state = VertexLimitState {
vertex_limit: u32::MAX,
Expand Down Expand Up @@ -1164,8 +1172,6 @@ pub(super) enum RenderBundleErrorInner {
#[error(transparent)]
RenderCommand(RenderCommandError),
#[error(transparent)]
ResourceUsageConflict(#[from] UsageConflict),
#[error(transparent)]
Draw(#[from] DrawError),
#[error(transparent)]
MissingDownlevelFlags(#[from] MissingDownlevelFlags),
Expand Down
Loading