@@ -44,6 +44,9 @@ pub mod vertex;
4444pub mod viewport;
4545pub mod window;
4646
47+ // Internal modules
48+ mod color_attachments;
49+
4750use std:: {
4851 collections:: HashSet ,
4952 iter,
@@ -398,6 +401,40 @@ impl RenderContext {
398401 return self . gpu . limits ( ) . min_uniform_buffer_offset_alignment ;
399402 }
400403
404+ /// Ensure the MSAA color attachment texture exists with the given sample
405+ /// count, recreating it if necessary. Returns the texture view reference.
406+ ///
407+ /// This method manages the lifecycle of the internal MSAA texture, creating
408+ /// or recreating it when the sample count changes.
409+ fn ensure_msaa_color_texture (
410+ & mut self ,
411+ sample_count : u32 ,
412+ ) -> platform:: surface:: TextureViewRef < ' _ > {
413+ let need_recreate = match & self . msaa_color {
414+ Some ( _) => self . msaa_sample_count != sample_count,
415+ None => true ,
416+ } ;
417+
418+ if need_recreate {
419+ self . msaa_color = Some (
420+ platform:: texture:: ColorAttachmentTextureBuilder :: new (
421+ self . config . format . to_platform ( ) ,
422+ )
423+ . with_size ( self . size . 0 . max ( 1 ) , self . size . 1 . max ( 1 ) )
424+ . with_sample_count ( sample_count)
425+ . with_label ( "lambda-msaa-color" )
426+ . build ( self . gpu ( ) ) ,
427+ ) ;
428+ self . msaa_sample_count = sample_count;
429+ }
430+
431+ return self
432+ . msaa_color
433+ . as_ref ( )
434+ . expect ( "MSAA color attachment should exist" )
435+ . view_ref ( ) ;
436+ }
437+
401438 /// Encode and submit GPU work for a single frame.
402439 fn render_internal (
403440 & mut self ,
@@ -407,16 +444,18 @@ impl RenderContext {
407444 return Ok ( ( ) ) ;
408445 }
409446
410- let mut frame = match self . surface . acquire_next_frame ( ) {
411- Ok ( frame) => frame,
447+ let frame = match self . surface . acquire_next_frame ( ) {
448+ Ok ( frame) => surface :: Frame :: from_platform ( frame) ,
412449 Err ( err) => {
413450 let high_level_err = surface:: SurfaceError :: from ( err) ;
414451 match high_level_err {
415452 surface:: SurfaceError :: Lost | surface:: SurfaceError :: Outdated => {
416453 self . reconfigure_surface ( self . size ) ?;
417- self . surface . acquire_next_frame ( ) . map_err ( |e| {
418- RenderError :: Surface ( surface:: SurfaceError :: from ( e) )
419- } ) ?
454+ let platform_frame =
455+ self . surface . acquire_next_frame ( ) . map_err ( |e| {
456+ RenderError :: Surface ( surface:: SurfaceError :: from ( e) )
457+ } ) ?;
458+ surface:: Frame :: from_platform ( platform_frame)
420459 }
421460 _ => return Err ( RenderError :: Surface ( high_level_err) ) ,
422461 }
@@ -436,11 +475,17 @@ impl RenderContext {
436475 render_pass,
437476 viewport,
438477 } => {
439- let pass = self . render_passes . get ( render_pass) . ok_or_else ( || {
440- RenderError :: Configuration ( format ! (
441- "Unknown render pass {render_pass}"
442- ) )
443- } ) ?;
478+ // Clone the render pass descriptor to avoid borrowing self while we
479+ // need mutable access for MSAA texture creation.
480+ let pass = self
481+ . render_passes
482+ . get ( render_pass)
483+ . ok_or_else ( || {
484+ RenderError :: Configuration ( format ! (
485+ "Unknown render pass {render_pass}"
486+ ) )
487+ } ) ?
488+ . clone ( ) ;
444489
445490 // Build (begin) the platform render pass using the builder API.
446491 let mut rp_builder = platform:: render_pass:: RenderPassBuilder :: new ( ) ;
@@ -464,39 +509,32 @@ impl RenderContext {
464509 rp_builder. with_store_op ( platform:: render_pass:: StoreOp :: Discard )
465510 }
466511 } ;
467- // Create variably sized color attachments and begin the pass.
468- let mut color_attachments =
469- platform:: render_pass:: RenderColorAttachments :: new ( ) ;
512+
513+ // Ensure MSAA texture exists if needed.
470514 let sample_count = pass. sample_count ( ) ;
471- if pass. uses_color ( ) {
472- if sample_count > 1 {
473- let need_recreate = match & self . msaa_color {
474- Some ( _) => self . msaa_sample_count != sample_count,
475- None => true ,
476- } ;
477- if need_recreate {
478- self . msaa_color = Some (
479- platform:: texture:: ColorAttachmentTextureBuilder :: new (
480- self . config . format . to_platform ( ) ,
481- )
482- . with_size ( self . size . 0 . max ( 1 ) , self . size . 1 . max ( 1 ) )
483- . with_sample_count ( sample_count)
484- . with_label ( "lambda-msaa-color" )
485- . build ( self . gpu ( ) ) ,
486- ) ;
487- self . msaa_sample_count = sample_count;
488- }
489- let msaa_view = self
490- . msaa_color
491- . as_ref ( )
492- . expect ( "MSAA color attachment should be created" )
493- . view_ref ( ) ;
494- color_attachments. push_msaa_color ( msaa_view, view) ;
495- } else {
496- color_attachments. push_color ( view) ;
497- }
515+ let uses_color = pass. uses_color ( ) ;
516+ if uses_color && sample_count > 1 {
517+ self . ensure_msaa_color_texture ( sample_count) ;
498518 }
499519
520+ // Create color attachments for the surface pass. The MSAA view is
521+ // retrieved here after the mutable borrow for texture creation ends.
522+ let msaa_view = if sample_count > 1 {
523+ self
524+ . msaa_color
525+ . as_ref ( )
526+ . map ( |t| surface:: TextureView :: from_platform ( t. view_ref ( ) ) )
527+ } else {
528+ None
529+ } ;
530+ let mut color_attachments =
531+ color_attachments:: RenderColorAttachments :: for_surface_pass (
532+ uses_color,
533+ sample_count,
534+ msaa_view,
535+ view,
536+ ) ;
537+
500538 // Depth/stencil attachment when either depth or stencil requested.
501539 let want_depth_attachment = Self :: has_depth_attachment (
502540 pass. depth_operations ( ) ,
@@ -583,7 +621,7 @@ impl RenderContext {
583621
584622 let mut pass_encoder = rp_builder. build (
585623 & mut encoder,
586- & mut color_attachments,
624+ color_attachments. as_platform_attachments_mut ( ) ,
587625 depth_view,
588626 depth_ops,
589627 stencil_ops,
0 commit comments