Separate renderpass arc resolve & renderpass consume on end (#5794)

This commit is contained in:
Andreas Reich 2024-06-25 09:37:29 +02:00 committed by GitHub
parent 29e3b984a4
commit b4c7987aa7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 1559 additions and 669 deletions

View File

@ -9,6 +9,7 @@ use deno_core::ResourceId;
use serde::Deserialize;
use std::borrow::Cow;
use std::cell::RefCell;
use wgpu_core::global::Global;
use super::error::WebGpuResult;
@ -41,7 +42,7 @@ pub fn op_webgpu_render_pass_set_viewport(
.resource_table
.get::<WebGpuRenderPass>(args.render_pass_rid)?;
wgpu_core::command::render_commands::wgpu_render_pass_set_viewport(
state.borrow::<Global>().render_pass_set_viewport(
&mut render_pass_resource.0.borrow_mut(),
args.x,
args.y,
@ -49,7 +50,7 @@ pub fn op_webgpu_render_pass_set_viewport(
args.height,
args.min_depth,
args.max_depth,
);
)?;
Ok(WebGpuResult::empty())
}
@ -68,13 +69,13 @@ pub fn op_webgpu_render_pass_set_scissor_rect(
.resource_table
.get::<WebGpuRenderPass>(render_pass_rid)?;
wgpu_core::command::render_commands::wgpu_render_pass_set_scissor_rect(
state.borrow::<Global>().render_pass_set_scissor_rect(
&mut render_pass_resource.0.borrow_mut(),
x,
y,
width,
height,
);
)?;
Ok(WebGpuResult::empty())
}
@ -90,10 +91,9 @@ pub fn op_webgpu_render_pass_set_blend_constant(
.resource_table
.get::<WebGpuRenderPass>(render_pass_rid)?;
wgpu_core::command::render_commands::wgpu_render_pass_set_blend_constant(
&mut render_pass_resource.0.borrow_mut(),
&color,
);
state
.borrow::<Global>()
.render_pass_set_blend_constant(&mut render_pass_resource.0.borrow_mut(), &color)?;
Ok(WebGpuResult::empty())
}
@ -109,10 +109,9 @@ pub fn op_webgpu_render_pass_set_stencil_reference(
.resource_table
.get::<WebGpuRenderPass>(render_pass_rid)?;
wgpu_core::command::render_commands::wgpu_render_pass_set_stencil_reference(
&mut render_pass_resource.0.borrow_mut(),
reference,
);
state
.borrow::<Global>()
.render_pass_set_stencil_reference(&mut render_pass_resource.0.borrow_mut(), reference)?;
Ok(WebGpuResult::empty())
}
@ -128,10 +127,9 @@ pub fn op_webgpu_render_pass_begin_occlusion_query(
.resource_table
.get::<WebGpuRenderPass>(render_pass_rid)?;
wgpu_core::command::render_commands::wgpu_render_pass_begin_occlusion_query(
&mut render_pass_resource.0.borrow_mut(),
query_index,
);
state
.borrow::<Global>()
.render_pass_begin_occlusion_query(&mut render_pass_resource.0.borrow_mut(), query_index)?;
Ok(WebGpuResult::empty())
}
@ -146,9 +144,9 @@ pub fn op_webgpu_render_pass_end_occlusion_query(
.resource_table
.get::<WebGpuRenderPass>(render_pass_rid)?;
wgpu_core::command::render_commands::wgpu_render_pass_end_occlusion_query(
&mut render_pass_resource.0.borrow_mut(),
);
state
.borrow::<Global>()
.render_pass_end_occlusion_query(&mut render_pass_resource.0.borrow_mut())?;
Ok(WebGpuResult::empty())
}
@ -174,10 +172,9 @@ pub fn op_webgpu_render_pass_execute_bundles(
.resource_table
.get::<WebGpuRenderPass>(render_pass_rid)?;
wgpu_core::command::render_commands::wgpu_render_pass_execute_bundles(
&mut render_pass_resource.0.borrow_mut(),
&bundles,
);
state
.borrow::<Global>()
.render_pass_execute_bundles(&mut render_pass_resource.0.borrow_mut(), &bundles)?;
Ok(WebGpuResult::empty())
}
@ -191,11 +188,15 @@ pub fn op_webgpu_render_pass_end(
let render_pass_resource = state
.resource_table
.take::<WebGpuRenderPass>(render_pass_rid)?;
let render_pass = &render_pass_resource.0.borrow();
let command_encoder = render_pass.parent_id();
let instance = state.borrow::<super::Instance>();
gfx_ok!(command_encoder => instance.render_pass_end(render_pass))
// TODO: Just like parent_id ComputePass, there's going to be DynComputePass soon which will eliminate the need of doing gfx_select here.
let instance = state.borrow::<Global>();
let parent_id = render_pass_resource.0.borrow().parent_id();
gfx_select!(parent_id => instance.render_pass_end(
&mut render_pass_resource.0.borrow_mut()
))?;
Ok(WebGpuResult::empty())
}
#[op2]
@ -225,12 +226,12 @@ pub fn op_webgpu_render_pass_set_bind_group(
let dynamic_offsets_data: &[u32] = &dynamic_offsets_data[start..start + len];
wgpu_core::command::render_commands::wgpu_render_pass_set_bind_group(
state.borrow::<Global>().render_pass_set_bind_group(
&mut render_pass_resource.0.borrow_mut(),
index,
bind_group_resource.1,
dynamic_offsets_data,
);
)?;
Ok(WebGpuResult::empty())
}
@ -246,11 +247,11 @@ pub fn op_webgpu_render_pass_push_debug_group(
.resource_table
.get::<WebGpuRenderPass>(render_pass_rid)?;
wgpu_core::command::render_commands::wgpu_render_pass_push_debug_group(
state.borrow::<Global>().render_pass_push_debug_group(
&mut render_pass_resource.0.borrow_mut(),
group_label,
0, // wgpu#975
);
)?;
Ok(WebGpuResult::empty())
}
@ -265,9 +266,9 @@ pub fn op_webgpu_render_pass_pop_debug_group(
.resource_table
.get::<WebGpuRenderPass>(render_pass_rid)?;
wgpu_core::command::render_commands::wgpu_render_pass_pop_debug_group(
&mut render_pass_resource.0.borrow_mut(),
);
state
.borrow::<Global>()
.render_pass_pop_debug_group(&mut render_pass_resource.0.borrow_mut())?;
Ok(WebGpuResult::empty())
}
@ -283,11 +284,11 @@ pub fn op_webgpu_render_pass_insert_debug_marker(
.resource_table
.get::<WebGpuRenderPass>(render_pass_rid)?;
wgpu_core::command::render_commands::wgpu_render_pass_insert_debug_marker(
state.borrow::<Global>().render_pass_insert_debug_marker(
&mut render_pass_resource.0.borrow_mut(),
marker_label,
0, // wgpu#975
);
)?;
Ok(WebGpuResult::empty())
}
@ -306,10 +307,10 @@ pub fn op_webgpu_render_pass_set_pipeline(
.resource_table
.get::<WebGpuRenderPass>(render_pass_rid)?;
wgpu_core::command::render_commands::wgpu_render_pass_set_pipeline(
state.borrow::<Global>().render_pass_set_pipeline(
&mut render_pass_resource.0.borrow_mut(),
render_pipeline_resource.1,
);
)?;
Ok(WebGpuResult::empty())
}
@ -340,12 +341,13 @@ pub fn op_webgpu_render_pass_set_index_buffer(
None
};
render_pass_resource.0.borrow_mut().set_index_buffer(
state.borrow::<Global>().render_pass_set_index_buffer(
&mut render_pass_resource.0.borrow_mut(),
buffer_resource.1,
index_format,
offset,
size,
);
)?;
Ok(WebGpuResult::empty())
}
@ -376,13 +378,13 @@ pub fn op_webgpu_render_pass_set_vertex_buffer(
None
};
wgpu_core::command::render_commands::wgpu_render_pass_set_vertex_buffer(
state.borrow::<Global>().render_pass_set_vertex_buffer(
&mut render_pass_resource.0.borrow_mut(),
slot,
buffer_resource.1,
offset,
size,
);
)?;
Ok(WebGpuResult::empty())
}
@ -401,13 +403,13 @@ pub fn op_webgpu_render_pass_draw(
.resource_table
.get::<WebGpuRenderPass>(render_pass_rid)?;
wgpu_core::command::render_commands::wgpu_render_pass_draw(
state.borrow::<Global>().render_pass_draw(
&mut render_pass_resource.0.borrow_mut(),
vertex_count,
instance_count,
first_vertex,
first_instance,
);
)?;
Ok(WebGpuResult::empty())
}
@ -427,14 +429,14 @@ pub fn op_webgpu_render_pass_draw_indexed(
.resource_table
.get::<WebGpuRenderPass>(render_pass_rid)?;
wgpu_core::command::render_commands::wgpu_render_pass_draw_indexed(
state.borrow::<Global>().render_pass_draw_indexed(
&mut render_pass_resource.0.borrow_mut(),
index_count,
instance_count,
first_index,
base_vertex,
first_instance,
);
)?;
Ok(WebGpuResult::empty())
}
@ -454,11 +456,11 @@ pub fn op_webgpu_render_pass_draw_indirect(
.resource_table
.get::<WebGpuRenderPass>(render_pass_rid)?;
wgpu_core::command::render_commands::wgpu_render_pass_draw_indirect(
state.borrow::<Global>().render_pass_draw_indirect(
&mut render_pass_resource.0.borrow_mut(),
buffer_resource.1,
indirect_offset,
);
)?;
Ok(WebGpuResult::empty())
}
@ -478,11 +480,11 @@ pub fn op_webgpu_render_pass_draw_indexed_indirect(
.resource_table
.get::<WebGpuRenderPass>(render_pass_rid)?;
wgpu_core::command::render_commands::wgpu_render_pass_draw_indexed_indirect(
state.borrow::<Global>().render_pass_draw_indexed_indirect(
&mut render_pass_resource.0.borrow_mut(),
buffer_resource.1,
indirect_offset,
);
)?;
Ok(WebGpuResult::empty())
}

