From f2a0e6fe15ea7039ed8082af318883bf4106dd86 Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Thu, 21 Feb 2019 12:57:21 -0500 Subject: [PATCH] Swapchain resize, merged with the surface --- wgpu-bindings/wgpu.h | 4 +- wgpu-native/src/device.rs | 77 +++++++++++++++++++++-------------- wgpu-native/src/hub.rs | 3 +- wgpu-native/src/instance.rs | 31 ++++++-------- wgpu-native/src/lib.rs | 3 +- wgpu-native/src/swap_chain.rs | 26 ++++++++++-- 6 files changed, 85 insertions(+), 59 deletions(-) diff --git a/wgpu-bindings/wgpu.h b/wgpu-bindings/wgpu.h index e21cb7e96..db6a7ade9 100644 --- a/wgpu-bindings/wgpu.h +++ b/wgpu-bindings/wgpu.h @@ -435,10 +435,10 @@ typedef struct { WGPUByteArray code; } WGPUShaderModuleDescriptor; -typedef WGPUId WGPUSwapChainId; - typedef WGPUId WGPUSurfaceId; +typedef WGPUSurfaceId WGPUSwapChainId; + typedef uint32_t WGPUTextureUsageFlags; typedef struct { diff --git a/wgpu-native/src/device.rs b/wgpu-native/src/device.rs index 8173e9edc..a71dd7936 100644 --- a/wgpu-native/src/device.rs +++ b/wgpu-native/src/device.rs @@ -965,17 +965,20 @@ pub extern "C" fn wgpu_queue_submit( let fence = device.raw.create_fence(false).unwrap(); { let command_buffer_guard = HUB.command_buffers.read(); - let swap_chain_guard = HUB.swap_chains.read(); + let surface_guard = HUB.surfaces.read(); let wait_semaphores = swap_chain_links .into_iter() - .map(|link| { + .flat_map(|link| { //TODO: check the epoch - let sem = &swap_chain_guard + surface_guard .get(link.swap_chain_id.0) - .frames[link.image_index as usize] - .sem_available; - (sem, hal::pso::PipelineStage::COLOR_ATTACHMENT_OUTPUT) + .swap_chain + .as_ref() + .map(|swap_chain| ( + &swap_chain.frames[link.image_index as usize].sem_available, + hal::pso::PipelineStage::COLOR_ATTACHMENT_OUTPUT, + )) }); let submission = @@ -1299,7 +1302,7 @@ pub fn device_create_swap_chain( surface_id: SurfaceId, desc: &swap_chain::SwapChainDescriptor, outdated: swap_chain::OutdatedFrame, -) -> (swap_chain::SwapChain, Vec>) { +) -> Vec> { let device_guard = HUB.devices.read(); let device = device_guard.get(device_id); let mut surface_guard = HUB.surfaces.write(); @@ -1331,25 +1334,38 @@ pub fn device_create_swap_chain( "Requested size {}x{} is outside of the supported range: {:?}", desc.width, desc.height, caps.extents); + + let (old_raw, sem_available, command_pool) = match surface.swap_chain.take() { + Some(old) => { + assert_eq!(old.device_id.value, device_id); + HUB.textures.unregister(old.outdated.texture_id.value); + HUB.texture_views.unregister(old.outdated.view_id.value); + (Some(old.raw), old.sem_available, old.command_pool) + } + _ => unsafe { + let sem_available = device.raw + .create_semaphore() + .unwrap(); + let command_pool = device.raw + .create_command_pool_typed( + &device.queue_group, + hal::pool::CommandPoolCreateFlags::RESET_INDIVIDUAL, + ) + .unwrap(); + (None, sem_available, command_pool) + } + }; + let (raw, backbuffer) = unsafe { device.raw .create_swapchain( &mut surface.raw, config.with_image_usage(usage), - None, + old_raw, ) .unwrap() }; - let command_pool = unsafe { - device.raw - .create_command_pool_typed( - &device.queue_group, - hal::pool::CommandPoolCreateFlags::RESET_INDIVIDUAL, - ) - .unwrap() - }; - - let swap_chain = swap_chain::SwapChain { + surface.swap_chain = Some(swap_chain::SwapChain { raw, device_id: Stored { value: device_id, @@ -1357,17 +1373,17 @@ pub fn device_create_swap_chain( }, frames: Vec::with_capacity(num_frames as usize), acquired: Vec::with_capacity(1), //TODO: get it from gfx-hal? - sem_available: device.raw.create_semaphore().unwrap(), + sem_available, outdated, command_pool, - }; + }); let images = match backbuffer { hal::Backbuffer::Images(images) => images, hal::Backbuffer::Framebuffer(_) => panic!("Deprecated API detected!"), }; - let textures = images + images .into_iter() .map(|raw| resource::Texture { raw, @@ -1385,9 +1401,7 @@ pub fn device_create_swap_chain( swap_chain_link: None, life_guard: LifeGuard::new(), }) - .collect(); - - (swap_chain, textures) + .collect() } #[cfg(feature = "local")] @@ -1395,8 +1409,12 @@ fn swap_chain_populate_textures( swap_chain_id: SwapChainId, textures: Vec>, ) { - let mut swap_chain_guard = HUB.swap_chains.write(); - let swap_chain = swap_chain_guard.get_mut(swap_chain_id); + let mut surface_guard = HUB.surfaces.write(); + let swap_chain = surface_guard + .get_mut(swap_chain_id) + .swap_chain + .as_mut() + .unwrap(); let device_guard = HUB.devices.read(); let device = device_guard.get(swap_chain.device_id.value); @@ -1477,10 +1495,9 @@ pub extern "C" fn wgpu_device_create_swap_chain( } }; - let (swap_chain, textures) = device_create_swap_chain(device_id, surface_id, desc, outdated); - let id = HUB.swap_chains.register(swap_chain); - swap_chain_populate_textures(id, textures); - id + let textures = device_create_swap_chain(device_id, surface_id, desc, outdated); + swap_chain_populate_textures(surface_id, textures); + surface_id } diff --git a/wgpu-native/src/hub.rs b/wgpu-native/src/hub.rs index 75c8ba992..202d0fe43 100644 --- a/wgpu-native/src/hub.rs +++ b/wgpu-native/src/hub.rs @@ -4,7 +4,7 @@ use crate::{ RenderPassHandle, ComputePassHandle, PipelineLayoutHandle, RenderPipelineHandle, ComputePipelineHandle, ShaderModuleHandle, BufferHandle, SamplerHandle, TextureHandle, TextureViewHandle, - SurfaceHandle, SwapChainHandle, + SurfaceHandle, }; use hal::backend::FastHashMap; @@ -126,7 +126,6 @@ pub struct Hub { pub(crate) texture_views: Arc>, pub(crate) samplers: Arc>, pub(crate) surfaces: Arc>, - pub(crate) swap_chains: Arc>, } lazy_static! { diff --git a/wgpu-native/src/instance.rs b/wgpu-native/src/instance.rs index 6654fecc6..7fcb8021f 100644 --- a/wgpu-native/src/instance.rs +++ b/wgpu-native/src/instance.rs @@ -54,10 +54,7 @@ pub extern "C" fn wgpu_instance_create_surface_from_winit( .read() .get(instance_id) .create_surface(window); - let surface = SurfaceHandle { - raw, - }; - + let surface = SurfaceHandle::new(raw); HUB.surfaces.register(surface) } @@ -71,12 +68,11 @@ pub fn instance_create_surface_from_xlib( unimplemented!(); #[cfg(all(unix, feature = "gfx-backend-vulkan"))] - SurfaceHandle { - raw: HUB.instances - .read() - .get(instance_id) - .create_surface_from_xlib(display, window), - } + SurfaceHandle::new(HUB.instances + .read() + .get(instance_id) + .create_surface_from_xlib(display, window) + ) } #[cfg(feature = "local")] @@ -99,12 +95,11 @@ pub fn instance_create_surface_from_macos_layer( unimplemented!(); #[cfg(feature = "gfx-backend-metal")] - SurfaceHandle { - raw: HUB.instances - .read() - .get(instance_id) - .create_surface_from_layer(layer as *mut _), - } + SurfaceHandle::new(HUB.instances + .read() + .get(instance_id) + .create_surface_from_layer(layer as *mut _) + ) } #[cfg(feature = "local")] @@ -139,9 +134,7 @@ pub fn instance_create_surface_from_windows_hwnd( .create_surface_from_hwnd(hinstance, hwnd); #[cfg_attr(not(target_os = "windows"), allow(unreachable_code))] - SurfaceHandle { - raw, - } + SurfaceHandle::new(raw) } #[cfg(feature = "local")] diff --git a/wgpu-native/src/lib.rs b/wgpu-native/src/lib.rs index c4255ad68..2667a414e 100644 --- a/wgpu-native/src/lib.rs +++ b/wgpu-native/src/lib.rs @@ -219,5 +219,4 @@ type ComputePassHandle = ComputePass; // Swap chain pub type SurfaceId = hub::Id; type SurfaceHandle = Surface; -pub type SwapChainId = hub::Id; -type SwapChainHandle = SwapChain; +pub type SwapChainId = SurfaceId; diff --git a/wgpu-native/src/swap_chain.rs b/wgpu-native/src/swap_chain.rs index 84e0130a4..16a027f32 100644 --- a/wgpu-native/src/swap_chain.rs +++ b/wgpu-native/src/swap_chain.rs @@ -24,6 +24,16 @@ pub(crate) struct SwapChainLink { pub struct Surface { pub(crate) raw: B::Surface, + pub(crate) swap_chain: Option>, +} + +impl Surface { + pub(crate) fn new(raw: B::Surface) -> Self { + Surface { + raw, + swap_chain: None, + } + } } pub(crate) struct Frame { @@ -88,8 +98,12 @@ pub struct SwapChainOutput { pub extern "C" fn wgpu_swap_chain_get_next_texture( swap_chain_id: SwapChainId, ) -> SwapChainOutput { - let mut swap_chain_guard = HUB.swap_chains.write(); - let swap_chain = swap_chain_guard.get_mut(swap_chain_id); + let mut surface_guard = HUB.surfaces.write(); + let swap_chain = surface_guard + .get_mut(swap_chain_id) + .swap_chain + .as_mut() + .unwrap(); let device_guard = HUB.devices.read(); let device = device_guard.get(swap_chain.device_id.value); @@ -136,8 +150,12 @@ pub extern "C" fn wgpu_swap_chain_get_next_texture( pub extern "C" fn wgpu_swap_chain_present( swap_chain_id: SwapChainId, ) { - let mut swap_chain_guard = HUB.swap_chains.write(); - let swap_chain = swap_chain_guard.get_mut(swap_chain_id); + let mut surface_guard = HUB.surfaces.write(); + let swap_chain = surface_guard + .get_mut(swap_chain_id) + .swap_chain + .as_mut() + .unwrap(); let image_index = swap_chain.acquired.remove(0); let frame = match swap_chain.frames.get_mut(image_index as usize) {