diff --git a/deno_webgpu/command_encoder.rs b/deno_webgpu/command_encoder.rs index d54a261762..373f0fb5e8 100644 --- a/deno_webgpu/command_encoder.rs +++ b/deno_webgpu/command_encoder.rs @@ -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 diff --git a/player/tests/data/quad.ron b/player/tests/data/quad.ron index 04df018993..1adfa7cfa7 100644 --- a/player/tests/data/quad.ron +++ b/player/tests/data/quad.ron @@ -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, ), )), ], diff --git a/player/tests/data/zero-init-texture-rendertarget.ron b/player/tests/data/zero-init-texture-rendertarget.ron index bcd4fccbf0..7f06de9b4e 100644 --- a/player/tests/data/zero-init-texture-rendertarget.ron +++ b/player/tests/data/zero-init-texture-rendertarget.ron @@ -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, ), )), ], diff --git a/wgpu-core/src/command/render.rs b/wgpu-core/src/command/render.rs index c35998b807..ac5984af19 100644 --- a/wgpu-core/src/command/render.rs +++ b/wgpu-core/src/command/render.rs @@ -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)] @@ -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)] @@ -104,16 +122,7 @@ pub struct PassChannel { impl PassChannel { 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() } } @@ -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, - /// What operations will be performed on this color attachment. - pub channel: PassChannel, + /// 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. @@ -137,8 +155,17 @@ struct ArcRenderPassColorAttachment { pub view: Arc, /// The view that will receive the resolved output if multisampling is used. pub resolve_target: Option>, - /// What operations will be performed on this color attachment. - pub channel: PassChannel, + /// 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. @@ -770,13 +797,14 @@ struct RenderPassInfo<'d> { } impl<'d> RenderPassInfo<'d> { - fn add_pass_texture_init_actions( - channel: &PassChannel, + 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(), @@ -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 @@ -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, @@ -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, @@ -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, })); } @@ -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()?; @@ -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); diff --git a/wgpu/src/backend/wgpu_core.rs b/wgpu/src/backend/wgpu_core.rs index 15f8f3b63e..779440f6de 100644 --- a/wgpu/src/backend/wgpu_core.rs +++ b/wgpu/src/backend/wgpu_core.rs @@ -404,28 +404,26 @@ fn map_store_op(op: StoreOp) -> wgc::command::StoreOp { } } +fn map_load_op(op: LoadOp) -> (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( ops: Option<&Operations>, ) -> wgc::command::PassChannel { 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, @@ -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::>();