mirror of
https://github.com/gfx-rs/wgpu.git
synced 2025-12-08 21:26:17 +00:00
Store pointers instead of IDs when tracing (1/2)
This updates pass operations. The trace player is temporarily broken.
This commit is contained in:
parent
a502e73c1d
commit
e584f382e0
3
Cargo.lock
generated
3
Cargo.lock
generated
@ -3792,6 +3792,9 @@ name = "smallvec"
|
||||
version = "1.15.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "smithay-client-toolkit"
|
||||
|
||||
@ -3,6 +3,7 @@ resolver = "2"
|
||||
members = [
|
||||
"cts_runner",
|
||||
"deno_webgpu",
|
||||
"player",
|
||||
|
||||
# default members
|
||||
"benches",
|
||||
@ -15,7 +16,6 @@ members = [
|
||||
"naga/fuzz",
|
||||
"naga/hlsl-snapshots",
|
||||
"naga/xtask",
|
||||
"player",
|
||||
"tests",
|
||||
"wgpu-core",
|
||||
"wgpu-core/platform-deps/*",
|
||||
@ -38,7 +38,6 @@ default-members = [
|
||||
"naga/fuzz",
|
||||
"naga/hlsl-snapshots",
|
||||
"naga/xtask",
|
||||
"player",
|
||||
"tests",
|
||||
"wgpu-core",
|
||||
"wgpu-core/platform-deps/*",
|
||||
|
||||
@ -18,7 +18,7 @@ pub trait GlobalPlay {
|
||||
fn encode_commands(
|
||||
&self,
|
||||
encoder: wgc::id::CommandEncoderId,
|
||||
commands: Vec<Command>,
|
||||
commands: Vec<Command<IdReferences>>,
|
||||
command_buffer_id_manager: &mut IdentityManager<wgc::id::markers::CommandBuffer>,
|
||||
) -> wgc::id::CommandBufferId;
|
||||
fn process(
|
||||
@ -36,7 +36,7 @@ impl GlobalPlay for wgc::global::Global {
|
||||
fn encode_commands(
|
||||
&self,
|
||||
encoder: wgc::id::CommandEncoderId,
|
||||
commands: Vec<Command>,
|
||||
commands: Vec<Command<IdReferences>>,
|
||||
command_buffer_id_manager: &mut IdentityManager<wgc::id::markers::CommandBuffer>,
|
||||
) -> wgc::id::CommandBufferId {
|
||||
for command in commands {
|
||||
@ -71,13 +71,13 @@ impl GlobalPlay for wgc::global::Global {
|
||||
.command_encoder_clear_texture(encoder, dst, &subresource_range)
|
||||
.unwrap(),
|
||||
Command::WriteTimestamp {
|
||||
query_set_id,
|
||||
query_set,
|
||||
query_index,
|
||||
} => self
|
||||
.command_encoder_write_timestamp(encoder, query_set_id, query_index)
|
||||
.command_encoder_write_timestamp(encoder, query_set, query_index)
|
||||
.unwrap(),
|
||||
Command::ResolveQuerySet {
|
||||
query_set_id,
|
||||
query_set,
|
||||
start_query,
|
||||
query_count,
|
||||
destination,
|
||||
@ -85,7 +85,7 @@ impl GlobalPlay for wgc::global::Global {
|
||||
} => self
|
||||
.command_encoder_resolve_query_set(
|
||||
encoder,
|
||||
query_set_id,
|
||||
query_set,
|
||||
start_query,
|
||||
query_count,
|
||||
destination,
|
||||
@ -100,29 +100,29 @@ impl GlobalPlay for wgc::global::Global {
|
||||
.command_encoder_insert_debug_marker(encoder, &marker)
|
||||
.unwrap(),
|
||||
Command::RunComputePass {
|
||||
base,
|
||||
pass,
|
||||
timestamp_writes,
|
||||
} => {
|
||||
self.compute_pass_end_with_unresolved_commands(
|
||||
encoder,
|
||||
base,
|
||||
pass,
|
||||
timestamp_writes.as_ref(),
|
||||
);
|
||||
}
|
||||
Command::RunRenderPass {
|
||||
base,
|
||||
target_colors,
|
||||
target_depth_stencil,
|
||||
pass,
|
||||
color_attachments,
|
||||
depth_stencil_attachment,
|
||||
timestamp_writes,
|
||||
occlusion_query_set_id,
|
||||
occlusion_query_set,
|
||||
} => {
|
||||
self.render_pass_end_with_unresolved_commands(
|
||||
encoder,
|
||||
base,
|
||||
&target_colors,
|
||||
target_depth_stencil.as_ref(),
|
||||
pass,
|
||||
&color_attachments,
|
||||
depth_stencil_attachment.as_ref(),
|
||||
timestamp_writes.as_ref(),
|
||||
occlusion_query_set_id,
|
||||
occlusion_query_set,
|
||||
);
|
||||
}
|
||||
Command::BuildAccelerationStructures { blas, tlas } => {
|
||||
@ -175,6 +175,7 @@ impl GlobalPlay for wgc::global::Global {
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
Command::TransitionResources { .. } => unimplemented!("not supported in a trace"),
|
||||
}
|
||||
}
|
||||
let (cmd_buf, error) = self.command_encoder_finish(
|
||||
@ -233,12 +234,8 @@ impl GlobalPlay for wgc::global::Global {
|
||||
Action::DestroyTexture(id) => {
|
||||
self.texture_drop(id);
|
||||
}
|
||||
Action::CreateTextureView {
|
||||
id,
|
||||
parent_id,
|
||||
desc,
|
||||
} => {
|
||||
let (_, error) = self.texture_create_view(parent_id, &desc, Some(id));
|
||||
Action::CreateTextureView { id, parent, desc } => {
|
||||
let (_, error) = self.texture_create_view(parent, &desc, Some(id));
|
||||
if let Some(e) = error {
|
||||
panic!("{e}");
|
||||
}
|
||||
@ -268,8 +265,8 @@ impl GlobalPlay for wgc::global::Global {
|
||||
Action::DestroySampler(id) => {
|
||||
self.sampler_drop(id);
|
||||
}
|
||||
Action::GetSurfaceTexture { id, parent_id } => {
|
||||
self.surface_get_current_texture(parent_id, Some(id))
|
||||
Action::GetSurfaceTexture { id, parent } => {
|
||||
self.surface_get_current_texture(parent, Some(id))
|
||||
.unwrap()
|
||||
.texture
|
||||
.unwrap();
|
||||
|
||||
@ -69,7 +69,7 @@ observe_locks = ["std", "dep:ron", "serde/serde_derive"]
|
||||
# --------------------------------------------------------------------
|
||||
|
||||
## Enables serialization via `serde` on common wgpu types.
|
||||
serde = ["dep:serde", "wgpu-types/serde", "arrayvec/serde", "hashbrown/serde"]
|
||||
serde = ["dep:serde", "wgpu-types/serde", "arrayvec/serde", "hashbrown/serde", "smallvec/serde"]
|
||||
|
||||
## Enable API tracing.
|
||||
trace = ["serde", "std", "dep:ron", "naga/serialize", "wgpu-types/trace"]
|
||||
|
||||
@ -96,11 +96,13 @@ use thiserror::Error;
|
||||
use wgpu_hal::ShouldBeNonZeroExt;
|
||||
use wgt::error::{ErrorType, WebGpuError};
|
||||
|
||||
#[cfg(feature = "trace")]
|
||||
use crate::command::ArcReferences;
|
||||
use crate::{
|
||||
binding_model::{BindError, BindGroup, PipelineLayout},
|
||||
command::{
|
||||
BasePass, BindGroupStateChange, ColorAttachmentError, DrawError, MapPassErr,
|
||||
PassErrorScope, RenderCommandError, StateChange,
|
||||
BasePass, BindGroupStateChange, ColorAttachmentError, DrawError, IdReferences, MapPassErr,
|
||||
PassErrorScope, RenderCommand, RenderCommandError, StateChange,
|
||||
},
|
||||
device::{
|
||||
AttachmentData, Device, DeviceError, MissingDownlevelFlags, RenderPassContext,
|
||||
@ -120,11 +122,7 @@ use crate::{
|
||||
Label, LabelHelpers,
|
||||
};
|
||||
|
||||
use super::{
|
||||
pass,
|
||||
render_command::{ArcRenderCommand, RenderCommand},
|
||||
DrawCommandFamily, DrawKind,
|
||||
};
|
||||
use super::{pass, render_command::ArcRenderCommand, DrawCommandFamily, DrawKind};
|
||||
|
||||
/// Describes a [`RenderBundleEncoder`].
|
||||
#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
|
||||
@ -158,7 +156,7 @@ pub struct RenderBundleEncoderDescriptor<'a> {
|
||||
#[derive(Debug)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
|
||||
pub struct RenderBundleEncoder {
|
||||
base: BasePass<RenderCommand, Infallible>,
|
||||
base: BasePass<RenderCommand<IdReferences>, Infallible>,
|
||||
parent_id: id::DeviceId,
|
||||
pub(crate) context: RenderPassContext,
|
||||
pub(crate) is_depth_read_only: bool,
|
||||
@ -175,7 +173,7 @@ impl RenderBundleEncoder {
|
||||
pub fn new(
|
||||
desc: &RenderBundleEncoderDescriptor,
|
||||
parent_id: id::DeviceId,
|
||||
base: Option<BasePass<RenderCommand, Infallible>>,
|
||||
base: Option<BasePass<RenderCommand<IdReferences>, Infallible>>,
|
||||
) -> Result<Self, CreateRenderBundleError> {
|
||||
let (is_depth_read_only, is_stencil_read_only) = match desc.depth_stencil {
|
||||
Some(ds) => {
|
||||
@ -252,11 +250,6 @@ impl RenderBundleEncoder {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "trace")]
|
||||
pub(crate) fn to_base_pass(&self) -> BasePass<RenderCommand, Infallible> {
|
||||
self.base.clone()
|
||||
}
|
||||
|
||||
pub fn parent(&self) -> id::DeviceId {
|
||||
self.parent_id
|
||||
}
|
||||
@ -305,12 +298,12 @@ impl RenderBundleEncoder {
|
||||
|
||||
let base = &self.base;
|
||||
|
||||
for &command in &base.commands {
|
||||
for command in &base.commands {
|
||||
match command {
|
||||
RenderCommand::SetBindGroup {
|
||||
&RenderCommand::SetBindGroup {
|
||||
index,
|
||||
num_dynamic_offsets,
|
||||
bind_group_id,
|
||||
bind_group,
|
||||
} => {
|
||||
let scope = PassErrorScope::SetBindGroup;
|
||||
set_bind_group(
|
||||
@ -319,11 +312,11 @@ impl RenderBundleEncoder {
|
||||
&base.dynamic_offsets,
|
||||
index,
|
||||
num_dynamic_offsets,
|
||||
bind_group_id,
|
||||
bind_group,
|
||||
)
|
||||
.map_pass_err(scope)?;
|
||||
}
|
||||
RenderCommand::SetPipeline(pipeline_id) => {
|
||||
&RenderCommand::SetPipeline(pipeline) => {
|
||||
let scope = PassErrorScope::SetPipelineRender;
|
||||
set_pipeline(
|
||||
&mut state,
|
||||
@ -331,12 +324,12 @@ impl RenderBundleEncoder {
|
||||
&self.context,
|
||||
self.is_depth_read_only,
|
||||
self.is_stencil_read_only,
|
||||
pipeline_id,
|
||||
pipeline,
|
||||
)
|
||||
.map_pass_err(scope)?;
|
||||
}
|
||||
RenderCommand::SetIndexBuffer {
|
||||
buffer_id,
|
||||
&RenderCommand::SetIndexBuffer {
|
||||
buffer,
|
||||
index_format,
|
||||
offset,
|
||||
size,
|
||||
@ -345,24 +338,24 @@ impl RenderBundleEncoder {
|
||||
set_index_buffer(
|
||||
&mut state,
|
||||
&buffer_guard,
|
||||
buffer_id,
|
||||
buffer,
|
||||
index_format,
|
||||
offset,
|
||||
size,
|
||||
)
|
||||
.map_pass_err(scope)?;
|
||||
}
|
||||
RenderCommand::SetVertexBuffer {
|
||||
&RenderCommand::SetVertexBuffer {
|
||||
slot,
|
||||
buffer_id,
|
||||
buffer,
|
||||
offset,
|
||||
size,
|
||||
} => {
|
||||
let scope = PassErrorScope::SetVertexBuffer;
|
||||
set_vertex_buffer(&mut state, &buffer_guard, slot, buffer_id, offset, size)
|
||||
set_vertex_buffer(&mut state, &buffer_guard, slot, buffer, offset, size)
|
||||
.map_pass_err(scope)?;
|
||||
}
|
||||
RenderCommand::SetPushConstant {
|
||||
&RenderCommand::SetPushConstant {
|
||||
stages,
|
||||
offset,
|
||||
size_bytes,
|
||||
@ -372,7 +365,7 @@ impl RenderBundleEncoder {
|
||||
set_push_constant(&mut state, stages, offset, size_bytes, values_offset)
|
||||
.map_pass_err(scope)?;
|
||||
}
|
||||
RenderCommand::Draw {
|
||||
&RenderCommand::Draw {
|
||||
vertex_count,
|
||||
instance_count,
|
||||
first_vertex,
|
||||
@ -392,7 +385,7 @@ impl RenderBundleEncoder {
|
||||
)
|
||||
.map_pass_err(scope)?;
|
||||
}
|
||||
RenderCommand::DrawIndexed {
|
||||
&RenderCommand::DrawIndexed {
|
||||
index_count,
|
||||
instance_count,
|
||||
first_index,
|
||||
@ -414,7 +407,7 @@ impl RenderBundleEncoder {
|
||||
)
|
||||
.map_pass_err(scope)?;
|
||||
}
|
||||
RenderCommand::DrawMeshTasks {
|
||||
&RenderCommand::DrawMeshTasks {
|
||||
group_count_x,
|
||||
group_count_y,
|
||||
group_count_z,
|
||||
@ -432,11 +425,13 @@ impl RenderBundleEncoder {
|
||||
)
|
||||
.map_pass_err(scope)?;
|
||||
}
|
||||
RenderCommand::DrawIndirect {
|
||||
buffer_id,
|
||||
&RenderCommand::DrawIndirect {
|
||||
buffer,
|
||||
offset,
|
||||
count: 1,
|
||||
family,
|
||||
vertex_or_index_limit: None,
|
||||
instance_limit: None,
|
||||
} => {
|
||||
let scope = PassErrorScope::Draw {
|
||||
kind: DrawKind::DrawIndirect,
|
||||
@ -446,32 +441,39 @@ impl RenderBundleEncoder {
|
||||
&mut state,
|
||||
&base.dynamic_offsets,
|
||||
&buffer_guard,
|
||||
buffer_id,
|
||||
buffer,
|
||||
offset,
|
||||
family,
|
||||
)
|
||||
.map_pass_err(scope)?;
|
||||
}
|
||||
RenderCommand::DrawIndirect { .. }
|
||||
| RenderCommand::MultiDrawIndirectCount { .. }
|
||||
| RenderCommand::PushDebugGroup { color: _, len: _ }
|
||||
| RenderCommand::InsertDebugMarker { color: _, len: _ }
|
||||
| RenderCommand::PopDebugGroup => {
|
||||
&RenderCommand::DrawIndirect {
|
||||
count,
|
||||
vertex_or_index_limit,
|
||||
instance_limit,
|
||||
..
|
||||
} => {
|
||||
unreachable!("unexpected (multi-)draw indirect with count {count}, vertex_or_index_limits {vertex_or_index_limit:?}, instance_limit {instance_limit:?} found in a render bundle");
|
||||
}
|
||||
&RenderCommand::MultiDrawIndirectCount { .. }
|
||||
| &RenderCommand::PushDebugGroup { color: _, len: _ }
|
||||
| &RenderCommand::InsertDebugMarker { color: _, len: _ }
|
||||
| &RenderCommand::PopDebugGroup => {
|
||||
unimplemented!("not supported by a render bundle")
|
||||
}
|
||||
// Must check the TIMESTAMP_QUERY_INSIDE_PASSES feature
|
||||
RenderCommand::WriteTimestamp { .. }
|
||||
| RenderCommand::BeginOcclusionQuery { .. }
|
||||
| RenderCommand::EndOcclusionQuery
|
||||
| RenderCommand::BeginPipelineStatisticsQuery { .. }
|
||||
| RenderCommand::EndPipelineStatisticsQuery => {
|
||||
&RenderCommand::WriteTimestamp { .. }
|
||||
| &RenderCommand::BeginOcclusionQuery { .. }
|
||||
| &RenderCommand::EndOcclusionQuery
|
||||
| &RenderCommand::BeginPipelineStatisticsQuery { .. }
|
||||
| &RenderCommand::EndPipelineStatisticsQuery => {
|
||||
unimplemented!("not supported by a render bundle")
|
||||
}
|
||||
RenderCommand::ExecuteBundle(_)
|
||||
| RenderCommand::SetBlendConstant(_)
|
||||
| RenderCommand::SetStencilReference(_)
|
||||
| RenderCommand::SetViewport { .. }
|
||||
| RenderCommand::SetScissor(_) => unreachable!("not supported by a render bundle"),
|
||||
&RenderCommand::ExecuteBundle(_)
|
||||
| &RenderCommand::SetBlendConstant(_)
|
||||
| &RenderCommand::SetStencilReference(_)
|
||||
| &RenderCommand::SetViewport { .. }
|
||||
| &RenderCommand::SetScissor(_) => unreachable!("not supported by a render bundle"),
|
||||
}
|
||||
}
|
||||
|
||||
@ -518,13 +520,13 @@ impl RenderBundleEncoder {
|
||||
|
||||
pub fn set_index_buffer(
|
||||
&mut self,
|
||||
buffer_id: id::BufferId,
|
||||
buffer: id::BufferId,
|
||||
index_format: wgt::IndexFormat,
|
||||
offset: wgt::BufferAddress,
|
||||
size: Option<wgt::BufferSize>,
|
||||
) {
|
||||
self.base.commands.push(RenderCommand::SetIndexBuffer {
|
||||
buffer_id,
|
||||
buffer,
|
||||
index_format,
|
||||
offset,
|
||||
size,
|
||||
@ -899,8 +901,8 @@ fn multi_draw_indirect(
|
||||
count: 1,
|
||||
family,
|
||||
|
||||
vertex_or_index_limit,
|
||||
instance_limit,
|
||||
vertex_or_index_limit: Some(vertex_or_index_limit),
|
||||
instance_limit: Some(instance_limit),
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
@ -941,6 +943,7 @@ 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.
|
||||
/// cbindgen:ignore
|
||||
#[derive(Debug)]
|
||||
pub struct RenderBundle {
|
||||
// Normalized command stream. It can be executed verbatim,
|
||||
@ -971,6 +974,11 @@ unsafe impl Send for RenderBundle {}
|
||||
unsafe impl Sync for RenderBundle {}
|
||||
|
||||
impl RenderBundle {
|
||||
#[cfg(feature = "trace")]
|
||||
pub(crate) fn to_base_pass(&self) -> BasePass<RenderCommand<ArcReferences>, Infallible> {
|
||||
self.base.clone()
|
||||
}
|
||||
|
||||
/// Actually encode the contents into a native command buffer.
|
||||
///
|
||||
/// This is partially duplicating the logic of `render_pass_end`.
|
||||
@ -1142,8 +1150,9 @@ impl RenderBundle {
|
||||
buffer,
|
||||
*offset,
|
||||
*family,
|
||||
*vertex_or_index_limit,
|
||||
*instance_limit,
|
||||
vertex_or_index_limit
|
||||
.expect("finalized render bundle missing vertex_or_index_limit"),
|
||||
instance_limit.expect("finalized render bundle missing instance_limit"),
|
||||
)?;
|
||||
|
||||
let dst_buffer =
|
||||
@ -1590,7 +1599,7 @@ impl State {
|
||||
|
||||
/// Error encountered when finishing recording a render bundle.
|
||||
#[derive(Clone, Debug, Error)]
|
||||
pub(super) enum RenderBundleErrorInner {
|
||||
pub enum RenderBundleErrorInner {
|
||||
#[error(transparent)]
|
||||
Device(#[from] DeviceError),
|
||||
#[error(transparent)]
|
||||
@ -1692,7 +1701,7 @@ pub mod bundle_ffi {
|
||||
bundle.base.commands.push(RenderCommand::SetBindGroup {
|
||||
index,
|
||||
num_dynamic_offsets: offset_length,
|
||||
bind_group_id,
|
||||
bind_group: bind_group_id,
|
||||
});
|
||||
}
|
||||
|
||||
@ -1719,7 +1728,7 @@ pub mod bundle_ffi {
|
||||
) {
|
||||
bundle.base.commands.push(RenderCommand::SetVertexBuffer {
|
||||
slot,
|
||||
buffer_id,
|
||||
buffer: buffer_id,
|
||||
offset,
|
||||
size,
|
||||
});
|
||||
@ -1813,10 +1822,12 @@ pub mod bundle_ffi {
|
||||
offset: BufferAddress,
|
||||
) {
|
||||
bundle.base.commands.push(RenderCommand::DrawIndirect {
|
||||
buffer_id,
|
||||
buffer: buffer_id,
|
||||
offset,
|
||||
count: 1,
|
||||
family: DrawCommandFamily::Draw,
|
||||
vertex_or_index_limit: None,
|
||||
instance_limit: None,
|
||||
});
|
||||
}
|
||||
|
||||
@ -1826,10 +1837,12 @@ pub mod bundle_ffi {
|
||||
offset: BufferAddress,
|
||||
) {
|
||||
bundle.base.commands.push(RenderCommand::DrawIndirect {
|
||||
buffer_id,
|
||||
buffer: buffer_id,
|
||||
offset,
|
||||
count: 1,
|
||||
family: DrawCommandFamily::DrawIndexed,
|
||||
vertex_or_index_limit: None,
|
||||
instance_limit: None,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -1,8 +1,6 @@
|
||||
use alloc::{sync::Arc, vec::Vec};
|
||||
use core::ops::Range;
|
||||
|
||||
#[cfg(feature = "trace")]
|
||||
use crate::command::Command as TraceCommand;
|
||||
use crate::{
|
||||
api_log,
|
||||
command::{encoder::EncodingState, ArcCommand, EncoderStateError},
|
||||
@ -119,11 +117,6 @@ impl Global {
|
||||
let cmd_enc = hub.command_encoders.get(command_encoder_id);
|
||||
let mut cmd_buf_data = cmd_enc.data.lock();
|
||||
|
||||
#[cfg(feature = "trace")]
|
||||
if let Some(ref mut list) = cmd_buf_data.trace() {
|
||||
list.push(TraceCommand::ClearBuffer { dst, offset, size });
|
||||
}
|
||||
|
||||
cmd_buf_data.push_with(|| -> Result<_, ClearError> {
|
||||
Ok(ArcCommand::ClearBuffer {
|
||||
dst: self.resolve_buffer_id(dst)?,
|
||||
@ -147,14 +140,6 @@ impl Global {
|
||||
let cmd_enc = hub.command_encoders.get(command_encoder_id);
|
||||
let mut cmd_buf_data = cmd_enc.data.lock();
|
||||
|
||||
#[cfg(feature = "trace")]
|
||||
if let Some(ref mut list) = cmd_buf_data.trace() {
|
||||
list.push(TraceCommand::ClearTexture {
|
||||
dst,
|
||||
subresource_range: *subresource_range,
|
||||
});
|
||||
}
|
||||
|
||||
cmd_buf_data.push_with(|| -> Result<_, ClearError> {
|
||||
Ok(ArcCommand::ClearTexture {
|
||||
dst: self.resolve_texture_id(dst)?,
|
||||
|
||||
@ -456,73 +456,6 @@ impl Global {
|
||||
}
|
||||
}
|
||||
|
||||
/// Note that this differs from [`Self::compute_pass_end`], it will
|
||||
/// create a new pass, replay the commands and end the pass.
|
||||
///
|
||||
/// # Panics
|
||||
/// On any error.
|
||||
#[doc(hidden)]
|
||||
#[cfg(any(feature = "serde", feature = "replay"))]
|
||||
pub fn compute_pass_end_with_unresolved_commands(
|
||||
&self,
|
||||
encoder_id: id::CommandEncoderId,
|
||||
base: BasePass<super::ComputeCommand, Infallible>,
|
||||
timestamp_writes: Option<&PassTimestampWrites>,
|
||||
) {
|
||||
#[cfg(feature = "trace")]
|
||||
{
|
||||
let cmd_enc = self.hub.command_encoders.get(encoder_id);
|
||||
let mut cmd_buf_data = cmd_enc.data.lock();
|
||||
let cmd_buf_data = cmd_buf_data.get_inner();
|
||||
|
||||
if let Some(ref mut list) = cmd_buf_data.trace_commands {
|
||||
list.push(crate::command::Command::RunComputePass {
|
||||
base: BasePass {
|
||||
label: base.label.clone(),
|
||||
error: None,
|
||||
commands: base.commands.clone(),
|
||||
dynamic_offsets: base.dynamic_offsets.clone(),
|
||||
string_data: base.string_data.clone(),
|
||||
push_constant_data: base.push_constant_data.clone(),
|
||||
},
|
||||
timestamp_writes: timestamp_writes.cloned(),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
let BasePass {
|
||||
label,
|
||||
error: _,
|
||||
commands,
|
||||
dynamic_offsets,
|
||||
string_data,
|
||||
push_constant_data,
|
||||
} = base;
|
||||
|
||||
let (mut compute_pass, encoder_error) = self.command_encoder_begin_compute_pass(
|
||||
encoder_id,
|
||||
&ComputePassDescriptor {
|
||||
label: label.as_deref().map(Cow::Borrowed),
|
||||
timestamp_writes: timestamp_writes.cloned(),
|
||||
},
|
||||
);
|
||||
if let Some(err) = encoder_error {
|
||||
panic!("{:?}", err);
|
||||
};
|
||||
|
||||
compute_pass.base = BasePass {
|
||||
label,
|
||||
error: None,
|
||||
commands: super::ComputeCommand::resolve_compute_command_ids(&self.hub, &commands)
|
||||
.unwrap(),
|
||||
dynamic_offsets,
|
||||
string_data,
|
||||
push_constant_data,
|
||||
};
|
||||
|
||||
self.compute_pass_end(&mut compute_pass).unwrap();
|
||||
}
|
||||
|
||||
pub fn compute_pass_end(&self, pass: &mut ComputePass) -> Result<(), EncoderStateError> {
|
||||
profiling::scope!(
|
||||
"CommandEncoder::run_compute_pass {}",
|
||||
|
||||
@ -1,208 +1,18 @@
|
||||
use alloc::sync::Arc;
|
||||
use crate::command::{serde_object_reference_struct, ArcReferences, ReferenceType};
|
||||
|
||||
use crate::{
|
||||
binding_model::BindGroup,
|
||||
id,
|
||||
pipeline::ComputePipeline,
|
||||
resource::{Buffer, QuerySet},
|
||||
};
|
||||
use macro_rules_attribute::apply;
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
pub enum ComputeCommand {
|
||||
SetBindGroup {
|
||||
index: u32,
|
||||
num_dynamic_offsets: usize,
|
||||
bind_group_id: Option<id::BindGroupId>,
|
||||
},
|
||||
|
||||
SetPipeline(id::ComputePipelineId),
|
||||
|
||||
/// Set a range of push constants to values stored in `push_constant_data`.
|
||||
SetPushConstant {
|
||||
/// The byte offset within the push constant storage to write to. This
|
||||
/// must be a multiple of four.
|
||||
offset: u32,
|
||||
|
||||
/// The number of bytes to write. This must be a multiple of four.
|
||||
size_bytes: u32,
|
||||
|
||||
/// Index in `push_constant_data` of the start of the data
|
||||
/// to be written.
|
||||
///
|
||||
/// Note: this is not a byte offset like `offset`. Rather, it is the
|
||||
/// index of the first `u32` element in `push_constant_data` to read.
|
||||
values_offset: u32,
|
||||
},
|
||||
|
||||
Dispatch([u32; 3]),
|
||||
|
||||
DispatchIndirect {
|
||||
buffer_id: id::BufferId,
|
||||
offset: wgt::BufferAddress,
|
||||
},
|
||||
|
||||
PushDebugGroup {
|
||||
color: u32,
|
||||
len: usize,
|
||||
},
|
||||
|
||||
PopDebugGroup,
|
||||
|
||||
InsertDebugMarker {
|
||||
color: u32,
|
||||
len: usize,
|
||||
},
|
||||
|
||||
WriteTimestamp {
|
||||
query_set_id: id::QuerySetId,
|
||||
query_index: u32,
|
||||
},
|
||||
|
||||
BeginPipelineStatisticsQuery {
|
||||
query_set_id: id::QuerySetId,
|
||||
query_index: u32,
|
||||
},
|
||||
|
||||
EndPipelineStatisticsQuery,
|
||||
}
|
||||
|
||||
impl ComputeCommand {
|
||||
/// Resolves all ids in a list of commands into the corresponding resource Arc.
|
||||
#[cfg(any(feature = "serde", feature = "replay"))]
|
||||
pub fn resolve_compute_command_ids(
|
||||
hub: &crate::hub::Hub,
|
||||
commands: &[ComputeCommand],
|
||||
) -> Result<alloc::vec::Vec<ArcComputeCommand>, super::ComputePassError> {
|
||||
use super::{ComputePassError, PassErrorScope};
|
||||
use alloc::vec::Vec;
|
||||
|
||||
let buffers_guard = hub.buffers.read();
|
||||
let bind_group_guard = hub.bind_groups.read();
|
||||
let query_set_guard = hub.query_sets.read();
|
||||
let pipelines_guard = hub.compute_pipelines.read();
|
||||
|
||||
let resolved_commands: Vec<ArcComputeCommand> = commands
|
||||
.iter()
|
||||
.map(|c| -> Result<ArcComputeCommand, ComputePassError> {
|
||||
Ok(match *c {
|
||||
ComputeCommand::SetBindGroup {
|
||||
index,
|
||||
num_dynamic_offsets,
|
||||
bind_group_id,
|
||||
} => {
|
||||
if bind_group_id.is_none() {
|
||||
return Ok(ArcComputeCommand::SetBindGroup {
|
||||
index,
|
||||
num_dynamic_offsets,
|
||||
bind_group: None,
|
||||
});
|
||||
}
|
||||
|
||||
let bind_group_id = bind_group_id.unwrap();
|
||||
let bg = bind_group_guard.get(bind_group_id).get().map_err(|e| {
|
||||
ComputePassError {
|
||||
scope: PassErrorScope::SetBindGroup,
|
||||
inner: e.into(),
|
||||
}
|
||||
})?;
|
||||
|
||||
ArcComputeCommand::SetBindGroup {
|
||||
index,
|
||||
num_dynamic_offsets,
|
||||
bind_group: Some(bg),
|
||||
}
|
||||
}
|
||||
ComputeCommand::SetPipeline(pipeline_id) => ArcComputeCommand::SetPipeline(
|
||||
pipelines_guard
|
||||
.get(pipeline_id)
|
||||
.get()
|
||||
.map_err(|e| ComputePassError {
|
||||
scope: PassErrorScope::SetPipelineCompute,
|
||||
inner: e.into(),
|
||||
})?,
|
||||
),
|
||||
|
||||
ComputeCommand::SetPushConstant {
|
||||
offset,
|
||||
size_bytes,
|
||||
values_offset,
|
||||
} => ArcComputeCommand::SetPushConstant {
|
||||
offset,
|
||||
size_bytes,
|
||||
values_offset,
|
||||
},
|
||||
|
||||
ComputeCommand::Dispatch(dim) => ArcComputeCommand::Dispatch(dim),
|
||||
|
||||
ComputeCommand::DispatchIndirect { buffer_id, offset } => {
|
||||
ArcComputeCommand::DispatchIndirect {
|
||||
buffer: buffers_guard.get(buffer_id).get().map_err(|e| {
|
||||
ComputePassError {
|
||||
scope: PassErrorScope::Dispatch { indirect: true },
|
||||
inner: e.into(),
|
||||
}
|
||||
})?,
|
||||
offset,
|
||||
}
|
||||
}
|
||||
|
||||
ComputeCommand::PushDebugGroup { color, len } => {
|
||||
ArcComputeCommand::PushDebugGroup { color, len }
|
||||
}
|
||||
|
||||
ComputeCommand::PopDebugGroup => ArcComputeCommand::PopDebugGroup,
|
||||
|
||||
ComputeCommand::InsertDebugMarker { color, len } => {
|
||||
ArcComputeCommand::InsertDebugMarker { color, len }
|
||||
}
|
||||
|
||||
ComputeCommand::WriteTimestamp {
|
||||
query_set_id,
|
||||
query_index,
|
||||
} => ArcComputeCommand::WriteTimestamp {
|
||||
query_set: query_set_guard.get(query_set_id).get().map_err(|e| {
|
||||
ComputePassError {
|
||||
scope: PassErrorScope::WriteTimestamp,
|
||||
inner: e.into(),
|
||||
}
|
||||
})?,
|
||||
query_index,
|
||||
},
|
||||
|
||||
ComputeCommand::BeginPipelineStatisticsQuery {
|
||||
query_set_id,
|
||||
query_index,
|
||||
} => ArcComputeCommand::BeginPipelineStatisticsQuery {
|
||||
query_set: query_set_guard.get(query_set_id).get().map_err(|e| {
|
||||
ComputePassError {
|
||||
scope: PassErrorScope::BeginPipelineStatisticsQuery,
|
||||
inner: e.into(),
|
||||
}
|
||||
})?,
|
||||
query_index,
|
||||
},
|
||||
|
||||
ComputeCommand::EndPipelineStatisticsQuery => {
|
||||
ArcComputeCommand::EndPipelineStatisticsQuery
|
||||
}
|
||||
})
|
||||
})
|
||||
.collect::<Result<Vec<_>, ComputePassError>>()?;
|
||||
Ok(resolved_commands)
|
||||
}
|
||||
}
|
||||
|
||||
/// Equivalent to `ComputeCommand` but the Ids resolved into resource Arcs.
|
||||
/// cbindgen:ignore
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum ArcComputeCommand {
|
||||
#[cfg_attr(feature = "serde", apply(serde_object_reference_struct))]
|
||||
pub enum ComputeCommand<R: ReferenceType> {
|
||||
SetBindGroup {
|
||||
index: u32,
|
||||
num_dynamic_offsets: usize,
|
||||
bind_group: Option<Arc<BindGroup>>,
|
||||
bind_group: Option<R::BindGroup>,
|
||||
},
|
||||
|
||||
SetPipeline(Arc<ComputePipeline>),
|
||||
SetPipeline(R::ComputePipeline),
|
||||
|
||||
/// Set a range of push constants to values stored in `push_constant_data`.
|
||||
SetPushConstant {
|
||||
@ -224,12 +34,12 @@ pub enum ArcComputeCommand {
|
||||
Dispatch([u32; 3]),
|
||||
|
||||
DispatchIndirect {
|
||||
buffer: Arc<Buffer>,
|
||||
buffer: R::Buffer,
|
||||
offset: wgt::BufferAddress,
|
||||
},
|
||||
|
||||
PushDebugGroup {
|
||||
#[cfg_attr(not(any(feature = "serde", feature = "replay")), allow(dead_code))]
|
||||
//#[cfg_attr(not(any(feature = "serde", feature = "replay")), allow(dead_code))]
|
||||
color: u32,
|
||||
len: usize,
|
||||
},
|
||||
@ -237,20 +47,22 @@ pub enum ArcComputeCommand {
|
||||
PopDebugGroup,
|
||||
|
||||
InsertDebugMarker {
|
||||
#[cfg_attr(not(any(feature = "serde", feature = "replay")), allow(dead_code))]
|
||||
color: u32,
|
||||
len: usize,
|
||||
},
|
||||
|
||||
WriteTimestamp {
|
||||
query_set: Arc<QuerySet>,
|
||||
query_set: R::QuerySet,
|
||||
query_index: u32,
|
||||
},
|
||||
|
||||
BeginPipelineStatisticsQuery {
|
||||
query_set: Arc<QuerySet>,
|
||||
query_set: R::QuerySet,
|
||||
query_index: u32,
|
||||
},
|
||||
|
||||
EndPipelineStatisticsQuery,
|
||||
}
|
||||
|
||||
/// cbindgen:ignore
|
||||
pub type ArcComputeCommand = ComputeCommand<ArcReferences>;
|
||||
|
||||
@ -2,15 +2,18 @@ use core::convert::Infallible;
|
||||
|
||||
use alloc::{string::String, sync::Arc, vec::Vec};
|
||||
#[cfg(feature = "serde")]
|
||||
use macro_rules_attribute::attribute_alias;
|
||||
use macro_rules_attribute::{apply, attribute_alias};
|
||||
|
||||
use crate::{
|
||||
command::ColorAttachments,
|
||||
id,
|
||||
instance::Surface,
|
||||
resource::{Buffer, QuerySet, Texture},
|
||||
};
|
||||
|
||||
pub trait ReferenceType {
|
||||
type Buffer: Clone + core::fmt::Debug;
|
||||
type Surface: Clone; // Surface does not implement Debug, although it probably could.
|
||||
type Texture: Clone + core::fmt::Debug;
|
||||
type TextureView: Clone + core::fmt::Debug;
|
||||
type QuerySet: Clone + core::fmt::Debug;
|
||||
@ -22,14 +25,26 @@ pub trait ReferenceType {
|
||||
type Tlas: Clone + core::fmt::Debug;
|
||||
}
|
||||
|
||||
/// Reference wgpu objects via numeric IDs assigned by [`crate::identity::IdentityManager`].
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct IdReferences;
|
||||
|
||||
/// Reference wgpu objects via the integer value of pointers.
|
||||
///
|
||||
/// This is used for trace recording and playback. Recording stores the pointer
|
||||
/// value of `Arc` references in the trace. Playback uses the integer values
|
||||
/// as keys to a `HashMap`.
|
||||
#[doc(hidden)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct PointerReferences;
|
||||
|
||||
/// Reference wgpu objects via `Arc`s.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct ArcReferences;
|
||||
|
||||
impl ReferenceType for IdReferences {
|
||||
type Buffer = id::BufferId;
|
||||
type Surface = id::SurfaceId;
|
||||
type Texture = id::TextureId;
|
||||
type TextureView = id::TextureViewId;
|
||||
type QuerySet = id::QuerySetId;
|
||||
@ -41,8 +56,23 @@ impl ReferenceType for IdReferences {
|
||||
type Tlas = id::TlasId;
|
||||
}
|
||||
|
||||
impl ReferenceType for PointerReferences {
|
||||
type Buffer = id::PointerId<id::markers::Buffer>;
|
||||
type Surface = id::PointerId<id::markers::Surface>;
|
||||
type Texture = id::PointerId<id::markers::Texture>;
|
||||
type TextureView = id::PointerId<id::markers::TextureView>;
|
||||
type QuerySet = id::PointerId<id::markers::QuerySet>;
|
||||
type BindGroup = id::PointerId<id::markers::BindGroup>;
|
||||
type RenderPipeline = id::PointerId<id::markers::RenderPipeline>;
|
||||
type RenderBundle = id::PointerId<id::markers::RenderBundle>;
|
||||
type ComputePipeline = id::PointerId<id::markers::ComputePipeline>;
|
||||
type Blas = id::PointerId<id::markers::Blas>;
|
||||
type Tlas = id::PointerId<id::markers::Tlas>;
|
||||
}
|
||||
|
||||
impl ReferenceType for ArcReferences {
|
||||
type Buffer = Arc<Buffer>;
|
||||
type Surface = Arc<Surface>;
|
||||
type Texture = Arc<Texture>;
|
||||
type TextureView = Arc<crate::resource::TextureView>;
|
||||
type QuerySet = Arc<QuerySet>;
|
||||
@ -60,6 +90,7 @@ attribute_alias! {
|
||||
#[derive(serde::Serialize, serde::Deserialize)]
|
||||
#[serde(bound =
|
||||
"R::Buffer: serde::Serialize + for<'d> serde::Deserialize<'d>,\
|
||||
R::Surface: serde::Serialize + for<'d> serde::Deserialize<'d>,\
|
||||
R::Texture: serde::Serialize + for<'d> serde::Deserialize<'d>,\
|
||||
R::TextureView: serde::Serialize + for<'d> serde::Deserialize<'d>,\
|
||||
R::QuerySet: serde::Serialize + for<'d> serde::Deserialize<'d>,\
|
||||
@ -68,139 +99,80 @@ attribute_alias! {
|
||||
R::RenderBundle: serde::Serialize + for<'d> serde::Deserialize<'d>,\
|
||||
R::ComputePipeline: serde::Serialize + for<'d> serde::Deserialize<'d>,\
|
||||
R::Blas: serde::Serialize + for<'d> serde::Deserialize<'d>,\
|
||||
R::Tlas: serde::Serialize + for<'d> serde::Deserialize<'d>"
|
||||
R::Tlas: serde::Serialize + for<'d> serde::Deserialize<'d>,\
|
||||
wgt::BufferTransition<R::Buffer>: serde::Serialize + for<'d> serde::Deserialize<'d>,\
|
||||
wgt::TextureTransition<R::Texture>: serde::Serialize + for<'d> serde::Deserialize<'d>"
|
||||
)];
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
pub enum Command {
|
||||
#[cfg_attr(feature = "serde", apply(serde_object_reference_struct))]
|
||||
pub enum Command<R: ReferenceType> {
|
||||
CopyBufferToBuffer {
|
||||
src: id::BufferId,
|
||||
src: R::Buffer,
|
||||
src_offset: wgt::BufferAddress,
|
||||
dst: id::BufferId,
|
||||
dst: R::Buffer,
|
||||
dst_offset: wgt::BufferAddress,
|
||||
size: Option<wgt::BufferAddress>,
|
||||
},
|
||||
CopyBufferToTexture {
|
||||
src: wgt::TexelCopyBufferInfo<id::BufferId>,
|
||||
dst: wgt::TexelCopyTextureInfo<id::TextureId>,
|
||||
src: wgt::TexelCopyBufferInfo<R::Buffer>,
|
||||
dst: wgt::TexelCopyTextureInfo<R::Texture>,
|
||||
size: wgt::Extent3d,
|
||||
},
|
||||
CopyTextureToBuffer {
|
||||
src: wgt::TexelCopyTextureInfo<id::TextureId>,
|
||||
dst: wgt::TexelCopyBufferInfo<id::BufferId>,
|
||||
src: wgt::TexelCopyTextureInfo<R::Texture>,
|
||||
dst: wgt::TexelCopyBufferInfo<R::Buffer>,
|
||||
size: wgt::Extent3d,
|
||||
},
|
||||
CopyTextureToTexture {
|
||||
src: wgt::TexelCopyTextureInfo<id::TextureId>,
|
||||
dst: wgt::TexelCopyTextureInfo<id::TextureId>,
|
||||
src: wgt::TexelCopyTextureInfo<R::Texture>,
|
||||
dst: wgt::TexelCopyTextureInfo<R::Texture>,
|
||||
size: wgt::Extent3d,
|
||||
},
|
||||
ClearBuffer {
|
||||
dst: id::BufferId,
|
||||
dst: R::Buffer,
|
||||
offset: wgt::BufferAddress,
|
||||
size: Option<wgt::BufferAddress>,
|
||||
},
|
||||
ClearTexture {
|
||||
dst: id::TextureId,
|
||||
dst: R::Texture,
|
||||
subresource_range: wgt::ImageSubresourceRange,
|
||||
},
|
||||
WriteTimestamp {
|
||||
query_set_id: id::QuerySetId,
|
||||
query_set: R::QuerySet,
|
||||
query_index: u32,
|
||||
},
|
||||
ResolveQuerySet {
|
||||
query_set_id: id::QuerySetId,
|
||||
query_set: R::QuerySet,
|
||||
start_query: u32,
|
||||
query_count: u32,
|
||||
destination: id::BufferId,
|
||||
destination: R::Buffer,
|
||||
destination_offset: wgt::BufferAddress,
|
||||
},
|
||||
PushDebugGroup(String),
|
||||
PopDebugGroup,
|
||||
InsertDebugMarker(String),
|
||||
RunComputePass {
|
||||
base: crate::command::BasePass<crate::command::ComputeCommand, Infallible>,
|
||||
timestamp_writes: Option<crate::command::PassTimestampWrites>,
|
||||
pass: crate::command::BasePass<crate::command::ComputeCommand<R>, Infallible>,
|
||||
timestamp_writes: Option<crate::command::PassTimestampWrites<R::QuerySet>>,
|
||||
},
|
||||
RunRenderPass {
|
||||
base: crate::command::BasePass<crate::command::RenderCommand, Infallible>,
|
||||
target_colors: Vec<Option<crate::command::RenderPassColorAttachment>>,
|
||||
target_depth_stencil: Option<crate::command::RenderPassDepthStencilAttachment>,
|
||||
timestamp_writes: Option<crate::command::PassTimestampWrites>,
|
||||
occlusion_query_set_id: Option<id::QuerySetId>,
|
||||
pass: crate::command::BasePass<crate::command::RenderCommand<R>, Infallible>,
|
||||
color_attachments: ColorAttachments<R::TextureView>,
|
||||
depth_stencil_attachment:
|
||||
Option<crate::command::ResolvedRenderPassDepthStencilAttachment<R::TextureView>>,
|
||||
timestamp_writes: Option<crate::command::PassTimestampWrites<R::QuerySet>>,
|
||||
occlusion_query_set: Option<R::QuerySet>,
|
||||
},
|
||||
BuildAccelerationStructures {
|
||||
blas: Vec<crate::ray_tracing::TraceBlasBuildEntry>,
|
||||
tlas: Vec<crate::ray_tracing::TraceTlasPackage>,
|
||||
blas: Vec<crate::ray_tracing::OwnedBlasBuildEntry<R>>,
|
||||
tlas: Vec<crate::ray_tracing::OwnedTlasPackage<R>>,
|
||||
},
|
||||
TransitionResources {
|
||||
buffer_transitions: Vec<wgt::BufferTransition<R::Buffer>>,
|
||||
texture_transitions: Vec<wgt::TextureTransition<R::Texture>>,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum ArcCommand {
|
||||
CopyBufferToBuffer {
|
||||
src: Arc<Buffer>,
|
||||
src_offset: wgt::BufferAddress,
|
||||
dst: Arc<Buffer>,
|
||||
dst_offset: wgt::BufferAddress,
|
||||
size: Option<wgt::BufferAddress>,
|
||||
},
|
||||
CopyBufferToTexture {
|
||||
src: wgt::TexelCopyBufferInfo<Arc<Buffer>>,
|
||||
dst: wgt::TexelCopyTextureInfo<Arc<Texture>>,
|
||||
size: wgt::Extent3d,
|
||||
},
|
||||
CopyTextureToBuffer {
|
||||
src: wgt::TexelCopyTextureInfo<Arc<Texture>>,
|
||||
dst: wgt::TexelCopyBufferInfo<Arc<Buffer>>,
|
||||
size: wgt::Extent3d,
|
||||
},
|
||||
CopyTextureToTexture {
|
||||
src: wgt::TexelCopyTextureInfo<Arc<Texture>>,
|
||||
dst: wgt::TexelCopyTextureInfo<Arc<Texture>>,
|
||||
size: wgt::Extent3d,
|
||||
},
|
||||
ClearBuffer {
|
||||
dst: Arc<Buffer>,
|
||||
offset: wgt::BufferAddress,
|
||||
size: Option<wgt::BufferAddress>,
|
||||
},
|
||||
ClearTexture {
|
||||
dst: Arc<Texture>,
|
||||
subresource_range: wgt::ImageSubresourceRange,
|
||||
},
|
||||
WriteTimestamp {
|
||||
query_set: Arc<QuerySet>,
|
||||
query_index: u32,
|
||||
},
|
||||
ResolveQuerySet {
|
||||
query_set: Arc<QuerySet>,
|
||||
start_query: u32,
|
||||
query_count: u32,
|
||||
destination: Arc<Buffer>,
|
||||
destination_offset: wgt::BufferAddress,
|
||||
},
|
||||
PushDebugGroup(String),
|
||||
PopDebugGroup,
|
||||
InsertDebugMarker(String),
|
||||
RunComputePass {
|
||||
pass: super::BasePass<super::ArcComputeCommand, Infallible>,
|
||||
timestamp_writes: Option<super::ArcPassTimestampWrites>,
|
||||
},
|
||||
RunRenderPass {
|
||||
pass: super::BasePass<super::ArcRenderCommand, Infallible>,
|
||||
color_attachments: super::ArcRenderPassColorAttachmentArray,
|
||||
depth_stencil_attachment: Option<super::ArcRenderPassDepthStencilAttachment>,
|
||||
timestamp_writes: Option<super::ArcPassTimestampWrites>,
|
||||
occlusion_query_set: Option<Arc<QuerySet>>,
|
||||
},
|
||||
BuildAccelerationStructures {
|
||||
blas: Vec<crate::ray_tracing::ArcBlasBuildEntry>,
|
||||
tlas: Vec<crate::ray_tracing::ArcTlasPackage>,
|
||||
},
|
||||
TransitionResources {
|
||||
buffer_transitions: Vec<wgt::BufferTransition<Arc<Buffer>>>,
|
||||
texture_transitions: Vec<wgt::TextureTransition<Arc<Texture>>>,
|
||||
},
|
||||
}
|
||||
pub type ArcCommand = Command<ArcReferences>;
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
//! Types that are useful for FFI bindings to `wgpu`.
|
||||
|
||||
use crate::id;
|
||||
use crate::{command::IdReferences, id};
|
||||
|
||||
pub type TexelCopyBufferInfo = wgt::TexelCopyBufferInfo<id::BufferId>;
|
||||
pub type TexelCopyTextureInfo = wgt::TexelCopyTextureInfo<id::TextureId>;
|
||||
pub type CopyExternalImageDestInfo = wgt::CopyExternalImageDestInfo<id::TextureId>;
|
||||
|
||||
pub type Command = super::Command<IdReferences>;
|
||||
|
||||
@ -36,20 +36,25 @@ use core::ops;
|
||||
pub(crate) use self::clear::clear_texture;
|
||||
#[cfg(feature = "serde")]
|
||||
pub(crate) use self::encoder_command::serde_object_reference_struct;
|
||||
#[cfg(feature = "trace")]
|
||||
pub(crate) use self::encoder_command::PointerReferences;
|
||||
pub use self::{
|
||||
bundle::*,
|
||||
clear::ClearError,
|
||||
compute::*,
|
||||
compute_command::{ArcComputeCommand, ComputeCommand},
|
||||
compute_command::ArcComputeCommand,
|
||||
draw::*,
|
||||
encoder_command::{ArcCommand, ArcReferences, Command, IdReferences, ReferenceType},
|
||||
query::*,
|
||||
render::*,
|
||||
render_command::{ArcRenderCommand, RenderCommand},
|
||||
render_command::ArcRenderCommand,
|
||||
transfer::*,
|
||||
};
|
||||
pub(crate) use allocator::CommandAllocator;
|
||||
|
||||
/// cbindgen:ignore
|
||||
pub use self::{compute_command::ComputeCommand, render_command::RenderCommand};
|
||||
|
||||
pub(crate) use timestamp_writes::ArcPassTimestampWrites;
|
||||
pub use timestamp_writes::PassTimestampWrites;
|
||||
|
||||
@ -83,9 +88,6 @@ use wgt::error::{ErrorType, WebGpuError};
|
||||
|
||||
use thiserror::Error;
|
||||
|
||||
#[cfg(feature = "trace")]
|
||||
type TraceCommand = Command;
|
||||
|
||||
/// cbindgen:ignore
|
||||
pub type TexelCopyBufferInfo = ffi::TexelCopyBufferInfo;
|
||||
/// cbindgen:ignore
|
||||
@ -150,14 +152,6 @@ pub(crate) enum CommandEncoderStatus {
|
||||
}
|
||||
|
||||
impl CommandEncoderStatus {
|
||||
#[cfg(feature = "trace")]
|
||||
fn trace(&mut self) -> Option<&mut Vec<TraceCommand>> {
|
||||
match self {
|
||||
Self::Recording(cmd_buf_data) => cmd_buf_data.trace_commands.as_mut(),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Push a command provided by a closure onto the encoder.
|
||||
///
|
||||
/// If the encoder is in the [`Self::Recording`] state, calls the closure to
|
||||
@ -279,20 +273,6 @@ impl CommandEncoderStatus {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "trace", any(feature = "serde", feature = "replay")))]
|
||||
fn get_inner(&mut self) -> &mut CommandBufferMutable {
|
||||
match self {
|
||||
Self::Locked(inner) | Self::Finished(inner) | Self::Recording(inner) => inner,
|
||||
// This is unreachable because this function is only used when
|
||||
// playing back a recorded trace. If only to avoid having to
|
||||
// implement serialization for all the error types, we don't support
|
||||
// storing the errors in a trace.
|
||||
Self::Consumed => unreachable!("command encoder is consumed"),
|
||||
Self::Error(_) => unreachable!("passes in a trace do not store errors"),
|
||||
Self::Transitioning => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Locks the encoder by putting it in the [`Self::Locked`] state.
|
||||
///
|
||||
/// Render or compute passes call this on start. At the end of the pass,
|
||||
@ -784,10 +764,12 @@ pub struct CommandBufferMutable {
|
||||
|
||||
indirect_draw_validation_resources: crate::indirect_validation::DrawResources,
|
||||
|
||||
pub(crate) commands: Vec<ArcCommand>,
|
||||
pub(crate) commands: Vec<Command<ArcReferences>>,
|
||||
|
||||
/// If tracing, `command_encoder_finish` replaces the `Arc`s in `commands`
|
||||
/// with integer pointers, and moves them into `trace_commands`.
|
||||
#[cfg(feature = "trace")]
|
||||
pub(crate) trace_commands: Option<Vec<TraceCommand>>,
|
||||
pub(crate) trace_commands: Option<Vec<Command<PointerReferences>>>,
|
||||
}
|
||||
|
||||
impl CommandBufferMutable {
|
||||
@ -974,7 +956,31 @@ impl CommandEncoder {
|
||||
}
|
||||
|
||||
let mut commands = mem::take(&mut cmd_buf_data.commands);
|
||||
for command in commands.drain(..) {
|
||||
#[cfg(not(feature = "trace"))]
|
||||
let command_iter = commands.drain(..);
|
||||
#[cfg(feature = "trace")]
|
||||
let mut trace_commands = None;
|
||||
|
||||
#[cfg(feature = "trace")]
|
||||
let command_iter = {
|
||||
if self.device.trace.lock().is_some() {
|
||||
trace_commands = Some(
|
||||
cmd_buf_data
|
||||
.trace_commands
|
||||
.insert(Vec::with_capacity(commands.len())),
|
||||
);
|
||||
}
|
||||
|
||||
commands.drain(..).inspect(|cmd| {
|
||||
use crate::device::trace::IntoTrace;
|
||||
|
||||
if let Some(ref mut trace) = trace_commands {
|
||||
trace.push(cmd.clone().to_trace());
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
for command in command_iter {
|
||||
if matches!(
|
||||
command,
|
||||
ArcCommand::RunRenderPass { .. } | ArcCommand::RunComputePass { .. }
|
||||
@ -1585,11 +1591,6 @@ impl Global {
|
||||
let cmd_enc = hub.command_encoders.get(encoder_id);
|
||||
let mut cmd_buf_data = cmd_enc.data.lock();
|
||||
|
||||
#[cfg(feature = "trace")]
|
||||
if let Some(ref mut list) = cmd_buf_data.trace() {
|
||||
list.push(TraceCommand::PushDebugGroup(label.to_owned()));
|
||||
}
|
||||
|
||||
cmd_buf_data.push_with(|| -> Result<_, CommandEncoderError> {
|
||||
Ok(ArcCommand::PushDebugGroup(label.to_owned()))
|
||||
})
|
||||
@ -1608,11 +1609,6 @@ impl Global {
|
||||
let cmd_enc = hub.command_encoders.get(encoder_id);
|
||||
let mut cmd_buf_data = cmd_enc.data.lock();
|
||||
|
||||
#[cfg(feature = "trace")]
|
||||
if let Some(ref mut list) = cmd_buf_data.trace() {
|
||||
list.push(TraceCommand::InsertDebugMarker(label.to_owned()));
|
||||
}
|
||||
|
||||
cmd_buf_data.push_with(|| -> Result<_, CommandEncoderError> {
|
||||
Ok(ArcCommand::InsertDebugMarker(label.to_owned()))
|
||||
})
|
||||
@ -1630,11 +1626,6 @@ impl Global {
|
||||
let cmd_enc = hub.command_encoders.get(encoder_id);
|
||||
let mut cmd_buf_data = cmd_enc.data.lock();
|
||||
|
||||
#[cfg(feature = "trace")]
|
||||
if let Some(ref mut list) = cmd_buf_data.trace() {
|
||||
list.push(TraceCommand::PopDebugGroup);
|
||||
}
|
||||
|
||||
cmd_buf_data
|
||||
.push_with(|| -> Result<_, CommandEncoderError> { Ok(ArcCommand::PopDebugGroup) })
|
||||
}
|
||||
|
||||
@ -1,8 +1,6 @@
|
||||
use alloc::{sync::Arc, vec, vec::Vec};
|
||||
use core::{iter, mem};
|
||||
|
||||
#[cfg(feature = "trace")]
|
||||
use crate::command::Command as TraceCommand;
|
||||
use crate::{
|
||||
command::{encoder::EncodingState, ArcCommand, EncoderStateError},
|
||||
device::{Device, DeviceError, MissingFeatures},
|
||||
@ -366,14 +364,6 @@ impl Global {
|
||||
let cmd_enc = hub.command_encoders.get(command_encoder_id);
|
||||
let mut cmd_buf_data = cmd_enc.data.lock();
|
||||
|
||||
#[cfg(feature = "trace")]
|
||||
if let Some(ref mut list) = cmd_buf_data.trace() {
|
||||
list.push(TraceCommand::WriteTimestamp {
|
||||
query_set_id,
|
||||
query_index,
|
||||
});
|
||||
}
|
||||
|
||||
cmd_buf_data.push_with(|| -> Result<_, QueryError> {
|
||||
Ok(ArcCommand::WriteTimestamp {
|
||||
query_set: self.resolve_query_set(query_set_id)?,
|
||||
@ -396,17 +386,6 @@ impl Global {
|
||||
let cmd_enc = hub.command_encoders.get(command_encoder_id);
|
||||
let mut cmd_buf_data = cmd_enc.data.lock();
|
||||
|
||||
#[cfg(feature = "trace")]
|
||||
if let Some(ref mut list) = cmd_buf_data.trace() {
|
||||
list.push(TraceCommand::ResolveQuerySet {
|
||||
query_set_id,
|
||||
start_query,
|
||||
query_count,
|
||||
destination,
|
||||
destination_offset,
|
||||
});
|
||||
}
|
||||
|
||||
cmd_buf_data.push_with(|| -> Result<_, QueryError> {
|
||||
Ok(ArcCommand::ResolveQuerySet {
|
||||
query_set: self.resolve_query_set(query_set_id)?,
|
||||
|
||||
@ -23,8 +23,7 @@ use crate::{
|
||||
ray_tracing::{
|
||||
ArcBlasBuildEntry, ArcBlasGeometries, ArcBlasTriangleGeometry, ArcTlasInstance,
|
||||
ArcTlasPackage, BlasBuildEntry, BlasGeometries, BuildAccelerationStructureError,
|
||||
OwnedBlasBuildEntry, OwnedTlasPackage, TlasPackage, TraceBlasBuildEntry,
|
||||
TraceBlasGeometries, TraceBlasTriangleGeometry, TraceTlasInstance, TraceTlasPackage,
|
||||
OwnedBlasBuildEntry, OwnedTlasPackage, TlasPackage,
|
||||
},
|
||||
resource::{Blas, BlasCompactState, Buffer, Labeled, StagingBuffer, Tlas},
|
||||
scratch::ScratchBuffer,
|
||||
@ -122,73 +121,14 @@ impl Global {
|
||||
let hub = &self.hub;
|
||||
|
||||
let cmd_enc = hub.command_encoders.get(command_encoder_id);
|
||||
|
||||
let trace_blas: Vec<TraceBlasBuildEntry> = blas_iter
|
||||
.map(|blas_entry| {
|
||||
let geometries = match blas_entry.geometries {
|
||||
BlasGeometries::TriangleGeometries(triangle_geometries) => {
|
||||
TraceBlasGeometries::TriangleGeometries(
|
||||
triangle_geometries
|
||||
.map(|tg| TraceBlasTriangleGeometry {
|
||||
size: tg.size.clone(),
|
||||
vertex_buffer: tg.vertex_buffer,
|
||||
index_buffer: tg.index_buffer,
|
||||
transform_buffer: tg.transform_buffer,
|
||||
first_vertex: tg.first_vertex,
|
||||
vertex_stride: tg.vertex_stride,
|
||||
first_index: tg.first_index,
|
||||
transform_buffer_offset: tg.transform_buffer_offset,
|
||||
})
|
||||
.collect(),
|
||||
)
|
||||
}
|
||||
};
|
||||
TraceBlasBuildEntry {
|
||||
blas: blas_entry.blas_id,
|
||||
geometries,
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
let trace_tlas: Vec<TraceTlasPackage> = tlas_iter
|
||||
.map(|package: TlasPackage| {
|
||||
let instances = package
|
||||
.instances
|
||||
.map(|instance| {
|
||||
instance.map(|instance| TraceTlasInstance {
|
||||
blas: instance.blas_id,
|
||||
transform: *instance.transform,
|
||||
custom_data: instance.custom_data,
|
||||
mask: instance.mask,
|
||||
})
|
||||
})
|
||||
.collect();
|
||||
TraceTlasPackage {
|
||||
tlas: package.tlas_id,
|
||||
instances,
|
||||
lowest_unmodified: package.lowest_unmodified,
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
let mut cmd_buf_data = cmd_enc.data.lock();
|
||||
|
||||
#[cfg(feature = "trace")]
|
||||
if let Some(ref mut list) = cmd_buf_data.trace() {
|
||||
list.push(crate::command::Command::BuildAccelerationStructures {
|
||||
blas: trace_blas.clone(),
|
||||
tlas: trace_tlas.clone(),
|
||||
});
|
||||
}
|
||||
|
||||
cmd_buf_data.push_with(|| -> Result<_, BuildAccelerationStructureError> {
|
||||
let blas = trace_blas
|
||||
.iter()
|
||||
let blas = blas_iter
|
||||
.map(|blas_entry| {
|
||||
let geometries = match &blas_entry.geometries {
|
||||
TraceBlasGeometries::TriangleGeometries(triangle_geometries) => {
|
||||
let geometries = match blas_entry.geometries {
|
||||
BlasGeometries::TriangleGeometries(triangle_geometries) => {
|
||||
let tri_geo = triangle_geometries
|
||||
.iter()
|
||||
.map(|tg| {
|
||||
Ok(ArcBlasTriangleGeometry {
|
||||
size: tg.size.clone(),
|
||||
@ -212,25 +152,23 @@ impl Global {
|
||||
}
|
||||
};
|
||||
Ok(ArcBlasBuildEntry {
|
||||
blas: self.resolve_blas_id(blas_entry.blas)?,
|
||||
blas: self.resolve_blas_id(blas_entry.blas_id)?,
|
||||
geometries,
|
||||
})
|
||||
})
|
||||
.collect::<Result<_, BuildAccelerationStructureError>>()?;
|
||||
|
||||
let tlas = trace_tlas
|
||||
.iter()
|
||||
let tlas = tlas_iter
|
||||
.map(|tlas_package| {
|
||||
let instances = tlas_package
|
||||
.instances
|
||||
.iter()
|
||||
.map(|instance| {
|
||||
instance
|
||||
.as_ref()
|
||||
.map(|instance| {
|
||||
Ok(ArcTlasInstance {
|
||||
blas: self.resolve_blas_id(instance.blas)?,
|
||||
transform: instance.transform,
|
||||
blas: self.resolve_blas_id(instance.blas_id)?,
|
||||
transform: *instance.transform,
|
||||
custom_data: instance.custom_data,
|
||||
mask: instance.mask,
|
||||
})
|
||||
@ -239,7 +177,7 @@ impl Global {
|
||||
})
|
||||
.collect::<Result<_, BuildAccelerationStructureError>>()?;
|
||||
Ok(ArcTlasPackage {
|
||||
tlas: self.resolve_tlas_id(tlas_package.tlas)?,
|
||||
tlas: self.resolve_tlas_id(tlas_package.tlas_id)?,
|
||||
instances,
|
||||
lowest_unmodified: tlas_package.lowest_unmodified,
|
||||
})
|
||||
|
||||
@ -77,6 +77,9 @@ fn store_hal_ops(store: StoreOp) -> hal::AttachmentOps {
|
||||
}
|
||||
|
||||
/// Describes an individual channel within a render pass, such as color, depth, or stencil.
|
||||
///
|
||||
/// A channel must either be read-only, or it must specify both load and store
|
||||
/// operations. See [`ResolvedPassChannel`] for a validated version.
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
@ -120,7 +123,12 @@ impl<V: Copy + Default> PassChannel<Option<V>> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Describes an individual channel within a render pass, such as color, depth, or stencil.
|
||||
///
|
||||
/// Unlike [`PassChannel`], this version uses the Rust type system to guarantee
|
||||
/// a valid specification.
|
||||
#[derive(Clone, Debug)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
pub enum ResolvedPassChannel<V> {
|
||||
ReadOnly,
|
||||
Operational(wgt::Operations<V>),
|
||||
@ -185,8 +193,8 @@ pub type ArcRenderPassColorAttachment = RenderPassColorAttachment<Arc<TextureVie
|
||||
|
||||
// Avoid allocation in the common case that there is only one color attachment,
|
||||
// but don't bloat `ArcCommand::RunRenderPass` excessively.
|
||||
pub type ArcRenderPassColorAttachmentArray =
|
||||
SmallVec<[Option<RenderPassColorAttachment<Arc<TextureView>>>; 1]>;
|
||||
pub type ColorAttachments<TV = Arc<TextureView>> =
|
||||
SmallVec<[Option<RenderPassColorAttachment<TV>>; 1]>;
|
||||
|
||||
impl ArcRenderPassColorAttachment {
|
||||
fn hal_ops(&self) -> hal::AttachmentOps {
|
||||
@ -202,12 +210,14 @@ impl ArcRenderPassColorAttachment {
|
||||
}
|
||||
|
||||
/// Describes a depth/stencil attachment to a render pass.
|
||||
///
|
||||
/// This version uses the unvalidated [`PassChannel`].
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
pub struct RenderPassDepthStencilAttachment {
|
||||
pub struct RenderPassDepthStencilAttachment<TV> {
|
||||
/// The view to use as an attachment.
|
||||
pub view: id::TextureViewId,
|
||||
pub view: TV,
|
||||
/// What operations will be performed on the depth part of the attachment.
|
||||
pub depth: PassChannel<Option<f32>>,
|
||||
/// What operations will be performed on the stencil part of the attachment.
|
||||
@ -215,10 +225,13 @@ pub struct RenderPassDepthStencilAttachment {
|
||||
}
|
||||
|
||||
/// Describes a depth/stencil attachment to a render pass.
|
||||
///
|
||||
/// This version uses the validated [`ResolvedPassChannel`].
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct ArcRenderPassDepthStencilAttachment {
|
||||
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||||
pub struct ResolvedRenderPassDepthStencilAttachment<TV> {
|
||||
/// The view to use as an attachment.
|
||||
pub view: Arc<TextureView>,
|
||||
pub view: TV,
|
||||
/// What operations will be performed on the depth part of the attachment.
|
||||
pub depth: ResolvedPassChannel<f32>,
|
||||
/// What operations will be performed on the stencil part of the attachment.
|
||||
@ -232,7 +245,7 @@ pub struct RenderPassDescriptor<'a> {
|
||||
/// The color attachments of the render pass.
|
||||
pub color_attachments: Cow<'a, [Option<RenderPassColorAttachment>]>,
|
||||
/// The depth and stencil attachment of the render pass, if any.
|
||||
pub depth_stencil_attachment: Option<&'a RenderPassDepthStencilAttachment>,
|
||||
pub depth_stencil_attachment: Option<&'a RenderPassDepthStencilAttachment<id::TextureViewId>>,
|
||||
/// Defines where and when timestamp values will be written for this pass.
|
||||
pub timestamp_writes: Option<&'a PassTimestampWrites>,
|
||||
/// Defines where the occlusion query results will be stored for this pass.
|
||||
@ -246,7 +259,8 @@ struct ArcRenderPassDescriptor<'a> {
|
||||
pub color_attachments:
|
||||
ArrayVec<Option<ArcRenderPassColorAttachment>, { hal::MAX_COLOR_ATTACHMENTS }>,
|
||||
/// The depth and stencil attachment of the render pass, if any.
|
||||
pub depth_stencil_attachment: Option<ArcRenderPassDepthStencilAttachment>,
|
||||
pub depth_stencil_attachment:
|
||||
Option<ResolvedRenderPassDepthStencilAttachment<Arc<TextureView>>>,
|
||||
/// Defines where and when timestamp values will be written for this pass.
|
||||
pub timestamp_writes: Option<ArcPassTimestampWrites>,
|
||||
/// Defines where the occlusion query results will be stored for this pass.
|
||||
@ -275,7 +289,7 @@ pub struct RenderPass {
|
||||
|
||||
color_attachments:
|
||||
ArrayVec<Option<ArcRenderPassColorAttachment>, { hal::MAX_COLOR_ATTACHMENTS }>,
|
||||
depth_stencil_attachment: Option<ArcRenderPassDepthStencilAttachment>,
|
||||
depth_stencil_attachment: Option<ResolvedRenderPassDepthStencilAttachment<Arc<TextureView>>>,
|
||||
timestamp_writes: Option<ArcPassTimestampWrites>,
|
||||
occlusion_query_set: Option<Arc<QuerySet>>,
|
||||
|
||||
@ -971,7 +985,9 @@ impl RenderPassInfo {
|
||||
device: &Arc<Device>,
|
||||
hal_label: Option<&str>,
|
||||
color_attachments: &[Option<ArcRenderPassColorAttachment>],
|
||||
mut depth_stencil_attachment: Option<ArcRenderPassDepthStencilAttachment>,
|
||||
mut depth_stencil_attachment: Option<
|
||||
ResolvedRenderPassDepthStencilAttachment<Arc<TextureView>>,
|
||||
>,
|
||||
mut timestamp_writes: Option<ArcPassTimestampWrites>,
|
||||
mut occlusion_query_set: Option<Arc<QuerySet>>,
|
||||
encoder: &mut dyn hal::DynCommandEncoder,
|
||||
@ -1650,7 +1666,7 @@ impl Global {
|
||||
)));
|
||||
}
|
||||
|
||||
Some(ArcRenderPassDepthStencilAttachment {
|
||||
Some(ResolvedRenderPassDepthStencilAttachment {
|
||||
view,
|
||||
depth: if format.has_depth_aspect() {
|
||||
depth_stencil_attachment.depth.resolve(|clear| if let Some(clear) = clear {
|
||||
@ -1762,79 +1778,6 @@ impl Global {
|
||||
}
|
||||
}
|
||||
|
||||
/// Note that this differs from [`Self::render_pass_end`], it will
|
||||
/// create a new pass, replay the commands and end the pass.
|
||||
#[doc(hidden)]
|
||||
#[cfg(any(feature = "serde", feature = "replay"))]
|
||||
pub fn render_pass_end_with_unresolved_commands(
|
||||
&self,
|
||||
encoder_id: id::CommandEncoderId,
|
||||
base: BasePass<super::RenderCommand, Infallible>,
|
||||
color_attachments: &[Option<RenderPassColorAttachment>],
|
||||
depth_stencil_attachment: Option<&RenderPassDepthStencilAttachment>,
|
||||
timestamp_writes: Option<&PassTimestampWrites>,
|
||||
occlusion_query_set: Option<id::QuerySetId>,
|
||||
) {
|
||||
#[cfg(feature = "trace")]
|
||||
{
|
||||
let cmd_enc = self.hub.command_encoders.get(encoder_id);
|
||||
let mut cmd_buf_data = cmd_enc.data.lock();
|
||||
let cmd_buf_data = cmd_buf_data.get_inner();
|
||||
|
||||
if let Some(ref mut list) = cmd_buf_data.trace_commands {
|
||||
list.push(crate::command::Command::RunRenderPass {
|
||||
base: BasePass {
|
||||
label: base.label.clone(),
|
||||
error: None,
|
||||
commands: base.commands.clone(),
|
||||
dynamic_offsets: base.dynamic_offsets.clone(),
|
||||
string_data: base.string_data.clone(),
|
||||
push_constant_data: base.push_constant_data.clone(),
|
||||
},
|
||||
target_colors: color_attachments.to_vec(),
|
||||
target_depth_stencil: depth_stencil_attachment.cloned(),
|
||||
timestamp_writes: timestamp_writes.cloned(),
|
||||
occlusion_query_set_id: occlusion_query_set,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
let BasePass {
|
||||
label,
|
||||
error: _,
|
||||
commands,
|
||||
dynamic_offsets,
|
||||
string_data,
|
||||
push_constant_data,
|
||||
} = base;
|
||||
|
||||
let (mut render_pass, encoder_error) = self.command_encoder_begin_render_pass(
|
||||
encoder_id,
|
||||
&RenderPassDescriptor {
|
||||
label: label.as_deref().map(Cow::Borrowed),
|
||||
color_attachments: Cow::Borrowed(color_attachments),
|
||||
depth_stencil_attachment,
|
||||
timestamp_writes,
|
||||
occlusion_query_set,
|
||||
},
|
||||
);
|
||||
if let Some(err) = encoder_error {
|
||||
panic!("{:?}", err);
|
||||
};
|
||||
|
||||
render_pass.base = BasePass {
|
||||
label,
|
||||
error: None,
|
||||
commands: super::RenderCommand::resolve_render_command_ids(&self.hub, &commands)
|
||||
.unwrap(),
|
||||
dynamic_offsets,
|
||||
string_data,
|
||||
push_constant_data,
|
||||
};
|
||||
|
||||
self.render_pass_end(&mut render_pass).unwrap();
|
||||
}
|
||||
|
||||
pub fn render_pass_end(&self, pass: &mut RenderPass) -> Result<(), EncoderStateError> {
|
||||
profiling::scope!(
|
||||
"CommandEncoder::run_render_pass {}",
|
||||
@ -1881,8 +1824,10 @@ impl Global {
|
||||
pub(super) fn encode_render_pass(
|
||||
parent_state: &mut EncodingState<InnerCommandEncoder>,
|
||||
mut base: BasePass<ArcRenderCommand, Infallible>,
|
||||
color_attachments: ArcRenderPassColorAttachmentArray,
|
||||
mut depth_stencil_attachment: Option<ArcRenderPassDepthStencilAttachment>,
|
||||
color_attachments: ColorAttachments<Arc<TextureView>>,
|
||||
mut depth_stencil_attachment: Option<
|
||||
ResolvedRenderPassDepthStencilAttachment<Arc<TextureView>>,
|
||||
>,
|
||||
mut timestamp_writes: Option<ArcPassTimestampWrites>,
|
||||
occlusion_query_set: Option<Arc<QuerySet>>,
|
||||
) -> Result<(), RenderPassError> {
|
||||
@ -3444,8 +3389,8 @@ impl Global {
|
||||
count: 1,
|
||||
family: DrawCommandFamily::Draw,
|
||||
|
||||
vertex_or_index_limit: 0,
|
||||
instance_limit: 0,
|
||||
vertex_or_index_limit: None,
|
||||
instance_limit: None,
|
||||
});
|
||||
|
||||
Ok(())
|
||||
@ -3469,8 +3414,8 @@ impl Global {
|
||||
count: 1,
|
||||
family: DrawCommandFamily::DrawIndexed,
|
||||
|
||||
vertex_or_index_limit: 0,
|
||||
instance_limit: 0,
|
||||
vertex_or_index_limit: None,
|
||||
instance_limit: None,
|
||||
});
|
||||
|
||||
Ok(())
|
||||
@ -3494,8 +3439,8 @@ impl Global {
|
||||
count: 1,
|
||||
family: DrawCommandFamily::DrawMeshTasks,
|
||||
|
||||
vertex_or_index_limit: 0,
|
||||
instance_limit: 0,
|
||||
vertex_or_index_limit: None,
|
||||
instance_limit: None,
|
||||
});
|
||||
|
||||
Ok(())
|
||||
@ -3520,8 +3465,8 @@ impl Global {
|
||||
count,
|
||||
family: DrawCommandFamily::Draw,
|
||||
|
||||
vertex_or_index_limit: 0,
|
||||
instance_limit: 0,
|
||||
vertex_or_index_limit: None,
|
||||
instance_limit: None,
|
||||
});
|
||||
|
||||
Ok(())
|
||||
@ -3546,8 +3491,8 @@ impl Global {
|
||||
count,
|
||||
family: DrawCommandFamily::DrawIndexed,
|
||||
|
||||
vertex_or_index_limit: 0,
|
||||
instance_limit: 0,
|
||||
vertex_or_index_limit: None,
|
||||
instance_limit: None,
|
||||
});
|
||||
|
||||
Ok(())
|
||||
@ -3572,8 +3517,8 @@ impl Global {
|
||||
count,
|
||||
family: DrawCommandFamily::DrawMeshTasks,
|
||||
|
||||
vertex_or_index_limit: 0,
|
||||
instance_limit: 0,
|
||||
vertex_or_index_limit: None,
|
||||
instance_limit: None,
|
||||
});
|
||||
|
||||
Ok(())
|
||||
|
||||
@ -1,34 +1,30 @@
|
||||
use alloc::sync::Arc;
|
||||
|
||||
use wgt::{BufferAddress, BufferSize, Color};
|
||||
|
||||
use super::{DrawCommandFamily, Rect, RenderBundle};
|
||||
use crate::{
|
||||
binding_model::BindGroup,
|
||||
id,
|
||||
pipeline::RenderPipeline,
|
||||
resource::{Buffer, QuerySet},
|
||||
};
|
||||
use super::{DrawCommandFamily, Rect};
|
||||
use crate::command::{serde_object_reference_struct, ArcReferences, ReferenceType};
|
||||
|
||||
use macro_rules_attribute::apply;
|
||||
|
||||
/// cbindgen:ignore
|
||||
#[doc(hidden)]
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
pub enum RenderCommand {
|
||||
#[derive(Clone, Debug)]
|
||||
#[cfg_attr(feature = "serde", apply(serde_object_reference_struct))]
|
||||
pub enum RenderCommand<R: ReferenceType> {
|
||||
SetBindGroup {
|
||||
index: u32,
|
||||
num_dynamic_offsets: usize,
|
||||
bind_group_id: Option<id::BindGroupId>,
|
||||
bind_group: Option<R::BindGroup>,
|
||||
},
|
||||
SetPipeline(id::RenderPipelineId),
|
||||
SetPipeline(R::RenderPipeline),
|
||||
SetIndexBuffer {
|
||||
buffer_id: id::BufferId,
|
||||
buffer: R::Buffer,
|
||||
index_format: wgt::IndexFormat,
|
||||
offset: BufferAddress,
|
||||
size: Option<BufferSize>,
|
||||
},
|
||||
SetVertexBuffer {
|
||||
slot: u32,
|
||||
buffer_id: id::BufferId,
|
||||
buffer: R::Buffer,
|
||||
offset: BufferAddress,
|
||||
size: Option<BufferSize>,
|
||||
},
|
||||
@ -88,30 +84,36 @@ pub enum RenderCommand {
|
||||
group_count_z: u32,
|
||||
},
|
||||
DrawIndirect {
|
||||
buffer_id: id::BufferId,
|
||||
buffer: R::Buffer,
|
||||
offset: BufferAddress,
|
||||
count: u32,
|
||||
family: DrawCommandFamily,
|
||||
/// This limit is only populated for commands in a finished [`RenderBundle`].
|
||||
vertex_or_index_limit: Option<u64>,
|
||||
/// This limit is only populated for commands in a finished [`RenderBundle`].
|
||||
instance_limit: Option<u64>,
|
||||
},
|
||||
MultiDrawIndirectCount {
|
||||
buffer_id: id::BufferId,
|
||||
buffer: R::Buffer,
|
||||
offset: BufferAddress,
|
||||
count_buffer_id: id::BufferId,
|
||||
count_buffer: R::Buffer,
|
||||
count_buffer_offset: BufferAddress,
|
||||
max_count: u32,
|
||||
family: DrawCommandFamily,
|
||||
},
|
||||
PushDebugGroup {
|
||||
#[cfg_attr(not(any(feature = "serde", feature = "replay")), allow(dead_code))]
|
||||
color: u32,
|
||||
len: usize,
|
||||
},
|
||||
PopDebugGroup,
|
||||
InsertDebugMarker {
|
||||
#[cfg_attr(not(any(feature = "serde", feature = "replay")), allow(dead_code))]
|
||||
color: u32,
|
||||
len: usize,
|
||||
},
|
||||
WriteTimestamp {
|
||||
query_set_id: id::QuerySetId,
|
||||
query_set: R::QuerySet,
|
||||
query_index: u32,
|
||||
},
|
||||
BeginOcclusionQuery {
|
||||
@ -119,290 +121,11 @@ pub enum RenderCommand {
|
||||
},
|
||||
EndOcclusionQuery,
|
||||
BeginPipelineStatisticsQuery {
|
||||
query_set_id: id::QuerySetId,
|
||||
query_set: R::QuerySet,
|
||||
query_index: u32,
|
||||
},
|
||||
EndPipelineStatisticsQuery,
|
||||
ExecuteBundle(id::RenderBundleId),
|
||||
}
|
||||
|
||||
impl RenderCommand {
|
||||
/// Resolves all ids in a list of commands into the corresponding resource Arc.
|
||||
#[cfg(any(feature = "serde", feature = "replay"))]
|
||||
pub fn resolve_render_command_ids(
|
||||
hub: &crate::hub::Hub,
|
||||
commands: &[RenderCommand],
|
||||
) -> Result<alloc::vec::Vec<ArcRenderCommand>, super::RenderPassError> {
|
||||
use super::{DrawKind, PassErrorScope, RenderPassError};
|
||||
use alloc::vec::Vec;
|
||||
|
||||
let buffers_guard = hub.buffers.read();
|
||||
let bind_group_guard = hub.bind_groups.read();
|
||||
let query_set_guard = hub.query_sets.read();
|
||||
let pipelines_guard = hub.render_pipelines.read();
|
||||
let render_bundles_guard = hub.render_bundles.read();
|
||||
|
||||
let resolved_commands: Vec<ArcRenderCommand> =
|
||||
commands
|
||||
.iter()
|
||||
.map(|c| -> Result<ArcRenderCommand, RenderPassError> {
|
||||
Ok(match *c {
|
||||
RenderCommand::SetBindGroup {
|
||||
index,
|
||||
num_dynamic_offsets,
|
||||
bind_group_id,
|
||||
} => {
|
||||
if bind_group_id.is_none() {
|
||||
return Ok(ArcRenderCommand::SetBindGroup {
|
||||
index,
|
||||
num_dynamic_offsets,
|
||||
bind_group: None,
|
||||
});
|
||||
}
|
||||
|
||||
let bind_group_id = bind_group_id.unwrap();
|
||||
let bg = bind_group_guard.get(bind_group_id).get().map_err(|e| {
|
||||
RenderPassError {
|
||||
scope: PassErrorScope::SetBindGroup,
|
||||
inner: e.into(),
|
||||
}
|
||||
})?;
|
||||
|
||||
ArcRenderCommand::SetBindGroup {
|
||||
index,
|
||||
num_dynamic_offsets,
|
||||
bind_group: Some(bg),
|
||||
}
|
||||
}
|
||||
|
||||
RenderCommand::SetPipeline(pipeline_id) => ArcRenderCommand::SetPipeline(
|
||||
pipelines_guard.get(pipeline_id).get().map_err(|e| {
|
||||
RenderPassError {
|
||||
scope: PassErrorScope::SetPipelineRender,
|
||||
inner: e.into(),
|
||||
}
|
||||
})?,
|
||||
),
|
||||
|
||||
RenderCommand::SetPushConstant {
|
||||
offset,
|
||||
size_bytes,
|
||||
values_offset,
|
||||
stages,
|
||||
} => ArcRenderCommand::SetPushConstant {
|
||||
offset,
|
||||
size_bytes,
|
||||
values_offset,
|
||||
stages,
|
||||
},
|
||||
|
||||
RenderCommand::PushDebugGroup { color, len } => {
|
||||
ArcRenderCommand::PushDebugGroup { color, len }
|
||||
}
|
||||
|
||||
RenderCommand::PopDebugGroup => ArcRenderCommand::PopDebugGroup,
|
||||
|
||||
RenderCommand::InsertDebugMarker { color, len } => {
|
||||
ArcRenderCommand::InsertDebugMarker { color, len }
|
||||
}
|
||||
|
||||
RenderCommand::WriteTimestamp {
|
||||
query_set_id,
|
||||
query_index,
|
||||
} => ArcRenderCommand::WriteTimestamp {
|
||||
query_set: query_set_guard.get(query_set_id).get().map_err(|e| {
|
||||
RenderPassError {
|
||||
scope: PassErrorScope::WriteTimestamp,
|
||||
inner: e.into(),
|
||||
}
|
||||
})?,
|
||||
query_index,
|
||||
},
|
||||
|
||||
RenderCommand::BeginPipelineStatisticsQuery {
|
||||
query_set_id,
|
||||
query_index,
|
||||
} => ArcRenderCommand::BeginPipelineStatisticsQuery {
|
||||
query_set: query_set_guard.get(query_set_id).get().map_err(|e| {
|
||||
RenderPassError {
|
||||
scope: PassErrorScope::BeginPipelineStatisticsQuery,
|
||||
inner: e.into(),
|
||||
}
|
||||
})?,
|
||||
query_index,
|
||||
},
|
||||
|
||||
RenderCommand::EndPipelineStatisticsQuery => {
|
||||
ArcRenderCommand::EndPipelineStatisticsQuery
|
||||
}
|
||||
|
||||
RenderCommand::SetIndexBuffer {
|
||||
buffer_id,
|
||||
index_format,
|
||||
offset,
|
||||
size,
|
||||
} => ArcRenderCommand::SetIndexBuffer {
|
||||
buffer: buffers_guard.get(buffer_id).get().map_err(|e| {
|
||||
RenderPassError {
|
||||
scope: PassErrorScope::SetIndexBuffer,
|
||||
inner: e.into(),
|
||||
}
|
||||
})?,
|
||||
index_format,
|
||||
offset,
|
||||
size,
|
||||
},
|
||||
|
||||
RenderCommand::SetVertexBuffer {
|
||||
slot,
|
||||
buffer_id,
|
||||
offset,
|
||||
size,
|
||||
} => ArcRenderCommand::SetVertexBuffer {
|
||||
slot,
|
||||
buffer: buffers_guard.get(buffer_id).get().map_err(|e| {
|
||||
RenderPassError {
|
||||
scope: PassErrorScope::SetVertexBuffer,
|
||||
inner: e.into(),
|
||||
}
|
||||
})?,
|
||||
offset,
|
||||
size,
|
||||
},
|
||||
|
||||
RenderCommand::SetBlendConstant(color) => {
|
||||
ArcRenderCommand::SetBlendConstant(color)
|
||||
}
|
||||
|
||||
RenderCommand::SetStencilReference(reference) => {
|
||||
ArcRenderCommand::SetStencilReference(reference)
|
||||
}
|
||||
|
||||
RenderCommand::SetViewport {
|
||||
rect,
|
||||
depth_min,
|
||||
depth_max,
|
||||
} => ArcRenderCommand::SetViewport {
|
||||
rect,
|
||||
depth_min,
|
||||
depth_max,
|
||||
},
|
||||
|
||||
RenderCommand::SetScissor(scissor) => ArcRenderCommand::SetScissor(scissor),
|
||||
|
||||
RenderCommand::Draw {
|
||||
vertex_count,
|
||||
instance_count,
|
||||
first_vertex,
|
||||
first_instance,
|
||||
} => ArcRenderCommand::Draw {
|
||||
vertex_count,
|
||||
instance_count,
|
||||
first_vertex,
|
||||
first_instance,
|
||||
},
|
||||
|
||||
RenderCommand::DrawIndexed {
|
||||
index_count,
|
||||
instance_count,
|
||||
first_index,
|
||||
base_vertex,
|
||||
first_instance,
|
||||
} => ArcRenderCommand::DrawIndexed {
|
||||
index_count,
|
||||
instance_count,
|
||||
first_index,
|
||||
base_vertex,
|
||||
first_instance,
|
||||
},
|
||||
RenderCommand::DrawMeshTasks {
|
||||
group_count_x,
|
||||
group_count_y,
|
||||
group_count_z,
|
||||
} => ArcRenderCommand::DrawMeshTasks {
|
||||
group_count_x,
|
||||
group_count_y,
|
||||
group_count_z,
|
||||
},
|
||||
|
||||
RenderCommand::DrawIndirect {
|
||||
buffer_id,
|
||||
offset,
|
||||
count,
|
||||
family,
|
||||
} => ArcRenderCommand::DrawIndirect {
|
||||
buffer: buffers_guard.get(buffer_id).get().map_err(|e| {
|
||||
RenderPassError {
|
||||
scope: PassErrorScope::Draw {
|
||||
kind: if count != 1 {
|
||||
DrawKind::MultiDrawIndirect
|
||||
} else {
|
||||
DrawKind::DrawIndirect
|
||||
},
|
||||
family,
|
||||
},
|
||||
inner: e.into(),
|
||||
}
|
||||
})?,
|
||||
offset,
|
||||
count,
|
||||
family,
|
||||
|
||||
vertex_or_index_limit: 0,
|
||||
instance_limit: 0,
|
||||
},
|
||||
|
||||
RenderCommand::MultiDrawIndirectCount {
|
||||
buffer_id,
|
||||
offset,
|
||||
count_buffer_id,
|
||||
count_buffer_offset,
|
||||
max_count,
|
||||
family,
|
||||
} => {
|
||||
let scope = PassErrorScope::Draw {
|
||||
kind: DrawKind::MultiDrawIndirectCount,
|
||||
family,
|
||||
};
|
||||
ArcRenderCommand::MultiDrawIndirectCount {
|
||||
buffer: buffers_guard.get(buffer_id).get().map_err(|e| {
|
||||
RenderPassError {
|
||||
scope,
|
||||
inner: e.into(),
|
||||
}
|
||||
})?,
|
||||
offset,
|
||||
count_buffer: buffers_guard.get(count_buffer_id).get().map_err(
|
||||
|e| RenderPassError {
|
||||
scope,
|
||||
inner: e.into(),
|
||||
},
|
||||
)?,
|
||||
count_buffer_offset,
|
||||
max_count,
|
||||
family,
|
||||
}
|
||||
}
|
||||
|
||||
RenderCommand::BeginOcclusionQuery { query_index } => {
|
||||
ArcRenderCommand::BeginOcclusionQuery { query_index }
|
||||
}
|
||||
|
||||
RenderCommand::EndOcclusionQuery => ArcRenderCommand::EndOcclusionQuery,
|
||||
|
||||
RenderCommand::ExecuteBundle(bundle) => ArcRenderCommand::ExecuteBundle(
|
||||
render_bundles_guard.get(bundle).get().map_err(|e| {
|
||||
RenderPassError {
|
||||
scope: PassErrorScope::ExecuteBundle,
|
||||
inner: e.into(),
|
||||
}
|
||||
})?,
|
||||
),
|
||||
})
|
||||
})
|
||||
.collect::<Result<Vec<_>, RenderPassError>>()?;
|
||||
Ok(resolved_commands)
|
||||
}
|
||||
ExecuteBundle(R::RenderBundle),
|
||||
}
|
||||
|
||||
/// Equivalent to `RenderCommand` with the Ids resolved into resource Arcs.
|
||||
@ -417,123 +140,6 @@ impl RenderCommand {
|
||||
/// is `finish()`ed and when the bundle is executed. Validation occurs when the
|
||||
/// bundle is finished, which means that parameters stored in an `ArcRenderCommand`
|
||||
/// for a render bundle operation must have been validated.
|
||||
#[doc(hidden)]
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum ArcRenderCommand {
|
||||
SetBindGroup {
|
||||
index: u32,
|
||||
num_dynamic_offsets: usize,
|
||||
bind_group: Option<Arc<BindGroup>>,
|
||||
},
|
||||
SetPipeline(Arc<RenderPipeline>),
|
||||
SetIndexBuffer {
|
||||
buffer: Arc<Buffer>,
|
||||
index_format: wgt::IndexFormat,
|
||||
offset: BufferAddress,
|
||||
size: Option<BufferSize>,
|
||||
},
|
||||
SetVertexBuffer {
|
||||
slot: u32,
|
||||
buffer: Arc<Buffer>,
|
||||
offset: BufferAddress,
|
||||
size: Option<BufferSize>,
|
||||
},
|
||||
SetBlendConstant(Color),
|
||||
SetStencilReference(u32),
|
||||
SetViewport {
|
||||
rect: Rect<f32>,
|
||||
depth_min: f32,
|
||||
depth_max: f32,
|
||||
},
|
||||
SetScissor(Rect<u32>),
|
||||
|
||||
/// Set a range of push constants to values stored in [`BasePass::push_constant_data`].
|
||||
///
|
||||
/// See [`wgpu::RenderPass::set_push_constants`] for a detailed explanation
|
||||
/// of the restrictions these commands must satisfy.
|
||||
SetPushConstant {
|
||||
/// Which stages we are setting push constant values for.
|
||||
stages: wgt::ShaderStages,
|
||||
|
||||
/// The byte offset within the push constant storage to write to. This
|
||||
/// must be a multiple of four.
|
||||
offset: u32,
|
||||
|
||||
/// The number of bytes to write. This must be a multiple of four.
|
||||
size_bytes: u32,
|
||||
|
||||
/// Index in [`BasePass::push_constant_data`] of the start of the data
|
||||
/// to be written.
|
||||
///
|
||||
/// Note: this is not a byte offset like `offset`. Rather, it is the
|
||||
/// index of the first `u32` element in `push_constant_data` to read.
|
||||
///
|
||||
/// `None` means zeros should be written to the destination range, and
|
||||
/// there is no corresponding data in `push_constant_data`. This is used
|
||||
/// by render bundles, which explicitly clear out any state that
|
||||
/// post-bundle code might see.
|
||||
values_offset: Option<u32>,
|
||||
},
|
||||
Draw {
|
||||
vertex_count: u32,
|
||||
instance_count: u32,
|
||||
first_vertex: u32,
|
||||
first_instance: u32,
|
||||
},
|
||||
DrawIndexed {
|
||||
index_count: u32,
|
||||
instance_count: u32,
|
||||
first_index: u32,
|
||||
base_vertex: i32,
|
||||
first_instance: u32,
|
||||
},
|
||||
DrawMeshTasks {
|
||||
group_count_x: u32,
|
||||
group_count_y: u32,
|
||||
group_count_z: u32,
|
||||
},
|
||||
DrawIndirect {
|
||||
buffer: Arc<Buffer>,
|
||||
offset: BufferAddress,
|
||||
count: u32,
|
||||
family: DrawCommandFamily,
|
||||
|
||||
/// This limit is only populated for commands in a [`RenderBundle`].
|
||||
vertex_or_index_limit: u64,
|
||||
/// This limit is only populated for commands in a [`RenderBundle`].
|
||||
instance_limit: u64,
|
||||
},
|
||||
MultiDrawIndirectCount {
|
||||
buffer: Arc<Buffer>,
|
||||
offset: BufferAddress,
|
||||
count_buffer: Arc<Buffer>,
|
||||
count_buffer_offset: BufferAddress,
|
||||
max_count: u32,
|
||||
family: DrawCommandFamily,
|
||||
},
|
||||
PushDebugGroup {
|
||||
#[cfg_attr(not(any(feature = "serde", feature = "replay")), allow(dead_code))]
|
||||
color: u32,
|
||||
len: usize,
|
||||
},
|
||||
PopDebugGroup,
|
||||
InsertDebugMarker {
|
||||
#[cfg_attr(not(any(feature = "serde", feature = "replay")), allow(dead_code))]
|
||||
color: u32,
|
||||
len: usize,
|
||||
},
|
||||
WriteTimestamp {
|
||||
query_set: Arc<QuerySet>,
|
||||
query_index: u32,
|
||||
},
|
||||
BeginOcclusionQuery {
|
||||
query_index: u32,
|
||||
},
|
||||
EndOcclusionQuery,
|
||||
BeginPipelineStatisticsQuery {
|
||||
query_set: Arc<QuerySet>,
|
||||
query_index: u32,
|
||||
},
|
||||
EndPipelineStatisticsQuery,
|
||||
ExecuteBundle(Arc<RenderBundle>),
|
||||
}
|
||||
///
|
||||
/// cbindgen:ignore
|
||||
pub type ArcRenderCommand = RenderCommand<ArcReferences>;
|
||||
|
||||
@ -8,8 +8,6 @@ use wgt::{
|
||||
TextureUsages,
|
||||
};
|
||||
|
||||
#[cfg(feature = "trace")]
|
||||
use crate::command::Command as TraceCommand;
|
||||
use crate::{
|
||||
api_log,
|
||||
command::{
|
||||
@ -825,17 +823,6 @@ impl Global {
|
||||
let cmd_enc = hub.command_encoders.get(command_encoder_id);
|
||||
let mut cmd_buf_data = cmd_enc.data.lock();
|
||||
|
||||
#[cfg(feature = "trace")]
|
||||
if let Some(ref mut list) = cmd_buf_data.trace() {
|
||||
list.push(TraceCommand::CopyBufferToBuffer {
|
||||
src: source,
|
||||
src_offset: source_offset,
|
||||
dst: destination,
|
||||
dst_offset: destination_offset,
|
||||
size,
|
||||
});
|
||||
}
|
||||
|
||||
cmd_buf_data.push_with(|| -> Result<_, CommandEncoderError> {
|
||||
Ok(ArcCommand::CopyBufferToBuffer {
|
||||
src: self.resolve_buffer_id(source)?,
|
||||
@ -864,15 +851,6 @@ impl Global {
|
||||
let cmd_enc = self.hub.command_encoders.get(command_encoder_id);
|
||||
let mut cmd_buf_data = cmd_enc.data.lock();
|
||||
|
||||
#[cfg(feature = "trace")]
|
||||
if let Some(ref mut list) = cmd_buf_data.trace() {
|
||||
list.push(TraceCommand::CopyBufferToTexture {
|
||||
src: *source,
|
||||
dst: *destination,
|
||||
size: *copy_size,
|
||||
});
|
||||
}
|
||||
|
||||
cmd_buf_data.push_with(|| -> Result<_, CommandEncoderError> {
|
||||
Ok(ArcCommand::CopyBufferToTexture {
|
||||
src: wgt::TexelCopyBufferInfo::<Arc<Buffer>> {
|
||||
@ -907,15 +885,6 @@ impl Global {
|
||||
let cmd_enc = self.hub.command_encoders.get(command_encoder_id);
|
||||
let mut cmd_buf_data = cmd_enc.data.lock();
|
||||
|
||||
#[cfg(feature = "trace")]
|
||||
if let Some(list) = cmd_buf_data.trace() {
|
||||
list.push(TraceCommand::CopyTextureToBuffer {
|
||||
src: *source,
|
||||
dst: *destination,
|
||||
size: *copy_size,
|
||||
});
|
||||
}
|
||||
|
||||
cmd_buf_data.push_with(|| -> Result<_, CommandEncoderError> {
|
||||
Ok(ArcCommand::CopyTextureToBuffer {
|
||||
src: wgt::TexelCopyTextureInfo::<Arc<Texture>> {
|
||||
@ -950,15 +919,6 @@ impl Global {
|
||||
let cmd_enc = self.hub.command_encoders.get(command_encoder_id);
|
||||
let mut cmd_buf_data = cmd_enc.data.lock();
|
||||
|
||||
#[cfg(feature = "trace")]
|
||||
if let Some(ref mut list) = cmd_buf_data.trace() {
|
||||
list.push(TraceCommand::CopyTextureToTexture {
|
||||
src: *source,
|
||||
dst: *destination,
|
||||
size: *copy_size,
|
||||
});
|
||||
}
|
||||
|
||||
cmd_buf_data.push_with(|| -> Result<_, CommandEncoderError> {
|
||||
Ok(ArcCommand::CopyTextureToTexture {
|
||||
src: wgt::TexelCopyTextureInfo {
|
||||
|
||||
@ -2,7 +2,7 @@ use alloc::{borrow::Cow, boxed::Box, string::String, sync::Arc, vec::Vec};
|
||||
use core::{ptr::NonNull, sync::atomic::Ordering};
|
||||
|
||||
#[cfg(feature = "trace")]
|
||||
use crate::device::trace;
|
||||
use crate::device::trace::{self, IntoTrace};
|
||||
use crate::{
|
||||
api_log,
|
||||
binding_model::{
|
||||
@ -106,6 +106,13 @@ impl Global {
|
||||
let error = 'error: {
|
||||
let device = self.hub.devices.get(device_id);
|
||||
|
||||
let buffer = match device.create_buffer(desc) {
|
||||
Ok(buffer) => buffer,
|
||||
Err(e) => {
|
||||
break 'error e;
|
||||
}
|
||||
};
|
||||
|
||||
#[cfg(feature = "trace")]
|
||||
if let Some(ref mut trace) = *device.trace.lock() {
|
||||
let mut desc = desc.clone();
|
||||
@ -113,16 +120,9 @@ impl Global {
|
||||
if mapped_at_creation && !desc.usage.contains(wgt::BufferUsages::MAP_WRITE) {
|
||||
desc.usage |= wgt::BufferUsages::COPY_DST;
|
||||
}
|
||||
trace.add(trace::Action::CreateBuffer(fid.id(), desc));
|
||||
trace.add(trace::Action::CreateBuffer(buffer.to_trace(), desc));
|
||||
}
|
||||
|
||||
let buffer = match device.create_buffer(desc) {
|
||||
Ok(buffer) => buffer,
|
||||
Err(e) => {
|
||||
break 'error e;
|
||||
}
|
||||
};
|
||||
|
||||
let id = fid.assign(Fallible::Valid(buffer));
|
||||
|
||||
api_log!(
|
||||
@ -240,13 +240,10 @@ impl Global {
|
||||
|
||||
#[cfg(feature = "trace")]
|
||||
if let Some(trace) = buffer.device.trace.lock().as_mut() {
|
||||
trace.add(trace::Action::FreeBuffer(buffer_id));
|
||||
trace.add(trace::Action::FreeBuffer(buffer.to_trace()));
|
||||
}
|
||||
|
||||
let _ = buffer.unmap(
|
||||
#[cfg(feature = "trace")]
|
||||
buffer_id,
|
||||
);
|
||||
let _ = buffer.unmap();
|
||||
|
||||
buffer.destroy();
|
||||
}
|
||||
@ -266,13 +263,10 @@ impl Global {
|
||||
|
||||
#[cfg(feature = "trace")]
|
||||
if let Some(t) = buffer.device.trace.lock().as_mut() {
|
||||
t.add(trace::Action::DestroyBuffer(buffer_id));
|
||||
t.add(trace::Action::DestroyBuffer(buffer.to_trace()));
|
||||
}
|
||||
|
||||
let _ = buffer.unmap(
|
||||
#[cfg(feature = "trace")]
|
||||
buffer_id,
|
||||
);
|
||||
let _ = buffer.unmap();
|
||||
}
|
||||
|
||||
pub fn device_create_texture(
|
||||
@ -290,16 +284,19 @@ impl Global {
|
||||
let error = 'error: {
|
||||
let device = self.hub.devices.get(device_id);
|
||||
|
||||
#[cfg(feature = "trace")]
|
||||
if let Some(ref mut trace) = *device.trace.lock() {
|
||||
trace.add(trace::Action::CreateTexture(fid.id(), desc.clone()));
|
||||
}
|
||||
|
||||
let texture = match device.create_texture(desc) {
|
||||
Ok(texture) => texture,
|
||||
Err(error) => break 'error error,
|
||||
};
|
||||
|
||||
#[cfg(feature = "trace")]
|
||||
if let Some(ref mut trace) = *device.trace.lock() {
|
||||
trace.add(trace::Action::CreateTexture(
|
||||
texture.to_trace(),
|
||||
desc.clone(),
|
||||
));
|
||||
}
|
||||
|
||||
let id = fid.assign(Fallible::Valid(texture));
|
||||
api_log!("Device::create_texture({desc:?}) -> {id:?}");
|
||||
|
||||
@ -331,18 +328,21 @@ impl Global {
|
||||
let error = 'error: {
|
||||
let device = self.hub.devices.get(device_id);
|
||||
|
||||
// NB: Any change done through the raw texture handle will not be
|
||||
// recorded in the replay
|
||||
#[cfg(feature = "trace")]
|
||||
if let Some(ref mut trace) = *device.trace.lock() {
|
||||
trace.add(trace::Action::CreateTexture(fid.id(), desc.clone()));
|
||||
}
|
||||
|
||||
let texture = match device.create_texture_from_hal(hal_texture, desc) {
|
||||
Ok(texture) => texture,
|
||||
Err(error) => break 'error error,
|
||||
};
|
||||
|
||||
// NB: Any change done through the raw texture handle will not be
|
||||
// recorded in the replay
|
||||
#[cfg(feature = "trace")]
|
||||
if let Some(ref mut trace) = *device.trace.lock() {
|
||||
trace.add(trace::Action::CreateTexture(
|
||||
texture.to_trace(),
|
||||
desc.clone(),
|
||||
));
|
||||
}
|
||||
|
||||
let id = fid.assign(Fallible::Valid(texture));
|
||||
api_log!("Device::create_texture({desc:?}) -> {id:?}");
|
||||
|
||||
@ -373,15 +373,20 @@ impl Global {
|
||||
|
||||
let device = self.hub.devices.get(device_id);
|
||||
|
||||
let (buffer, err) = unsafe { device.create_buffer_from_hal(Box::new(hal_buffer), desc) };
|
||||
|
||||
// NB: Any change done through the raw buffer handle will not be
|
||||
// recorded in the replay
|
||||
#[cfg(feature = "trace")]
|
||||
if let Some(trace) = device.trace.lock().as_mut() {
|
||||
trace.add(trace::Action::CreateBuffer(fid.id(), desc.clone()));
|
||||
match &buffer {
|
||||
Fallible::Valid(arc) => {
|
||||
trace.add(trace::Action::CreateBuffer(arc.to_trace(), desc.clone()))
|
||||
}
|
||||
Fallible::Invalid(_) => {}
|
||||
}
|
||||
}
|
||||
|
||||
let (buffer, err) = unsafe { device.create_buffer_from_hal(Box::new(hal_buffer), desc) };
|
||||
|
||||
let id = fid.assign(buffer);
|
||||
api_log!("Device::create_buffer -> {id:?}");
|
||||
|
||||
@ -401,7 +406,7 @@ impl Global {
|
||||
|
||||
#[cfg(feature = "trace")]
|
||||
if let Some(trace) = texture.device.trace.lock().as_mut() {
|
||||
trace.add(trace::Action::FreeTexture(texture_id));
|
||||
trace.add(trace::Action::FreeTexture(texture.to_trace()));
|
||||
}
|
||||
|
||||
texture.destroy();
|
||||
@ -417,7 +422,7 @@ impl Global {
|
||||
#[cfg(feature = "trace")]
|
||||
if let Ok(texture) = _texture.get() {
|
||||
if let Some(t) = texture.device.trace.lock().as_mut() {
|
||||
t.add(trace::Action::DestroyTexture(texture_id));
|
||||
t.add(trace::Action::DestroyTexture(texture.to_trace()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -441,20 +446,20 @@ impl Global {
|
||||
};
|
||||
let device = &texture.device;
|
||||
|
||||
#[cfg(feature = "trace")]
|
||||
if let Some(ref mut trace) = *device.trace.lock() {
|
||||
trace.add(trace::Action::CreateTextureView {
|
||||
id: fid.id(),
|
||||
parent_id: texture_id,
|
||||
desc: desc.clone(),
|
||||
});
|
||||
}
|
||||
|
||||
let view = match device.create_texture_view(&texture, desc) {
|
||||
Ok(view) => view,
|
||||
Err(e) => break 'error e,
|
||||
};
|
||||
|
||||
#[cfg(feature = "trace")]
|
||||
if let Some(ref mut trace) = *device.trace.lock() {
|
||||
trace.add(trace::Action::CreateTextureView {
|
||||
id: view.to_trace(),
|
||||
parent: texture.to_trace(),
|
||||
desc: desc.clone(),
|
||||
});
|
||||
}
|
||||
|
||||
let id = fid.assign(Fallible::Valid(view));
|
||||
|
||||
api_log!("Texture::create_view({texture_id:?}) -> {id:?}");
|
||||
@ -480,7 +485,7 @@ impl Global {
|
||||
#[cfg(feature = "trace")]
|
||||
if let Ok(view) = _view.get() {
|
||||
if let Some(t) = view.device.trace.lock().as_mut() {
|
||||
t.add(trace::Action::DestroyTextureView(texture_view_id));
|
||||
t.add(trace::Action::DestroyTextureView(view.to_trace()));
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
@ -1170,24 +1175,27 @@ impl Global {
|
||||
let device = self.hub.devices.get(bundle_encoder.parent());
|
||||
|
||||
#[cfg(feature = "trace")]
|
||||
if let Some(ref mut trace) = *device.trace.lock() {
|
||||
trace.add(trace::Action::CreateRenderBundle {
|
||||
id: fid.id(),
|
||||
desc: trace::new_render_bundle_encoder_descriptor(
|
||||
desc.label.clone(),
|
||||
&bundle_encoder.context,
|
||||
bundle_encoder.is_depth_read_only,
|
||||
bundle_encoder.is_stencil_read_only,
|
||||
),
|
||||
base: bundle_encoder.to_base_pass(),
|
||||
});
|
||||
}
|
||||
let trace_desc = trace::new_render_bundle_encoder_descriptor(
|
||||
desc.label.clone(),
|
||||
&bundle_encoder.context,
|
||||
bundle_encoder.is_depth_read_only,
|
||||
bundle_encoder.is_stencil_read_only,
|
||||
);
|
||||
|
||||
let render_bundle = match bundle_encoder.finish(desc, &device, hub) {
|
||||
Ok(bundle) => bundle,
|
||||
Err(e) => break 'error e,
|
||||
};
|
||||
|
||||
#[cfg(feature = "trace")]
|
||||
if let Some(ref mut trace) = *device.trace.lock() {
|
||||
trace.add(trace::Action::CreateRenderBundle {
|
||||
id: render_bundle.to_trace(),
|
||||
desc: trace_desc,
|
||||
base: render_bundle.to_base_pass().to_trace(),
|
||||
});
|
||||
}
|
||||
|
||||
let id = fid.assign(Fallible::Valid(render_bundle));
|
||||
api_log!("RenderBundleEncoder::finish -> {id:?}");
|
||||
|
||||
@ -1742,7 +1750,10 @@ impl Global {
|
||||
|
||||
#[cfg(feature = "trace")]
|
||||
if let Some(ref mut trace) = *device.trace.lock() {
|
||||
trace.add(trace::Action::ConfigureSurface(surface_id, config.clone()));
|
||||
trace.add(trace::Action::ConfigureSurface(
|
||||
surface.to_trace(),
|
||||
config.clone(),
|
||||
));
|
||||
}
|
||||
|
||||
device.configure_surface(&surface, config)
|
||||
@ -2082,9 +2093,6 @@ impl Global {
|
||||
drop(snatch_guard);
|
||||
|
||||
buffer.device.check_is_valid()?;
|
||||
buffer.unmap(
|
||||
#[cfg(feature = "trace")]
|
||||
buffer_id,
|
||||
)
|
||||
buffer.unmap()
|
||||
}
|
||||
}
|
||||
|
||||
@ -15,7 +15,7 @@ use wgt::{
|
||||
|
||||
use super::{life::LifetimeTracker, Device};
|
||||
#[cfg(feature = "trace")]
|
||||
use crate::device::trace::Action;
|
||||
use crate::device::trace::{Action, IntoTrace};
|
||||
use crate::{
|
||||
api_log,
|
||||
command::{
|
||||
@ -521,7 +521,7 @@ impl WebGpuError for QueueSubmitError {
|
||||
impl Queue {
|
||||
pub fn write_buffer(
|
||||
&self,
|
||||
buffer: Fallible<Buffer>,
|
||||
buffer: Arc<Buffer>,
|
||||
buffer_offset: wgt::BufferAddress,
|
||||
data: &[u8],
|
||||
) -> Result<(), QueueWriteError> {
|
||||
@ -530,8 +530,6 @@ impl Queue {
|
||||
|
||||
self.device.check_is_valid()?;
|
||||
|
||||
let buffer = buffer.get()?;
|
||||
|
||||
let data_size = data.len() as wgt::BufferAddress;
|
||||
|
||||
self.same_device_as(buffer.as_ref())?;
|
||||
@ -728,7 +726,7 @@ impl Queue {
|
||||
|
||||
pub fn write_texture(
|
||||
&self,
|
||||
destination: wgt::TexelCopyTextureInfo<Fallible<Texture>>,
|
||||
destination: wgt::TexelCopyTextureInfo<Arc<Texture>>,
|
||||
data: &[u8],
|
||||
data_layout: &wgt::TexelCopyBufferLayout,
|
||||
size: &wgt::Extent3d,
|
||||
@ -738,7 +736,7 @@ impl Queue {
|
||||
|
||||
self.device.check_is_valid()?;
|
||||
|
||||
let dst = destination.texture.get()?;
|
||||
let dst = destination.texture;
|
||||
let destination = wgt::TexelCopyTextureInfo {
|
||||
texture: (),
|
||||
mip_level: destination.mip_level,
|
||||
@ -1559,19 +1557,19 @@ impl Global {
|
||||
data: &[u8],
|
||||
) -> Result<(), QueueWriteError> {
|
||||
let queue = self.hub.queues.get(queue_id);
|
||||
let buffer = self.hub.buffers.get(buffer_id).get()?;
|
||||
|
||||
#[cfg(feature = "trace")]
|
||||
if let Some(ref mut trace) = *queue.device.trace.lock() {
|
||||
let data_path = trace.make_binary("bin", data);
|
||||
trace.add(Action::WriteBuffer {
|
||||
id: buffer_id,
|
||||
id: buffer.to_trace(),
|
||||
data: data_path,
|
||||
range: buffer_offset..buffer_offset + data.len() as u64,
|
||||
queued: true,
|
||||
});
|
||||
}
|
||||
|
||||
let buffer = self.hub.buffers.get(buffer_id);
|
||||
queue.write_buffer(buffer, buffer_offset, data)
|
||||
}
|
||||
|
||||
@ -1624,24 +1622,25 @@ impl Global {
|
||||
size: &wgt::Extent3d,
|
||||
) -> Result<(), QueueWriteError> {
|
||||
let queue = self.hub.queues.get(queue_id);
|
||||
let texture = self.hub.textures.get(destination.texture).get()?;
|
||||
let destination = wgt::TexelCopyTextureInfo {
|
||||
texture,
|
||||
mip_level: destination.mip_level,
|
||||
origin: destination.origin,
|
||||
aspect: destination.aspect,
|
||||
};
|
||||
|
||||
#[cfg(feature = "trace")]
|
||||
if let Some(ref mut trace) = *queue.device.trace.lock() {
|
||||
let data_path = trace.make_binary("bin", data);
|
||||
trace.add(Action::WriteTexture {
|
||||
to: *destination,
|
||||
to: destination.to_trace(),
|
||||
data: data_path,
|
||||
layout: *data_layout,
|
||||
size: *size,
|
||||
});
|
||||
}
|
||||
|
||||
let destination = wgt::TexelCopyTextureInfo {
|
||||
texture: self.hub.textures.get(destination.texture),
|
||||
mip_level: destination.mip_level,
|
||||
origin: destination.origin,
|
||||
aspect: destination.aspect,
|
||||
};
|
||||
queue.write_texture(destination, data, data_layout, size)
|
||||
}
|
||||
|
||||
|
||||
@ -1993,7 +1993,7 @@ impl Device {
|
||||
};
|
||||
let params = self.create_buffer(¶ms_desc)?;
|
||||
self.get_queue().unwrap().write_buffer(
|
||||
Fallible::Valid(params.clone()),
|
||||
params.clone(),
|
||||
0,
|
||||
bytemuck::bytes_of(¶ms_data),
|
||||
)?;
|
||||
|
||||
@ -27,7 +27,7 @@ pub enum Action<'a, R: ReferenceType> {
|
||||
backend: wgt::Backend,
|
||||
},
|
||||
ConfigureSurface(
|
||||
id::SurfaceId,
|
||||
R::Surface,
|
||||
wgt::SurfaceConfiguration<Vec<wgt::TextureFormat>>,
|
||||
),
|
||||
CreateBuffer(R::Buffer, crate::resource::BufferDescriptor<'a>),
|
||||
@ -38,7 +38,7 @@ pub enum Action<'a, R: ReferenceType> {
|
||||
DestroyTexture(R::Texture),
|
||||
CreateTextureView {
|
||||
id: R::TextureView,
|
||||
parent_id: R::Texture,
|
||||
parent: R::Texture,
|
||||
desc: crate::resource::TextureViewDescriptor<'a>,
|
||||
},
|
||||
DestroyTextureView(R::TextureView),
|
||||
@ -53,10 +53,10 @@ pub enum Action<'a, R: ReferenceType> {
|
||||
DestroySampler(id::SamplerId),
|
||||
GetSurfaceTexture {
|
||||
id: R::Texture,
|
||||
parent_id: id::SurfaceId,
|
||||
parent: R::Surface,
|
||||
},
|
||||
Present(id::SurfaceId),
|
||||
DiscardSurfaceTexture(id::SurfaceId),
|
||||
Present(R::Surface),
|
||||
DiscardSurfaceTexture(R::Surface),
|
||||
CreateBindGroupLayout(
|
||||
id::BindGroupLayoutId,
|
||||
crate::binding_model::BindGroupLayoutDescriptor<'a>,
|
||||
@ -107,9 +107,9 @@ pub enum Action<'a, R: ReferenceType> {
|
||||
},
|
||||
DestroyPipelineCache(id::PipelineCacheId),
|
||||
CreateRenderBundle {
|
||||
id: id::RenderBundleId,
|
||||
id: R::RenderBundle,
|
||||
desc: crate::command::RenderBundleEncoderDescriptor<'a>,
|
||||
base: BasePass<RenderCommand, Infallible>,
|
||||
base: BasePass<RenderCommand<R>, Infallible>,
|
||||
},
|
||||
DestroyRenderBundle(id::RenderBundleId),
|
||||
CreateQuerySet {
|
||||
@ -129,7 +129,7 @@ pub enum Action<'a, R: ReferenceType> {
|
||||
layout: wgt::TexelCopyBufferLayout,
|
||||
size: wgt::Extent3d,
|
||||
},
|
||||
Submit(crate::SubmissionIndex, Vec<Command>),
|
||||
Submit(crate::SubmissionIndex, Vec<Command<R>>),
|
||||
CreateBlas {
|
||||
id: id::BlasId,
|
||||
desc: crate::resource::BlasDescriptor<'a>,
|
||||
|
||||
@ -1,19 +1,32 @@
|
||||
use alloc::{borrow::Cow, string::String};
|
||||
use alloc::{
|
||||
borrow::Cow,
|
||||
string::{String, ToString},
|
||||
sync::Arc,
|
||||
};
|
||||
use core::convert::Infallible;
|
||||
use std::io::Write as _;
|
||||
|
||||
use crate::command::IdReferences;
|
||||
use crate::{
|
||||
command::{
|
||||
ArcCommand, ArcComputeCommand, ArcPassTimestampWrites, ArcReferences, ArcRenderCommand,
|
||||
BasePass, ColorAttachments, Command, ComputeCommand, PointerReferences, RenderCommand,
|
||||
RenderPassColorAttachment, ResolvedRenderPassDepthStencilAttachment,
|
||||
},
|
||||
id,
|
||||
storage::StorageItem,
|
||||
};
|
||||
|
||||
use super::{Action, FILE_NAME};
|
||||
|
||||
pub(crate) fn new_render_bundle_encoder_descriptor<'a>(
|
||||
label: crate::Label<'a>,
|
||||
context: &'a crate::device::RenderPassContext,
|
||||
pub(crate) fn new_render_bundle_encoder_descriptor(
|
||||
label: crate::Label<'_>,
|
||||
context: &crate::device::RenderPassContext,
|
||||
depth_read_only: bool,
|
||||
stencil_read_only: bool,
|
||||
) -> crate::command::RenderBundleEncoderDescriptor<'a> {
|
||||
) -> crate::command::RenderBundleEncoderDescriptor<'static> {
|
||||
crate::command::RenderBundleEncoderDescriptor {
|
||||
label,
|
||||
color_formats: Cow::Borrowed(&context.attachments.colors),
|
||||
label: label.map(|l| Cow::from(l.to_string())),
|
||||
color_formats: Cow::from(context.attachments.colors.to_vec()),
|
||||
depth_stencil: context.attachments.depth_stencil.map(|format| {
|
||||
wgt::RenderBundleDepthStencil {
|
||||
format,
|
||||
@ -54,9 +67,9 @@ impl Trace {
|
||||
name
|
||||
}
|
||||
|
||||
pub(crate) fn add(&mut self, action: Action<'_, IdReferences>)
|
||||
pub(crate) fn add(&mut self, action: Action<'_, PointerReferences>)
|
||||
where
|
||||
for<'a> Action<'a, IdReferences>: serde::Serialize,
|
||||
for<'a> Action<'a, PointerReferences>: serde::Serialize,
|
||||
{
|
||||
match ron::ser::to_string_pretty(&action, self.config.clone()) {
|
||||
Ok(string) => {
|
||||
@ -74,3 +87,476 @@ impl Drop for Trace {
|
||||
let _ = self.file.write_all(b"]");
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) trait IntoTrace {
|
||||
type Output;
|
||||
fn into_trace(self) -> Self::Output;
|
||||
|
||||
fn to_trace(&self) -> Self::Output
|
||||
where
|
||||
Self: Sized + Clone,
|
||||
{
|
||||
self.clone().into_trace()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: StorageItem> IntoTrace for Arc<T> {
|
||||
type Output = id::PointerId<T::Marker>;
|
||||
fn into_trace(self) -> Self::Output {
|
||||
self.to_trace()
|
||||
}
|
||||
|
||||
fn to_trace(&self) -> Self::Output {
|
||||
id::PointerId::from(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoTrace for ArcCommand {
|
||||
type Output = Command<PointerReferences>;
|
||||
fn into_trace(self) -> Self::Output {
|
||||
match self {
|
||||
ArcCommand::CopyBufferToBuffer {
|
||||
src,
|
||||
src_offset,
|
||||
dst,
|
||||
dst_offset,
|
||||
size,
|
||||
} => Command::CopyBufferToBuffer {
|
||||
src: src.to_trace(),
|
||||
src_offset,
|
||||
dst: dst.to_trace(),
|
||||
dst_offset,
|
||||
size,
|
||||
},
|
||||
ArcCommand::CopyBufferToTexture { src, dst, size } => Command::CopyBufferToTexture {
|
||||
src: src.into_trace(),
|
||||
dst: dst.into_trace(),
|
||||
size,
|
||||
},
|
||||
ArcCommand::CopyTextureToBuffer { src, dst, size } => Command::CopyTextureToBuffer {
|
||||
src: src.into_trace(),
|
||||
dst: dst.into_trace(),
|
||||
size,
|
||||
},
|
||||
ArcCommand::CopyTextureToTexture { src, dst, size } => Command::CopyTextureToTexture {
|
||||
src: src.into_trace(),
|
||||
dst: dst.into_trace(),
|
||||
size,
|
||||
},
|
||||
ArcCommand::ClearBuffer { dst, offset, size } => Command::ClearBuffer {
|
||||
dst: dst.to_trace(),
|
||||
offset,
|
||||
size,
|
||||
},
|
||||
ArcCommand::ClearTexture {
|
||||
dst,
|
||||
subresource_range,
|
||||
} => Command::ClearTexture {
|
||||
dst: dst.to_trace(),
|
||||
subresource_range,
|
||||
},
|
||||
ArcCommand::WriteTimestamp {
|
||||
query_set,
|
||||
query_index,
|
||||
} => Command::WriteTimestamp {
|
||||
query_set: query_set.to_trace(),
|
||||
query_index,
|
||||
},
|
||||
ArcCommand::ResolveQuerySet {
|
||||
query_set,
|
||||
start_query,
|
||||
query_count,
|
||||
destination,
|
||||
destination_offset,
|
||||
} => Command::ResolveQuerySet {
|
||||
query_set: query_set.to_trace(),
|
||||
start_query,
|
||||
query_count,
|
||||
destination: destination.to_trace(),
|
||||
destination_offset,
|
||||
},
|
||||
ArcCommand::PushDebugGroup(label) => Command::PushDebugGroup(label),
|
||||
ArcCommand::PopDebugGroup => Command::PopDebugGroup,
|
||||
ArcCommand::InsertDebugMarker(label) => Command::InsertDebugMarker(label),
|
||||
ArcCommand::RunComputePass {
|
||||
pass,
|
||||
timestamp_writes,
|
||||
} => Command::RunComputePass {
|
||||
pass: pass.into_trace(),
|
||||
timestamp_writes: timestamp_writes.map(|tw| tw.into_trace()),
|
||||
},
|
||||
ArcCommand::RunRenderPass {
|
||||
pass,
|
||||
color_attachments,
|
||||
depth_stencil_attachment,
|
||||
timestamp_writes,
|
||||
occlusion_query_set,
|
||||
} => Command::RunRenderPass {
|
||||
pass: pass.into_trace(),
|
||||
color_attachments: color_attachments.into_trace(),
|
||||
depth_stencil_attachment: depth_stencil_attachment.map(|d| d.into_trace()),
|
||||
timestamp_writes: timestamp_writes.map(|tw| tw.into_trace()),
|
||||
occlusion_query_set: occlusion_query_set.map(|q| q.to_trace()),
|
||||
},
|
||||
ArcCommand::BuildAccelerationStructures { blas, tlas } => {
|
||||
Command::BuildAccelerationStructures {
|
||||
blas: blas.into_iter().map(|b| b.into_trace()).collect(),
|
||||
tlas: tlas.into_iter().map(|b| b.into_trace()).collect(),
|
||||
}
|
||||
}
|
||||
ArcCommand::TransitionResources {
|
||||
buffer_transitions: _,
|
||||
texture_transitions: _,
|
||||
} => {
|
||||
// TransitionResources does not exist in Command, so skip or handle as needed.
|
||||
// If you want to ignore, you could panic or return a default.
|
||||
panic!("TransitionResources cannot be converted to Command");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: IntoTrace> IntoTrace for wgt::TexelCopyBufferInfo<T> {
|
||||
type Output = wgt::TexelCopyBufferInfo<T::Output>;
|
||||
fn into_trace(self) -> Self::Output {
|
||||
wgt::TexelCopyBufferInfo {
|
||||
buffer: self.buffer.into_trace(),
|
||||
layout: self.layout,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: IntoTrace> IntoTrace for wgt::TexelCopyTextureInfo<T> {
|
||||
type Output = wgt::TexelCopyTextureInfo<T::Output>;
|
||||
fn into_trace(self) -> Self::Output {
|
||||
wgt::TexelCopyTextureInfo {
|
||||
texture: self.texture.into_trace(),
|
||||
mip_level: self.mip_level,
|
||||
origin: self.origin,
|
||||
aspect: self.aspect,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoTrace for ArcPassTimestampWrites {
|
||||
type Output = crate::command::PassTimestampWrites<id::PointerId<id::markers::QuerySet>>;
|
||||
fn into_trace(self) -> Self::Output {
|
||||
crate::command::PassTimestampWrites {
|
||||
query_set: self.query_set.into_trace(),
|
||||
beginning_of_pass_write_index: self.beginning_of_pass_write_index,
|
||||
end_of_pass_write_index: self.end_of_pass_write_index,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoTrace for ColorAttachments {
|
||||
type Output = ColorAttachments<id::PointerId<id::markers::TextureView>>;
|
||||
fn into_trace(self) -> Self::Output {
|
||||
self.into_iter()
|
||||
.map(|opt| {
|
||||
opt.map(|att| RenderPassColorAttachment {
|
||||
view: att.view.into_trace(),
|
||||
depth_slice: att.depth_slice,
|
||||
resolve_target: att.resolve_target.map(|r| r.into_trace()),
|
||||
load_op: att.load_op,
|
||||
store_op: att.store_op,
|
||||
})
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
impl<TV: IntoTrace> IntoTrace for ResolvedRenderPassDepthStencilAttachment<TV> {
|
||||
type Output = ResolvedRenderPassDepthStencilAttachment<TV::Output>;
|
||||
fn into_trace(self) -> Self::Output {
|
||||
ResolvedRenderPassDepthStencilAttachment {
|
||||
view: self.view.into_trace(),
|
||||
depth: self.depth,
|
||||
stencil: self.stencil,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoTrace for crate::ray_tracing::OwnedBlasBuildEntry<ArcReferences> {
|
||||
type Output = crate::ray_tracing::OwnedBlasBuildEntry<PointerReferences>;
|
||||
fn into_trace(self) -> Self::Output {
|
||||
crate::ray_tracing::OwnedBlasBuildEntry {
|
||||
blas: self.blas.into_trace(),
|
||||
geometries: self.geometries.into_trace(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoTrace for crate::ray_tracing::OwnedBlasGeometries<ArcReferences> {
|
||||
type Output = crate::ray_tracing::OwnedBlasGeometries<PointerReferences>;
|
||||
fn into_trace(self) -> Self::Output {
|
||||
match self {
|
||||
crate::ray_tracing::OwnedBlasGeometries::TriangleGeometries(geos) => {
|
||||
crate::ray_tracing::OwnedBlasGeometries::TriangleGeometries(
|
||||
geos.into_iter().map(|g| g.into_trace()).collect(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoTrace for crate::ray_tracing::OwnedBlasTriangleGeometry<ArcReferences> {
|
||||
type Output = crate::ray_tracing::OwnedBlasTriangleGeometry<PointerReferences>;
|
||||
fn into_trace(self) -> Self::Output {
|
||||
crate::ray_tracing::OwnedBlasTriangleGeometry {
|
||||
size: self.size,
|
||||
vertex_buffer: self.vertex_buffer.into_trace(),
|
||||
index_buffer: self.index_buffer.map(|b| b.into_trace()),
|
||||
transform_buffer: self.transform_buffer.map(|b| b.into_trace()),
|
||||
first_vertex: self.first_vertex,
|
||||
vertex_stride: self.vertex_stride,
|
||||
first_index: self.first_index,
|
||||
transform_buffer_offset: self.transform_buffer_offset,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoTrace for crate::ray_tracing::OwnedTlasPackage<ArcReferences> {
|
||||
type Output = crate::ray_tracing::OwnedTlasPackage<PointerReferences>;
|
||||
fn into_trace(self) -> Self::Output {
|
||||
crate::ray_tracing::OwnedTlasPackage {
|
||||
tlas: self.tlas.into_trace(),
|
||||
instances: self
|
||||
.instances
|
||||
.into_iter()
|
||||
.map(|opt| opt.map(|inst| inst.into_trace()))
|
||||
.collect(),
|
||||
lowest_unmodified: self.lowest_unmodified,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoTrace for crate::ray_tracing::OwnedTlasInstance<ArcReferences> {
|
||||
type Output = crate::ray_tracing::OwnedTlasInstance<PointerReferences>;
|
||||
fn into_trace(self) -> Self::Output {
|
||||
crate::ray_tracing::OwnedTlasInstance {
|
||||
blas: self.blas.into_trace(),
|
||||
transform: self.transform,
|
||||
custom_data: self.custom_data,
|
||||
mask: self.mask,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<C: IntoTrace> IntoTrace for BasePass<C, Infallible> {
|
||||
type Output = BasePass<C::Output, Infallible>;
|
||||
|
||||
fn into_trace(self) -> Self::Output {
|
||||
BasePass {
|
||||
label: self.label,
|
||||
error: self.error,
|
||||
commands: self
|
||||
.commands
|
||||
.into_iter()
|
||||
.map(|cmd| cmd.into_trace())
|
||||
.collect(),
|
||||
dynamic_offsets: self.dynamic_offsets,
|
||||
string_data: self.string_data,
|
||||
push_constant_data: self.push_constant_data,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoTrace for ArcComputeCommand {
|
||||
type Output = ComputeCommand<PointerReferences>;
|
||||
fn into_trace(self) -> Self::Output {
|
||||
use ComputeCommand as C;
|
||||
match self {
|
||||
C::SetBindGroup {
|
||||
index,
|
||||
num_dynamic_offsets,
|
||||
bind_group,
|
||||
} => C::SetBindGroup {
|
||||
index,
|
||||
num_dynamic_offsets,
|
||||
bind_group: bind_group.map(|bg| bg.into_trace()),
|
||||
},
|
||||
C::SetPipeline(id) => C::SetPipeline(id.into_trace()),
|
||||
C::SetPushConstant {
|
||||
offset,
|
||||
size_bytes,
|
||||
values_offset,
|
||||
} => C::SetPushConstant {
|
||||
offset,
|
||||
size_bytes,
|
||||
values_offset,
|
||||
},
|
||||
C::Dispatch(groups) => C::Dispatch(groups),
|
||||
C::DispatchIndirect { buffer, offset } => C::DispatchIndirect {
|
||||
buffer: buffer.into_trace(),
|
||||
offset,
|
||||
},
|
||||
C::PushDebugGroup { color, len } => C::PushDebugGroup { color, len },
|
||||
C::PopDebugGroup => C::PopDebugGroup,
|
||||
C::InsertDebugMarker { color, len } => C::InsertDebugMarker { color, len },
|
||||
C::WriteTimestamp {
|
||||
query_set,
|
||||
query_index,
|
||||
} => C::WriteTimestamp {
|
||||
query_set: query_set.into_trace(),
|
||||
query_index,
|
||||
},
|
||||
C::BeginPipelineStatisticsQuery {
|
||||
query_set,
|
||||
query_index,
|
||||
} => C::BeginPipelineStatisticsQuery {
|
||||
query_set: query_set.into_trace(),
|
||||
query_index,
|
||||
},
|
||||
C::EndPipelineStatisticsQuery => C::EndPipelineStatisticsQuery,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoTrace for ArcRenderCommand {
|
||||
type Output = RenderCommand<PointerReferences>;
|
||||
fn into_trace(self) -> Self::Output {
|
||||
use RenderCommand as C;
|
||||
match self {
|
||||
C::SetBindGroup {
|
||||
index,
|
||||
num_dynamic_offsets,
|
||||
bind_group,
|
||||
} => C::SetBindGroup {
|
||||
index,
|
||||
num_dynamic_offsets,
|
||||
bind_group: bind_group.map(|bg| bg.into_trace()),
|
||||
},
|
||||
C::SetPipeline(id) => C::SetPipeline(id.into_trace()),
|
||||
C::SetIndexBuffer {
|
||||
buffer,
|
||||
index_format,
|
||||
offset,
|
||||
size,
|
||||
} => C::SetIndexBuffer {
|
||||
buffer: buffer.into_trace(),
|
||||
index_format,
|
||||
offset,
|
||||
size,
|
||||
},
|
||||
C::SetVertexBuffer {
|
||||
slot,
|
||||
buffer,
|
||||
offset,
|
||||
size,
|
||||
} => C::SetVertexBuffer {
|
||||
slot,
|
||||
buffer: buffer.into_trace(),
|
||||
offset,
|
||||
size,
|
||||
},
|
||||
C::SetBlendConstant(color) => C::SetBlendConstant(color),
|
||||
C::SetStencilReference(val) => C::SetStencilReference(val),
|
||||
C::SetViewport {
|
||||
rect,
|
||||
depth_min,
|
||||
depth_max,
|
||||
} => C::SetViewport {
|
||||
rect,
|
||||
depth_min,
|
||||
depth_max,
|
||||
},
|
||||
C::SetScissor(rect) => C::SetScissor(rect),
|
||||
C::SetPushConstant {
|
||||
stages,
|
||||
offset,
|
||||
size_bytes,
|
||||
values_offset,
|
||||
} => C::SetPushConstant {
|
||||
stages,
|
||||
offset,
|
||||
size_bytes,
|
||||
values_offset,
|
||||
},
|
||||
C::Draw {
|
||||
vertex_count,
|
||||
instance_count,
|
||||
first_vertex,
|
||||
first_instance,
|
||||
} => C::Draw {
|
||||
vertex_count,
|
||||
instance_count,
|
||||
first_vertex,
|
||||
first_instance,
|
||||
},
|
||||
C::DrawIndexed {
|
||||
index_count,
|
||||
instance_count,
|
||||
first_index,
|
||||
base_vertex,
|
||||
first_instance,
|
||||
} => C::DrawIndexed {
|
||||
index_count,
|
||||
instance_count,
|
||||
first_index,
|
||||
base_vertex,
|
||||
first_instance,
|
||||
},
|
||||
C::DrawMeshTasks {
|
||||
group_count_x,
|
||||
group_count_y,
|
||||
group_count_z,
|
||||
} => C::DrawMeshTasks {
|
||||
group_count_x,
|
||||
group_count_y,
|
||||
group_count_z,
|
||||
},
|
||||
C::DrawIndirect {
|
||||
buffer,
|
||||
offset,
|
||||
count,
|
||||
family,
|
||||
vertex_or_index_limit,
|
||||
instance_limit,
|
||||
} => C::DrawIndirect {
|
||||
buffer: buffer.into_trace(),
|
||||
offset,
|
||||
count,
|
||||
family,
|
||||
vertex_or_index_limit,
|
||||
instance_limit,
|
||||
},
|
||||
C::MultiDrawIndirectCount {
|
||||
buffer,
|
||||
offset,
|
||||
count_buffer,
|
||||
count_buffer_offset,
|
||||
max_count,
|
||||
family,
|
||||
} => C::MultiDrawIndirectCount {
|
||||
buffer: buffer.into_trace(),
|
||||
offset,
|
||||
count_buffer: count_buffer.into_trace(),
|
||||
count_buffer_offset,
|
||||
max_count,
|
||||
family,
|
||||
},
|
||||
C::PushDebugGroup { color, len } => C::PushDebugGroup { color, len },
|
||||
C::PopDebugGroup => C::PopDebugGroup,
|
||||
C::InsertDebugMarker { color, len } => C::InsertDebugMarker { color, len },
|
||||
C::WriteTimestamp {
|
||||
query_set,
|
||||
query_index,
|
||||
} => C::WriteTimestamp {
|
||||
query_set: query_set.into_trace(),
|
||||
query_index,
|
||||
},
|
||||
C::BeginOcclusionQuery { query_index } => C::BeginOcclusionQuery { query_index },
|
||||
C::EndOcclusionQuery => C::EndOcclusionQuery,
|
||||
C::BeginPipelineStatisticsQuery {
|
||||
query_set,
|
||||
query_index,
|
||||
} => C::BeginPipelineStatisticsQuery {
|
||||
query_set: query_set.into_trace(),
|
||||
query_index,
|
||||
},
|
||||
C::EndPipelineStatisticsQuery => C::EndPipelineStatisticsQuery,
|
||||
C::ExecuteBundle(bundle) => C::ExecuteBundle(bundle.into_trace()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
use crate::{Epoch, Index};
|
||||
use crate::{storage::StorageItem, Epoch, Index};
|
||||
use alloc::sync::Arc;
|
||||
use core::{
|
||||
cmp::Ordering,
|
||||
fmt::{self, Debug},
|
||||
@ -82,18 +83,15 @@ impl RawId {
|
||||
/// [`Registry`]: crate::registry::Registry
|
||||
/// [`Noop`]: hal::api::Noop
|
||||
#[repr(transparent)]
|
||||
#[cfg_attr(any(feature = "serde", feature = "trace"), derive(serde::Serialize))]
|
||||
#[cfg_attr(any(feature = "serde", feature = "replay"), derive(serde::Deserialize))]
|
||||
#[cfg_attr(
|
||||
any(feature = "serde", feature = "trace", feature = "replay"),
|
||||
serde(transparent)
|
||||
)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
#[cfg_attr(feature = "serde", serde(transparent))]
|
||||
pub struct Id<T: Marker>(RawId, PhantomData<T>);
|
||||
|
||||
// This type represents Id in a more readable (and editable) way.
|
||||
#[allow(dead_code)]
|
||||
#[cfg(feature = "serde")]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
enum SerialId {
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum SerialId {
|
||||
// The only variant forces RON to not ignore "Id"
|
||||
Id(Index, Epoch),
|
||||
}
|
||||
@ -125,6 +123,48 @@ impl TryFrom<SerialId> for RawId {
|
||||
}
|
||||
}
|
||||
|
||||
/// Identify an object by the pointer returned by `Arc::as_ptr`.
|
||||
///
|
||||
/// This is used for tracing.
|
||||
#[allow(dead_code)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
#[derive(Debug)]
|
||||
pub struct PointerId<T: Marker>(usize, #[serde(skip)] PhantomData<T>);
|
||||
|
||||
impl<T: Marker> Copy for PointerId<T> {}
|
||||
|
||||
impl<T: Marker> Clone for PointerId<T> {
|
||||
fn clone(&self) -> Self {
|
||||
*self
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Marker> PartialEq for PointerId<T> {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.0 == other.0
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Marker> Eq for PointerId<T> {}
|
||||
|
||||
impl<T: Marker> Hash for PointerId<T> {
|
||||
fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
|
||||
self.0.hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: StorageItem> From<&Arc<T>> for PointerId<T::Marker> {
|
||||
fn from(arc: &Arc<T>) -> Self {
|
||||
// Since the memory representation of `Arc<T>` is just a pointer, it
|
||||
// would be nice to use that pointer as the trace ID, since many
|
||||
// `into_trace` implementations would then be no-ops at runtime.
|
||||
// Unfortunately, because `Arc::as_ptr` returns a pointer to the
|
||||
// contained data, and `Arc` stores reference counts before the data,
|
||||
// we are adding an offset to the pointer here.
|
||||
Self(Arc::as_ptr(arc) as usize, PhantomData)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Id<T>
|
||||
where
|
||||
T: Marker,
|
||||
|
||||
@ -13,7 +13,7 @@ use alloc::{sync::Arc, vec::Vec};
|
||||
use core::mem::ManuallyDrop;
|
||||
|
||||
#[cfg(feature = "trace")]
|
||||
use crate::device::trace::Action;
|
||||
use crate::device::trace::{Action, IntoTrace};
|
||||
use crate::{
|
||||
conv,
|
||||
device::{Device, DeviceError, MissingDownlevelFlags, WaitIdleError},
|
||||
@ -363,10 +363,12 @@ impl Global {
|
||||
#[cfg(feature = "trace")]
|
||||
if let Some(present) = surface.presentation.lock().as_ref() {
|
||||
if let Some(ref mut trace) = *present.device.trace.lock() {
|
||||
trace.add(Action::GetSurfaceTexture {
|
||||
id: fid.id(),
|
||||
parent_id: surface_id,
|
||||
});
|
||||
if let Some(texture) = present.acquired_texture.as_ref() {
|
||||
trace.add(Action::GetSurfaceTexture {
|
||||
id: texture.to_trace(),
|
||||
parent: surface.to_trace(),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -389,7 +391,7 @@ impl Global {
|
||||
#[cfg(feature = "trace")]
|
||||
if let Some(present) = surface.presentation.lock().as_ref() {
|
||||
if let Some(ref mut trace) = *present.device.trace.lock() {
|
||||
trace.add(Action::Present(surface_id));
|
||||
trace.add(Action::Present(surface.to_trace()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -402,7 +404,7 @@ impl Global {
|
||||
#[cfg(feature = "trace")]
|
||||
if let Some(present) = surface.presentation.lock().as_ref() {
|
||||
if let Some(ref mut trace) = *present.device.trace.lock() {
|
||||
trace.add(Action::DiscardSurfaceTexture(surface_id));
|
||||
trace.add(Action::DiscardSurfaceTexture(surface.to_trace()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -337,7 +337,7 @@ pub type TraceBlasGeometries = OwnedBlasGeometries<IdReferences>;
|
||||
#[cfg_attr(feature = "serde", apply(serde_object_reference_struct))]
|
||||
pub struct OwnedBlasBuildEntry<R: ReferenceType> {
|
||||
pub blas: R::Blas,
|
||||
pub geometries: OwnedBlasGeometries<R>, // TODO
|
||||
pub geometries: OwnedBlasGeometries<R>,
|
||||
}
|
||||
|
||||
pub type ArcBlasBuildEntry = OwnedBlasBuildEntry<ArcReferences>;
|
||||
|
||||
@ -797,14 +797,8 @@ impl Buffer {
|
||||
}
|
||||
|
||||
// Note: This must not be called while holding a lock.
|
||||
pub(crate) fn unmap(
|
||||
self: &Arc<Self>,
|
||||
#[cfg(feature = "trace")] buffer_id: crate::id::BufferId,
|
||||
) -> Result<(), BufferAccessError> {
|
||||
if let Some((mut operation, status)) = self.unmap_inner(
|
||||
#[cfg(feature = "trace")]
|
||||
buffer_id,
|
||||
)? {
|
||||
pub(crate) fn unmap(self: &Arc<Self>) -> Result<(), BufferAccessError> {
|
||||
if let Some((mut operation, status)) = self.unmap_inner()? {
|
||||
if let Some(callback) = operation.callback.take() {
|
||||
callback(status);
|
||||
}
|
||||
@ -813,10 +807,7 @@ impl Buffer {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn unmap_inner(
|
||||
self: &Arc<Self>,
|
||||
#[cfg(feature = "trace")] buffer_id: crate::id::BufferId,
|
||||
) -> Result<Option<BufferMapPendingClosure>, BufferAccessError> {
|
||||
fn unmap_inner(self: &Arc<Self>) -> Result<Option<BufferMapPendingClosure>, BufferAccessError> {
|
||||
let device = &self.device;
|
||||
let snatch_guard = device.snatchable_lock.read();
|
||||
let raw_buf = self.try_raw(&snatch_guard)?;
|
||||
@ -824,9 +815,11 @@ impl Buffer {
|
||||
BufferMapState::Init { staging_buffer } => {
|
||||
#[cfg(feature = "trace")]
|
||||
if let Some(ref mut trace) = *device.trace.lock() {
|
||||
use crate::device::trace::IntoTrace;
|
||||
|
||||
let data = trace.make_binary("bin", staging_buffer.get_data());
|
||||
trace.add(trace::Action::WriteBuffer {
|
||||
id: buffer_id,
|
||||
id: self.to_trace(),
|
||||
data,
|
||||
range: 0..self.size,
|
||||
queued: true,
|
||||
@ -886,12 +879,14 @@ impl Buffer {
|
||||
if host == HostMap::Write {
|
||||
#[cfg(feature = "trace")]
|
||||
if let Some(ref mut trace) = *device.trace.lock() {
|
||||
use crate::device::trace::IntoTrace;
|
||||
|
||||
let size = range.end - range.start;
|
||||
let data = trace.make_binary("bin", unsafe {
|
||||
core::slice::from_raw_parts(mapping.ptr.as_ptr(), size as usize)
|
||||
});
|
||||
trace.add(trace::Action::WriteBuffer {
|
||||
id: buffer_id,
|
||||
id: self.to_trace(),
|
||||
data,
|
||||
range: range.clone(),
|
||||
queued: false,
|
||||
|
||||
@ -19,7 +19,9 @@ where
|
||||
Occupied(T, Epoch),
|
||||
}
|
||||
|
||||
pub(crate) trait StorageItem: ResourceType {
|
||||
/// Not a public API. For use only by `player`.
|
||||
#[doc(hidden)]
|
||||
pub trait StorageItem: ResourceType {
|
||||
type Marker: Marker;
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user