View File

@ -113,9 +113,9 @@ impl GlobalPlay for wgc::global::Global {
timestamp_writes,
occlusion_query_set_id,
} => {
self.render_pass_end_impl::<A>(
self.render_pass_end_with_unresolved_commands::<A>(
encoder,
base.as_ref(),
base,
&target_colors,
target_depth_stencil.as_ref(),
timestamp_writes.as_ref(),

View File

@ -48,7 +48,7 @@ To create a render bundle:
3) Call [`Global::render_bundle_encoder_finish`][Grbef], which analyzes and cleans up
the command stream and returns a `RenderBundleId`.
4) Then, any number of times, call [`wgpu_render_pass_execute_bundles`][wrpeb] to
4) Then, any number of times, call [`render_pass_execute_bundles`][wrpeb] to
execute the bundle as part of some render pass.
## Implementation
@ -73,7 +73,7 @@ index format changes.
[Gdcrbe]: crate::global::Global::device_create_render_bundle_encoder
[Grbef]: crate::global::Global::render_bundle_encoder_finish
[wrpeb]: crate::command::render::render_commands::wgpu_render_pass_execute_bundles
[wrpeb]: crate::global::Global::render_pass_execute_bundles
!*/
#![allow(clippy::reversed_empty_ranges)]
@ -84,7 +84,7 @@ use crate::{
binding_model::{buffer_binding_type_alignment, BindGroup, BindGroupLayout, PipelineLayout},
command::{
BasePass, BindGroupStateChange, ColorAttachmentError, DrawError, MapPassErr,
PassErrorScope, RenderCommand, RenderCommandError, StateChange,
PassErrorScope, RenderCommandError, StateChange,
},
conv,
device::{
@ -112,7 +112,10 @@ use thiserror::Error;
use hal::CommandEncoder as _;
use super::ArcRenderCommand;
use super::{
render_command::{ArcRenderCommand, RenderCommand},
DrawKind,
};
/// <https://gpuweb.github.io/gpuweb/#dom-gpurendercommandsmixin-draw>
fn validate_draw<A: HalApi>(
@ -327,7 +330,7 @@ impl RenderBundleEncoder {
#[cfg(feature = "trace")]
pub(crate) fn to_base_pass(&self) -> BasePass<RenderCommand> {
BasePass::from_ref(self.base.as_ref())
self.base.clone()
}
pub fn parent(&self) -> id::DeviceId {
@ -398,10 +401,11 @@ impl RenderBundleEncoder {
let mut buffer_memory_init_actions = Vec::new();
let mut texture_memory_init_actions = Vec::new();
let base = self.base.as_ref();
let mut next_dynamic_offset = 0;
for &command in base.commands {
let base = &self.base;
for &command in &base.commands {
match command {
RenderCommand::SetBindGroup {
index,
@ -621,8 +625,8 @@ impl RenderBundleEncoder {
first_instance,
} => {
let scope = PassErrorScope::Draw {
kind: DrawKind::Draw,
indexed: false,
indirect: false,
pipeline: state.pipeline_id(),
};
let pipeline = state.pipeline(scope)?;
@ -639,7 +643,7 @@ impl RenderBundleEncoder {
if instance_count > 0 && vertex_count > 0 {
commands.extend(state.flush_vertices());
commands.extend(state.flush_binds(used_bind_groups, base.dynamic_offsets));
commands.extend(state.flush_binds(used_bind_groups, &base.dynamic_offsets));
commands.push(ArcRenderCommand::Draw {
vertex_count,
instance_count,
@ -656,8 +660,8 @@ impl RenderBundleEncoder {
first_instance,
} => {
let scope = PassErrorScope::Draw {
kind: DrawKind::Draw,
indexed: true,
indirect: false,
pipeline: state.pipeline_id(),
};
let pipeline = state.pipeline(scope)?;
@ -680,7 +684,7 @@ impl RenderBundleEncoder {
if instance_count > 0 && index_count > 0 {
commands.extend(state.flush_index());
commands.extend(state.flush_vertices());
commands.extend(state.flush_binds(used_bind_groups, base.dynamic_offsets));
commands.extend(state.flush_binds(used_bind_groups, &base.dynamic_offsets));
commands.push(ArcRenderCommand::DrawIndexed { index_count, instance_count, first_index, base_vertex, first_instance });
}
}
@ -691,8 +695,8 @@ impl RenderBundleEncoder {
indexed: false,
} => {
let scope = PassErrorScope::Draw {
kind: DrawKind::DrawIndirect,
indexed: false,
indirect: true,
pipeline: state.pipeline_id(),
};
device
@ -724,7 +728,7 @@ impl RenderBundleEncoder {
));
commands.extend(state.flush_vertices());
commands.extend(state.flush_binds(used_bind_groups, base.dynamic_offsets));
commands.extend(state.flush_binds(used_bind_groups, &base.dynamic_offsets));
commands.push(ArcRenderCommand::MultiDrawIndirect { buffer: buffer.clone(), offset, count: None, indexed: false });
}
RenderCommand::MultiDrawIndirect {
@ -734,8 +738,8 @@ impl RenderBundleEncoder {
indexed: true,
} => {
let scope = PassErrorScope::Draw {
kind: DrawKind::DrawIndirect,
indexed: true,
indirect: true,
pipeline: state.pipeline_id(),
};
device
@ -773,7 +777,7 @@ impl RenderBundleEncoder {
commands.extend(index.flush());
commands.extend(state.flush_vertices());
commands.extend(state.flush_binds(used_bind_groups, base.dynamic_offsets));
commands.extend(state.flush_binds(used_bind_groups, &base.dynamic_offsets));
commands.push(ArcRenderCommand::MultiDrawIndirect { buffer: buffer.clone(), offset, count: None, indexed: true });
}
RenderCommand::MultiDrawIndirect { .. }

View File

@ -72,7 +72,7 @@ pub enum ComputeCommand {
impl ComputeCommand {
/// Resolves all ids in a list of commands into the corresponding resource Arc.
///
//
// TODO: Once resolving is done on-the-fly during recording, this function should be only needed with the replay feature:
// #[cfg(feature = "replay")]
pub fn resolve_compute_command_ids<A: HalApi>(

View File

@ -1,24 +1,14 @@
/*! Draw structures - shared between render passes and bundles.
!*/
use crate::{
binding_model::{BindGroup, LateMinBufferBindingSizeMismatch, PushConstantUploadError},
binding_model::{LateMinBufferBindingSizeMismatch, PushConstantUploadError},
error::ErrorFormatter,
hal_api::HalApi,
id,
pipeline::RenderPipeline,
resource::{
Buffer, DestroyedResourceError, MissingBufferUsageError, MissingTextureUsageError, QuerySet,
},
resource::{DestroyedResourceError, MissingBufferUsageError, MissingTextureUsageError},
track::ResourceUsageCompatibilityError,
};
use wgt::{BufferAddress, BufferSize, Color, VertexStepMode};
use wgt::VertexStepMode;
use std::{num::NonZeroU32, sync::Arc};
use thiserror::Error;
use super::RenderBundle;
/// Error validating a draw call.
#[derive(Clone, Debug, Error, Eq, PartialEq)]
#[non_exhaustive]
@ -134,226 +124,3 @@ pub struct Rect<T> {
pub w: T,
pub h: T,
}
#[doc(hidden)]
#[derive(Clone, Copy, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum RenderCommand {
SetBindGroup {
index: u32,
num_dynamic_offsets: usize,
bind_group_id: id::BindGroupId,
},
SetPipeline(id::RenderPipelineId),
SetIndexBuffer {
buffer_id: id::BufferId,
index_format: wgt::IndexFormat,
offset: BufferAddress,
size: Option<BufferSize>,
},
SetVertexBuffer {
slot: u32,
buffer_id: id::BufferId,
offset: BufferAddress,
size: Option<BufferSize>,
},
SetBlendConstant(Color),
SetStencilReference(u32),
SetViewport {
rect: Rect<f32>,
//TODO: use half-float to reduce the size?
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,
},
MultiDrawIndirect {
buffer_id: id::BufferId,
offset: BufferAddress,
/// Count of `None` represents a non-multi call.
count: Option<NonZeroU32>,
indexed: bool,
},
MultiDrawIndirectCount {
buffer_id: id::BufferId,
offset: BufferAddress,
count_buffer_id: id::BufferId,
count_buffer_offset: BufferAddress,
max_count: u32,
indexed: bool,
},
PushDebugGroup {
color: u32,
len: usize,
},
PopDebugGroup,
InsertDebugMarker {
color: u32,
len: usize,
},
WriteTimestamp {
query_set_id: id::QuerySetId,
query_index: u32,
},
BeginOcclusionQuery {
query_index: u32,
},
EndOcclusionQuery,
BeginPipelineStatisticsQuery {
query_set_id: id::QuerySetId,
query_index: u32,
},
EndPipelineStatisticsQuery,
ExecuteBundle(id::RenderBundleId),
}
/// Equivalent to `RenderCommand` with the Ids resolved into resource Arcs.
#[doc(hidden)]
#[derive(Clone, Debug)]
pub enum ArcRenderCommand<A: HalApi> {
SetBindGroup {
index: u32,
num_dynamic_offsets: usize,
bind_group: Arc<BindGroup<A>>,
},
SetPipeline(Arc<RenderPipeline<A>>),
SetIndexBuffer {
buffer: Arc<Buffer<A>>,
index_format: wgt::IndexFormat,
offset: BufferAddress,
size: Option<BufferSize>,
},
SetVertexBuffer {
slot: u32,
buffer: Arc<Buffer<A>>,
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,
},
MultiDrawIndirect {
buffer: Arc<Buffer<A>>,
offset: BufferAddress,
/// Count of `None` represents a non-multi call.
count: Option<NonZeroU32>,
indexed: bool,
},
MultiDrawIndirectCount {
buffer: Arc<Buffer<A>>,
offset: BufferAddress,
count_buffer: Arc<Buffer<A>>,
count_buffer_offset: BufferAddress,
max_count: u32,
indexed: bool,
},
PushDebugGroup {
color: u32,
len: usize,
},
PopDebugGroup,
InsertDebugMarker {
color: u32,
len: usize,
},
WriteTimestamp {
query_set: Arc<QuerySet<A>>,
query_index: u32,
},
BeginOcclusionQuery {
query_index: u32,
},
EndOcclusionQuery,
BeginPipelineStatisticsQuery {
query_set: Arc<QuerySet<A>>,
query_index: u32,
},
EndPipelineStatisticsQuery,
ExecuteBundle(Arc<RenderBundle<A>>),
}

View File

@ -9,6 +9,7 @@ mod dyn_compute_pass;
mod memory_init;
mod query;
mod render;
mod render_command;
mod transfer;
use std::sync::Arc;
@ -16,7 +17,8 @@ use std::sync::Arc;
pub(crate) use self::clear::clear_texture;
pub use self::{
bundle::*, clear::ClearError, compute::*, compute_command::ComputeCommand, draw::*,
dyn_compute_pass::DynComputePass, query::*, render::*, transfer::*,
dyn_compute_pass::DynComputePass, query::*, render::*, render_command::RenderCommand,
transfer::*,
};
pub(crate) use allocator::CommandAllocator;
@ -544,15 +546,6 @@ impl<A: HalApi> ParentDevice<A> for CommandBuffer<A> {
}
}
#[derive(Copy, Clone, Debug)]
pub struct BasePassRef<'a, C> {
pub label: Option<&'a str>,
pub commands: &'a [C],
pub dynamic_offsets: &'a [wgt::DynamicOffset],
pub string_data: &'a [u8],
pub push_constant_data: &'a [u32],
}
/// A stream of commands for a render pass or compute pass.
///
/// This also contains side tables referred to by certain commands,
@ -565,7 +558,7 @@ pub struct BasePassRef<'a, C> {
/// [`SetBindGroup`]: RenderCommand::SetBindGroup
/// [`InsertDebugMarker`]: RenderCommand::InsertDebugMarker
#[doc(hidden)]
#[derive(Debug)]
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct BasePass<C> {
pub label: Option<String>,
@ -602,27 +595,6 @@ impl<C: Clone> BasePass<C> {
push_constant_data: Vec::new(),
}
}
#[cfg(feature = "trace")]
fn from_ref(base: BasePassRef<C>) -> Self {
Self {
label: base.label.map(str::to_string),
commands: base.commands.to_vec(),
dynamic_offsets: base.dynamic_offsets.to_vec(),
string_data: base.string_data.to_vec(),
push_constant_data: base.push_constant_data.to_vec(),
}
}
pub fn as_ref(&self) -> BasePassRef<C> {
BasePassRef {
label: self.label.as_deref(),
commands: &self.commands,
dynamic_offsets: &self.dynamic_offsets,
string_data: &self.string_data,
push_constant_data: &self.push_constant_data,
}
}
}
#[derive(Clone, Debug, Error)]
@ -879,6 +851,14 @@ trait MapPassErr<T, O> {
fn map_pass_err(self, scope: PassErrorScope) -> Result<T, O>;
}
#[derive(Clone, Copy, Debug)]
pub enum DrawKind {
Draw,
DrawIndirect,
MultiDrawIndirect,
MultiDrawIndirectCount,
}
#[derive(Clone, Copy, Debug, Error)]
pub enum PassErrorScope {
#[error("In a bundle parameter")]
@ -902,14 +882,18 @@ pub enum PassErrorScope {
SetVertexBuffer(id::BufferId),
#[error("In a set_index_buffer command")]
SetIndexBuffer(id::BufferId),
#[error("In a set_blend_constant command")]
SetBlendConstant,
#[error("In a set_stencil_reference command")]
SetStencilReference,
#[error("In a set_viewport command")]
SetViewport,
#[error("In a set_scissor_rect command")]
SetScissorRect,
#[error("In a draw command, indexed:{indexed} indirect:{indirect}")]
#[error("In a draw command, kind: {kind:?}")]
Draw {
kind: DrawKind,
indexed: bool,
indirect: bool,
pipeline: Option<id::RenderPipelineId>,
},
#[error("While resetting queries after the renderpass was ran")]

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,668 @@
use crate::{
binding_model::BindGroup,
hal_api::HalApi,
id,
pipeline::RenderPipeline,
resource::{Buffer, QuerySet},
};
use wgt::{BufferAddress, BufferSize, Color};
use std::{num::NonZeroU32, sync::Arc};
use super::{
DrawKind, PassErrorScope, Rect, RenderBundle, RenderCommandError, RenderPassError,
RenderPassErrorInner,
};
#[doc(hidden)]
#[derive(Clone, Copy, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum RenderCommand {
SetBindGroup {
index: u32,
num_dynamic_offsets: usize,
bind_group_id: id::BindGroupId,
},
SetPipeline(id::RenderPipelineId),
SetIndexBuffer {
buffer_id: id::BufferId,
index_format: wgt::IndexFormat,
offset: BufferAddress,
size: Option<BufferSize>,
},
SetVertexBuffer {
slot: u32,
buffer_id: id::BufferId,
offset: BufferAddress,
size: Option<BufferSize>,
},
SetBlendConstant(Color),
SetStencilReference(u32),
SetViewport {
rect: Rect<f32>,
//TODO: use half-float to reduce the size?
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,
},
MultiDrawIndirect {
buffer_id: id::BufferId,
offset: BufferAddress,
/// Count of `None` represents a non-multi call.
count: Option<NonZeroU32>,
indexed: bool,
},
MultiDrawIndirectCount {
buffer_id: id::BufferId,
offset: BufferAddress,
count_buffer_id: id::BufferId,
count_buffer_offset: BufferAddress,
max_count: u32,
indexed: bool,
},
PushDebugGroup {
color: u32,
len: usize,
},
PopDebugGroup,
InsertDebugMarker {
color: u32,
len: usize,
},
WriteTimestamp {
query_set_id: id::QuerySetId,
query_index: u32,
},
BeginOcclusionQuery {
query_index: u32,
},
EndOcclusionQuery,
BeginPipelineStatisticsQuery {
query_set_id: id::QuerySetId,
query_index: u32,
},
EndPipelineStatisticsQuery,
ExecuteBundle(id::RenderBundleId),
}
impl RenderCommand {
/// Resolves all ids in a list of commands into the corresponding resource Arc.
//
// TODO: Once resolving is done on-the-fly during recording, this function should be only needed with the replay feature:
// #[cfg(feature = "replay")]
pub fn resolve_render_command_ids<A: HalApi>(
hub: &crate::hub::Hub<A>,
commands: &[RenderCommand],
) -> Result<Vec<ArcRenderCommand<A>>, RenderPassError> {
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 resolved_commands: Vec<ArcRenderCommand<A>> = commands
.iter()
.map(|c| -> Result<ArcRenderCommand<A>, RenderPassError> {
Ok(match *c {
RenderCommand::SetBindGroup {
index,
num_dynamic_offsets,
bind_group_id,
} => ArcRenderCommand::SetBindGroup {
index,
num_dynamic_offsets,
bind_group: bind_group_guard.get_owned(bind_group_id).map_err(|_| {
RenderPassError {
scope: PassErrorScope::SetBindGroup(bind_group_id),
inner: RenderPassErrorInner::InvalidBindGroup(index),
}
})?,
},
RenderCommand::SetPipeline(pipeline_id) => ArcRenderCommand::SetPipeline(
pipelines_guard
.get_owned(pipeline_id)
.map_err(|_| RenderPassError {
scope: PassErrorScope::SetPipelineRender(pipeline_id),
inner: RenderCommandError::InvalidPipeline(pipeline_id).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_owned(query_set_id).map_err(|_| {
RenderPassError {
scope: PassErrorScope::WriteTimestamp,
inner: RenderPassErrorInner::InvalidQuerySet(query_set_id),
}
})?,
query_index,
},
RenderCommand::BeginPipelineStatisticsQuery {
query_set_id,
query_index,
} => ArcRenderCommand::BeginPipelineStatisticsQuery {
query_set: query_set_guard.get_owned(query_set_id).map_err(|_| {
RenderPassError {
scope: PassErrorScope::BeginPipelineStatisticsQuery,
inner: RenderPassErrorInner::InvalidQuerySet(query_set_id),
}
})?,
query_index,
},
RenderCommand::EndPipelineStatisticsQuery => {
ArcRenderCommand::EndPipelineStatisticsQuery
}
RenderCommand::SetIndexBuffer {
buffer_id,
index_format,
offset,
size,
} => ArcRenderCommand::SetIndexBuffer {
buffer: buffers_guard.get_owned(buffer_id).map_err(|_| {
RenderPassError {
scope: PassErrorScope::SetIndexBuffer(buffer_id),
inner: RenderCommandError::InvalidBufferId(buffer_id).into(),
}
})?,
index_format,
offset,
size,
},
RenderCommand::SetVertexBuffer {
slot,
buffer_id,
offset,
size,
} => ArcRenderCommand::SetVertexBuffer {
slot,
buffer: buffers_guard.get_owned(buffer_id).map_err(|_| {
RenderPassError {
scope: PassErrorScope::SetVertexBuffer(buffer_id),
inner: RenderCommandError::InvalidBufferId(buffer_id).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::MultiDrawIndirect {
buffer_id,
offset,
count,
indexed,
} => ArcRenderCommand::MultiDrawIndirect {
buffer: buffers_guard.get_owned(buffer_id).map_err(|_| {
RenderPassError {
scope: PassErrorScope::Draw {
kind: if count.is_some() {
DrawKind::MultiDrawIndirect
} else {
DrawKind::DrawIndirect
},
indexed,
pipeline: None,
},
inner: RenderCommandError::InvalidBufferId(buffer_id).into(),
}
})?,
offset,
count,
indexed,
},
RenderCommand::MultiDrawIndirectCount {
buffer_id,
offset,
count_buffer_id,
count_buffer_offset,
max_count,
indexed,
} => {
let scope = PassErrorScope::Draw {
kind: DrawKind::MultiDrawIndirectCount,
indexed,
pipeline: None,
};
ArcRenderCommand::MultiDrawIndirectCount {
buffer: buffers_guard.get_owned(buffer_id).map_err(|_| {
RenderPassError {
scope,
inner: RenderCommandError::InvalidBufferId(buffer_id).into(),
}
})?,
offset,
count_buffer: buffers_guard.get_owned(count_buffer_id).map_err(
|_| RenderPassError {
scope,
inner: RenderCommandError::InvalidBufferId(count_buffer_id)
.into(),
},
)?,
count_buffer_offset,
max_count,
indexed,
}
}
RenderCommand::BeginOcclusionQuery { query_index } => {
ArcRenderCommand::BeginOcclusionQuery { query_index }
}
RenderCommand::EndOcclusionQuery => ArcRenderCommand::EndOcclusionQuery,
RenderCommand::ExecuteBundle(bundle) => ArcRenderCommand::ExecuteBundle(
hub.render_bundles.read().get_owned(bundle).map_err(|_| {
RenderPassError {
scope: PassErrorScope::ExecuteBundle,
inner: RenderCommandError::InvalidRenderBundle(bundle).into(),
}
})?,
),
})
})
.collect::<Result<Vec<_>, RenderPassError>>()?;
Ok(resolved_commands)
}
}
/// Equivalent to `RenderCommand` with the Ids resolved into resource Arcs.
#[doc(hidden)]
#[derive(Clone, Debug)]
pub enum ArcRenderCommand<A: HalApi> {
SetBindGroup {
index: u32,
num_dynamic_offsets: usize,
bind_group: Arc<BindGroup<A>>,
},
SetPipeline(Arc<RenderPipeline<A>>),
SetIndexBuffer {
buffer: Arc<Buffer<A>>,
index_format: wgt::IndexFormat,
offset: BufferAddress,
size: Option<BufferSize>,
},
SetVertexBuffer {
slot: u32,
buffer: Arc<Buffer<A>>,
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,
},
MultiDrawIndirect {
buffer: Arc<Buffer<A>>,
offset: BufferAddress,
/// Count of `None` represents a non-multi call.
count: Option<NonZeroU32>,
indexed: bool,
},
MultiDrawIndirectCount {
buffer: Arc<Buffer<A>>,
offset: BufferAddress,
count_buffer: Arc<Buffer<A>>,
count_buffer_offset: BufferAddress,
max_count: u32,
indexed: bool,
},
PushDebugGroup {
color: u32,
len: usize,
},
PopDebugGroup,
InsertDebugMarker {
color: u32,
len: usize,
},
WriteTimestamp {
query_set: Arc<QuerySet<A>>,
query_index: u32,
},
BeginOcclusionQuery {
query_index: u32,
},
EndOcclusionQuery,
BeginPipelineStatisticsQuery {
query_set: Arc<QuerySet<A>>,
query_index: u32,
},
EndPipelineStatisticsQuery,
ExecuteBundle(Arc<RenderBundle<A>>),
}
#[cfg(feature = "trace")]
impl<A: HalApi> From<&ArcRenderCommand<A>> for RenderCommand {
fn from(value: &ArcRenderCommand<A>) -> Self {
use crate::resource::Resource as _;
match value {
ArcRenderCommand::SetBindGroup {
index,
num_dynamic_offsets,
bind_group,
} => RenderCommand::SetBindGroup {
index: *index,
num_dynamic_offsets: *num_dynamic_offsets,
bind_group_id: bind_group.as_info().id(),
},
ArcRenderCommand::SetPipeline(pipeline) => {
RenderCommand::SetPipeline(pipeline.as_info().id())
}
ArcRenderCommand::SetPushConstant {
offset,
size_bytes,
values_offset,
stages,
} => RenderCommand::SetPushConstant {
offset: *offset,
size_bytes: *size_bytes,
values_offset: *values_offset,
stages: *stages,
},
ArcRenderCommand::PushDebugGroup { color, len } => RenderCommand::PushDebugGroup {
color: *color,
len: *len,
},
ArcRenderCommand::PopDebugGroup => RenderCommand::PopDebugGroup,
ArcRenderCommand::InsertDebugMarker { color, len } => {
RenderCommand::InsertDebugMarker {
color: *color,
len: *len,
}
}
ArcRenderCommand::WriteTimestamp {
query_set,
query_index,
} => RenderCommand::WriteTimestamp {
query_set_id: query_set.as_info().id(),
query_index: *query_index,
},
ArcRenderCommand::BeginPipelineStatisticsQuery {
query_set,
query_index,
} => RenderCommand::BeginPipelineStatisticsQuery {
query_set_id: query_set.as_info().id(),
query_index: *query_index,
},
ArcRenderCommand::EndPipelineStatisticsQuery => {
RenderCommand::EndPipelineStatisticsQuery
}
ArcRenderCommand::SetIndexBuffer {
buffer,
index_format,
offset,
size,
} => RenderCommand::SetIndexBuffer {
buffer_id: buffer.as_info().id(),
index_format: *index_format,
offset: *offset,
size: *size,
},
ArcRenderCommand::SetVertexBuffer {
slot,
buffer,
offset,
size,
} => RenderCommand::SetVertexBuffer {
slot: *slot,
buffer_id: buffer.as_info().id(),
offset: *offset,
size: *size,
},
ArcRenderCommand::SetBlendConstant(color) => RenderCommand::SetBlendConstant(*color),
ArcRenderCommand::SetStencilReference(reference) => {
RenderCommand::SetStencilReference(*reference)
}
ArcRenderCommand::SetViewport {
rect,
depth_min,
depth_max,
} => RenderCommand::SetViewport {
rect: *rect,
depth_min: *depth_min,
depth_max: *depth_max,
},
ArcRenderCommand::SetScissor(scissor) => RenderCommand::SetScissor(*scissor),
ArcRenderCommand::Draw {
vertex_count,
instance_count,
first_vertex,
first_instance,
} => RenderCommand::Draw {
vertex_count: *vertex_count,
instance_count: *instance_count,
first_vertex: *first_vertex,
first_instance: *first_instance,
},
ArcRenderCommand::DrawIndexed {
index_count,
instance_count,
first_index,
base_vertex,
first_instance,
} => RenderCommand::DrawIndexed {
index_count: *index_count,
instance_count: *instance_count,
first_index: *first_index,
base_vertex: *base_vertex,
first_instance: *first_instance,
},
ArcRenderCommand::MultiDrawIndirect {
buffer,
offset,
count,
indexed,
} => RenderCommand::MultiDrawIndirect {
buffer_id: buffer.as_info().id(),
offset: *offset,
count: *count,
indexed: *indexed,
},
ArcRenderCommand::MultiDrawIndirectCount {
buffer,
offset,
count_buffer,
count_buffer_offset,
max_count,
indexed,
} => RenderCommand::MultiDrawIndirectCount {
buffer_id: buffer.as_info().id(),
offset: *offset,
count_buffer_id: count_buffer.as_info().id(),
count_buffer_offset: *count_buffer_offset,
max_count: *max_count,
indexed: *indexed,
},
ArcRenderCommand::BeginOcclusionQuery { query_index } => {
RenderCommand::BeginOcclusionQuery {
query_index: *query_index,
}
}
ArcRenderCommand::EndOcclusionQuery => RenderCommand::EndOcclusionQuery,
ArcRenderCommand::ExecuteBundle(bundle) => {
RenderCommand::ExecuteBundle(bundle.as_info().id())
}
}
}
}

View File

@ -24,12 +24,8 @@ use std::{
sync::Arc,
};
use wgc::{
command::{bundle_ffi::*, render_commands::*},
device::DeviceLostClosure,
gfx_select,
id::CommandEncoderId,
id::TextureViewId,
pipeline::CreateShaderModuleError,
command::bundle_ffi::*, device::DeviceLostClosure, gfx_select, id::CommandEncoderId,
id::TextureViewId, pipeline::CreateShaderModuleError,
};
use wgt::WasmNotSendSync;
@ -2814,7 +2810,18 @@ impl crate::Context for ContextWgpuCore {
pipeline: &Self::RenderPipelineId,
_pipeline_data: &Self::RenderPipelineData,
) {
wgpu_render_pass_set_pipeline(&mut pass_data.pass, *pipeline)
if let Err(cause) = self
.0
.render_pass_set_pipeline(&mut pass_data.pass, *pipeline)
{
self.handle_error(
&pass_data.error_sink,
cause,
LABEL,
pass_data.pass.label(),
"RenderPass::set_pipeline",
);
}
}
fn render_pass_set_bind_group(
@ -2826,7 +2833,18 @@ impl crate::Context for ContextWgpuCore {
_bind_group_data: &Self::BindGroupData,
offsets: &[wgt::DynamicOffset],
) {
wgpu_render_pass_set_bind_group(&mut pass_data.pass, index, *bind_group, offsets)
if let Err(cause) =
self.0
.render_pass_set_bind_group(&mut pass_data.pass, index, *bind_group, offsets)
{
self.handle_error(
&pass_data.error_sink,
cause,
LABEL,
pass_data.pass.label(),
"RenderPass::set_bind_group",
);
}
}
fn render_pass_set_index_buffer(
@ -2839,9 +2857,21 @@ impl crate::Context for ContextWgpuCore {
offset: wgt::BufferAddress,
size: Option<wgt::BufferSize>,
) {
pass_data
.pass
.set_index_buffer(*buffer, index_format, offset, size)
if let Err(cause) = self.0.render_pass_set_index_buffer(
&mut pass_data.pass,
*buffer,
index_format,
offset,
size,
) {
self.handle_error(
&pass_data.error_sink,
cause,
LABEL,
pass_data.pass.label(),
"RenderPass::set_index_buffer",
);
}
}
fn render_pass_set_vertex_buffer(
@ -2854,7 +2884,18 @@ impl crate::Context for ContextWgpuCore {
offset: wgt::BufferAddress,
size: Option<wgt::BufferSize>,
) {
wgpu_render_pass_set_vertex_buffer(&mut pass_data.pass, slot, *buffer, offset, size)
if let Err(cause) =
self.0
.render_pass_set_vertex_buffer(&mut pass_data.pass, slot, *buffer, offset, size)
{
self.handle_error(
&pass_data.error_sink,
cause,
LABEL,
pass_data.pass.label(),
"RenderPass::set_vertex_buffer",
);
}
}
fn render_pass_set_push_constants(
@ -2865,7 +2906,18 @@ impl crate::Context for ContextWgpuCore {
offset: u32,
data: &[u8],
) {
wgpu_render_pass_set_push_constants(&mut pass_data.pass, stages, offset, data)
if let Err(cause) =
self.0
.render_pass_set_push_constants(&mut pass_data.pass, stages, offset, data)
{
self.handle_error(
&pass_data.error_sink,
cause,
LABEL,
pass_data.pass.label(),
"RenderPass::set_push_constants",
);
}
}
fn render_pass_draw(
@ -2875,13 +2927,21 @@ impl crate::Context for ContextWgpuCore {
vertices: Range<u32>,
instances: Range<u32>,
) {
wgpu_render_pass_draw(
if let Err(cause) = self.0.render_pass_draw(
&mut pass_data.pass,
vertices.end - vertices.start,
instances.end - instances.start,
vertices.start,
instances.start,
)
) {
self.handle_error(
&pass_data.error_sink,
cause,
LABEL,
pass_data.pass.label(),
"RenderPass::draw",
);
}
}
fn render_pass_draw_indexed(
@ -2892,14 +2952,22 @@ impl crate::Context for ContextWgpuCore {
base_vertex: i32,
instances: Range<u32>,
) {
wgpu_render_pass_draw_indexed(
if let Err(cause) = self.0.render_pass_draw_indexed(
&mut pass_data.pass,
indices.end - indices.start,
instances.end - instances.start,
indices.start,
base_vertex,
instances.start,
)
) {
self.handle_error(
&pass_data.error_sink,
cause,
LABEL,
pass_data.pass.label(),
"RenderPass::draw_indexed",
);
}
}
fn render_pass_draw_indirect(
@ -2910,7 +2978,18 @@ impl crate::Context for ContextWgpuCore {
_indirect_buffer_data: &Self::BufferData,
indirect_offset: wgt::BufferAddress,
) {
wgpu_render_pass_draw_indirect(&mut pass_data.pass, *indirect_buffer, indirect_offset)
if let Err(cause) =
self.0
.render_pass_draw_indirect(&mut pass_data.pass, *indirect_buffer, indirect_offset)
{
self.handle_error(
&pass_data.error_sink,
cause,
LABEL,
pass_data.pass.label(),
"RenderPass::draw_indirect",
);
}
}
fn render_pass_draw_indexed_indirect(
@ -2921,11 +3000,19 @@ impl crate::Context for ContextWgpuCore {
_indirect_buffer_data: &Self::BufferData,
indirect_offset: wgt::BufferAddress,
) {
wgpu_render_pass_draw_indexed_indirect(
if let Err(cause) = self.0.render_pass_draw_indexed_indirect(
&mut pass_data.pass,
*indirect_buffer,
indirect_offset,
)
) {
self.handle_error(
&pass_data.error_sink,
cause,
LABEL,
pass_data.pass.label(),
"RenderPass::draw_indexed_indirect",
);
}
}
fn render_pass_multi_draw_indirect(
@ -2937,12 +3024,20 @@ impl crate::Context for ContextWgpuCore {
indirect_offset: wgt::BufferAddress,
count: u32,
) {
wgpu_render_pass_multi_draw_indirect(
if let Err(cause) = self.0.render_pass_multi_draw_indirect(
&mut pass_data.pass,
*indirect_buffer,
indirect_offset,
count,
)
) {
self.handle_error(
&pass_data.error_sink,
cause,
LABEL,
pass_data.pass.label(),
"RenderPass::multi_draw_indirect",
);
}
}
fn render_pass_multi_draw_indexed_indirect(
@ -2954,12 +3049,20 @@ impl crate::Context for ContextWgpuCore {
indirect_offset: wgt::BufferAddress,
count: u32,
) {
wgpu_render_pass_multi_draw_indexed_indirect(
if let Err(cause) = self.0.render_pass_multi_draw_indexed_indirect(
&mut pass_data.pass,
*indirect_buffer,
indirect_offset,
count,
)
) {
self.handle_error(
&pass_data.error_sink,
cause,
LABEL,
pass_data.pass.label(),
"RenderPass::multi_draw_indexed_indirect",
);
}
}
fn render_pass_multi_draw_indirect_count(
@ -2974,14 +3077,22 @@ impl crate::Context for ContextWgpuCore {
count_buffer_offset: wgt::BufferAddress,
max_count: u32,
) {
wgpu_render_pass_multi_draw_indirect_count(
if let Err(cause) = self.0.render_pass_multi_draw_indirect_count(
&mut pass_data.pass,
*indirect_buffer,
indirect_offset,
*count_buffer,
count_buffer_offset,
max_count,
)
) {
self.handle_error(
&pass_data.error_sink,
cause,
LABEL,
pass_data.pass.label(),
"RenderPass::multi_draw_indirect_count",
);
}
}
fn render_pass_multi_draw_indexed_indirect_count(
@ -2996,14 +3107,22 @@ impl crate::Context for ContextWgpuCore {
count_buffer_offset: wgt::BufferAddress,
max_count: u32,
) {
wgpu_render_pass_multi_draw_indexed_indirect_count(
if let Err(cause) = self.0.render_pass_multi_draw_indexed_indirect_count(
&mut pass_data.pass,
*indirect_buffer,
indirect_offset,
*count_buffer,
count_buffer_offset,
max_count,
)
) {
self.handle_error(
&pass_data.error_sink,
cause,
LABEL,
pass_data.pass.label(),
"RenderPass::multi_draw_indexed_indirect_count",
);
}
}
fn render_pass_set_blend_constant(
@ -3012,7 +3131,18 @@ impl crate::Context for ContextWgpuCore {
pass_data: &mut Self::RenderPassData,
color: wgt::Color,
) {
wgpu_render_pass_set_blend_constant(&mut pass_data.pass, &color)
if let Err(cause) = self
.0
.render_pass_set_blend_constant(&mut pass_data.pass, &color)
{
self.handle_error(
&pass_data.error_sink,
cause,
LABEL,
pass_data.pass.label(),
"RenderPass::set_blend_constant",
);
}
}
fn render_pass_set_scissor_rect(
@ -3024,7 +3154,18 @@ impl crate::Context for ContextWgpuCore {
width: u32,
height: u32,
) {
wgpu_render_pass_set_scissor_rect(&mut pass_data.pass, x, y, width, height)
if let Err(cause) =
self.0
.render_pass_set_scissor_rect(&mut pass_data.pass, x, y, width, height)
{
self.handle_error(
&pass_data.error_sink,
cause,
LABEL,
pass_data.pass.label(),
"RenderPass::set_scissor_rect",
);
}
}
fn render_pass_set_viewport(
@ -3038,7 +3179,7 @@ impl crate::Context for ContextWgpuCore {
min_depth: f32,
max_depth: f32,
) {
wgpu_render_pass_set_viewport(
if let Err(cause) = self.0.render_pass_set_viewport(
&mut pass_data.pass,
x,
y,
@ -3046,7 +3187,15 @@ impl crate::Context for ContextWgpuCore {
height,
min_depth,
max_depth,
)
) {
self.handle_error(
&pass_data.error_sink,
cause,
LABEL,
pass_data.pass.label(),
"RenderPass::set_viewport",
);
}
}
fn render_pass_set_stencil_reference(
@ -3055,7 +3204,18 @@ impl crate::Context for ContextWgpuCore {
pass_data: &mut Self::RenderPassData,
reference: u32,
) {
wgpu_render_pass_set_stencil_reference(&mut pass_data.pass, reference)
if let Err(cause) = self
.0
.render_pass_set_stencil_reference(&mut pass_data.pass, reference)
{
self.handle_error(
&pass_data.error_sink,
cause,
LABEL,
pass_data.pass.label(),
"RenderPass::set_stencil_reference",
);
}
}
fn render_pass_insert_debug_marker(
@ -3064,7 +3224,18 @@ impl crate::Context for ContextWgpuCore {
pass_data: &mut Self::RenderPassData,
label: &str,
) {
wgpu_render_pass_insert_debug_marker(&mut pass_data.pass, label, 0);
if let Err(cause) = self
.0
.render_pass_insert_debug_marker(&mut pass_data.pass, label, 0)
{
self.handle_error(
&pass_data.error_sink,
cause,
LABEL,
pass_data.pass.label(),
"RenderPass::insert_debug_marker",
);
}
}
fn render_pass_push_debug_group(
@ -3073,7 +3244,18 @@ impl crate::Context for ContextWgpuCore {
pass_data: &mut Self::RenderPassData,
group_label: &str,
) {
wgpu_render_pass_push_debug_group(&mut pass_data.pass, group_label, 0);
if let Err(cause) = self
.0
.render_pass_push_debug_group(&mut pass_data.pass, group_label, 0)
{
self.handle_error(
&pass_data.error_sink,
cause,
LABEL,
pass_data.pass.label(),
"RenderPass::push_debug_group",
);
}
}
fn render_pass_pop_debug_group(
@ -3081,7 +3263,15 @@ impl crate::Context for ContextWgpuCore {
_pass: &mut Self::RenderPassId,
pass_data: &mut Self::RenderPassData,
) {
wgpu_render_pass_pop_debug_group(&mut pass_data.pass);
if let Err(cause) = self.0.render_pass_pop_debug_group(&mut pass_data.pass) {
self.handle_error(
&pass_data.error_sink,
cause,
LABEL,
pass_data.pass.label(),
"RenderPass::pop_debug_group",
);
}
}
fn render_pass_write_timestamp(
@ -3092,7 +3282,18 @@ impl crate::Context for ContextWgpuCore {
_query_set_data: &Self::QuerySetData,
query_index: u32,
) {
wgpu_render_pass_write_timestamp(&mut pass_data.pass, *query_set, query_index)
if let Err(cause) =
self.0
.render_pass_write_timestamp(&mut pass_data.pass, *query_set, query_index)
{
self.handle_error(
&pass_data.error_sink,
cause,
LABEL,
pass_data.pass.label(),
"RenderPass::write_timestamp",
);
}
}
fn render_pass_begin_occlusion_query(
@ -3101,7 +3302,18 @@ impl crate::Context for ContextWgpuCore {
pass_data: &mut Self::RenderPassData,
query_index: u32,
) {
wgpu_render_pass_begin_occlusion_query(&mut pass_data.pass, query_index)
if let Err(cause) = self
.0
.render_pass_begin_occlusion_query(&mut pass_data.pass, query_index)
{
self.handle_error(
&pass_data.error_sink,
cause,
LABEL,
pass_data.pass.label(),
"RenderPass::begin_occlusion_query",
);
}
}
fn render_pass_end_occlusion_query(
@ -3109,7 +3321,15 @@ impl crate::Context for ContextWgpuCore {
_pass: &mut Self::RenderPassId,
pass_data: &mut Self::RenderPassData,
) {
wgpu_render_pass_end_occlusion_query(&mut pass_data.pass)
if let Err(cause) = self.0.render_pass_end_occlusion_query(&mut pass_data.pass) {
self.handle_error(
&pass_data.error_sink,
cause,
LABEL,
pass_data.pass.label(),
"RenderPass::end_occlusion_query",
);
}
}
fn render_pass_begin_pipeline_statistics_query(
@ -3120,11 +3340,19 @@ impl crate::Context for ContextWgpuCore {
_query_set_data: &Self::QuerySetData,
query_index: u32,
) {
wgpu_render_pass_begin_pipeline_statistics_query(
if let Err(cause) = self.0.render_pass_begin_pipeline_statistics_query(
&mut pass_data.pass,
*query_set,
query_index,
)
) {
self.handle_error(
&pass_data.error_sink,
cause,
LABEL,
pass_data.pass.label(),
"RenderPass::begin_pipeline_statistics_query",
);
}
}
fn render_pass_end_pipeline_statistics_query(
@ -3132,7 +3360,18 @@ impl crate::Context for ContextWgpuCore {
_pass: &mut Self::RenderPassId,
pass_data: &mut Self::RenderPassData,
) {
wgpu_render_pass_end_pipeline_statistics_query(&mut pass_data.pass)
if let Err(cause) = self
.0
.render_pass_end_pipeline_statistics_query(&mut pass_data.pass)
{
self.handle_error(
&pass_data.error_sink,
cause,
LABEL,
pass_data.pass.label(),
"RenderPass::end_pipeline_statistics_query",
);
}
}
fn render_pass_execute_bundles(
@ -3142,7 +3381,18 @@ impl crate::Context for ContextWgpuCore {
render_bundles: &mut dyn Iterator<Item = (Self::RenderBundleId, &Self::RenderBundleData)>,
) {
let temp_render_bundles = render_bundles.map(|(i, _)| i).collect::<SmallVec<[_; 4]>>();
wgpu_render_pass_execute_bundles(&mut pass_data.pass, &temp_render_bundles)
if let Err(cause) = self
.0
.render_pass_execute_bundles(&mut pass_data.pass, &temp_render_bundles)
{
self.handle_error(
&pass_data.error_sink,
cause,
LABEL,
pass_data.pass.label(),
"RenderPass::execute_bundles",
);
}
}
fn render_pass_end(
@ -3151,7 +3401,8 @@ impl crate::Context for ContextWgpuCore {
pass_data: &mut Self::RenderPassData,
) {
let encoder = pass_data.pass.parent_id();
if let Err(cause) = wgc::gfx_select!(encoder => self.0.render_pass_end(&pass_data.pass)) {
if let Err(cause) = wgc::gfx_select!(encoder => self.0.render_pass_end(&mut pass_data.pass))
{
self.handle_error(
&pass_data.error_sink,
cause,