1515//!
1616//! ```ignore
1717//! let mut encoder = CommandEncoder::new(&render_context, "frame-encoder");
18- //! encoder.with_render_pass(config , &mut attachments, depth, None, None, Some("main-pass"), |pass | {
19- //! pass .set_pipeline(&pipeline)?;
20- //! pass .draw(0..3, 0..1)?;
18+ //! encoder.with_render_pass(&pass , &mut attachments, depth, |rp_encoder | {
19+ //! rp_encoder .set_pipeline(&pipeline)?;
20+ //! rp_encoder .draw(0..3, 0..1)?;
2121//! Ok(())
2222//! })?;
2323//! encoder.finish(&render_context);
@@ -43,11 +43,9 @@ use super::{
4343 pipeline:: RenderPipeline ,
4444 render_pass:: {
4545 ColorLoadOp ,
46- ColorOperations ,
4746 DepthLoadOp ,
48- DepthOperations ,
47+ RenderPass ,
4948 StencilLoadOp ,
50- StencilOperations ,
5149 StoreOp ,
5250 } ,
5351 texture:: DepthTexture ,
@@ -90,42 +88,37 @@ impl CommandEncoder {
9088 /// returns. This ensures proper resource cleanup and lifetime management.
9189 ///
9290 /// # Arguments
93- /// * `config ` - Configuration for the render pass (label, color/depth ops) .
91+ /// * `pass ` - The high-level render pass configuration .
9492 /// * `color_attachments` - Color attachment views for the pass.
9593 /// * `depth_texture` - Optional depth texture for depth/stencil operations.
96- /// * `depth_ops` - Optional depth operations (load/store).
97- /// * `stencil_ops` - Optional stencil operations (load/store).
98- /// * `label` - Optional debug label for the pass (must outlive the pass).
99- /// * `f` - Closure that records commands to the render pass.
94+ /// * `f` - Closure that records commands to the render pass encoder.
95+ ///
96+ /// # Type Parameters
97+ /// * `'pass` - Lifetime of resources borrowed during the render pass.
98+ /// * `PassFn` - The closure type that records commands to the pass.
99+ /// * `Output` - The return type of the closure.
100100 ///
101101 /// # Returns
102102 /// The result of the closure, or any render pass error encountered.
103- pub ( crate ) fn with_render_pass < ' a , F , R > (
104- & ' a mut self ,
105- config : RenderPassConfig ,
106- color_attachments : & ' a mut RenderColorAttachments < ' a > ,
107- depth_texture : Option < & ' a DepthTexture > ,
108- depth_ops : Option < DepthOperations > ,
109- stencil_ops : Option < StencilOperations > ,
110- label : Option < & ' a str > ,
111- f : F ,
112- ) -> Result < R , RenderPassError >
103+ pub ( crate ) fn with_render_pass < ' pass , PassFn , Output > (
104+ & ' pass mut self ,
105+ pass : & ' pass RenderPass ,
106+ color_attachments : & ' pass mut RenderColorAttachments < ' pass > ,
107+ depth_texture : Option < & ' pass DepthTexture > ,
108+ f : PassFn ,
109+ ) -> Result < Output , RenderPassError >
113110 where
114- F : FnOnce ( & mut RenderPassEncoder < ' _ > ) -> Result < R , RenderPassError > ,
111+ PassFn :
112+ FnOnce ( & mut RenderPassEncoder < ' _ > ) -> Result < Output , RenderPassError > ,
115113 {
116- let mut pass_encoder = RenderPassEncoder :: new (
114+ let pass_encoder = RenderPassEncoder :: new (
117115 & mut self . inner ,
118- config ,
116+ pass ,
119117 color_attachments,
120118 depth_texture,
121- depth_ops,
122- stencil_ops,
123- label,
124119 ) ;
125120
126- let result = f ( & mut pass_encoder) ;
127- // Pass is automatically dropped here, ending the render pass
128- return result;
121+ return f ( & mut { pass_encoder } ) ;
129122 }
130123
131124 /// Finish recording and submit the command buffer to the GPU.
@@ -144,81 +137,6 @@ impl std::fmt::Debug for CommandEncoder {
144137 }
145138}
146139
147- // ---------------------------------------------------------------------------
148- // RenderPassConfig
149- // ---------------------------------------------------------------------------
150-
151- /// Configuration for beginning a render pass.
152- #[ derive( Clone , Debug ) ]
153- pub struct RenderPassConfig {
154- /// Optional debug label for the pass.
155- pub label : Option < String > ,
156- /// Color operations (load/store) for color attachments.
157- pub color_operations : ColorOperations ,
158- /// Initial viewport for the pass.
159- pub viewport : Viewport ,
160- /// Whether the pass uses color attachments.
161- pub uses_color : bool ,
162- /// MSAA sample count for the pass.
163- pub sample_count : u32 ,
164- }
165-
166- impl RenderPassConfig {
167- /// Create a new render pass configuration with default settings.
168- pub fn new ( ) -> Self {
169- return Self {
170- label : None ,
171- color_operations : ColorOperations :: default ( ) ,
172- viewport : Viewport {
173- x : 0 ,
174- y : 0 ,
175- width : 1 ,
176- height : 1 ,
177- min_depth : 0.0 ,
178- max_depth : 1.0 ,
179- } ,
180- uses_color : true ,
181- sample_count : 1 ,
182- } ;
183- }
184-
185- /// Set the debug label for the pass.
186- pub fn with_label ( mut self , label : & str ) -> Self {
187- self . label = Some ( label. to_string ( ) ) ;
188- return self ;
189- }
190-
191- /// Set the color operations for the pass.
192- pub fn with_color_operations ( mut self , ops : ColorOperations ) -> Self {
193- self . color_operations = ops;
194- return self ;
195- }
196-
197- /// Set the initial viewport for the pass.
198- pub fn with_viewport ( mut self , viewport : Viewport ) -> Self {
199- self . viewport = viewport;
200- return self ;
201- }
202-
203- /// Set whether the pass uses color attachments.
204- pub fn with_color ( mut self , uses_color : bool ) -> Self {
205- self . uses_color = uses_color;
206- return self ;
207- }
208-
209- /// Set the MSAA sample count for the pass.
210- pub fn with_sample_count ( mut self , sample_count : u32 ) -> Self {
211- self . sample_count = sample_count;
212- return self ;
213- }
214- }
215-
216- impl Default for RenderPassConfig {
217- fn default ( ) -> Self {
218- return Self :: new ( ) ;
219- }
220- }
221-
222140// ---------------------------------------------------------------------------
223141// RenderPassEncoder
224142// ---------------------------------------------------------------------------
@@ -230,9 +148,13 @@ impl Default for RenderPassConfig {
230148///
231149/// The encoder borrows the command encoder for the duration of the pass and
232150/// performs validation on all operations.
233- pub struct RenderPassEncoder < ' a > {
151+ ///
152+ /// # Type Parameters
153+ /// * `'pass` - The lifetime of the render pass, tied to the borrowed encoder
154+ /// and attachments.
155+ pub struct RenderPassEncoder < ' pass > {
234156 /// Platform render pass for issuing GPU commands.
235- pass : platform:: render_pass:: RenderPass < ' a > ,
157+ pass : platform:: render_pass:: RenderPass < ' pass > ,
236158 /// Whether the pass uses color attachments.
237159 uses_color : bool ,
238160 /// Whether the pass has a depth attachment.
@@ -280,29 +202,27 @@ struct BoundIndexBuffer {
280202 max_indices : u32 ,
281203}
282204
283- impl < ' a > RenderPassEncoder < ' a > {
205+ impl < ' pass > RenderPassEncoder < ' pass > {
284206 /// Create a new render pass encoder (internal).
285207 fn new (
286- encoder : & ' a mut platform:: command:: CommandEncoder ,
287- config : RenderPassConfig ,
288- color_attachments : & ' a mut RenderColorAttachments < ' a > ,
289- depth_texture : Option < & ' a DepthTexture > ,
290- depth_ops : Option < DepthOperations > ,
291- stencil_ops : Option < StencilOperations > ,
292- label : Option < & ' a str > ,
208+ encoder : & ' pass mut platform:: command:: CommandEncoder ,
209+ pass : & ' pass RenderPass ,
210+ color_attachments : & ' pass mut RenderColorAttachments < ' pass > ,
211+ depth_texture : Option < & ' pass DepthTexture > ,
293212 ) -> Self {
294213 // Build the platform render pass
295214 let mut rp_builder = platform:: render_pass:: RenderPassBuilder :: new ( ) ;
296215
297- // Map color operations
298- rp_builder = match config. color_operations . load {
216+ // Map color operations from the high-level RenderPass
217+ let color_ops = pass. color_operations ( ) ;
218+ rp_builder = match color_ops. load {
299219 ColorLoadOp :: Load => {
300220 rp_builder. with_color_load_op ( platform:: render_pass:: ColorLoadOp :: Load )
301221 }
302222 ColorLoadOp :: Clear ( color) => rp_builder
303223 . with_color_load_op ( platform:: render_pass:: ColorLoadOp :: Clear ( color) ) ,
304224 } ;
305- rp_builder = match config . color_operations . store {
225+ rp_builder = match color_ops . store {
306226 StoreOp :: Store => {
307227 rp_builder. with_store_op ( platform:: render_pass:: StoreOp :: Store )
308228 }
@@ -311,9 +231,9 @@ impl<'a> RenderPassEncoder<'a> {
311231 }
312232 } ;
313233
314- // Map depth operations
315- let platform_depth_ops =
316- depth_ops . map ( |dop| platform:: render_pass:: DepthOperations {
234+ // Map depth operations from the high-level RenderPass
235+ let platform_depth_ops = pass . depth_operations ( ) . map ( |dop| {
236+ platform:: render_pass:: DepthOperations {
317237 load : match dop. load {
318238 DepthLoadOp :: Load => platform:: render_pass:: DepthLoadOp :: Load ,
319239 DepthLoadOp :: Clear ( v) => {
@@ -324,11 +244,12 @@ impl<'a> RenderPassEncoder<'a> {
324244 StoreOp :: Store => platform:: render_pass:: StoreOp :: Store ,
325245 StoreOp :: Discard => platform:: render_pass:: StoreOp :: Discard ,
326246 } ,
327- } ) ;
247+ }
248+ } ) ;
328249
329- // Map stencil operations
330- let platform_stencil_ops =
331- stencil_ops . map ( |sop| platform:: render_pass:: StencilOperations {
250+ // Map stencil operations from the high-level RenderPass
251+ let platform_stencil_ops = pass . stencil_operations ( ) . map ( |sop| {
252+ platform:: render_pass:: StencilOperations {
332253 load : match sop. load {
333254 StencilLoadOp :: Load => platform:: render_pass:: StencilLoadOp :: Load ,
334255 StencilLoadOp :: Clear ( v) => {
@@ -339,27 +260,28 @@ impl<'a> RenderPassEncoder<'a> {
339260 StoreOp :: Store => platform:: render_pass:: StoreOp :: Store ,
340261 StoreOp :: Discard => platform:: render_pass:: StoreOp :: Discard ,
341262 } ,
342- } ) ;
263+ }
264+ } ) ;
343265
344266 let depth_view = depth_texture. map ( |dt| dt. platform_view_ref ( ) ) ;
345267 let has_depth_attachment = depth_texture. is_some ( ) ;
346- let has_stencil = stencil_ops . is_some ( ) ;
268+ let has_stencil = pass . stencil_operations ( ) . is_some ( ) ;
347269
348- let pass = rp_builder. build (
270+ let platform_pass = rp_builder. build (
349271 encoder,
350272 color_attachments. as_platform_attachments_mut ( ) ,
351273 depth_view,
352274 platform_depth_ops,
353275 platform_stencil_ops,
354- label,
276+ pass . label ( ) ,
355277 ) ;
356278
357- let mut encoder_instance = RenderPassEncoder {
358- pass,
359- uses_color : config . uses_color ,
279+ return RenderPassEncoder {
280+ pass : platform_pass ,
281+ uses_color : pass . uses_color ( ) ,
360282 has_depth_attachment,
361283 has_stencil,
362- sample_count : config . sample_count ,
284+ sample_count : pass . sample_count ( ) ,
363285 #[ cfg( any( debug_assertions, feature = "render-validation-encoder" ) ) ]
364286 current_pipeline : None ,
365287 #[ cfg( any( debug_assertions, feature = "render-validation-encoder" ) ) ]
@@ -379,11 +301,6 @@ impl<'a> RenderPassEncoder<'a> {
379301 ) ) ]
380302 warned_no_depth_for_pipeline : HashSet :: new ( ) ,
381303 } ;
382-
383- // Apply initial viewport
384- encoder_instance. set_viewport ( & config. viewport ) ;
385-
386- return encoder_instance;
387304 }
388305
389306 /// Set the active render pipeline.
@@ -496,6 +413,7 @@ impl<'a> RenderPassEncoder<'a> {
496413 self
497414 . pass
498415 . set_viewport ( x, y, width, height, min_depth, max_depth) ;
416+
499417 let ( sx, sy, sw, sh) = viewport. scissor_u32 ( ) ;
500418 self . pass . set_scissor_rect ( sx, sy, sw, sh) ;
501419 }
0 commit comments