Swapchain resize, merged with the surface

This commit is contained in:
Dzmitry Malyshau 2019-02-21 12:57:21 -05:00
parent 5b509692d1
commit f2a0e6fe15
6 changed files with 85 additions and 59 deletions

View File

@ -435,10 +435,10 @@ typedef struct {
WGPUByteArray code;
} WGPUShaderModuleDescriptor;
typedef WGPUId WGPUSwapChainId;
typedef WGPUId WGPUSurfaceId;
typedef WGPUSurfaceId WGPUSwapChainId;
typedef uint32_t WGPUTextureUsageFlags;
typedef struct {

View File

@ -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<back::Backend>, Vec<resource::Texture<back::Backend>>) {
) -> Vec<resource::Texture<back::Backend>> {
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<resource::Texture<back::Backend>>,
) {
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
}

View File

@ -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<Registry<TextureViewHandle>>,
pub(crate) samplers: Arc<Registry<SamplerHandle>>,
pub(crate) surfaces: Arc<Registry<SurfaceHandle>>,
pub(crate) swap_chains: Arc<Registry<SwapChainHandle>>,
}
lazy_static! {

View File

@ -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")]

View File

@ -219,5 +219,4 @@ type ComputePassHandle = ComputePass<back::Backend>;
// Swap chain
pub type SurfaceId = hub::Id;
type SurfaceHandle = Surface<back::Backend>;
pub type SwapChainId = hub::Id;
type SwapChainHandle = SwapChain<back::Backend>;
pub type SwapChainId = SurfaceId;

View File

@ -24,6 +24,16 @@ pub(crate) struct SwapChainLink<E> {
pub struct Surface<B: hal::Backend> {
pub(crate) raw: B::Surface,
pub(crate) swap_chain: Option<SwapChain<B>>,
}
impl<B: hal::Backend> Surface<B> {
pub(crate) fn new(raw: B::Surface) -> Self {
Surface {
raw,
swap_chain: None,
}
}
}
pub(crate) struct Frame<B: hal::Backend> {
@ -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) {