From 5b509692d1fb9654ae45b8c3eb752794ffc9e652 Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Thu, 21 Feb 2019 11:52:22 -0500 Subject: [PATCH 1/5] Outdated frame for the swapchain --- wgpu-native/src/device.rs | 24 +++++++- wgpu-native/src/swap_chain.rs | 111 +++++++++++++++++++++++----------- 2 files changed, 99 insertions(+), 36 deletions(-) diff --git a/wgpu-native/src/device.rs b/wgpu-native/src/device.rs index b2d84231b..8173e9edc 100644 --- a/wgpu-native/src/device.rs +++ b/wgpu-native/src/device.rs @@ -1294,11 +1294,11 @@ pub extern "C" fn wgpu_device_create_compute_pipeline( HUB.compute_pipelines.register(pipeline) } - pub fn device_create_swap_chain( device_id: DeviceId, surface_id: SurfaceId, desc: &swap_chain::SwapChainDescriptor, + outdated: swap_chain::OutdatedFrame, ) -> (swap_chain::SwapChain, Vec>) { let device_guard = HUB.devices.read(); let device = device_guard.get(device_id); @@ -1358,6 +1358,7 @@ 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(), + outdated, command_pool, }; @@ -1457,7 +1458,26 @@ pub extern "C" fn wgpu_device_create_swap_chain( surface_id: SurfaceId, desc: &swap_chain::SwapChainDescriptor, ) -> SwapChainId { - let (swap_chain, textures) = device_create_swap_chain(device_id, surface_id, desc); + let outdated = { + let outdated_texture = device_create_texture(device_id, &desc.to_texture_desc()); + let texture_id = Stored { + ref_count: outdated_texture.life_guard.ref_count.clone(), + value: HUB.textures.register(outdated_texture), + }; + device_track_texture(device_id, texture_id.value, texture_id.ref_count.clone()); + + let outdated_view = texture_create_default_view(texture_id.value); + let view_id = Stored { + ref_count: outdated_view.life_guard.ref_count.clone(), + value: HUB.texture_views.register(outdated_view), + }; + swap_chain::OutdatedFrame { + texture_id, + view_id, + } + }; + + 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 diff --git a/wgpu-native/src/swap_chain.rs b/wgpu-native/src/swap_chain.rs index 53552fee7..84e0130a4 100644 --- a/wgpu-native/src/swap_chain.rs +++ b/wgpu-native/src/swap_chain.rs @@ -1,4 +1,5 @@ -use crate::{Stored, WeaklyStored, +use crate::{ + Extent3d, Stored, WeaklyStored, DeviceId, SwapChainId, TextureId, TextureViewId, }; use crate::{conv, resource}; @@ -8,7 +9,7 @@ use crate::track::{TrackPermit}; use hal; use hal::{Device as _Device, Swapchain as _Swapchain}; -use log::trace; +use log::{trace, warn}; use std::{iter, mem}; @@ -34,6 +35,12 @@ pub(crate) struct Frame { pub comb: hal::command::CommandBuffer, } +pub struct OutdatedFrame { + pub(crate) texture_id: Stored, + pub(crate) view_id: Stored, +} + +const OUTDATED_IMAGE_INDEX: u32 = !0; //TODO: does it need a ref-counted lifetime? pub struct SwapChain { @@ -42,6 +49,7 @@ pub struct SwapChain { pub(crate) frames: Vec>, pub(crate) acquired: Vec, pub(crate) sem_available: B::Semaphore, + pub(crate) outdated: OutdatedFrame, #[cfg_attr(not(feature = "local"), allow(dead_code))] //TODO: remove pub(crate) command_pool: hal::CommandPool, } @@ -54,6 +62,22 @@ pub struct SwapChainDescriptor { pub height: u32, } +impl SwapChainDescriptor { + pub fn to_texture_desc(&self) -> resource::TextureDescriptor { + resource::TextureDescriptor { + size: Extent3d { + width: self.width, + height: self.height, + depth: 1, + }, + array_size: 1, + dimension: resource::TextureDimension::D2, + format: self.format, + usage: self.usage, + } + } +} + #[repr(C)] pub struct SwapChainOutput { pub texture_id: TextureId, @@ -66,35 +90,45 @@ pub extern "C" fn wgpu_swap_chain_get_next_texture( ) -> SwapChainOutput { let mut swap_chain_guard = HUB.swap_chains.write(); let swap_chain = swap_chain_guard.get_mut(swap_chain_id); - assert_ne!(swap_chain.acquired.len(), swap_chain.acquired.capacity(), - "Unable to acquire any more swap chain images before presenting"); - let device_guard = HUB.devices.read(); let device = device_guard.get(swap_chain.device_id.value); - let image_index = unsafe { + assert_ne!(swap_chain.acquired.len(), swap_chain.acquired.capacity(), + "Unable to acquire any more swap chain images before presenting"); + + match { let sync = hal::FrameSync::Semaphore(&swap_chain.sem_available); - swap_chain.raw.acquire_image(!0, sync).unwrap() - }; + unsafe { swap_chain.raw.acquire_image(!0, sync) } + } { + Ok(image_index) => { + swap_chain.acquired.push(image_index); + let frame = &mut swap_chain.frames[image_index as usize]; + unsafe { + device.raw.wait_for_fence(&frame.fence, !0).unwrap(); + } - swap_chain.acquired.push(image_index); - let frame = &mut swap_chain.frames[image_index as usize]; - unsafe { - device.raw.wait_for_fence(&frame.fence, !0).unwrap(); - } + mem::swap(&mut frame.sem_available, &mut swap_chain.sem_available); - mem::swap(&mut frame.sem_available, &mut swap_chain.sem_available); + let texture_guard = HUB.textures.read(); + let texture = texture_guard.get(frame.texture_id.value); + match texture.swap_chain_link { + Some(ref link) => *link.epoch.lock() += 1, + None => unreachable!(), + } - let texture_guard = HUB.textures.read(); - let texture = texture_guard.get(frame.texture_id.value); - match texture.swap_chain_link { - Some(ref link) => *link.epoch.lock() += 1, - None => unreachable!(), - } - - SwapChainOutput { - texture_id: frame.texture_id.value, - view_id: frame.view_id.value, + SwapChainOutput { + texture_id: frame.texture_id.value, + view_id: frame.view_id.value, + } + } + Err(e) => { + warn!("acquire_image failed: {:?}", e); + swap_chain.acquired.push(OUTDATED_IMAGE_INDEX); + SwapChainOutput { + texture_id: swap_chain.outdated.texture_id.value, + view_id: swap_chain.outdated.view_id.value, + } + } } } @@ -104,11 +138,18 @@ pub extern "C" fn wgpu_swap_chain_present( ) { let mut swap_chain_guard = HUB.swap_chains.write(); let swap_chain = swap_chain_guard.get_mut(swap_chain_id); - let mut device_guard = HUB.devices.write(); - let device = device_guard.get_mut(swap_chain.device_id.value); let image_index = swap_chain.acquired.remove(0); - let frame = &mut swap_chain.frames[image_index as usize]; + let frame = match swap_chain.frames.get_mut(image_index as usize) { + Some(frame) => frame, + None => { + assert_eq!(image_index, OUTDATED_IMAGE_INDEX); + return + } + }; + + let mut device_guard = HUB.devices.write(); + let device = device_guard.get_mut(swap_chain.device_id.value); let texture_guard = HUB.textures.read(); let texture = texture_guard.get(frame.texture_id.value); @@ -138,7 +179,7 @@ pub extern "C" fn wgpu_swap_chain_present( range: texture.full_range.clone(), }); - unsafe { + let err = unsafe { frame.comb.begin(false); frame.comb.pipeline_barrier( all_image_stages() .. hal::pso::PipelineStage::COLOR_ATTACHMENT_OUTPUT, @@ -157,11 +198,13 @@ pub extern "C" fn wgpu_swap_chain_present( device.raw.reset_fence(&frame.fence).unwrap(); let queue = &mut device.queue_group.queues[0]; queue.submit(submission, Some(&frame.fence)); - queue - .present( - iter::once((&swap_chain.raw, image_index)), - iter::once(&frame.sem_present), - ) - .unwrap(); + queue.present( + iter::once((&swap_chain.raw, image_index)), + iter::once(&frame.sem_present), + ) + }; + + if let Err(e) = err { + warn!("present failed: {:?}", e); } } From f2a0e6fe15ea7039ed8082af318883bf4106dd86 Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Thu, 21 Feb 2019 12:57:21 -0500 Subject: [PATCH 2/5] 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) { From 28551103c269ae420eceae318e4708f458ecc57c Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Thu, 21 Feb 2019 13:53:31 -0500 Subject: [PATCH 3/5] Fix old outdated frame cleanup --- wgpu-native/src/device.rs | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/wgpu-native/src/device.rs b/wgpu-native/src/device.rs index a71dd7936..b296da22a 100644 --- a/wgpu-native/src/device.rs +++ b/wgpu-native/src/device.rs @@ -98,9 +98,8 @@ unsafe impl Send for DestroyedResources {} unsafe impl Sync for DestroyedResources {} impl DestroyedResources { - fn add(&mut self, resource_id: ResourceId, life_guard: &LifeGuard) { - self.referenced - .push((resource_id, life_guard.ref_count.clone())); + fn add(&mut self, resource_id: ResourceId, ref_count: RefCount) { + self.referenced.push((resource_id, ref_count)); } /// Returns the last submission index that is done. @@ -369,7 +368,10 @@ pub extern "C" fn wgpu_buffer_destroy(buffer_id: BufferId) { .get(buffer.device_id.value) .destroyed .lock() - .add(ResourceId::Buffer(buffer_id), &buffer.life_guard); + .add( + ResourceId::Buffer(buffer_id), + buffer.life_guard.ref_count.clone(), + ); } @@ -579,7 +581,10 @@ pub extern "C" fn wgpu_texture_destroy(texture_id: TextureId) { .get(texture.device_id.value) .destroyed .lock() - .add(ResourceId::Texture(texture_id), &texture.life_guard); + .add( + ResourceId::Texture(texture_id), + texture.life_guard.ref_count.clone(), + ); } #[no_mangle] @@ -595,7 +600,10 @@ pub extern "C" fn wgpu_texture_view_destroy(texture_view_id: TextureViewId) { .get(device_id) .destroyed .lock() - .add(ResourceId::TextureView(texture_view_id), &view.life_guard); + .add( + ResourceId::TextureView(texture_view_id), + view.life_guard.ref_count.clone(), + ); } @@ -1336,10 +1344,14 @@ pub fn device_create_swap_chain( let (old_raw, sem_available, command_pool) = match surface.swap_chain.take() { - Some(old) => { + Some(mut 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); + let mut destroyed = device.destroyed.lock(); + destroyed.add(ResourceId::Texture(old.outdated.texture_id.value), old.outdated.texture_id.ref_count); + destroyed.add(ResourceId::TextureView(old.outdated.view_id.value), old.outdated.view_id.ref_count); + unsafe { + old.command_pool.reset() + }; (Some(old.raw), old.sem_available, old.command_pool) } _ => unsafe { From 14ee80f463a83950a24e7f9573e8a11371e39e40 Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Thu, 21 Feb 2019 14:14:30 -0500 Subject: [PATCH 4/5] Update the trackers on resource destruction --- wgpu-native/src/device.rs | 14 ++++++++++---- wgpu-native/src/track.rs | 5 +++++ 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/wgpu-native/src/device.rs b/wgpu-native/src/device.rs index b296da22a..480ddd1ab 100644 --- a/wgpu-native/src/device.rs +++ b/wgpu-native/src/device.rs @@ -138,7 +138,11 @@ impl DestroyedResources { } impl DestroyedResources { - fn triage_referenced(&mut self) { + fn triage_referenced( + &mut self, + buffer_tracker: &mut BufferTracker, + texture_tracker: &mut TextureTracker, + ) { for i in (0..self.referenced.len()).rev() { // one in resource itself, and one here in this list let num_refs = self.referenced[i].1.load(); @@ -147,11 +151,13 @@ impl DestroyedResources { let resource_id = self.referenced.swap_remove(i).0; let (submit_index, resource) = match resource_id { ResourceId::Buffer(id) => { + buffer_tracker.remove(id); let buf = HUB.buffers.unregister(id); let si = buf.life_guard.submission_index.load(Ordering::Acquire); (si, Resource::Buffer(buf)) } ResourceId::Texture(id) => { + texture_tracker.remove(id); let tex = HUB.textures.unregister(id); let si = tex.life_guard.submission_index.load(Ordering::Acquire); (si, Resource::Texture(tex)) @@ -910,6 +916,8 @@ pub extern "C" fn wgpu_queue_submit( .life_guard .submission_index .fetch_add(1, Ordering::Relaxed); + let mut buffer_tracker = device.buffer_tracker.lock(); + let mut texture_tracker = device.texture_tracker.lock(); //TODO: if multiple command buffers are submitted, we can re-use the last // native command buffer of the previous chain instead of always creating @@ -918,8 +926,6 @@ pub extern "C" fn wgpu_queue_submit( let mut command_buffer_guard = HUB.command_buffers.write(); let buffer_guard = HUB.buffers.read(); let texture_guard = HUB.textures.read(); - let mut buffer_tracker = device.buffer_tracker.lock(); - let mut texture_tracker = device.texture_tracker.lock(); // finish all the command buffers first for &cmb_id in command_buffer_ids { @@ -1008,7 +1014,7 @@ pub extern "C" fn wgpu_queue_submit( let last_done = { let mut destroyed = device.destroyed.lock(); - destroyed.triage_referenced(); + destroyed.triage_referenced(&mut *buffer_tracker, &mut *texture_tracker); let last_done = destroyed.cleanup(&device.raw); destroyed.active.push(ActiveSubmission { diff --git a/wgpu-native/src/track.rs b/wgpu-native/src/track.rs index 808f8b785..f0bd086a0 100644 --- a/wgpu-native/src/track.rs +++ b/wgpu-native/src/track.rs @@ -87,6 +87,11 @@ impl + PartialE } } + /// Remove an id from the tracked map. + pub(crate) fn remove(&mut self, id: I) -> bool { + self.map.remove(&WeaklyStored(id)).is_some() + } + /// Get the last usage on a resource. pub(crate) fn query(&mut self, stored: &Stored, default: U) -> Query { match self.map.entry(WeaklyStored(stored.value.clone())) { From 59fe34963335f5a23b37cc3f28769e851b8ae7ed Mon Sep 17 00:00:00 2001 From: Dzmitry Malyshau Date: Thu, 21 Feb 2019 14:14:42 -0500 Subject: [PATCH 5/5] Resize support for gfx-cube and framework --- gfx-examples/src/cube.rs | 36 ++++++++++++++++++++++------------- gfx-examples/src/framework.rs | 8 ++++++-- 2 files changed, 29 insertions(+), 15 deletions(-) diff --git a/gfx-examples/src/cube.rs b/gfx-examples/src/cube.rs index 1cc540997..13f839c6f 100644 --- a/gfx-examples/src/cube.rs +++ b/gfx-examples/src/cube.rs @@ -88,9 +88,22 @@ struct Cube { index_buf: wgpu::Buffer, index_count: usize, bind_group: wgpu::BindGroup, + uniform_buf: wgpu::Buffer, pipeline: wgpu::RenderPipeline, } +impl Cube { + fn generate_matrix(aspect_ratio: f32) -> cgmath::Matrix4 { + let mx_projection = cgmath::perspective(cgmath::Deg(45f32), aspect_ratio, 1.0, 10.0); + let mx_view = cgmath::Matrix4::look_at( + cgmath::Point3::new(1.5f32, -5.0, 3.0), + cgmath::Point3::new(0f32, 0.0, 0.0), + cgmath::Vector3::unit_z(), + ); + mx_projection * mx_view + } +} + impl framework::Example for Cube { fn init(device: &mut wgpu::Device, sc_desc: &wgpu::SwapChainDescriptor) -> Self { use std::mem; @@ -196,18 +209,9 @@ impl framework::Example for Cube { size: 64, usage: wgpu::BufferUsageFlags::UNIFORM | wgpu::BufferUsageFlags::TRANSFER_DST, }); - { - let aspect_ratio = sc_desc.width as f32 / sc_desc.height as f32; - let mx_projection = cgmath::perspective(cgmath::Deg(45f32), aspect_ratio, 1.0, 10.0); - let mx_view = cgmath::Matrix4::look_at( - cgmath::Point3::new(1.5f32, -5.0, 3.0), - cgmath::Point3::new(0f32, 0.0, 0.0), - cgmath::Vector3::unit_z(), - ); - let mx_total = mx_projection * mx_view; - let mx_raw: &[f32; 16] = mx_total.as_ref(); - uniform_buf.set_sub_data(0, framework::cast_slice(&mx_raw[..])); - } + let mx_total = Self::generate_matrix(sc_desc.width as f32 / sc_desc.height as f32); + let mx_ref: &[f32; 16] = mx_total.as_ref(); + uniform_buf.set_sub_data(0, framework::cast_slice(&mx_ref[..])); // Create bind group let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { @@ -294,11 +298,17 @@ impl framework::Example for Cube { index_buf, index_count: index_data.len(), bind_group, + uniform_buf, pipeline, } } - fn update(&mut self, _event: wgpu::winit::WindowEvent) { + fn update(&mut self, event: wgpu::winit::WindowEvent) { + if let wgpu::winit::WindowEvent::Resized(size) = event { + let mx_total = Self::generate_matrix(size.width as f32 / size.height as f32); + let mx_ref: &[f32; 16] = mx_total.as_ref(); + self.uniform_buf.set_sub_data(0, framework::cast_slice(&mx_ref[..])); + } } fn render(&mut self, frame: &wgpu::SwapChainOutput, device: &mut wgpu::Device) { diff --git a/gfx-examples/src/framework.rs b/gfx-examples/src/framework.rs index a0a07479f..ec0514ef7 100644 --- a/gfx-examples/src/framework.rs +++ b/gfx-examples/src/framework.rs @@ -70,7 +70,7 @@ pub fn run(title: &str) { .to_physical(window.get_hidpi_factor()); let surface = instance.create_surface(&window); - let sc_desc = wgpu::SwapChainDescriptor { + let mut sc_desc = wgpu::SwapChainDescriptor { usage: wgpu::TextureUsageFlags::OUTPUT_ATTACHMENT, format: wgpu::TextureFormat::B8g8r8a8Unorm, width: size.width as u32, @@ -91,7 +91,11 @@ pub fn run(title: &str) { .. } => { let physical = size.to_physical(window.get_hidpi_factor()); - info!("Resized to {:?}", physical); + info!("Resizing to {:?}", physical); + sc_desc.width = physical.width as u32; + sc_desc.height = physical.height as u32; + swap_chain = device.create_swap_chain(&surface, &sc_desc); + example.update(WindowEvent::Resized(size)); } Event::WindowEvent { event, .. } => match event { WindowEvent::KeyboardInput {