Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 9 additions & 17 deletions wgpu-native/src/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1911,19 +1911,7 @@ pub fn device_create_swap_chain<B: GfxBackend>(
suf.compatibility(&adapter.raw.physical_device)
};
let num_frames = *caps.image_count.start(); //TODO: configure?
let usage = conv::map_texture_usage(desc.usage, hal::format::Aspects::COLOR);
let mut config = hal::SwapchainConfig::new(
desc.width,
desc.height,
conv::map_texture_format(desc.format),
num_frames, //TODO: configure?
);
//TODO: check for supported
config.composite_alpha = hal::window::CompositeAlpha::OPAQUE;
config.present_mode = match desc.present_mode {
swap_chain::PresentMode::NoVsync => hal::PresentMode::Immediate,
swap_chain::PresentMode::Vsync => hal::PresentMode::Fifo,
};
let config = desc.to_hal(num_frames);

if let Some(formats) = formats {
assert!(
Expand Down Expand Up @@ -1960,9 +1948,9 @@ pub fn device_create_swap_chain<B: GfxBackend>(
);
}
unsafe { old.command_pool.reset(false) };
(Some(old.raw), old.sem_available, old.command_pool)
(old.raw, old.sem_available, old.command_pool)
}
_ => unsafe {
None => unsafe {
let sem_available = device.raw.create_semaphore().unwrap();
let command_pool = device
.raw
Expand All @@ -1979,7 +1967,7 @@ pub fn device_create_swap_chain<B: GfxBackend>(
let suf = B::get_surface_mut(surface);
device
.raw
.create_swapchain(suf, config.with_image_usage(usage), old_raw)
.create_swapchain(suf, config, old_raw)
.unwrap()
};

Expand All @@ -1988,7 +1976,11 @@ pub fn device_create_swap_chain<B: GfxBackend>(

let mut trackers = device.trackers.lock();
let mut swap_chain = swap_chain::SwapChain {
raw: raw_swap_chain,
raw: Some(raw_swap_chain),
surface_id: Stored {
value: surface_id,
ref_count: surface.ref_count.clone(),
},
device_id: Stored {
value: device_id,
ref_count: device.life_guard.ref_count.clone(),
Expand Down
11 changes: 10 additions & 1 deletion wgpu-native/src/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@ use crate::{
Backend,
Device,
DeviceId,
RefCount,
SwapChainId,
};
#[cfg(not(feature = "remote"))]
use crate::{gfx_select, SurfaceId};
use crate::{gfx_select, LifeGuard, SurfaceId};

#[cfg(not(feature = "remote"))]
use bitflags::bitflags;
Expand Down Expand Up @@ -59,6 +60,7 @@ type GfxSurface<B> = <B as hal::Backend>::Surface;
#[derive(Debug)]
pub struct Surface {
pub(crate) swap_chain: Option<SwapChainId>,
pub(crate) ref_count: RefCount,
pub(crate) vulkan: Option<GfxSurface<backend::Vulkan>>,
#[cfg(any(target_os = "ios", target_os = "macos"))]
pub(crate) metal: GfxSurface<backend::Metal>,
Expand Down Expand Up @@ -158,10 +160,12 @@ pub fn wgpu_create_surface(raw_handle: raw_window_handle::RawWindowHandle) -> Su
use raw_window_handle::RawWindowHandle as Rwh;

let instance = &GLOBAL.instance;
let ref_count = LifeGuard::new().ref_count;
let surface = match raw_handle {
#[cfg(target_os = "ios")]
Rwh::IOS(h) => Surface {
swap_chain: None,
ref_count,
vulkan: None,
metal: instance
.metal
Expand All @@ -170,6 +174,7 @@ pub fn wgpu_create_surface(raw_handle: raw_window_handle::RawWindowHandle) -> Su
#[cfg(target_os = "macos")]
Rwh::MacOS(h) => Surface {
swap_chain: None,
ref_count,
vulkan: instance
.vulkan
.as_ref()
Expand All @@ -181,6 +186,7 @@ pub fn wgpu_create_surface(raw_handle: raw_window_handle::RawWindowHandle) -> Su
#[cfg(all(unix, not(target_os = "ios"), not(target_os = "macos")))]
Rwh::X11(h) => Surface {
swap_chain: None,
ref_count,
vulkan: instance
.vulkan
.as_ref()
Expand All @@ -189,6 +195,7 @@ pub fn wgpu_create_surface(raw_handle: raw_window_handle::RawWindowHandle) -> Su
#[cfg(all(unix, not(target_os = "ios"), not(target_os = "macos")))]
Rwh::Wayland(h) => Surface {
swap_chain: None,
ref_count,
vulkan: instance
.vulkan
.as_ref()
Expand All @@ -197,6 +204,7 @@ pub fn wgpu_create_surface(raw_handle: raw_window_handle::RawWindowHandle) -> Su
#[cfg(windows)]
Rwh::Windows(h) => Surface {
swap_chain: None,
ref_count,
vulkan: instance
.vulkan
.as_ref()
Expand Down Expand Up @@ -235,6 +243,7 @@ pub extern "C" fn wgpu_create_surface_from_xlib(
pub extern "C" fn wgpu_create_surface_from_metal_layer(layer: *mut std::ffi::c_void) -> SurfaceId {
let surface = Surface {
swap_chain: None,
ref_count: LifeGuard::new().ref_count,
vulkan: None, //TODO: currently requires `NSView`
metal: GLOBAL
.instance
Expand Down
95 changes: 82 additions & 13 deletions wgpu-native/src/swap_chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,12 @@ use crate::{
Extent3d,
Stored,
SwapChainId,
SurfaceId,
TextureId,
TextureViewId,
};
#[cfg(not(feature = "remote"))]
use crate::hub::GLOBAL;

use hal::{self, Device as _, Swapchain as _};
use log::{trace, warn};
Expand Down Expand Up @@ -56,13 +59,16 @@ pub(crate) struct Frame<B: hal::Backend> {
//TODO: does it need a ref-counted lifetime?
#[derive(Debug)]
pub struct SwapChain<B: hal::Backend> {
pub(crate) raw: B::Swapchain,
//Note: it's only an option because we may need to move it out
// and then put a new swapchain back in.
pub(crate) raw: Option<B::Swapchain>,
pub(crate) surface_id: Stored<SurfaceId>,
pub(crate) device_id: Stored<DeviceId>,
pub(crate) desc: SwapChainDescriptor,
pub(crate) frames: Vec<Frame<B>>,
pub(crate) acquired: Vec<hal::SwapImageIndex>,
pub(crate) sem_available: B::Semaphore,
#[cfg_attr(not(not(feature = "remote")), allow(dead_code))] //TODO: remove
#[cfg_attr(feature = "remote", allow(dead_code))] //TODO: remove
pub(crate) command_pool: hal::CommandPool<B, hal::General>,
}

Expand All @@ -84,6 +90,23 @@ pub struct SwapChainDescriptor {
}

impl SwapChainDescriptor {
pub(crate) fn to_hal(&self, num_frames: u32) -> hal::window::SwapchainConfig {
let mut config = hal::SwapchainConfig::new(
self.width,
self.height,
conv::map_texture_format(self.format),
num_frames,
);
//TODO: check for supported
config.image_usage = conv::map_texture_usage(self.usage, hal::format::Aspects::COLOR);
config.composite_alpha = hal::window::CompositeAlpha::OPAQUE;
config.present_mode = match self.present_mode {
PresentMode::NoVsync => hal::PresentMode::Immediate,
PresentMode::Vsync => hal::PresentMode::Fifo,
};
config
}

pub fn to_texture_desc(&self) -> resource::TextureDescriptor {
resource::TextureDescriptor {
size: Extent3d {
Expand All @@ -108,10 +131,14 @@ pub struct SwapChainOutput {
pub view_id: TextureViewId,
}

pub fn swap_chain_get_next_texture<B: GfxBackend>(swap_chain_id: SwapChainId) -> SwapChainOutput {
pub fn swap_chain_get_next_texture<B: GfxBackend>(
swap_chain_id: SwapChainId
) -> SwapChainOutput {
let hub = B::hub();
let mut token = Token::root();

#[cfg(not(feature = "remote"))]
let (mut surface_guard, mut token) = GLOBAL.surfaces.write(&mut token);
let (device_guard, mut token) = hub.devices.read(&mut token);
let (mut swap_chain_guard, _) = hub.swap_chains.write(&mut token);
let swap_chain = &mut swap_chain_guard[swap_chain_id];
Expand All @@ -120,31 +147,73 @@ pub fn swap_chain_get_next_texture<B: GfxBackend>(swap_chain_id: SwapChainId) ->
let image_index = unsafe {
swap_chain
.raw
.as_mut()
.unwrap()
.acquire_image(!0, Some(&swap_chain.sem_available), None)
}
.ok();
};

#[cfg(not(feature = "remote"))]
{
//use crate::device::device_create_swap_chain_textures}
if image_index.is_none() {
if image_index.is_err() {
warn!("acquire_image failed, re-creating");
unimplemented!()
//let textures = device_create_swap_chain(device_id, swap_chain_id, &descriptor, &mut token);
//swap_chain_populate_textures(swap_chain_id, textures, &mut token); //TODO?
//TODO: remove this once gfx-rs stops destroying the old swapchain
device.raw.wait_idle().unwrap();
let (mut texture_guard, mut token) = hub.textures.write(&mut token);
let (mut texture_view_guard, _) = hub.texture_views.write(&mut token);
let mut trackers = device.trackers.lock();

let old_raw = swap_chain.raw.take();
let config = swap_chain.desc.to_hal(swap_chain.frames.len() as u32);
let surface = &mut surface_guard[swap_chain.surface_id.value];

let (raw, images) = unsafe {
let suf = B::get_surface_mut(surface);
device
.raw
.create_swapchain(suf, config, old_raw)
.unwrap()
};
swap_chain.raw = Some(raw);
for (frame, image) in swap_chain.frames.iter_mut().zip(images) {
let texture = &mut texture_guard[frame.texture_id.value];
let view_raw = unsafe {
device
.raw
.create_image_view(
&image,
hal::image::ViewKind::D2,
conv::map_texture_format(texture.format),
hal::format::Swizzle::NO,
texture.full_range.clone(),
)
.unwrap()
};
texture.raw = image;
trackers.textures.reset(
frame.texture_id.value,
texture.full_range.clone(),
resource::TextureUsage::UNINITIALIZED,
);
let old_view = mem::replace(&mut texture_view_guard[frame.view_id.value].raw, view_raw);
unsafe {
device.raw.destroy_image_view(old_view);
}
}
}
}

let image_index = match image_index {
Some((index, suboptimal)) => {
Ok((index, suboptimal)) => {
if suboptimal.is_some() {
warn!("acquire_image: sub-optimal");
}
index
}
None => unsafe {
Err(_) => unsafe {
swap_chain
.raw
.as_mut()
.unwrap()
.acquire_image(!0, Some(&swap_chain.sem_available), None)
.unwrap()
.0
Expand Down Expand Up @@ -266,7 +335,7 @@ pub fn swap_chain_present<B: GfxBackend>(swap_chain_id: SwapChainId) {
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((swap_chain.raw.as_ref().unwrap(), image_index)),
iter::once(&frame.sem_present),
)
};
Expand Down
21 changes: 21 additions & 0 deletions wgpu-native/src/track/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,27 @@ impl<S: ResourceState> ResourceTracker<S> {
.is_none()
}

/// Resets a resource to the specified usage.
#[cfg(not(feature = "remote"))]
pub fn reset(
&mut self,
id: S::Id,
selector: S::Selector,
default: S::Usage,
) {
let mut state = S::default();
match state.change(id, selector, default, None) {
Ok(()) => (),
Err(_) => unreachable!(),
}

let (index, epoch, backend) = id.unzip();
debug_assert_eq!(backend, self.backend);
let res = self.map.get_mut(&index).unwrap();
assert_eq!(res.epoch, epoch);
res.state = state;
}

/// Query the usage of a resource selector.
///
/// Returns `Some(Usage)` only if this usage is consistent
Expand Down