Port to the new swapchain model

This commit is contained in:
Dzmitry Malyshau 2020-04-03 15:27:52 -04:00 committed by Dzmitry Malyshau
parent 0a7426f847
commit bef4517f83
4 changed files with 357 additions and 179 deletions

18
Cargo.lock generated
View file

@ -249,7 +249,7 @@ dependencies = [
[[package]] [[package]]
name = "gfx-auxil" name = "gfx-auxil"
version = "0.3.0" version = "0.3.0"
source = "git+https://github.com/gfx-rs/gfx#425d9155a0e349d05514dce7ae4e85b01ed43738" source = "git+https://github.com/gfx-rs/gfx#55d1449948f57a8fb0ebb25b567246ac6add46e8"
dependencies = [ dependencies = [
"fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gfx-hal 0.5.0 (git+https://github.com/gfx-rs/gfx)", "gfx-hal 0.5.0 (git+https://github.com/gfx-rs/gfx)",
@ -259,7 +259,7 @@ dependencies = [
[[package]] [[package]]
name = "gfx-backend-dx11" name = "gfx-backend-dx11"
version = "0.5.0" version = "0.5.0"
source = "git+https://github.com/gfx-rs/gfx#425d9155a0e349d05514dce7ae4e85b01ed43738" source = "git+https://github.com/gfx-rs/gfx#55d1449948f57a8fb0ebb25b567246ac6add46e8"
dependencies = [ dependencies = [
"bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"gfx-auxil 0.3.0 (git+https://github.com/gfx-rs/gfx)", "gfx-auxil 0.3.0 (git+https://github.com/gfx-rs/gfx)",
@ -278,7 +278,7 @@ dependencies = [
[[package]] [[package]]
name = "gfx-backend-dx12" name = "gfx-backend-dx12"
version = "0.5.0" version = "0.5.0"
source = "git+https://github.com/gfx-rs/gfx#425d9155a0e349d05514dce7ae4e85b01ed43738" source = "git+https://github.com/gfx-rs/gfx#55d1449948f57a8fb0ebb25b567246ac6add46e8"
dependencies = [ dependencies = [
"bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"d3d12 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "d3d12 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -295,7 +295,7 @@ dependencies = [
[[package]] [[package]]
name = "gfx-backend-empty" name = "gfx-backend-empty"
version = "0.5.0" version = "0.5.0"
source = "git+https://github.com/gfx-rs/gfx#425d9155a0e349d05514dce7ae4e85b01ed43738" source = "git+https://github.com/gfx-rs/gfx#55d1449948f57a8fb0ebb25b567246ac6add46e8"
dependencies = [ dependencies = [
"gfx-hal 0.5.0 (git+https://github.com/gfx-rs/gfx)", "gfx-hal 0.5.0 (git+https://github.com/gfx-rs/gfx)",
"raw-window-handle 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "raw-window-handle 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
@ -304,7 +304,7 @@ dependencies = [
[[package]] [[package]]
name = "gfx-backend-gl" name = "gfx-backend-gl"
version = "0.5.0" version = "0.5.0"
source = "git+https://github.com/gfx-rs/gfx#425d9155a0e349d05514dce7ae4e85b01ed43738" source = "git+https://github.com/gfx-rs/gfx#55d1449948f57a8fb0ebb25b567246ac6add46e8"
dependencies = [ dependencies = [
"arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -327,7 +327,7 @@ dependencies = [
[[package]] [[package]]
name = "gfx-backend-metal" name = "gfx-backend-metal"
version = "0.5.0" version = "0.5.0"
source = "git+https://github.com/gfx-rs/gfx#425d9155a0e349d05514dce7ae4e85b01ed43738" source = "git+https://github.com/gfx-rs/gfx#55d1449948f57a8fb0ebb25b567246ac6add46e8"
dependencies = [ dependencies = [
"arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -353,7 +353,7 @@ dependencies = [
[[package]] [[package]]
name = "gfx-backend-vulkan" name = "gfx-backend-vulkan"
version = "0.5.0" version = "0.5.0"
source = "git+https://github.com/gfx-rs/gfx#425d9155a0e349d05514dce7ae4e85b01ed43738" source = "git+https://github.com/gfx-rs/gfx#55d1449948f57a8fb0ebb25b567246ac6add46e8"
dependencies = [ dependencies = [
"arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"ash 0.30.0 (registry+https://github.com/rust-lang/crates.io-index)", "ash 0.30.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -373,7 +373,7 @@ dependencies = [
[[package]] [[package]]
name = "gfx-hal" name = "gfx-hal"
version = "0.5.0" version = "0.5.0"
source = "git+https://github.com/gfx-rs/gfx#425d9155a0e349d05514dce7ae4e85b01ed43738" source = "git+https://github.com/gfx-rs/gfx#55d1449948f57a8fb0ebb25b567246ac6add46e8"
dependencies = [ dependencies = [
"bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"raw-window-handle 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "raw-window-handle 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
@ -731,7 +731,7 @@ dependencies = [
[[package]] [[package]]
name = "range-alloc" name = "range-alloc"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/gfx-rs/gfx#425d9155a0e349d05514dce7ae4e85b01ed43738" source = "git+https://github.com/gfx-rs/gfx#55d1449948f57a8fb0ebb25b567246ac6add46e8"
[[package]] [[package]]
name = "raw-window-handle" name = "raw-window-handle"

View file

@ -355,7 +355,7 @@ pub fn map_image_usage(usage: VkImageUsageFlags) -> image::Usage {
image::Usage::from_bits_truncate(usage) image::Usage::from_bits_truncate(usage)
} }
pub fn map_image_usage_from_hal(usage: image::Usage) -> VkImageUsageFlags { pub fn _map_image_usage_from_hal(usage: image::Usage) -> VkImageUsageFlags {
usage.bits() usage.bits()
} }

View file

@ -6,7 +6,7 @@ use hal::{
pool::CommandPool as _, pool::CommandPool as _,
pso::DescriptorPool, pso::DescriptorPool,
queue::{CommandQueue as _, QueueFamily}, queue::{CommandQueue as _, QueueFamily},
window::{PresentMode, Surface, Swapchain as _}, window::{PresentMode, PresentationSurface as _, Surface as _},
{command as com, memory, pass, pso, queue}, {command as com, memory, pass, pso, queue},
{Features, Instance}, {Features, Instance},
}; };
@ -1173,7 +1173,8 @@ pub extern "C" fn gfxQueueSubmit(
stages stages
.into_iter() .into_iter()
.zip(semaphores) .zip(semaphores)
.map(|(stage, semaphore)| (&**semaphore, conv::map_pipeline_stage_flags(*stage))) .filter(|(_, semaphore)| !semaphore.is_fake)
.map(|(stage, semaphore)| (&semaphore.raw, conv::map_pipeline_stage_flags(*stage)))
}; };
let signal_semaphores = unsafe { let signal_semaphores = unsafe {
slice::from_raw_parts( slice::from_raw_parts(
@ -1181,7 +1182,10 @@ pub extern "C" fn gfxQueueSubmit(
submission.signalSemaphoreCount as _, submission.signalSemaphoreCount as _,
) )
.into_iter() .into_iter()
.map(|semaphore| &**semaphore) .map(|semaphore| {
semaphore.as_mut().unwrap().is_fake = false;
&semaphore.raw
})
}; };
let submission = hal::queue::Submission { let submission = hal::queue::Submission {
@ -1210,8 +1214,9 @@ pub extern "C" fn gfxQueueSubmit(
wait_semaphores: empty(), wait_semaphores: empty(),
signal_semaphores: empty(), signal_semaphores: empty(),
}; };
type RawSemaphore = <B as hal::Backend>::Semaphore;
unsafe { unsafe {
queue.submit::<VkCommandBuffer, _, VkSemaphore, _, _>(submission, fence.as_ref()) queue.submit::<VkCommandBuffer, _, RawSemaphore, _, _>(submission, fence.as_ref())
}; };
} }
@ -1356,9 +1361,13 @@ pub extern "C" fn gfxBindImageMemory(
memory: VkDeviceMemory, memory: VkDeviceMemory,
memoryOffset: VkDeviceSize, memoryOffset: VkDeviceSize,
) -> VkResult { ) -> VkResult {
let raw = match *image {
Image::Native { ref mut raw, .. } => raw,
Image::SwapchainFrame { .. } => panic!("Unexpected swapchain image"),
};
unsafe { unsafe {
gpu.device gpu.device
.bind_image_memory(&memory, memoryOffset, &mut image.raw) .bind_image_memory(&memory, memoryOffset, raw)
.unwrap(); //TODO .unwrap(); //TODO
} }
VkResult::VK_SUCCESS VkResult::VK_SUCCESS
@ -1383,7 +1392,8 @@ pub extern "C" fn gfxGetImageMemoryRequirements(
image: VkImage, image: VkImage,
pMemoryRequirements: *mut VkMemoryRequirements, pMemoryRequirements: *mut VkMemoryRequirements,
) { ) {
let req = unsafe { gpu.device.get_image_requirements(&image.raw) }; let raw = image.to_native().unwrap().raw;
let req = unsafe { gpu.device.get_image_requirements(raw) };
*unsafe { &mut *pMemoryRequirements } = VkMemoryRequirements { *unsafe { &mut *pMemoryRequirements } = VkMemoryRequirements {
size: req.size, size: req.size,
@ -1546,7 +1556,7 @@ pub extern "C" fn gfxCreateSemaphore(
pSemaphore: *mut VkSemaphore, pSemaphore: *mut VkSemaphore,
) -> VkResult { ) -> VkResult {
let semaphore = match gpu.device.create_semaphore() { let semaphore = match gpu.device.create_semaphore() {
Ok(s) => s, Ok(raw) => Semaphore { raw, is_fake: false },
Err(oom) => return map_oom(oom), Err(oom) => return map_oom(oom),
}; };
@ -1563,7 +1573,7 @@ pub extern "C" fn gfxDestroySemaphore(
) { ) {
if let Some(sem) = semaphore.unbox() { if let Some(sem) = semaphore.unbox() {
unsafe { unsafe {
gpu.device.destroy_semaphore(sem); gpu.device.destroy_semaphore(sem.raw);
} }
} }
} }
@ -1794,7 +1804,7 @@ pub extern "C" fn gfxCreateImage(
) )
.expect("Error on creating image"); .expect("Error on creating image");
*pImage = Handle::new(Image { *pImage = Handle::new(Image::Native {
raw: image, raw: image,
mip_levels: info.mipLevels, mip_levels: info.mipLevels,
array_layers: info.arrayLayers, array_layers: info.arrayLayers,
@ -1809,9 +1819,9 @@ pub extern "C" fn gfxDestroyImage(
image: VkImage, image: VkImage,
_pAllocator: *const VkAllocationCallbacks, _pAllocator: *const VkAllocationCallbacks,
) { ) {
if let Some(image) = image.unbox() { if let Some(Image::Native { raw, .. }) = image.unbox() {
unsafe { unsafe {
gpu.device.destroy_image(image.raw); gpu.device.destroy_image(raw);
} }
} }
} }
@ -1822,9 +1832,10 @@ pub extern "C" fn gfxGetImageSubresourceLayout(
pSubresource: *const VkImageSubresource, pSubresource: *const VkImageSubresource,
pLayout: *mut VkSubresourceLayout, pLayout: *mut VkSubresourceLayout,
) { ) {
let img = image.to_native().unwrap();
let footprint = unsafe { let footprint = unsafe {
gpu.device gpu.device
.get_image_subresource_footprint(&image.raw, image.map_subresource(*pSubresource)) .get_image_subresource_footprint(img.raw, img.map_subresource(*pSubresource))
}; };
let sub_layout = VkSubresourceLayout { let sub_layout = VkSubresourceLayout {
@ -1847,19 +1858,30 @@ pub extern "C" fn gfxCreateImageView(
pView: *mut VkImageView, pView: *mut VkImageView,
) -> VkResult { ) -> VkResult {
let info = unsafe { &*pCreateInfo }; let info = unsafe { &*pCreateInfo };
if let Image::SwapchainFrame { swapchain, frame } = *info.image {
unsafe {
*pView = Handle::new(ImageView::SwapchainFrame {
swapchain,
frame,
});
}
return VkResult::VK_SUCCESS;
}
let img = info.image.to_native().unwrap();
let view = unsafe { let view = unsafe {
gpu.device.create_image_view( gpu.device.create_image_view(
&info.image.raw, img.raw,
conv::map_view_kind(info.viewType), conv::map_view_kind(info.viewType),
conv::map_format(info.format).unwrap(), conv::map_format(info.format).unwrap(),
conv::map_swizzle(info.components), conv::map_swizzle(info.components),
info.image.map_subresource_range(info.subresourceRange), img.map_subresource_range(info.subresourceRange),
) )
}; };
match view { match view {
Ok(view) => { Ok(view) => {
unsafe { *pView = Handle::new(view) }; unsafe { *pView = Handle::new(ImageView::Native(view)) };
VkResult::VK_SUCCESS VkResult::VK_SUCCESS
} }
Err(err) => panic!("Unexpected image view creation error: {:?}", err), Err(err) => panic!("Unexpected image view creation error: {:?}", err),
@ -1871,7 +1893,7 @@ pub extern "C" fn gfxDestroyImageView(
imageView: VkImageView, imageView: VkImageView,
_pAllocator: *const VkAllocationCallbacks, _pAllocator: *const VkAllocationCallbacks,
) { ) {
if let Some(view) = imageView.unbox() { if let Some(ImageView::Native(view)) = imageView.unbox() {
unsafe { unsafe {
gpu.device.destroy_image_view(view); gpu.device.destroy_image_view(view);
} }
@ -2902,8 +2924,7 @@ pub extern "C" fn gfxAllocateDescriptorSets(
} }
error!("{:?}", e); error!("{:?}", e);
match e { match e {
pso::AllocationError::Host => VkResult::VK_ERROR_OUT_OF_HOST_MEMORY, pso::AllocationError::OutOfMemory(oom) => map_oom(oom),
pso::AllocationError::Device => VkResult::VK_ERROR_OUT_OF_DEVICE_MEMORY,
pso::AllocationError::OutOfPoolMemory => VkResult::VK_ERROR_OUT_OF_POOL_MEMORY_KHR, pso::AllocationError::OutOfPoolMemory => VkResult::VK_ERROR_OUT_OF_POOL_MEMORY_KHR,
pso::AllocationError::IncompatibleLayout => VkResult::VK_ERROR_DEVICE_LOST, pso::AllocationError::IncompatibleLayout => VkResult::VK_ERROR_DEVICE_LOST,
pso::AllocationError::FragmentedPool => VkResult::VK_ERROR_FRAGMENTED_POOL, pso::AllocationError::FragmentedPool => VkResult::VK_ERROR_FRAGMENTED_POOL,
@ -2950,7 +2971,7 @@ impl<'a> Iterator for DescriptorIter<'a> {
ty: pso::ImageDescriptorType::Sampled { with_sampler: true }, ty: pso::ImageDescriptorType::Sampled { with_sampler: true },
} => self.image_infos.next().map(|image| { } => self.image_infos.next().map(|image| {
pso::Descriptor::CombinedImageSampler( pso::Descriptor::CombinedImageSampler(
&*image.imageView, image.imageView.to_native().unwrap(),
conv::map_image_layout(image.imageLayout), conv::map_image_layout(image.imageLayout),
&*image.sampler, &*image.sampler,
) )
@ -2959,7 +2980,7 @@ impl<'a> Iterator for DescriptorIter<'a> {
pso::DescriptorType::InputAttachment | pso::DescriptorType::Image { .. } => { pso::DescriptorType::InputAttachment | pso::DescriptorType::Image { .. } => {
self.image_infos.next().map(|image| { self.image_infos.next().map(|image| {
pso::Descriptor::Image( pso::Descriptor::Image(
&*image.imageView, image.imageView.to_native().unwrap(),
conv::map_image_layout(image.imageLayout), conv::map_image_layout(image.imageLayout),
) )
}) })
@ -3047,27 +3068,37 @@ pub extern "C" fn gfxCreateFramebuffer(
pFramebuffer: *mut VkFramebuffer, pFramebuffer: *mut VkFramebuffer,
) -> VkResult { ) -> VkResult {
let info = unsafe { &*pCreateInfo }; let info = unsafe { &*pCreateInfo };
let attachments_slice =
unsafe { slice::from_raw_parts(info.pAttachments, info.attachmentCount as _) };
let attachments = attachments_slice
.into_iter()
.map(|attachment| &**attachment);
let extent = hal::image::Extent { let extent = hal::image::Extent {
width: info.width, width: info.width,
height: info.height, height: info.height,
depth: info.layers, depth: info.layers,
}; };
unsafe { let attachments_slice =
let framebuffer = gpu unsafe { slice::from_raw_parts(info.pAttachments, info.attachmentCount as _) };
let framebuffer = if attachments_slice.iter().any(|attachment| match **attachment {
ImageView::Native(_) => false,
ImageView::SwapchainFrame { .. } => true,
}) {
Framebuffer::Lazy {
extent,
views: attachments_slice.to_vec(),
}
} else {
let attachments = attachments_slice
.iter()
.map(|attachment| attachment.to_native().unwrap());
Framebuffer::Native(unsafe {
gpu
.device .device
.create_framebuffer(&*info.renderPass, attachments, extent) .create_framebuffer(&*info.renderPass, attachments, extent)
.unwrap(); .unwrap()
*pFramebuffer = Handle::new(framebuffer); })
} };
unsafe {
*pFramebuffer = Handle::new(framebuffer)
};
VkResult::VK_SUCCESS VkResult::VK_SUCCESS
} }
#[inline] #[inline]
@ -3077,8 +3108,11 @@ pub extern "C" fn gfxDestroyFramebuffer(
_pAllocator: *const VkAllocationCallbacks, _pAllocator: *const VkAllocationCallbacks,
) { ) {
if let Some(fbo) = framebuffer.unbox() { if let Some(fbo) = framebuffer.unbox() {
unsafe { match fbo {
gpu.device.destroy_framebuffer(fbo); Framebuffer::Native(raw) => unsafe {
gpu.device.destroy_framebuffer(raw);
},
Framebuffer::Lazy { .. } => {}
} }
} }
} }
@ -3236,7 +3270,7 @@ pub extern "C" fn gfxCreateRenderPass(
gpu.device gpu.device
.create_render_pass(attachments, subpasses, dependencies) .create_render_pass(attachments, subpasses, dependencies)
} { } {
Ok(pass) => pass, Ok(raw) => raw,
Err(oom) => return map_oom(oom), Err(oom) => return map_oom(oom),
}; };
@ -3384,11 +3418,11 @@ pub extern "C" fn gfxBeginCommandBuffer(
let info = unsafe { &*pBeginInfo }; let info = unsafe { &*pBeginInfo };
let inheritance = match unsafe { info.pInheritanceInfo.as_ref() } { let inheritance = match unsafe { info.pInheritanceInfo.as_ref() } {
Some(ii) => com::CommandBufferInheritanceInfo { Some(ii) => com::CommandBufferInheritanceInfo {
subpass: ii.renderPass.as_ref().map(|main_pass| pass::Subpass { subpass: ii.renderPass.as_ref().map(|rp| pass::Subpass {
main_pass, main_pass: &*rp,
index: ii.subpass as _, index: ii.subpass as _,
}), }),
framebuffer: ii.framebuffer.as_ref(), framebuffer: ii.framebuffer.as_ref().map(|fbo| fbo.resolve(ii.renderPass)),
occlusion_query_enable: ii.occlusionQueryEnable != VK_FALSE, occlusion_query_enable: ii.occlusionQueryEnable != VK_FALSE,
occlusion_query_flags: conv::map_query_control(ii.queryFlags), occlusion_query_flags: conv::map_query_control(ii.queryFlags),
pipeline_statistics: conv::map_pipeline_statistics(ii.pipelineStatistics), pipeline_statistics: conv::map_pipeline_statistics(ii.pipelineStatistics),
@ -3713,21 +3747,36 @@ pub extern "C" fn gfxCmdCopyImage(
regionCount: u32, regionCount: u32,
pRegions: *const VkImageCopy, pRegions: *const VkImageCopy,
) { ) {
let src = match srcImage.to_native() {
Ok(img) => img,
Err(_) => {
warn!("Unable to copy from a swapchain image!");
return;
}
};
let dst = match dstImage.to_native() {
Ok(img) => img,
Err(_) => {
warn!("Unable to copy into a swapchain image!");
return;
}
};
let regions = unsafe { slice::from_raw_parts(pRegions, regionCount as _) } let regions = unsafe { slice::from_raw_parts(pRegions, regionCount as _) }
.iter() .iter()
.map(|r| com::ImageCopy { .map(|r| com::ImageCopy {
src_subresource: srcImage.map_subresource_layers(r.srcSubresource), src_subresource: src.map_subresource_layers(r.srcSubresource),
src_offset: conv::map_offset(r.srcOffset), src_offset: conv::map_offset(r.srcOffset),
dst_subresource: dstImage.map_subresource_layers(r.dstSubresource), dst_subresource: dst.map_subresource_layers(r.dstSubresource),
dst_offset: conv::map_offset(r.dstOffset), dst_offset: conv::map_offset(r.dstOffset),
extent: conv::map_extent(r.extent), extent: conv::map_extent(r.extent),
}); });
unsafe { unsafe {
commandBuffer.copy_image( commandBuffer.copy_image(
&srcImage.raw, src.raw,
conv::map_image_layout(srcImageLayout), conv::map_image_layout(srcImageLayout),
&dstImage.raw, dst.raw,
conv::map_image_layout(dstImageLayout), conv::map_image_layout(dstImageLayout),
regions, regions,
); );
@ -3744,20 +3793,23 @@ pub extern "C" fn gfxCmdBlitImage(
pRegions: *const VkImageBlit, pRegions: *const VkImageBlit,
filter: VkFilter, filter: VkFilter,
) { ) {
let src = srcImage.to_native().unwrap();
let dst = dstImage.to_native().unwrap();
let regions = unsafe { slice::from_raw_parts(pRegions, regionCount as _) } let regions = unsafe { slice::from_raw_parts(pRegions, regionCount as _) }
.iter() .iter()
.map(|r| com::ImageBlit { .map(|r| com::ImageBlit {
src_subresource: srcImage.map_subresource_layers(r.srcSubresource), src_subresource: src.map_subresource_layers(r.srcSubresource),
src_bounds: conv::map_offset(r.srcOffsets[0])..conv::map_offset(r.srcOffsets[1]), src_bounds: conv::map_offset(r.srcOffsets[0])..conv::map_offset(r.srcOffsets[1]),
dst_subresource: dstImage.map_subresource_layers(r.dstSubresource), dst_subresource: dst.map_subresource_layers(r.dstSubresource),
dst_bounds: conv::map_offset(r.dstOffsets[0])..conv::map_offset(r.dstOffsets[1]), dst_bounds: conv::map_offset(r.dstOffsets[0])..conv::map_offset(r.dstOffsets[1]),
}); });
unsafe { unsafe {
commandBuffer.blit_image( commandBuffer.blit_image(
&srcImage.raw, src.raw,
conv::map_image_layout(srcImageLayout), conv::map_image_layout(srcImageLayout),
&dstImage.raw, dst.raw,
conv::map_image_layout(dstImageLayout), conv::map_image_layout(dstImageLayout),
conv::map_filter(filter), conv::map_filter(filter),
regions, regions,
@ -3773,13 +3825,15 @@ pub extern "C" fn gfxCmdCopyBufferToImage(
regionCount: u32, regionCount: u32,
pRegions: *const VkBufferImageCopy, pRegions: *const VkBufferImageCopy,
) { ) {
let dst = dstImage.to_native().unwrap();
let regions = unsafe { slice::from_raw_parts(pRegions, regionCount as _) } let regions = unsafe { slice::from_raw_parts(pRegions, regionCount as _) }
.iter() .iter()
.map(|r| com::BufferImageCopy { .map(|r| com::BufferImageCopy {
buffer_offset: r.bufferOffset, buffer_offset: r.bufferOffset,
buffer_width: r.bufferRowLength, buffer_width: r.bufferRowLength,
buffer_height: r.bufferImageHeight, buffer_height: r.bufferImageHeight,
image_layers: dstImage.map_subresource_layers(r.imageSubresource), image_layers: dst.map_subresource_layers(r.imageSubresource),
image_offset: conv::map_offset(r.imageOffset), image_offset: conv::map_offset(r.imageOffset),
image_extent: conv::map_extent(r.imageExtent), image_extent: conv::map_extent(r.imageExtent),
}); });
@ -3787,7 +3841,7 @@ pub extern "C" fn gfxCmdCopyBufferToImage(
unsafe { unsafe {
commandBuffer.copy_buffer_to_image( commandBuffer.copy_buffer_to_image(
&*srcBuffer, &*srcBuffer,
&dstImage.raw, dst.raw,
conv::map_image_layout(dstImageLayout), conv::map_image_layout(dstImageLayout),
regions, regions,
); );
@ -3802,20 +3856,22 @@ pub extern "C" fn gfxCmdCopyImageToBuffer(
regionCount: u32, regionCount: u32,
pRegions: *const VkBufferImageCopy, pRegions: *const VkBufferImageCopy,
) { ) {
let src = srcImage.to_native().unwrap();
let regions = unsafe { slice::from_raw_parts(pRegions, regionCount as _) } let regions = unsafe { slice::from_raw_parts(pRegions, regionCount as _) }
.iter() .iter()
.map(|r| com::BufferImageCopy { .map(|r| com::BufferImageCopy {
buffer_offset: r.bufferOffset, buffer_offset: r.bufferOffset,
buffer_width: r.bufferRowLength, buffer_width: r.bufferRowLength,
buffer_height: r.bufferImageHeight, buffer_height: r.bufferImageHeight,
image_layers: srcImage.map_subresource_layers(r.imageSubresource), image_layers: src.map_subresource_layers(r.imageSubresource),
image_offset: conv::map_offset(r.imageOffset), image_offset: conv::map_offset(r.imageOffset),
image_extent: conv::map_extent(r.imageExtent), image_extent: conv::map_extent(r.imageExtent),
}); });
unsafe { unsafe {
commandBuffer.copy_image_to_buffer( commandBuffer.copy_image_to_buffer(
&srcImage.raw, src.raw,
conv::map_image_layout(srcImageLayout), conv::map_image_layout(srcImageLayout),
&*dstBuffer, &*dstBuffer,
regions, regions,
@ -3863,13 +3919,21 @@ pub extern "C" fn gfxCmdClearColorImage(
rangeCount: u32, rangeCount: u32,
pRanges: *const VkImageSubresourceRange, pRanges: *const VkImageSubresourceRange,
) { ) {
let img = match image.to_native() {
Ok(img) => img,
Err(_) => {
warn!("Unable to clear a swapchain image!");
return;
}
};
let subresource_ranges = unsafe { slice::from_raw_parts(pRanges, rangeCount as _) } let subresource_ranges = unsafe { slice::from_raw_parts(pRanges, rangeCount as _) }
.iter() .iter()
.map(|&range| image.map_subresource_range(range)); .map(|&range| img.map_subresource_range(range));
unsafe { unsafe {
commandBuffer.clear_image( commandBuffer.clear_image(
&image.raw, img.raw,
conv::map_image_layout(imageLayout), conv::map_image_layout(imageLayout),
com::ClearValue { com::ClearValue {
color: mem::transmute(*pColor), color: mem::transmute(*pColor),
@ -3887,13 +3951,14 @@ pub extern "C" fn gfxCmdClearDepthStencilImage(
rangeCount: u32, rangeCount: u32,
pRanges: *const VkImageSubresourceRange, pRanges: *const VkImageSubresourceRange,
) { ) {
let img = image.to_native().unwrap();
let subresource_ranges = unsafe { slice::from_raw_parts(pRanges, rangeCount as _) } let subresource_ranges = unsafe { slice::from_raw_parts(pRanges, rangeCount as _) }
.iter() .iter()
.map(|&range| image.map_subresource_range(range)); .map(|&range| img.map_subresource_range(range));
unsafe { unsafe {
commandBuffer.clear_image( commandBuffer.clear_image(
&image.raw, img.raw,
conv::map_image_layout(imageLayout), conv::map_image_layout(imageLayout),
com::ClearValue { com::ClearValue {
depth_stencil: mem::transmute(*pDepthStencil), depth_stencil: mem::transmute(*pDepthStencil),
@ -3955,22 +4020,25 @@ pub extern "C" fn gfxCmdResolveImage(
regionCount: u32, regionCount: u32,
pRegions: *const VkImageResolve, pRegions: *const VkImageResolve,
) { ) {
let src = srcImage.to_native().unwrap();
let dst = dstImage.to_native().unwrap();
let regions = unsafe { slice::from_raw_parts(pRegions, regionCount as _) } let regions = unsafe { slice::from_raw_parts(pRegions, regionCount as _) }
.iter() .iter()
.cloned() .cloned()
.map(|resolve| com::ImageResolve { .map(|resolve| com::ImageResolve {
src_subresource: srcImage.map_subresource_layers(resolve.srcSubresource), src_subresource: src.map_subresource_layers(resolve.srcSubresource),
src_offset: conv::map_offset(resolve.srcOffset), src_offset: conv::map_offset(resolve.srcOffset),
dst_subresource: srcImage.map_subresource_layers(resolve.dstSubresource), dst_subresource: dst.map_subresource_layers(resolve.dstSubresource),
dst_offset: conv::map_offset(resolve.dstOffset), dst_offset: conv::map_offset(resolve.dstOffset),
extent: conv::map_extent(resolve.extent), extent: conv::map_extent(resolve.extent),
}); });
unsafe { unsafe {
commandBuffer.resolve_image( commandBuffer.resolve_image(
&srcImage.raw, src.raw,
conv::map_image_layout(srcImageLayout), conv::map_image_layout(srcImageLayout),
&dstImage.raw, dst.raw,
conv::map_image_layout(dstImageLayout), conv::map_image_layout(dstImageLayout),
regions, regions,
); );
@ -4028,18 +4096,22 @@ fn make_barriers<'a>(
size: if b.size as i32 == VK_WHOLE_SIZE { None } else { Some(b.size) }, size: if b.size as i32 == VK_WHOLE_SIZE { None } else { Some(b.size) },
}, },
}); });
let images = raw_images.iter().map(|b| memory::Barrier::Image { let images = raw_images.iter().map(|b| {
states: ( let img = b.image.to_native().unwrap();
let from = (
conv::map_image_access(b.srcAccessMask), conv::map_image_access(b.srcAccessMask),
conv::map_image_layout(b.oldLayout), conv::map_image_layout(b.oldLayout),
) );
..( let to = (
conv::map_image_access(b.dstAccessMask), conv::map_image_access(b.dstAccessMask),
conv::map_image_layout(b.newLayout), conv::map_image_layout(b.newLayout),
), );
target: &b.image.raw, memory::Barrier::Image {
range: b.image.map_subresource_range(b.subresourceRange), states: from .. to,
target: img.raw,
range: img.map_subresource_range(b.subresourceRange),
families: None, families: None,
}
}); });
globals.chain(buffers).chain(images) globals.chain(buffers).chain(images)
@ -4235,11 +4307,12 @@ pub extern "C" fn gfxCmdBeginRenderPass(
}) })
}; };
let contents = conv::map_subpass_contents(contents); let contents = conv::map_subpass_contents(contents);
let framebuffer = info.framebuffer.resolve(info.renderPass);
unsafe { unsafe {
commandBuffer.begin_render_pass( commandBuffer.begin_render_pass(
&*info.renderPass, &*info.renderPass,
&*info.framebuffer, framebuffer,
render_area, render_area,
clear_values, clear_values,
contents, contents,
@ -4322,7 +4395,8 @@ pub extern "C" fn gfxGetPhysicalDeviceSurfaceCapabilitiesKHR(
as _, as _,
currentTransform: VkSurfaceTransformFlagBitsKHR::VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR, currentTransform: VkSurfaceTransformFlagBitsKHR::VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR,
supportedCompositeAlpha: caps.composite_alpha_modes.bits(), supportedCompositeAlpha: caps.composite_alpha_modes.bits(),
supportedUsageFlags: conv::map_image_usage_from_hal(caps.usage), // Ignoring `caps.usage` since we only work with the new swapchain model here.
supportedUsageFlags: VkImageUsageFlagBits::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT as _,
}; };
unsafe { *pSurfaceCapabilities = output }; unsafe { *pSurfaceCapabilities = output };
@ -4422,6 +4496,10 @@ pub extern "C" fn gfxCreateSwapchainKHR(
VkSharingMode::VK_SHARING_MODE_EXCLUSIVE VkSharingMode::VK_SHARING_MODE_EXCLUSIVE
); // TODO ); // TODO
if info.imageUsage != VkImageUsageFlagBits::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT as _ {
warn!("Unsupported swapchain usage: {:?}", info.imageUsage);
}
let config = hal::window::SwapchainConfig { let config = hal::window::SwapchainConfig {
present_mode: conv::map_present_mode(info.presentMode), present_mode: conv::map_present_mode(info.presentMode),
composite_alpha_mode: conv::map_composite_alpha(info.compositeAlpha), composite_alpha_mode: conv::map_composite_alpha(info.compositeAlpha),
@ -4429,73 +4507,52 @@ pub extern "C" fn gfxCreateSwapchainKHR(
extent: conv::map_extent2d(info.imageExtent), extent: conv::map_extent2d(info.imageExtent),
image_count: info.minImageCount, image_count: info.minImageCount,
image_layers: 1, image_layers: 1,
image_usage: conv::map_image_usage(info.imageUsage), image_usage: hal::image::Usage::COLOR_ATTACHMENT,
}; };
#[allow(unused_mut)] // Metal branch performs mutation. match unsafe {
let (mut swapchain, backbuffers) = match unsafe { info.surface
gpu.device.create_swapchain( .as_mut()
&mut info.surface.clone(), .unwrap()
config, .configure_swapchain(&gpu.device, config)
info.oldSwapchain.as_mut().and_then(|s| s.raw.take()), //Note: no unboxing!
)
} { } {
Ok(pair) => pair, Ok(()) => {
Err(hal::window::CreationError::OutOfMemory(oom)) => return map_oom(oom),
Err(hal::window::CreationError::DeviceLost(hal::device::DeviceLost)) => {
return VkResult::VK_ERROR_DEVICE_LOST
}
Err(hal::window::CreationError::SurfaceLost(hal::device::SurfaceLost)) => {
return VkResult::VK_ERROR_SURFACE_LOST_KHR
}
Err(hal::window::CreationError::WindowInUse(hal::device::WindowInUse)) => {
return VkResult::VK_ERROR_NATIVE_WINDOW_IN_USE_KHR
}
};
#[cfg(feature = "gfx-backend-metal")]
{
use back::AcquireMode;
if let Ok(value) = env::var("GFX_METAL_ACQUIRING") {
swapchain.acquire_mode = match value.to_lowercase().as_str() {
"wait" => AcquireMode::Wait,
"oldest" => AcquireMode::Oldest,
other => panic!("unknown acquiring option: {}", other),
};
println!("GFX: acquiring override {:?}", swapchain.acquire_mode);
}
}
let images = backbuffers
.into_iter()
.map(|raw| {
Handle::new(Image {
raw,
mip_levels: 1,
array_layers: 1,
})
})
.collect();
let swapchain = Swapchain { let swapchain = Swapchain {
raw: Some(swapchain), gpu,
images, surface: info.surface,
count: info.minImageCount as u8,
current_index: 0,
active: None,
lazy_framebuffers: Vec::with_capacity(1),
}; };
unsafe { *pSwapchain = Handle::new(swapchain) }; unsafe { *pSwapchain = Handle::new(swapchain) };
VkResult::VK_SUCCESS VkResult::VK_SUCCESS
}
Err(err) => {
use hal::window::CreationError as Ce;
match err {
Ce::OutOfMemory(oom) => map_oom(oom),
Ce::DeviceLost(hal::device::DeviceLost) =>
VkResult::VK_ERROR_DEVICE_LOST,
Ce::SurfaceLost(hal::device::SurfaceLost) =>
VkResult::VK_ERROR_SURFACE_LOST_KHR,
Ce::WindowInUse(hal::device::WindowInUse) =>
VkResult::VK_ERROR_NATIVE_WINDOW_IN_USE_KHR,
}
}
}
} }
#[inline] #[inline]
pub extern "C" fn gfxDestroySwapchainKHR( pub extern "C" fn gfxDestroySwapchainKHR(
_gpu: VkDevice, gpu: VkDevice,
mut swapchain: VkSwapchainKHR, swapchain: VkSwapchainKHR,
_pAllocator: *const VkAllocationCallbacks, _pAllocator: *const VkAllocationCallbacks,
) { ) {
for image in &mut swapchain.images { if let Some(mut sc) = swapchain.unbox() {
let _ = image.unbox(); unsafe {
sc.surface.unconfigure_swapchain(&gpu.device)
};
} }
let _ = swapchain.unbox();
} }
#[inline] #[inline]
pub extern "C" fn gfxGetSwapchainImagesKHR( pub extern "C" fn gfxGetSwapchainImagesKHR(
@ -4507,18 +4564,21 @@ pub extern "C" fn gfxGetSwapchainImagesKHR(
debug_assert!(!pSwapchainImageCount.is_null()); debug_assert!(!pSwapchainImageCount.is_null());
let swapchain_image_count = unsafe { &mut *pSwapchainImageCount }; let swapchain_image_count = unsafe { &mut *pSwapchainImageCount };
let available_images = swapchain.images.len() as u32; let available_images = swapchain.count as u32;
if pSwapchainImages.is_null() { if pSwapchainImages.is_null() {
// If NULL the number of presentable images is returned. // If NULL the number of presentable images is returned.
*swapchain_image_count = available_images; *swapchain_image_count = available_images;
} else { } else {
*swapchain_image_count = available_images.min(*swapchain_image_count); *swapchain_image_count = available_images.min(*swapchain_image_count);
let swapchain_images =
unsafe { slice::from_raw_parts_mut(pSwapchainImages, *swapchain_image_count as _) };
for i in 0..*swapchain_image_count as _ { for frame in 0 .. *swapchain_image_count as u8 {
swapchain_images[i] = swapchain.images[i]; unsafe {
*pSwapchainImages.offset(frame as isize) = Handle::new(Image::SwapchainFrame {
swapchain,
frame,
});
};
} }
if *swapchain_image_count < available_images { if *swapchain_image_count < available_images {
@ -4744,36 +4804,41 @@ pub extern "C" fn gfxCreateXcbSurfaceKHR(
} }
#[inline] #[inline]
pub extern "C" fn gfxAcquireNextImageKHR( pub extern "C" fn gfxAcquireNextImageKHR(
_device: VkDevice, gpu: VkDevice,
mut swapchain: VkSwapchainKHR, mut swapchain: VkSwapchainKHR,
timeout: u64, timeout: u64,
semaphore: VkSemaphore, semaphore: VkSemaphore,
fence: VkFence, fence: VkFence,
pImageIndex: *mut u32, pImageIndex: *mut u32,
) -> VkResult { ) -> VkResult {
let raw = match swapchain.raw { if let Some(fence) = fence.as_ref() {
Some(ref mut raw) => raw, let _ = unsafe { gpu.device.reset_fences(std::iter::once(&*fence)) };
None => return VkResult::VK_ERROR_OUT_OF_DATE_KHR, }
}; if let Some(sem) = semaphore.as_mut() {
sem.is_fake = true;
use hal::device::OutOfMemory::{Device, Host}; }
match unsafe { raw.acquire_image(timeout, semaphore.as_ref(), fence.as_ref()) } { if let Some(_old_frame) = swapchain.active.take() {
Ok(frame) => { warn!("Swapchain frame {} was not presented!", swapchain.current_index);
unsafe { }
*pImageIndex = frame.0; match unsafe { swapchain.surface.acquire_image(timeout) } {
Ok((frame, suboptimal)) => {
swapchain.current_index = (swapchain.current_index + 1) % swapchain.count;
swapchain.active = Some(frame);
unsafe {
*pImageIndex = swapchain.current_index as u32;
}
match suboptimal {
Some(_) => VkResult::VK_SUBOPTIMAL_KHR,
None => VkResult::VK_SUCCESS,
} }
VkResult::VK_SUCCESS
} }
Err(hal::window::AcquireError::NotReady) => VkResult::VK_NOT_READY, Err(hal::window::AcquireError::NotReady) => VkResult::VK_NOT_READY,
Err(hal::window::AcquireError::OutOfDate) => VkResult::VK_ERROR_OUT_OF_DATE_KHR, Err(hal::window::AcquireError::OutOfDate) => VkResult::VK_ERROR_OUT_OF_DATE_KHR,
Err(hal::window::AcquireError::SurfaceLost(_)) => VkResult::VK_ERROR_SURFACE_LOST_KHR, Err(hal::window::AcquireError::SurfaceLost(_)) => VkResult::VK_ERROR_SURFACE_LOST_KHR,
Err(hal::window::AcquireError::DeviceLost(_)) => VkResult::VK_ERROR_DEVICE_LOST, Err(hal::window::AcquireError::DeviceLost(_)) => VkResult::VK_ERROR_DEVICE_LOST,
Err(hal::window::AcquireError::Timeout) => VkResult::VK_TIMEOUT, Err(hal::window::AcquireError::Timeout) => VkResult::VK_TIMEOUT,
Err(hal::window::AcquireError::OutOfMemory(Device)) => { Err(hal::window::AcquireError::OutOfMemory(oom)) => map_oom(oom),
VkResult::VK_ERROR_OUT_OF_DEVICE_MEMORY
}
Err(hal::window::AcquireError::OutOfMemory(Host)) => VkResult::VK_ERROR_OUT_OF_HOST_MEMORY,
} }
} }
#[inline] #[inline]
@ -4787,21 +4852,34 @@ pub extern "C" fn gfxQueuePresentKHR(
unsafe { slice::from_raw_parts(info.pSwapchains, info.swapchainCount as _) }; unsafe { slice::from_raw_parts(info.pSwapchains, info.swapchainCount as _) };
let index_slice = let index_slice =
unsafe { slice::from_raw_parts(info.pImageIndices, info.swapchainCount as _) }; unsafe { slice::from_raw_parts(info.pImageIndices, info.swapchainCount as _) };
let swapchains = swapchain_slice
.into_iter()
.zip(index_slice)
.map(|(swapchain, index)| (swapchain.raw.as_ref().unwrap(), *index));
let wait_semaphores = unsafe { let wait_semaphores = unsafe {
slice::from_raw_parts(info.pWaitSemaphores, info.waitSemaphoreCount as _) slice::from_raw_parts(info.pWaitSemaphores, info.waitSemaphoreCount as _)
.into_iter()
.map(|semaphore| &**semaphore)
}; };
if wait_semaphores.len() > 1 {
match unsafe { queue.present(swapchains, wait_semaphores) } { warn!("Only one semaphore is supported for present, {} are given", wait_semaphores.len());
Ok(_) => VkResult::VK_SUCCESS,
Err(_) => VkResult::VK_ERROR_SURFACE_LOST_KHR,
} }
for (swapchain, index) in swapchain_slice.iter().zip(index_slice) {
let sc = swapchain.as_mut().unwrap();
let frame = sc.active.take().expect("Frame was not acquired properly!");
if sc.current_index == *index as u8 {
let sem = wait_semaphores.first().map(|s| &s.raw);
if let Err(_) = unsafe {
queue.present_surface(&mut *sc.surface, frame, sem)
} {
return VkResult::VK_ERROR_SURFACE_LOST_KHR;
}
} else {
warn!("Swapchain frame {} is stale, can't be presented.", *index);
}
for framebuffer in sc.lazy_framebuffers.drain(..) {
unsafe {
sc.gpu.device.destroy_framebuffer(framebuffer)
};
}
}
VkResult::VK_SUCCESS
} }
#[inline] #[inline]

View file

@ -63,13 +63,13 @@ pub type VkSampler = Handle<<B as hal::Backend>::Sampler>;
pub type VkBufferView = Handle<<B as hal::Backend>::BufferView>; pub type VkBufferView = Handle<<B as hal::Backend>::BufferView>;
pub type VkShaderModule = Handle<<B as hal::Backend>::ShaderModule>; pub type VkShaderModule = Handle<<B as hal::Backend>::ShaderModule>;
pub type VkImage = Handle<Image<B>>; pub type VkImage = Handle<Image<B>>;
pub type VkImageView = Handle<<B as hal::Backend>::ImageView>; pub type VkImageView = Handle<ImageView>;
pub type VkBuffer = Handle<<B as hal::Backend>::Buffer>; pub type VkBuffer = Handle<<B as hal::Backend>::Buffer>;
pub type VkSemaphore = Handle<<B as hal::Backend>::Semaphore>; pub type VkSemaphore = Handle<Semaphore<B>>;
pub type VkEvent = Handle<<B as hal::Backend>::Event>; pub type VkEvent = Handle<<B as hal::Backend>::Event>;
pub type VkFence = Handle<<B as hal::Backend>::Fence>; pub type VkFence = Handle<<B as hal::Backend>::Fence>;
pub type VkRenderPass = Handle<<B as hal::Backend>::RenderPass>; pub type VkRenderPass = Handle<<B as hal::Backend>::RenderPass>;
pub type VkFramebuffer = Handle<<B as hal::Backend>::Framebuffer>; pub type VkFramebuffer = Handle<Framebuffer>;
pub type VkPipeline = Handle<Pipeline<B>>; pub type VkPipeline = Handle<Pipeline<B>>;
pub type VkPipelineCache = Handle<<B as hal::Backend>::PipelineCache>; pub type VkPipelineCache = Handle<<B as hal::Backend>::PipelineCache>;
pub type VkQueryPool = Handle<<B as hal::Backend>::QueryPool>; pub type VkQueryPool = Handle<<B as hal::Backend>::QueryPool>;
@ -103,13 +103,38 @@ pub enum Pipeline<B: hal::Backend> {
Compute(B::ComputePipeline), Compute(B::ComputePipeline),
} }
pub struct Image<B: hal::Backend> { pub enum Image<B: hal::Backend> {
Native {
raw: B::Image, raw: B::Image,
mip_levels: u32, mip_levels: u32,
array_layers: u32, array_layers: u32,
},
SwapchainFrame {
swapchain: VkSwapchainKHR,
frame: u8,
},
}
#[derive(Debug)]
struct UnexpectedSwapchainImage;
impl<B: hal::Backend> Image<B> {
fn to_native(&self) -> Result<NativeImage<B>, UnexpectedSwapchainImage> {
match *self {
Image::Native { ref raw, mip_levels, array_layers } =>
Ok(NativeImage { raw, mip_levels, array_layers }),
Image::SwapchainFrame { .. } => Err(UnexpectedSwapchainImage),
}
}
}
struct NativeImage<'a, B: hal::Backend> {
raw: &'a B::Image,
mip_levels: u32,
array_layers: u32,
} }
impl<B: hal::Backend> Image<B> { impl<B: hal::Backend> NativeImage<'_, B> {
fn map_subresource(&self, subresource: VkImageSubresource) -> hal::image::Subresource { fn map_subresource(&self, subresource: VkImageSubresource) -> hal::image::Subresource {
hal::image::Subresource { hal::image::Subresource {
aspects: conv::map_aspect(subresource.aspectMask), aspects: conv::map_aspect(subresource.aspectMask),
@ -156,6 +181,76 @@ impl<B: hal::Backend> Image<B> {
} }
} }
pub enum ImageView {
Native(<B as hal::Backend>::ImageView),
SwapchainFrame {
swapchain: VkSwapchainKHR,
frame: u8,
},
}
impl ImageView {
fn to_native(&self) -> Result<&<B as hal::Backend>::ImageView, UnexpectedSwapchainImage> {
match *self {
ImageView::Native(ref raw) => Ok(raw),
ImageView::SwapchainFrame {..} => Err(UnexpectedSwapchainImage),
}
}
}
pub enum Framebuffer {
Native(<B as hal::Backend>::Framebuffer),
Lazy {
extent: hal::image::Extent,
views: Vec<VkImageView>,
},
}
impl Framebuffer {
fn resolve(&self, render_pass: VkRenderPass) -> &<B as hal::Backend>::Framebuffer {
let mut sc = None;
match *self {
Framebuffer::Native(ref fbo) => fbo,
Framebuffer::Lazy { extent, ref views } => {
for view in views {
if let Some(&mut ImageView::SwapchainFrame { ref swapchain, .. }) = view.as_mut() {
assert!(sc.is_none());
sc = Some(swapchain.as_mut().unwrap());
}
}
let attachments = views
.iter()
.map(|view| match **view {
ImageView::Native(ref raw) => raw,
ImageView::SwapchainFrame { ref swapchain, frame } => {
use std::borrow::Borrow;
debug_assert_eq!(frame, swapchain.current_index);
swapchain.active
.as_ref()
.expect("Swapchain frame isn't acquired")
.borrow()
},
});
let sc = sc.expect("No swapchain frames detected");
let gpu = sc.gpu;
sc.lazy_framebuffers.push(unsafe {
use hal::device::Device;
gpu.device
.create_framebuffer(&*render_pass, attachments, extent)
.unwrap()
});
sc.lazy_framebuffers.last().unwrap()
}
}
}
}
pub struct Semaphore<B: hal::Backend> {
raw: B::Semaphore,
is_fake: bool,
}
pub struct CommandPool<B: hal::Backend> { pub struct CommandPool<B: hal::Backend> {
pool: B::CommandPool, pool: B::CommandPool,
buffers: Vec<VkCommandBuffer>, buffers: Vec<VkCommandBuffer>,
@ -164,12 +259,17 @@ pub struct CommandPool<B: hal::Backend> {
//NOTE: all *KHR types have to be pure `Handle` things for compatibility with //NOTE: all *KHR types have to be pure `Handle` things for compatibility with
//`VK_DEFINE_NON_DISPATCHABLE_HANDLE` used in `vulkan.h` //`VK_DEFINE_NON_DISPATCHABLE_HANDLE` used in `vulkan.h`
pub type VkSurfaceKHR = Handle<<B as hal::Backend>::Surface>; pub type VkSurfaceKHR = Handle<<B as hal::Backend>::Surface>;
pub type VkSwapchainKHR = Handle<Swapchain>; pub type VkSwapchainKHR = Handle<Swapchain<B>>;
pub struct Swapchain { pub struct Swapchain<B: hal::Backend> {
// this can become None if it was used as the "old_swapchain" gpu: VkDevice,
raw: Option<<B as hal::Backend>::Swapchain>, surface: VkSurfaceKHR,
images: Vec<VkImage>, count: u8,
current_index: u8,
active: Option<<B::Surface as hal::window::PresentationSurface<B>>::SwapchainImage>,
// This is totally unsafe: if multiple threads would start recording render passes into
// that uses this swapchain, we'd have a race condition.
lazy_framebuffers: Vec<<B as hal::Backend>::Framebuffer>,
} }
/* automatically generated by rust-bindgen */ /* automatically generated by rust-bindgen */