Skip to content

Commit

Permalink
Merge #1128
Browse files Browse the repository at this point in the history
1128: Add pipeline statistics and timeline queries r=kvark a=cwfitzgerald

**Connections**

Closes #721 

**Description**

This adds Pipeline Statistics queries and Timeline queries. Shoutout to @z2oh for doing a good chunk of the work to enable this feature.

Currently blocked on both gfx-rs/gfx#3563 and rollup of gfx-hal mutability changes, but is ready to review.

**Testing**

Tested in various ways on the hello-compute and hello-triangle example, tested validation extensively. Queries will be permanently added to the mipmap example once the wgpu-rs PR is finished.

Co-authored-by: Connor Fitzgerald <connorwadefitzgerald@gmail.com>
  • Loading branch information
bors[bot] and cwfitzgerald authored Jan 16, 2021
2 parents 0491d00 + a22037c commit 9dce0af
Show file tree
Hide file tree
Showing 18 changed files with 1,153 additions and 12 deletions.
32 changes: 32 additions & 0 deletions player/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,28 @@ impl GlobalPlay for wgc::hub::Global<IdentityPassThroughFactory> {
trace::Command::CopyTextureToTexture { src, dst, size } => self
.command_encoder_copy_texture_to_texture::<B>(encoder, &src, &dst, &size)
.unwrap(),
trace::Command::WriteTimestamp {
query_set_id,
query_index,
} => self
.command_encoder_write_timestamp::<B>(encoder, query_set_id, query_index)
.unwrap(),
trace::Command::ResolveQuerySet {
query_set_id,
start_query,
query_count,
destination,
destination_offset,
} => self
.command_encoder_resolve_query_set::<B>(
encoder,
query_set_id,
start_query,
query_count,
destination,
destination_offset,
)
.unwrap(),
trace::Command::RunComputePass { base } => {
self.command_encoder_run_compute_pass_impl::<B>(encoder, base.as_ref())
.unwrap();
Expand Down Expand Up @@ -267,6 +289,16 @@ impl GlobalPlay for wgc::hub::Global<IdentityPassThroughFactory> {
A::DestroyRenderBundle(id) => {
self.render_bundle_drop::<B>(id);
}
A::CreateQuerySet { id, desc } => {
self.device_maintain_ids::<B>(device).unwrap();
let (_, error) = self.device_create_query_set::<B>(device, &desc, id);
if let Some(e) = error {
panic!("{:?}", e);
}
}
A::DestroyQuerySet(id) => {
self.query_set_drop::<B>(id);
}
A::WriteBuffer {
id,
data,
Expand Down
6 changes: 6 additions & 0 deletions wgpu-core/src/command/bundle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,9 @@ impl RenderBundleEncoder {
RenderCommand::PushDebugGroup { color: _, len: _ } => unimplemented!(),
RenderCommand::InsertDebugMarker { color: _, len: _ } => unimplemented!(),
RenderCommand::PopDebugGroup => unimplemented!(),
RenderCommand::WriteTimestamp { .. }
| RenderCommand::BeginPipelineStatisticsQuery { .. }
| RenderCommand::EndPipelineStatisticsQuery => unimplemented!(),
RenderCommand::ExecuteBundle(_)
| RenderCommand::SetBlendColor(_)
| RenderCommand::SetStencilReference(_)
Expand Down Expand Up @@ -693,6 +696,9 @@ impl RenderBundle {
RenderCommand::PushDebugGroup { color: _, len: _ } => unimplemented!(),
RenderCommand::InsertDebugMarker { color: _, len: _ } => unimplemented!(),
RenderCommand::PopDebugGroup => unimplemented!(),
RenderCommand::WriteTimestamp { .. }
| RenderCommand::BeginPipelineStatisticsQuery { .. }
| RenderCommand::EndPipelineStatisticsQuery => unimplemented!(),
RenderCommand::ExecuteBundle(_)
| RenderCommand::SetBlendColor(_)
| RenderCommand::SetStencilReference(_)
Expand Down
121 changes: 119 additions & 2 deletions wgpu-core/src/command/compute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ use crate::{
binding_model::{BindError, BindGroup, PushConstantUploadError},
command::{
bind::{Binder, LayoutChange},
BasePass, BasePassRef, CommandBuffer, CommandEncoderError, MapPassErr, PassErrorScope,
StateChange,
end_pipeline_statistics_query, BasePass, BasePassRef, CommandBuffer, CommandEncoderError,
MapPassErr, PassErrorScope, QueryUseError, StateChange,
},
hub::{GfxBackend, Global, GlobalIdentityHandlerFactory, Storage, Token},
id,
Expand All @@ -23,6 +23,7 @@ use hal::command::CommandBuffer as _;
use thiserror::Error;
use wgt::{BufferAddress, BufferUsage, ShaderStage};

use crate::track::UseExtendError;
use std::{fmt, iter, str};

#[doc(hidden)]
Expand Down Expand Up @@ -61,6 +62,15 @@ pub enum ComputeCommand {
color: u32,
len: usize,
},
WriteTimestamp {
query_set_id: id::QuerySetId,
query_index: u32,
},
BeginPipelineStatisticsQuery {
query_set_id: id::QuerySetId,
query_index: u32,
},
EndPipelineStatisticsQuery,
}

#[cfg_attr(feature = "serial-pass", derive(serde::Deserialize, serde::Serialize))]
Expand Down Expand Up @@ -127,6 +137,8 @@ pub enum ComputePassErrorInner {
BindGroupIndexOutOfRange { index: u8, max: u32 },
#[error("compute pipeline {0:?} is invalid")]
InvalidPipeline(id::ComputePipelineId),
#[error("QuerySet {0:?} is invalid")]
InvalidQuerySet(id::QuerySetId),
#[error("indirect buffer {0:?} is invalid or destroyed")]
InvalidIndirectBuffer(id::BufferId),
#[error(transparent)]
Expand All @@ -141,6 +153,8 @@ pub enum ComputePassErrorInner {
Bind(#[from] BindError),
#[error(transparent)]
PushConstants(#[from] PushConstantUploadError),
#[error(transparent)]
QueryUse(#[from] QueryUseError),
}

/// Error encountered when performing a compute pass.
Expand Down Expand Up @@ -260,6 +274,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
let (pipeline_layout_guard, mut token) = hub.pipeline_layouts.read(&mut token);
let (bind_group_guard, mut token) = hub.bind_groups.read(&mut token);
let (pipeline_guard, mut token) = hub.compute_pipelines.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);

Expand All @@ -272,6 +287,7 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
let mut temp_offsets = Vec::new();
let mut dynamic_offset_count = 0;
let mut string_offset = 0;
let mut active_query = None;

for command in base.commands {
match *command {
Expand Down Expand Up @@ -525,6 +541,62 @@ impl<G: GlobalIdentityHandlerFactory> Global<G> {
string_offset += len;
unsafe { raw.insert_debug_marker(label, color) }
}
ComputeCommand::WriteTimestamp {
query_set_id,
query_index,
} => {
let scope = PassErrorScope::WriteTimestamp;

let query_set = cmd_buf
.trackers
.query_sets
.use_extend(&*query_set_guard, query_set_id, (), ())
.map_err(|e| match e {
UseExtendError::InvalidResource => {
ComputePassErrorInner::InvalidQuerySet(query_set_id)
}
_ => unreachable!(),
})
.map_pass_err(scope)?;

query_set
.validate_and_write_timestamp(raw, query_set_id, query_index, None)
.map_pass_err(scope)?;
}
ComputeCommand::BeginPipelineStatisticsQuery {
query_set_id,
query_index,
} => {
let scope = PassErrorScope::BeginPipelineStatisticsQuery;

let query_set = cmd_buf
.trackers
.query_sets
.use_extend(&*query_set_guard, query_set_id, (), ())
.map_err(|e| match e {
UseExtendError::InvalidResource => {
ComputePassErrorInner::InvalidQuerySet(query_set_id)
}
_ => unreachable!(),
})
.map_pass_err(scope)?;

query_set
.validate_and_begin_pipeline_statistics_query(
raw,
query_set_id,
query_index,
None,
&mut active_query,
)
.map_pass_err(scope)?;
}
ComputeCommand::EndPipelineStatisticsQuery => {
let scope = PassErrorScope::EndPipelineStatisticsQuery;

end_pipeline_statistics_query(raw, &*query_set_guard, &mut active_query)
.map_pass_err(scope)?;
}
}
}

Expand Down Expand Up @@ -680,4 +752,49 @@ pub mod compute_ffi {
len: bytes.len(),
});
}

#[no_mangle]
pub unsafe extern "C" fn wgpu_compute_pass_write_timestamp(
pass: &mut ComputePass,
query_set_id: id::QuerySetId,
query_index: u32,
) {
span!(_guard, DEBUG, "ComputePass::write_timestamp");

pass.base.commands.push(ComputeCommand::WriteTimestamp {
query_set_id,
query_index,
});
}

#[no_mangle]
pub unsafe extern "C" fn wgpu_compute_pass_begin_pipeline_statistics_query(
pass: &mut ComputePass,
query_set_id: id::QuerySetId,
query_index: u32,
) {
span!(
_guard,
DEBUG,
"ComputePass::begin_pipeline_statistics query"
);

pass.base
.commands
.push(ComputeCommand::BeginPipelineStatisticsQuery {
query_set_id,
query_index,
});
}

#[no_mangle]
pub unsafe extern "C" fn wgpu_compute_pass_end_pipeline_statistics_query(
pass: &mut ComputePass,
) {
span!(_guard, DEBUG, "ComputePass::end_pipeline_statistics_query");

pass.base
.commands
.push(ComputeCommand::EndPipelineStatisticsQuery);
}
}
11 changes: 11 additions & 0 deletions wgpu-core/src/command/draw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ pub enum RenderCommandError {
InvalidDynamicOffsetCount { actual: usize, expected: usize },
#[error("render pipeline {0:?} is invalid")]
InvalidPipeline(id::RenderPipelineId),
#[error("QuerySet {0:?} is invalid")]
InvalidQuerySet(id::QuerySetId),
#[error("Render pipeline is incompatible with render pass")]
IncompatiblePipeline(#[from] crate::device::RenderPassCompatibilityError),
#[error("pipeline is not compatible with the depth-stencil read-only render pass")]
Expand Down Expand Up @@ -195,5 +197,14 @@ pub enum RenderCommand {
color: u32,
len: usize,
},
WriteTimestamp {
query_set_id: id::QuerySetId,
query_index: u32,
},
BeginPipelineStatisticsQuery {
query_set_id: id::QuerySetId,
query_index: u32,
},
EndPipelineStatisticsQuery,
ExecuteBundle(id::RenderBundleId),
}
10 changes: 10 additions & 0 deletions wgpu-core/src/command/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ mod bind;
mod bundle;
mod compute;
mod draw;
mod query;
mod render;
mod transfer;

Expand All @@ -15,6 +16,7 @@ pub use self::allocator::CommandAllocatorError;
pub use self::bundle::*;
pub use self::compute::*;
pub use self::draw::*;
pub use self::query::*;
pub use self::render::*;
pub use self::transfer::*;

Expand Down Expand Up @@ -367,6 +369,14 @@ pub enum PassErrorScope {
indirect: bool,
pipeline: Option<id::RenderPipelineId>,
},
#[error("While resetting queries after the renderpass was ran")]
QueryReset,
#[error("In a write_timestamp command")]
WriteTimestamp,
#[error("In a begin_pipeline_statistics_query command")]
BeginPipelineStatisticsQuery,
#[error("In a end_pipeline_statistics_query command")]
EndPipelineStatisticsQuery,
#[error("In a execute_bundle command")]
ExecuteBundle,
#[error("In a dispatch command, indirect:{indirect}")]
Expand Down
Loading

0 comments on commit 9dce0af

Please sign in to comment.