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();
|
||||||
@ -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