Skip to content

Commit

Permalink
Inline PassChannel into ColorAttachment (#6704)
Browse files Browse the repository at this point in the history
Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>
  • Loading branch information
sagudev authored Dec 12, 2024
1 parent 3d3937e commit 8f82992
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 71 deletions.
9 changes: 3 additions & 6 deletions deno_webgpu/command_encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,12 +133,9 @@ pub fn op_webgpu_command_encoder_begin_render_pass(
Some(wgpu_core::command::RenderPassColorAttachment {
view: texture_view_resource.1,
resolve_target,
channel: wgpu_core::command::PassChannel {
load_op: at.load_op,
store_op: at.store_op,
clear_value: at.clear_value.unwrap_or_default(),
read_only: false,
},
load_op: at.load_op,
store_op: at.store_op,
clear_value: at.clear_value.unwrap_or_default(),
})
} else {
None
Expand Down
17 changes: 7 additions & 10 deletions player/tests/data/quad.ron
Original file line number Diff line number Diff line change
Expand Up @@ -100,16 +100,13 @@
Some((
view: Id(0, 1),
resolve_target: None,
channel: (
load_op: clear,
store_op: store,
clear_value: (
r: 0,
g: 0,
b: 0,
a: 1,
),
read_only: false,
load_op: clear,
store_op: store,
clear_value: (
r: 0,
g: 0,
b: 0,
a: 1,
),
)),
],
Expand Down
11 changes: 4 additions & 7 deletions player/tests/data/zero-init-texture-rendertarget.ron
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,10 @@
Some((
view: Id(0, 1),
resolve_target: None,
channel: (
load_op: load,
store_op: store,
clear_value: (
r: 1, g: 1, b: 1, a: 1,
),
read_only: false,
load_op: load,
store_op: store,
clear_value: (
r: 1, g: 1, b: 1, a: 1,
),
)),
],
Expand Down
87 changes: 61 additions & 26 deletions wgpu-core/src/command/render.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,15 @@ pub enum LoadOp {
Load = 1,
}

impl LoadOp {
fn hal_ops(&self) -> hal::AttachmentOps {
match self {
LoadOp::Load => hal::AttachmentOps::LOAD,
LoadOp::Clear => hal::AttachmentOps::empty(),
}
}
}

/// Operation to perform to the output attachment at the end of a renderpass.
#[repr(C)]
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
Expand All @@ -80,6 +89,15 @@ pub enum StoreOp {
Store = 1,
}

impl StoreOp {
fn hal_ops(&self) -> hal::AttachmentOps {
match self {
StoreOp::Store => hal::AttachmentOps::STORE,
StoreOp::Discard => hal::AttachmentOps::empty(),
}
}
}

/// Describes an individual channel within a render pass, such as color, depth, or stencil.
#[repr(C)]
#[derive(Clone, Debug, Eq, PartialEq)]
Expand All @@ -104,16 +122,7 @@ pub struct PassChannel<V> {

impl<V> PassChannel<V> {
fn hal_ops(&self) -> hal::AttachmentOps {
let mut ops = hal::AttachmentOps::empty();
match self.load_op {
LoadOp::Load => ops |= hal::AttachmentOps::LOAD,
LoadOp::Clear => (),
};
match self.store_op {
StoreOp::Store => ops |= hal::AttachmentOps::STORE,
StoreOp::Discard => (),
};
ops
self.load_op.hal_ops() | self.store_op.hal_ops()
}
}

Expand All @@ -126,8 +135,17 @@ pub struct RenderPassColorAttachment {
pub view: id::TextureViewId,
/// The view that will receive the resolved output if multisampling is used.
pub resolve_target: Option<id::TextureViewId>,
/// What operations will be performed on this color attachment.
pub channel: PassChannel<Color>,
/// Operation to perform to the output attachment at the start of a
/// renderpass.
///
/// This must be clear if it is the first renderpass rendering to a swap
/// chain image.
pub load_op: LoadOp,
/// Operation to perform to the output attachment at the end of a renderpass.
pub store_op: StoreOp,
/// If load_op is [`LoadOp::Clear`], the attachment will be cleared to this
/// color.
pub clear_value: Color,
}

/// Describes a color attachment to a render pass.
Expand All @@ -137,8 +155,17 @@ struct ArcRenderPassColorAttachment {
pub view: Arc<TextureView>,
/// The view that will receive the resolved output if multisampling is used.
pub resolve_target: Option<Arc<TextureView>>,
/// What operations will be performed on this color attachment.
pub channel: PassChannel<Color>,
/// Operation to perform to the output attachment at the start of a
/// renderpass.
///
/// This must be clear if it is the first renderpass rendering to a swap
/// chain image.
pub load_op: LoadOp,
/// Operation to perform to the output attachment at the end of a renderpass.
pub store_op: StoreOp,
/// If load_op is [`LoadOp::Clear`], the attachment will be cleared to this
/// color.
pub clear_value: Color,
}

/// Describes a depth/stencil attachment to a render pass.
Expand Down Expand Up @@ -770,13 +797,14 @@ struct RenderPassInfo<'d> {
}

impl<'d> RenderPassInfo<'d> {
fn add_pass_texture_init_actions<V>(
channel: &PassChannel<V>,
fn add_pass_texture_init_actions(
load_op: LoadOp,
store_op: StoreOp,
texture_memory_actions: &mut CommandBufferTextureMemoryActions,
view: &TextureView,
pending_discard_init_fixups: &mut SurfacesInDiscardState,
) {
if channel.load_op == LoadOp::Load {
if load_op == LoadOp::Load {
pending_discard_init_fixups.extend(texture_memory_actions.register_init_action(
&TextureInitTrackerAction {
texture: view.parent.clone(),
Expand All @@ -785,14 +813,14 @@ impl<'d> RenderPassInfo<'d> {
kind: MemoryInitKind::NeedsInitializedMemory,
},
));
} else if channel.store_op == StoreOp::Store {
} else if store_op == StoreOp::Store {
// Clear + Store
texture_memory_actions.register_implicit_init(
&view.parent,
TextureInitRange::from(view.selector.clone()),
);
}
if channel.store_op == StoreOp::Discard {
if store_op == StoreOp::Discard {
// the discard happens at the *end* of a pass, but recording the
// discard right away be alright since the texture can't be used
// during the pass anyways
Expand Down Expand Up @@ -923,14 +951,16 @@ impl<'d> RenderPassInfo<'d> {
&& at.stencil.store_op == at.depth.store_op)
{
Self::add_pass_texture_init_actions(
&at.depth,
at.depth.load_op,
at.depth.store_op,
texture_memory_actions,
view,
&mut pending_discard_init_fixups,
);
} else if !ds_aspects.contains(hal::FormatAspects::DEPTH) {
Self::add_pass_texture_init_actions(
&at.stencil,
at.stencil.load_op,
at.stencil.store_op,
texture_memory_actions,
view,
&mut pending_discard_init_fixups,
Expand Down Expand Up @@ -1059,7 +1089,8 @@ impl<'d> RenderPassInfo<'d> {
}

Self::add_pass_texture_init_actions(
&at.channel,
at.load_op,
at.store_op,
texture_memory_actions,
color_view,
&mut pending_discard_init_fixups,
Expand Down Expand Up @@ -1135,8 +1166,8 @@ impl<'d> RenderPassInfo<'d> {
usage: hal::TextureUses::COLOR_TARGET,
},
resolve_target: hal_resolve_target,
ops: at.channel.hal_ops(),
clear_value: at.channel.clear_value,
ops: at.load_op.hal_ops() | at.store_op.hal_ops(),
clear_value: at.clear_value,
}));
}

Expand Down Expand Up @@ -1351,7 +1382,9 @@ impl Global {
if let Some(RenderPassColorAttachment {
view: view_id,
resolve_target,
channel,
load_op,
store_op,
clear_value,
}) = color_attachment
{
let view = texture_views.get(*view_id).get()?;
Expand All @@ -1371,7 +1404,9 @@ impl Global {
.push(Some(ArcRenderPassColorAttachment {
view,
resolve_target,
channel: channel.clone(),
load_op: *load_op,
store_op: *store_op,
clear_value: *clear_value,
}));
} else {
arc_desc.color_attachments.push(None);
Expand Down
46 changes: 24 additions & 22 deletions wgpu/src/backend/wgpu_core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -404,28 +404,26 @@ fn map_store_op(op: StoreOp) -> wgc::command::StoreOp {
}
}

fn map_load_op<V: Default>(op: LoadOp<V>) -> (wgc::command::LoadOp, V) {
match op {
LoadOp::Clear(v) => (wgc::command::LoadOp::Clear, v),
LoadOp::Load => (wgc::command::LoadOp::Load, V::default()),
}
}

fn map_pass_channel<V: Copy + Default>(
ops: Option<&Operations<V>>,
) -> wgc::command::PassChannel<V> {
match ops {
Some(&Operations {
load: LoadOp::Clear(clear_value),
store,
}) => wgc::command::PassChannel {
load_op: wgc::command::LoadOp::Clear,
store_op: map_store_op(store),
clear_value,
read_only: false,
},
Some(&Operations {
load: LoadOp::Load,
store,
}) => wgc::command::PassChannel {
load_op: wgc::command::LoadOp::Load,
store_op: map_store_op(store),
clear_value: V::default(),
read_only: false,
},
Some(&Operations { load, store }) => {
let (load_op, clear_value) = map_load_op(load);
wgc::command::PassChannel {
load_op,
store_op: map_store_op(store),
clear_value,
read_only: false,
}
}
None => wgc::command::PassChannel {
load_op: wgc::command::LoadOp::Load,
store_op: wgc::command::StoreOp::Store,
Expand Down Expand Up @@ -2249,12 +2247,16 @@ impl dispatch::CommandEncoderInterface for CoreCommandEncoder {
.color_attachments
.iter()
.map(|ca| {
ca.as_ref()
.map(|at| wgc::command::RenderPassColorAttachment {
ca.as_ref().map(|at| {
let (load_op, clear_value) = map_load_op(at.ops.load);
wgc::command::RenderPassColorAttachment {
view: at.view.inner.as_core().id,
resolve_target: at.resolve_target.map(|view| view.inner.as_core().id),
channel: map_pass_channel(Some(&at.ops)),
})
load_op,
store_op: map_store_op(at.ops.store),
clear_value,
}
})
})
.collect::<Vec<_>>();

Expand Down

0 comments on commit 8f82992

Please sign in to comment.