begin work on supporting multiple swap chains
This commit is contained in:
		
							parent
							
								
									bfa8afbc97
								
							
						
					
					
						commit
						8a759d3b18
					
				| @ -16,4 +16,5 @@ pub struct CreateWindow { | |||||||
| #[derive(Debug, Clone)] | #[derive(Debug, Clone)] | ||||||
| pub struct WindowCreated { | pub struct WindowCreated { | ||||||
|     pub id: WindowId, |     pub id: WindowId, | ||||||
|  |     pub is_primary: bool, | ||||||
| } | } | ||||||
|  | |||||||
| @ -11,6 +11,12 @@ use uuid::Uuid; | |||||||
| #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] | #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] | ||||||
| pub struct WindowId(Uuid); | pub struct WindowId(Uuid); | ||||||
| 
 | 
 | ||||||
|  | impl WindowId { | ||||||
|  |     pub fn to_string(&self) -> String { | ||||||
|  |         self.0.to_simple().to_string() | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| pub struct Window { | pub struct Window { | ||||||
|     pub id: WindowId, |     pub id: WindowId, | ||||||
|     pub width: u32, |     pub width: u32, | ||||||
|  | |||||||
| @ -107,7 +107,9 @@ fn handle_create_window_events( | |||||||
|     for create_window_event in create_window_events.iter(create_window_event_handle) { |     for create_window_event in create_window_events.iter(create_window_event_handle) { | ||||||
|         let window = Window::new(&create_window_event.descriptor); |         let window = Window::new(&create_window_event.descriptor); | ||||||
|         winit_windows.create_window(event_loop, &window); |         winit_windows.create_window(event_loop, &window); | ||||||
|         window_created_events.send(WindowCreated { id: window.id }); |         let window_id = window.id; | ||||||
|         windows.add(window); |         windows.add(window); | ||||||
|  |         let is_primary = windows.get_primary().map(|primary| primary.id == window_id).unwrap_or(false); | ||||||
|  |         window_created_events.send(WindowCreated { id: window_id, is_primary }); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -221,7 +221,8 @@ impl WgpuRenderer { | |||||||
|         pass_descriptor: &PassDescriptor, |         pass_descriptor: &PassDescriptor, | ||||||
|         global_render_resource_assignments: &RenderResourceAssignments, |         global_render_resource_assignments: &RenderResourceAssignments, | ||||||
|         encoder: &'a mut wgpu::CommandEncoder, |         encoder: &'a mut wgpu::CommandEncoder, | ||||||
|         frame: &'a wgpu::SwapChainOutput, |         primary_swap_chain: &Option<String>, | ||||||
|  |         swap_chain_outputs: &'a HashMap<String, wgpu::SwapChainOutput>, | ||||||
|     ) -> wgpu::RenderPass<'a> { |     ) -> wgpu::RenderPass<'a> { | ||||||
|         encoder.begin_render_pass(&wgpu::RenderPassDescriptor { |         encoder.begin_render_pass(&wgpu::RenderPassDescriptor { | ||||||
|             color_attachments: &pass_descriptor |             color_attachments: &pass_descriptor | ||||||
| @ -232,7 +233,8 @@ impl WgpuRenderer { | |||||||
|                         wgpu_resources, |                         wgpu_resources, | ||||||
|                         global_render_resource_assignments, |                         global_render_resource_assignments, | ||||||
|                         c, |                         c, | ||||||
|                         frame, |                         primary_swap_chain, | ||||||
|  |                         swap_chain_outputs, | ||||||
|                     ) |                     ) | ||||||
|                 }) |                 }) | ||||||
|                 .collect::<Vec<wgpu::RenderPassColorAttachmentDescriptor>>(), |                 .collect::<Vec<wgpu::RenderPassColorAttachmentDescriptor>>(), | ||||||
| @ -241,46 +243,69 @@ impl WgpuRenderer { | |||||||
|                     wgpu_resources, |                     wgpu_resources, | ||||||
|                     global_render_resource_assignments, |                     global_render_resource_assignments, | ||||||
|                     d, |                     d, | ||||||
|                     frame, |                     primary_swap_chain, | ||||||
|  |                     swap_chain_outputs, | ||||||
|                 ) |                 ) | ||||||
|             }), |             }), | ||||||
|         }) |         }) | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     fn get_texture_view<'a>( | ||||||
|  |         wgpu_resources: &'a WgpuResources, | ||||||
|  |         global_render_resource_assignments: &RenderResourceAssignments, | ||||||
|  |         primary_swap_chain: &Option<String>, | ||||||
|  |         swap_chain_outputs: &'a HashMap<String, wgpu::SwapChainOutput>, | ||||||
|  |         name: &str, | ||||||
|  |     ) -> &'a wgpu::TextureView { | ||||||
|  |         match name { | ||||||
|  |             resource_name::texture::SWAP_CHAIN => { | ||||||
|  |                 if let Some(primary_swap_chain) = primary_swap_chain { | ||||||
|  |                     swap_chain_outputs | ||||||
|  |                         .get(primary_swap_chain) | ||||||
|  |                         .map(|output| &output.view) | ||||||
|  |                         .unwrap() | ||||||
|  |                 } else { | ||||||
|  |                     panic!("No primary swap chain found for color attachment"); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             _ => match global_render_resource_assignments.get(name) { | ||||||
|  |                 Some(resource) => wgpu_resources.textures.get(&resource).unwrap(), | ||||||
|  |                 None => if let Some(swap_chain_output) = swap_chain_outputs.get(name) { | ||||||
|  |                     &swap_chain_output.view 
 | ||||||
|  |                 }  else { | ||||||
|  |                     panic!("Color attachment {} does not exist", name); | ||||||
|  |                 } | ||||||
|  |             }, | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     fn create_wgpu_color_attachment_descriptor<'a>( |     fn create_wgpu_color_attachment_descriptor<'a>( | ||||||
|         wgpu_resources: &'a WgpuResources, |         wgpu_resources: &'a WgpuResources, | ||||||
|         global_render_resource_assignments: &RenderResourceAssignments, |         global_render_resource_assignments: &RenderResourceAssignments, | ||||||
|         color_attachment_descriptor: &RenderPassColorAttachmentDescriptor, |         color_attachment_descriptor: &RenderPassColorAttachmentDescriptor, | ||||||
|         frame: &'a wgpu::SwapChainOutput, |         primary_swap_chain: &Option<String>, | ||||||
|  |         swap_chain_outputs: &'a HashMap<String, wgpu::SwapChainOutput>, | ||||||
|     ) -> wgpu::RenderPassColorAttachmentDescriptor<'a> { |     ) -> wgpu::RenderPassColorAttachmentDescriptor<'a> { | ||||||
|         let attachment = match color_attachment_descriptor.attachment.as_str() { |         let attachment = Self::get_texture_view( | ||||||
|             resource_name::texture::SWAP_CHAIN => &frame.view, |             wgpu_resources, | ||||||
|             _ => { |             global_render_resource_assignments, | ||||||
|                 match global_render_resource_assignments |             primary_swap_chain, | ||||||
|                     .get(&color_attachment_descriptor.attachment) |             swap_chain_outputs, | ||||||
|                 { |             color_attachment_descriptor.attachment.as_str(), | ||||||
|                     Some(resource) => wgpu_resources.textures.get(&resource).unwrap(), |         ); | ||||||
|                     None => panic!( |  | ||||||
|                         "Color attachment {} does not exist", |  | ||||||
|                         &color_attachment_descriptor.attachment |  | ||||||
|                     ), |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         }; |  | ||||||
| 
 | 
 | ||||||
|         let resolve_target = match color_attachment_descriptor.resolve_target { |         let resolve_target = color_attachment_descriptor | ||||||
|             Some(ref target) => match target.as_str() { |             .resolve_target | ||||||
|                 resource_name::texture::SWAP_CHAIN => Some(&frame.view), |             .as_ref() | ||||||
|                 _ => match global_render_resource_assignments.get(target.as_str()) { |             .map(|target| { | ||||||
|                     Some(resource) => Some(wgpu_resources.textures.get(&resource).unwrap()), |                 Self::get_texture_view( | ||||||
|                     None => panic!( |                     wgpu_resources, | ||||||
|                         "Color attachment {} does not exist", |                     global_render_resource_assignments, | ||||||
|                         &color_attachment_descriptor.attachment |                     primary_swap_chain, | ||||||
|                     ), |                     swap_chain_outputs, | ||||||
|                 }, |                     target.as_str(), | ||||||
|             }, |                 ) | ||||||
|             None => None, |             }); | ||||||
|         }; |  | ||||||
| 
 | 
 | ||||||
|         wgpu::RenderPassColorAttachmentDescriptor { |         wgpu::RenderPassColorAttachmentDescriptor { | ||||||
|             store_op: color_attachment_descriptor.store_op.into(), |             store_op: color_attachment_descriptor.store_op.into(), | ||||||
| @ -295,22 +320,16 @@ impl WgpuRenderer { | |||||||
|         wgpu_resources: &'a WgpuResources, |         wgpu_resources: &'a WgpuResources, | ||||||
|         global_render_resource_assignments: &RenderResourceAssignments, |         global_render_resource_assignments: &RenderResourceAssignments, | ||||||
|         depth_stencil_attachment_descriptor: &RenderPassDepthStencilAttachmentDescriptor, |         depth_stencil_attachment_descriptor: &RenderPassDepthStencilAttachmentDescriptor, | ||||||
|         frame: &'a wgpu::SwapChainOutput, |         primary_swap_chain: &Option<String>, | ||||||
|  |         swap_chain_outputs: &'a HashMap<String, wgpu::SwapChainOutput>, | ||||||
|     ) -> wgpu::RenderPassDepthStencilAttachmentDescriptor<'a> { |     ) -> wgpu::RenderPassDepthStencilAttachmentDescriptor<'a> { | ||||||
|         let attachment = match depth_stencil_attachment_descriptor.attachment.as_str() { |         let attachment = Self::get_texture_view( | ||||||
|             resource_name::texture::SWAP_CHAIN => &frame.view, |             wgpu_resources, | ||||||
|             _ => { |             global_render_resource_assignments, | ||||||
|                 match global_render_resource_assignments |             primary_swap_chain, | ||||||
|                     .get(&depth_stencil_attachment_descriptor.attachment) |             swap_chain_outputs, | ||||||
|                 { |             depth_stencil_attachment_descriptor.attachment.as_str(), | ||||||
|                     Some(ref resource) => wgpu_resources.textures.get(&resource).unwrap(), |         ); | ||||||
|                     None => panic!( |  | ||||||
|                         "Depth stencil attachment {} does not exist", |  | ||||||
|                         &depth_stencil_attachment_descriptor.attachment |  | ||||||
|                     ), |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         }; |  | ||||||
| 
 | 
 | ||||||
|         wgpu::RenderPassDepthStencilAttachmentDescriptor { |         wgpu::RenderPassDepthStencilAttachmentDescriptor { | ||||||
|             attachment, |             attachment, | ||||||
| @ -422,6 +441,33 @@ impl WgpuRenderer { | |||||||
|             .window_swap_chains |             .window_swap_chains | ||||||
|             .insert(window.id, swap_chain); |             .insert(window.id, swap_chain); | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     fn get_swap_chain_outputs( | ||||||
|  |         &mut self, | ||||||
|  |         resources: &Resources, | ||||||
|  |     ) -> (Option<String>, HashMap<String, wgpu::SwapChainOutput>) { | ||||||
|  |         let primary_window_id = resources | ||||||
|  |             .get::<Windows>() | ||||||
|  |             .unwrap() | ||||||
|  |             .get_primary() | ||||||
|  |             .map(|window| window.id); | ||||||
|  |         let primary_swap_chain = | ||||||
|  |             primary_window_id.map(|primary_window_id| primary_window_id.to_string()); | ||||||
|  |         let swap_chain_outputs = self | ||||||
|  |             .wgpu_resources | ||||||
|  |             .window_swap_chains | ||||||
|  |             .iter_mut() | ||||||
|  |             // TODO: include non-primary swap chains
 | ||||||
|  |             .filter(|(window_id, _swap_chain)| **window_id == primary_window_id.unwrap()) | ||||||
|  |             .map(|(window_id, swap_chain)| { | ||||||
|  |                 let swap_chain_texture = swap_chain | ||||||
|  |                     .get_next_texture() | ||||||
|  |                     .expect("Timeout when acquiring next swap chain texture"); | ||||||
|  |                 (window_id.to_string(), swap_chain_texture) | ||||||
|  |             }) | ||||||
|  |             .collect::<HashMap<String, wgpu::SwapChainOutput>>(); | ||||||
|  |         (primary_swap_chain, swap_chain_outputs) | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl Renderer for WgpuRenderer { | impl Renderer for WgpuRenderer { | ||||||
| @ -444,18 +490,6 @@ impl Renderer for WgpuRenderer { | |||||||
| 
 | 
 | ||||||
|         let mut encoder = self.encoder.take().unwrap(); |         let mut encoder = self.encoder.take().unwrap(); | ||||||
| 
 | 
 | ||||||
|         // TODO: create swap chain outputs for every swap chain
 |  | ||||||
|         let swap_chain = self |  | ||||||
|             .wgpu_resources |  | ||||||
|             .window_swap_chains |  | ||||||
|             .values_mut() |  | ||||||
|             .next() |  | ||||||
|             .unwrap(); |  | ||||||
|         let frame = swap_chain |  | ||||||
|             .get_next_texture() |  | ||||||
|             .expect("Timeout when acquiring next swap chain texture"); |  | ||||||
| 
 |  | ||||||
|         // setup, pipelines, bind groups, and resources
 |  | ||||||
|         let mut pipeline_storage = resources |         let mut pipeline_storage = resources | ||||||
|             .get_mut::<AssetStorage<PipelineDescriptor>>() |             .get_mut::<AssetStorage<PipelineDescriptor>>() | ||||||
|             .unwrap(); |             .unwrap(); | ||||||
| @ -485,7 +519,7 @@ impl Renderer for WgpuRenderer { | |||||||
|                                     &shader_storage, |                                     &shader_storage, | ||||||
|                                 ); |                                 ); | ||||||
|                             } |                             } | ||||||
|                             
 | 
 | ||||||
|                             // setup pipeline draw targets
 |                             // setup pipeline draw targets
 | ||||||
|                             for draw_target_name in compiled_pipeline_descriptor.draw_targets.iter() |                             for draw_target_name in compiled_pipeline_descriptor.draw_targets.iter() | ||||||
|                             { |                             { | ||||||
| @ -506,6 +540,8 @@ impl Renderer for WgpuRenderer { | |||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |         let (primary_swap_chain, swap_chain_outputs) = self.get_swap_chain_outputs(resources); | ||||||
|  | 
 | ||||||
|         // begin render passes
 |         // begin render passes
 | ||||||
|         for (pass_name, pass_descriptor) in render_graph.pass_descriptors.iter() { |         for (pass_name, pass_descriptor) in render_graph.pass_descriptors.iter() { | ||||||
|             let mut render_pass = Self::create_render_pass( |             let mut render_pass = Self::create_render_pass( | ||||||
| @ -513,7 +549,8 @@ impl Renderer for WgpuRenderer { | |||||||
|                 pass_descriptor, |                 pass_descriptor, | ||||||
|                 &global_render_resource_assignments, |                 &global_render_resource_assignments, | ||||||
|                 &mut encoder, |                 &mut encoder, | ||||||
|                 &frame, |                 &primary_swap_chain, | ||||||
|  |                 &swap_chain_outputs, | ||||||
|             ); |             ); | ||||||
|             if let Some(pass_pipelines) = render_graph.pass_pipelines.get(pass_name) { |             if let Some(pass_pipelines) = render_graph.pass_pipelines.get(pass_name) { | ||||||
|                 for pass_pipeline in pass_pipelines.iter() { |                 for pass_pipeline in pass_pipelines.iter() { | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Carter Anderson
						Carter Anderson