mirror of
https://github.com/italicsjenga/portability.git
synced 2024-11-26 17:01:31 +11:00
Port to the new swapchain model
This commit is contained in:
parent
0a7426f847
commit
bef4517f83
18
Cargo.lock
generated
18
Cargo.lock
generated
|
@ -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"
|
||||||
|
|
|
@ -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()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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]
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
Loading…
Reference in a new issue