mirror of
https://github.com/vulkano-rs/vulkano.git
synced 2024-11-25 16:25:31 +00:00
ValidationError-ify Surface
and Swapchain
(#2236)
* Add `RequiresAllOf`, automatically enable required extensions and features * Add more missing backticks and backslashes to error messages * Use updated VUIDs that require `acceleration_structure` * ValidationError-ify `Surface` and `Swapchain` * Update vulkano/src/lib.rs Co-authored-by: marc0246 <40955683+marc0246@users.noreply.github.com> * Update vulkano/src/lib.rs Co-authored-by: marc0246 <40955683+marc0246@users.noreply.github.com> * Don't draw if the window has zero size --------- Co-authored-by: marc0246 <40955683+marc0246@users.noreply.github.com>
This commit is contained in:
parent
2d6ff1061c
commit
da09477d01
@ -85,7 +85,7 @@ use vulkano::{
|
|||||||
sampler::{Sampler, SamplerCreateInfo},
|
sampler::{Sampler, SamplerCreateInfo},
|
||||||
swapchain::{
|
swapchain::{
|
||||||
acquire_next_image, AcquireError, Surface, Swapchain, SwapchainCreateInfo,
|
acquire_next_image, AcquireError, Surface, Swapchain, SwapchainCreateInfo,
|
||||||
SwapchainCreationError, SwapchainPresentInfo,
|
SwapchainPresentInfo,
|
||||||
},
|
},
|
||||||
sync::{self, FlushError, GpuFuture},
|
sync::{self, FlushError, GpuFuture},
|
||||||
VulkanLibrary,
|
VulkanLibrary,
|
||||||
@ -545,21 +545,19 @@ fn main() {
|
|||||||
channel.send(()).unwrap();
|
channel.send(()).unwrap();
|
||||||
}
|
}
|
||||||
Event::RedrawEventsCleared => {
|
Event::RedrawEventsCleared => {
|
||||||
let dimensions = window.inner_size();
|
let image_extent: [u32; 2] = window.inner_size().into();
|
||||||
if dimensions.width == 0 || dimensions.height == 0 {
|
|
||||||
|
if image_extent.contains(&0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if recreate_swapchain {
|
if recreate_swapchain {
|
||||||
let (new_swapchain, new_images) =
|
let (new_swapchain, new_images) = swapchain
|
||||||
match swapchain.recreate(SwapchainCreateInfo {
|
.recreate(SwapchainCreateInfo {
|
||||||
image_extent: dimensions.into(),
|
image_extent,
|
||||||
..swapchain.create_info()
|
..swapchain.create_info()
|
||||||
}) {
|
})
|
||||||
Ok(r) => r,
|
.expect("failed to recreate swapchain");
|
||||||
Err(SwapchainCreationError::ImageExtentNotSupported { .. }) => return,
|
|
||||||
Err(e) => panic!("failed to recreate swapchain: {e}"),
|
|
||||||
};
|
|
||||||
|
|
||||||
swapchain = new_swapchain;
|
swapchain = new_swapchain;
|
||||||
framebuffers = window_size_dependent_setup(
|
framebuffers = window_size_dependent_setup(
|
||||||
|
@ -45,7 +45,7 @@ use vulkano::{
|
|||||||
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
|
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
|
||||||
swapchain::{
|
swapchain::{
|
||||||
acquire_next_image, AcquireError, Surface, Swapchain, SwapchainCreateInfo,
|
acquire_next_image, AcquireError, Surface, Swapchain, SwapchainCreateInfo,
|
||||||
SwapchainCreationError, SwapchainPresentInfo,
|
SwapchainPresentInfo,
|
||||||
},
|
},
|
||||||
sync::{self, FlushError, GpuFuture},
|
sync::{self, FlushError, GpuFuture},
|
||||||
VulkanLibrary,
|
VulkanLibrary,
|
||||||
@ -292,23 +292,21 @@ fn main() {
|
|||||||
recreate_swapchain = true;
|
recreate_swapchain = true;
|
||||||
}
|
}
|
||||||
Event::RedrawEventsCleared => {
|
Event::RedrawEventsCleared => {
|
||||||
let dimensions = window.inner_size();
|
let image_extent: [u32; 2] = window.inner_size().into();
|
||||||
if dimensions.width == 0 || dimensions.height == 0 {
|
|
||||||
|
if image_extent.contains(&0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
previous_frame_end.as_mut().unwrap().cleanup_finished();
|
previous_frame_end.as_mut().unwrap().cleanup_finished();
|
||||||
|
|
||||||
if recreate_swapchain {
|
if recreate_swapchain {
|
||||||
let (new_swapchain, new_images) =
|
let (new_swapchain, new_images) = swapchain
|
||||||
match swapchain.recreate(SwapchainCreateInfo {
|
.recreate(SwapchainCreateInfo {
|
||||||
image_extent: dimensions.into(),
|
image_extent,
|
||||||
..swapchain.create_info()
|
..swapchain.create_info()
|
||||||
}) {
|
})
|
||||||
Ok(r) => r,
|
.expect("failed to recreate swapchain");
|
||||||
Err(SwapchainCreationError::ImageExtentNotSupported { .. }) => return,
|
|
||||||
Err(e) => panic!("failed to recreate swapchain: {e}"),
|
|
||||||
};
|
|
||||||
|
|
||||||
swapchain = new_swapchain;
|
swapchain = new_swapchain;
|
||||||
framebuffers = window_size_dependent_setup(
|
framebuffers = window_size_dependent_setup(
|
||||||
|
@ -22,7 +22,7 @@ use vulkano::{
|
|||||||
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass},
|
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass},
|
||||||
swapchain::{
|
swapchain::{
|
||||||
acquire_next_image, AcquireError, Surface, Swapchain, SwapchainCreateInfo,
|
acquire_next_image, AcquireError, Surface, Swapchain, SwapchainCreateInfo,
|
||||||
SwapchainCreationError, SwapchainPresentInfo,
|
SwapchainPresentInfo,
|
||||||
},
|
},
|
||||||
sync::{self, FlushError, GpuFuture},
|
sync::{self, FlushError, GpuFuture},
|
||||||
VulkanLibrary,
|
VulkanLibrary,
|
||||||
@ -175,22 +175,21 @@ fn main() {
|
|||||||
recreate_swapchain = true;
|
recreate_swapchain = true;
|
||||||
}
|
}
|
||||||
Event::RedrawEventsCleared => {
|
Event::RedrawEventsCleared => {
|
||||||
let dimensions = window.inner_size();
|
let image_extent: [u32; 2] = window.inner_size().into();
|
||||||
if dimensions.width == 0 || dimensions.height == 0 {
|
|
||||||
|
if image_extent.contains(&0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
previous_frame_end.as_mut().unwrap().cleanup_finished();
|
previous_frame_end.as_mut().unwrap().cleanup_finished();
|
||||||
|
|
||||||
if recreate_swapchain {
|
if recreate_swapchain {
|
||||||
let (new_swapchain, new_images) = match swapchain.recreate(SwapchainCreateInfo {
|
let (new_swapchain, new_images) = swapchain
|
||||||
image_extent: dimensions.into(),
|
.recreate(SwapchainCreateInfo {
|
||||||
..swapchain.create_info()
|
image_extent,
|
||||||
}) {
|
..swapchain.create_info()
|
||||||
Ok(r) => r,
|
})
|
||||||
Err(SwapchainCreationError::ImageExtentNotSupported { .. }) => return,
|
.expect("failed to recreate swapchain");
|
||||||
Err(e) => panic!("failed to recreate swapchain: {e}"),
|
|
||||||
};
|
|
||||||
|
|
||||||
swapchain = new_swapchain;
|
swapchain = new_swapchain;
|
||||||
width = swapchain.image_extent()[0];
|
width = swapchain.image_extent()[0];
|
||||||
|
@ -42,7 +42,7 @@ use vulkano::{
|
|||||||
memory::allocator::StandardMemoryAllocator,
|
memory::allocator::StandardMemoryAllocator,
|
||||||
swapchain::{
|
swapchain::{
|
||||||
acquire_next_image, AcquireError, Surface, Swapchain, SwapchainCreateInfo,
|
acquire_next_image, AcquireError, Surface, Swapchain, SwapchainCreateInfo,
|
||||||
SwapchainCreationError, SwapchainPresentInfo,
|
SwapchainPresentInfo,
|
||||||
},
|
},
|
||||||
sync::{self, FlushError, GpuFuture},
|
sync::{self, FlushError, GpuFuture},
|
||||||
VulkanLibrary,
|
VulkanLibrary,
|
||||||
@ -199,22 +199,21 @@ fn main() {
|
|||||||
recreate_swapchain = true;
|
recreate_swapchain = true;
|
||||||
}
|
}
|
||||||
Event::RedrawEventsCleared => {
|
Event::RedrawEventsCleared => {
|
||||||
let dimensions = window.inner_size();
|
let image_extent: [u32; 2] = window.inner_size().into();
|
||||||
if dimensions.width == 0 || dimensions.height == 0 {
|
|
||||||
|
if image_extent.contains(&0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
previous_frame_end.as_mut().unwrap().cleanup_finished();
|
previous_frame_end.as_mut().unwrap().cleanup_finished();
|
||||||
|
|
||||||
if recreate_swapchain {
|
if recreate_swapchain {
|
||||||
let (new_swapchain, new_images) = match swapchain.recreate(SwapchainCreateInfo {
|
let (new_swapchain, new_images) = swapchain
|
||||||
image_extent: dimensions.into(),
|
.recreate(SwapchainCreateInfo {
|
||||||
..swapchain.create_info()
|
image_extent,
|
||||||
}) {
|
..swapchain.create_info()
|
||||||
Ok(r) => r,
|
})
|
||||||
Err(SwapchainCreationError::ImageExtentNotSupported { .. }) => return,
|
.expect("failed to recreate swapchain");
|
||||||
Err(e) => panic!("failed to recreate swapchain: {e}"),
|
|
||||||
};
|
|
||||||
let new_images = new_images
|
let new_images = new_images
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|image| ImageView::new_default(image).unwrap())
|
.map(|image| ImageView::new_default(image).unwrap())
|
||||||
|
@ -50,10 +50,7 @@ mod linux {
|
|||||||
},
|
},
|
||||||
render_pass::{Framebuffer, RenderPass, Subpass},
|
render_pass::{Framebuffer, RenderPass, Subpass},
|
||||||
sampler::{Filter, Sampler, SamplerAddressMode, SamplerCreateInfo},
|
sampler::{Filter, Sampler, SamplerAddressMode, SamplerCreateInfo},
|
||||||
swapchain::{
|
swapchain::{AcquireError, Surface, Swapchain, SwapchainCreateInfo, SwapchainPresentInfo},
|
||||||
AcquireError, Surface, Swapchain, SwapchainCreateInfo, SwapchainCreationError,
|
|
||||||
SwapchainPresentInfo,
|
|
||||||
},
|
|
||||||
sync::{
|
sync::{
|
||||||
now,
|
now,
|
||||||
semaphore::{
|
semaphore::{
|
||||||
@ -287,20 +284,21 @@ mod linux {
|
|||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
let image_extent: [u32; 2] = window.inner_size().into();
|
||||||
|
|
||||||
|
if image_extent.contains(&0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
previous_frame_end.as_mut().unwrap().cleanup_finished();
|
previous_frame_end.as_mut().unwrap().cleanup_finished();
|
||||||
|
|
||||||
if recreate_swapchain {
|
if recreate_swapchain {
|
||||||
let (new_swapchain, new_images) =
|
let (new_swapchain, new_images) = swapchain
|
||||||
match swapchain.recreate(SwapchainCreateInfo {
|
.recreate(SwapchainCreateInfo {
|
||||||
image_extent: window.inner_size().into(),
|
image_extent,
|
||||||
..swapchain.create_info()
|
..swapchain.create_info()
|
||||||
}) {
|
})
|
||||||
Ok(r) => r,
|
.expect("failed to recreate swapchain");
|
||||||
Err(SwapchainCreationError::ImageExtentNotSupported { .. }) => {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
Err(e) => panic!("failed to recreate swapchain: {e}"),
|
|
||||||
};
|
|
||||||
|
|
||||||
swapchain = new_swapchain;
|
swapchain = new_swapchain;
|
||||||
framebuffers = window_size_dependent_setup(
|
framebuffers = window_size_dependent_setup(
|
||||||
|
@ -48,7 +48,7 @@ use vulkano::{
|
|||||||
sampler::{Filter, Sampler, SamplerAddressMode, SamplerCreateInfo},
|
sampler::{Filter, Sampler, SamplerAddressMode, SamplerCreateInfo},
|
||||||
swapchain::{
|
swapchain::{
|
||||||
acquire_next_image, AcquireError, Surface, Swapchain, SwapchainCreateInfo,
|
acquire_next_image, AcquireError, Surface, Swapchain, SwapchainCreateInfo,
|
||||||
SwapchainCreationError, SwapchainPresentInfo,
|
SwapchainPresentInfo,
|
||||||
},
|
},
|
||||||
sync::{self, FlushError, GpuFuture},
|
sync::{self, FlushError, GpuFuture},
|
||||||
VulkanLibrary,
|
VulkanLibrary,
|
||||||
@ -421,22 +421,21 @@ fn main() {
|
|||||||
recreate_swapchain = true;
|
recreate_swapchain = true;
|
||||||
}
|
}
|
||||||
Event::RedrawEventsCleared => {
|
Event::RedrawEventsCleared => {
|
||||||
let dimensions = window.inner_size();
|
let image_extent: [u32; 2] = window.inner_size().into();
|
||||||
if dimensions.width == 0 || dimensions.height == 0 {
|
|
||||||
|
if image_extent.contains(&0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
previous_frame_end.as_mut().unwrap().cleanup_finished();
|
previous_frame_end.as_mut().unwrap().cleanup_finished();
|
||||||
|
|
||||||
if recreate_swapchain {
|
if recreate_swapchain {
|
||||||
let (new_swapchain, new_images) = match swapchain.recreate(SwapchainCreateInfo {
|
let (new_swapchain, new_images) = swapchain
|
||||||
image_extent: dimensions.into(),
|
.recreate(SwapchainCreateInfo {
|
||||||
..swapchain.create_info()
|
image_extent,
|
||||||
}) {
|
..swapchain.create_info()
|
||||||
Ok(r) => r,
|
})
|
||||||
Err(SwapchainCreationError::ImageExtentNotSupported { .. }) => return,
|
.expect("failed to recreate swapchain");
|
||||||
Err(e) => panic!("failed to recreate swapchain: {e}"),
|
|
||||||
};
|
|
||||||
|
|
||||||
swapchain = new_swapchain;
|
swapchain = new_swapchain;
|
||||||
framebuffers =
|
framebuffers =
|
||||||
|
@ -46,7 +46,7 @@ use vulkano::{
|
|||||||
sampler::{Filter, Sampler, SamplerAddressMode, SamplerCreateInfo},
|
sampler::{Filter, Sampler, SamplerAddressMode, SamplerCreateInfo},
|
||||||
swapchain::{
|
swapchain::{
|
||||||
acquire_next_image, AcquireError, Surface, Swapchain, SwapchainCreateInfo,
|
acquire_next_image, AcquireError, Surface, Swapchain, SwapchainCreateInfo,
|
||||||
SwapchainCreationError, SwapchainPresentInfo,
|
SwapchainPresentInfo,
|
||||||
},
|
},
|
||||||
sync::{self, FlushError, GpuFuture},
|
sync::{self, FlushError, GpuFuture},
|
||||||
VulkanLibrary,
|
VulkanLibrary,
|
||||||
@ -347,22 +347,21 @@ fn main() {
|
|||||||
recreate_swapchain = true;
|
recreate_swapchain = true;
|
||||||
}
|
}
|
||||||
Event::RedrawEventsCleared => {
|
Event::RedrawEventsCleared => {
|
||||||
let dimensions = window.inner_size();
|
let image_extent: [u32; 2] = window.inner_size().into();
|
||||||
if dimensions.width == 0 || dimensions.height == 0 {
|
|
||||||
|
if image_extent.contains(&0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
previous_frame_end.as_mut().unwrap().cleanup_finished();
|
previous_frame_end.as_mut().unwrap().cleanup_finished();
|
||||||
|
|
||||||
if recreate_swapchain {
|
if recreate_swapchain {
|
||||||
let (new_swapchain, new_images) = match swapchain.recreate(SwapchainCreateInfo {
|
let (new_swapchain, new_images) = swapchain
|
||||||
image_extent: dimensions.into(),
|
.recreate(SwapchainCreateInfo {
|
||||||
..swapchain.create_info()
|
image_extent,
|
||||||
}) {
|
..swapchain.create_info()
|
||||||
Ok(r) => r,
|
})
|
||||||
Err(SwapchainCreationError::ImageExtentNotSupported { .. }) => return,
|
.expect("failed to recreate swapchain");
|
||||||
Err(e) => panic!("failed to recreate swapchain: {e}"),
|
|
||||||
};
|
|
||||||
|
|
||||||
swapchain = new_swapchain;
|
swapchain = new_swapchain;
|
||||||
framebuffers =
|
framebuffers =
|
||||||
|
@ -55,7 +55,7 @@ use vulkano::{
|
|||||||
sampler::{Filter, Sampler, SamplerAddressMode, SamplerCreateInfo},
|
sampler::{Filter, Sampler, SamplerAddressMode, SamplerCreateInfo},
|
||||||
swapchain::{
|
swapchain::{
|
||||||
acquire_next_image, AcquireError, Surface, Swapchain, SwapchainCreateInfo,
|
acquire_next_image, AcquireError, Surface, Swapchain, SwapchainCreateInfo,
|
||||||
SwapchainCreationError, SwapchainPresentInfo,
|
SwapchainPresentInfo,
|
||||||
},
|
},
|
||||||
sync::{self, FlushError, GpuFuture},
|
sync::{self, FlushError, GpuFuture},
|
||||||
VulkanLibrary,
|
VulkanLibrary,
|
||||||
@ -368,22 +368,21 @@ fn main() {
|
|||||||
recreate_swapchain = true;
|
recreate_swapchain = true;
|
||||||
}
|
}
|
||||||
Event::RedrawEventsCleared => {
|
Event::RedrawEventsCleared => {
|
||||||
let dimensions = window.inner_size();
|
let image_extent: [u32; 2] = window.inner_size().into();
|
||||||
if dimensions.width == 0 || dimensions.height == 0 {
|
|
||||||
|
if image_extent.contains(&0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
previous_frame_end.as_mut().unwrap().cleanup_finished();
|
previous_frame_end.as_mut().unwrap().cleanup_finished();
|
||||||
|
|
||||||
if recreate_swapchain {
|
if recreate_swapchain {
|
||||||
let (new_swapchain, new_images) = match swapchain.recreate(SwapchainCreateInfo {
|
let (new_swapchain, new_images) = swapchain
|
||||||
image_extent: dimensions.into(),
|
.recreate(SwapchainCreateInfo {
|
||||||
..swapchain.create_info()
|
image_extent,
|
||||||
}) {
|
..swapchain.create_info()
|
||||||
Ok(r) => r,
|
})
|
||||||
Err(SwapchainCreationError::ImageExtentNotSupported { .. }) => return,
|
.expect("failed to recreate swapchain");
|
||||||
Err(e) => panic!("failed to recreate swapchain: {e}"),
|
|
||||||
};
|
|
||||||
|
|
||||||
swapchain = new_swapchain;
|
swapchain = new_swapchain;
|
||||||
framebuffers =
|
framebuffers =
|
||||||
|
@ -62,7 +62,7 @@ use vulkano::{
|
|||||||
single_pass_renderpass,
|
single_pass_renderpass,
|
||||||
swapchain::{
|
swapchain::{
|
||||||
acquire_next_image, AcquireError, Surface, Swapchain, SwapchainCreateInfo,
|
acquire_next_image, AcquireError, Surface, Swapchain, SwapchainCreateInfo,
|
||||||
SwapchainCreationError, SwapchainPresentInfo,
|
SwapchainPresentInfo,
|
||||||
},
|
},
|
||||||
sync::{self, FlushError, GpuFuture},
|
sync::{self, FlushError, GpuFuture},
|
||||||
VulkanLibrary,
|
VulkanLibrary,
|
||||||
@ -384,23 +384,21 @@ fn main() {
|
|||||||
recreate_swapchain = true;
|
recreate_swapchain = true;
|
||||||
}
|
}
|
||||||
Event::RedrawEventsCleared => {
|
Event::RedrawEventsCleared => {
|
||||||
let dimensions = window.inner_size();
|
let image_extent: [u32; 2] = window.inner_size().into();
|
||||||
if dimensions.width == 0 || dimensions.height == 0 {
|
|
||||||
|
if image_extent.contains(&0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
previous_frame_end.as_mut().unwrap().cleanup_finished();
|
previous_frame_end.as_mut().unwrap().cleanup_finished();
|
||||||
|
|
||||||
if recreate_swapchain {
|
if recreate_swapchain {
|
||||||
let (new_swapchain, new_images) =
|
let (new_swapchain, new_images) = swapchain
|
||||||
match swapchain.recreate(SwapchainCreateInfo {
|
.recreate(SwapchainCreateInfo {
|
||||||
image_extent: dimensions.into(),
|
image_extent,
|
||||||
..swapchain.create_info()
|
..swapchain.create_info()
|
||||||
}) {
|
})
|
||||||
Ok(r) => r,
|
.expect("failed to recreate swapchain");
|
||||||
Err(SwapchainCreationError::ImageExtentNotSupported { .. }) => return,
|
|
||||||
Err(e) => panic!("failed to recreate swapchain: {e}"),
|
|
||||||
};
|
|
||||||
|
|
||||||
swapchain = new_swapchain;
|
swapchain = new_swapchain;
|
||||||
framebuffers = window_size_dependent_setup(
|
framebuffers = window_size_dependent_setup(
|
||||||
|
@ -43,7 +43,7 @@ use vulkano::{
|
|||||||
single_pass_renderpass,
|
single_pass_renderpass,
|
||||||
swapchain::{
|
swapchain::{
|
||||||
acquire_next_image, AcquireError, Surface, Swapchain, SwapchainCreateInfo,
|
acquire_next_image, AcquireError, Surface, Swapchain, SwapchainCreateInfo,
|
||||||
SwapchainCreationError, SwapchainPresentInfo,
|
SwapchainPresentInfo,
|
||||||
},
|
},
|
||||||
sync::{self, FlushError, GpuFuture},
|
sync::{self, FlushError, GpuFuture},
|
||||||
VulkanLibrary,
|
VulkanLibrary,
|
||||||
@ -364,23 +364,21 @@ fn main() {
|
|||||||
recreate_swapchain = true;
|
recreate_swapchain = true;
|
||||||
}
|
}
|
||||||
Event::RedrawEventsCleared => {
|
Event::RedrawEventsCleared => {
|
||||||
let dimensions = window.inner_size();
|
let image_extent: [u32; 2] = window.inner_size().into();
|
||||||
if dimensions.width == 0 || dimensions.height == 0 {
|
|
||||||
|
if image_extent.contains(&0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
previous_frame_end.as_mut().unwrap().cleanup_finished();
|
previous_frame_end.as_mut().unwrap().cleanup_finished();
|
||||||
|
|
||||||
if recreate_swapchain {
|
if recreate_swapchain {
|
||||||
let (new_swapchain, new_images) =
|
let (new_swapchain, new_images) = swapchain
|
||||||
match swapchain.recreate(SwapchainCreateInfo {
|
.recreate(SwapchainCreateInfo {
|
||||||
image_extent: dimensions.into(),
|
image_extent,
|
||||||
..swapchain.create_info()
|
..swapchain.create_info()
|
||||||
}) {
|
})
|
||||||
Ok(r) => r,
|
.expect("failed to recreate swapchain");
|
||||||
Err(SwapchainCreationError::ImageExtentNotSupported { .. }) => return,
|
|
||||||
Err(e) => panic!("failed to recreate swapchain: {e}"),
|
|
||||||
};
|
|
||||||
|
|
||||||
swapchain = new_swapchain;
|
swapchain = new_swapchain;
|
||||||
framebuffers = window_size_dependent_setup(
|
framebuffers = window_size_dependent_setup(
|
||||||
|
@ -46,7 +46,7 @@ use vulkano::{
|
|||||||
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
|
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
|
||||||
swapchain::{
|
swapchain::{
|
||||||
acquire_next_image, AcquireError, Surface, Swapchain, SwapchainCreateInfo,
|
acquire_next_image, AcquireError, Surface, Swapchain, SwapchainCreateInfo,
|
||||||
SwapchainCreationError, SwapchainPresentInfo,
|
SwapchainPresentInfo,
|
||||||
},
|
},
|
||||||
sync::{self, FlushError, GpuFuture},
|
sync::{self, FlushError, GpuFuture},
|
||||||
VulkanLibrary,
|
VulkanLibrary,
|
||||||
@ -415,22 +415,21 @@ fn main() {
|
|||||||
previous_frame_end,
|
previous_frame_end,
|
||||||
} = window_surfaces.get_mut(&window_id).unwrap();
|
} = window_surfaces.get_mut(&window_id).unwrap();
|
||||||
|
|
||||||
let dimensions = window.inner_size();
|
let image_extent: [u32; 2] = window.inner_size().into();
|
||||||
if dimensions.width == 0 || dimensions.height == 0 {
|
|
||||||
|
if image_extent.contains(&0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
previous_frame_end.as_mut().unwrap().cleanup_finished();
|
previous_frame_end.as_mut().unwrap().cleanup_finished();
|
||||||
|
|
||||||
if *recreate_swapchain {
|
if *recreate_swapchain {
|
||||||
let (new_swapchain, new_images) = match swapchain.recreate(SwapchainCreateInfo {
|
let (new_swapchain, new_images) = swapchain
|
||||||
image_extent: dimensions.into(),
|
.recreate(SwapchainCreateInfo {
|
||||||
..swapchain.create_info()
|
image_extent,
|
||||||
}) {
|
..swapchain.create_info()
|
||||||
Ok(r) => r,
|
})
|
||||||
Err(SwapchainCreationError::ImageExtentNotSupported { .. }) => return,
|
.expect("failed to recreate swapchain");
|
||||||
Err(e) => panic!("failed to recreate swapchain: {e}"),
|
|
||||||
};
|
|
||||||
|
|
||||||
*swapchain = new_swapchain;
|
*swapchain = new_swapchain;
|
||||||
*framebuffers =
|
*framebuffers =
|
||||||
|
@ -44,7 +44,7 @@ use vulkano::{
|
|||||||
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
|
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
|
||||||
swapchain::{
|
swapchain::{
|
||||||
acquire_next_image, AcquireError, Surface, Swapchain, SwapchainCreateInfo,
|
acquire_next_image, AcquireError, Surface, Swapchain, SwapchainCreateInfo,
|
||||||
SwapchainCreationError, SwapchainPresentInfo,
|
SwapchainPresentInfo,
|
||||||
},
|
},
|
||||||
sync::{self, FlushError, GpuFuture},
|
sync::{self, FlushError, GpuFuture},
|
||||||
VulkanLibrary,
|
VulkanLibrary,
|
||||||
@ -382,22 +382,21 @@ fn main() {
|
|||||||
recreate_swapchain = true;
|
recreate_swapchain = true;
|
||||||
}
|
}
|
||||||
Event::RedrawEventsCleared => {
|
Event::RedrawEventsCleared => {
|
||||||
let dimensions = window.inner_size();
|
let image_extent: [u32; 2] = window.inner_size().into();
|
||||||
if dimensions.width == 0 || dimensions.height == 0 {
|
|
||||||
|
if image_extent.contains(&0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
previous_frame_end.as_mut().unwrap().cleanup_finished();
|
previous_frame_end.as_mut().unwrap().cleanup_finished();
|
||||||
|
|
||||||
if recreate_swapchain {
|
if recreate_swapchain {
|
||||||
let (new_swapchain, new_images) = match swapchain.recreate(SwapchainCreateInfo {
|
let (new_swapchain, new_images) = swapchain
|
||||||
image_extent: dimensions.into(),
|
.recreate(SwapchainCreateInfo {
|
||||||
..swapchain.create_info()
|
image_extent,
|
||||||
}) {
|
..swapchain.create_info()
|
||||||
Ok(r) => r,
|
})
|
||||||
Err(SwapchainCreationError::ImageExtentNotSupported { .. }) => return,
|
.expect("failed to recreate swapchain");
|
||||||
Err(e) => panic!("failed to recreate swapchain: {e}"),
|
|
||||||
};
|
|
||||||
|
|
||||||
swapchain = new_swapchain;
|
swapchain = new_swapchain;
|
||||||
framebuffers = window_size_dependent_setup(
|
framebuffers = window_size_dependent_setup(
|
||||||
|
@ -44,7 +44,7 @@ use vulkano::{
|
|||||||
sampler::{Filter, Sampler, SamplerAddressMode, SamplerCreateInfo},
|
sampler::{Filter, Sampler, SamplerAddressMode, SamplerCreateInfo},
|
||||||
swapchain::{
|
swapchain::{
|
||||||
acquire_next_image, AcquireError, Surface, Swapchain, SwapchainCreateInfo,
|
acquire_next_image, AcquireError, Surface, Swapchain, SwapchainCreateInfo,
|
||||||
SwapchainCreationError, SwapchainPresentInfo,
|
SwapchainPresentInfo,
|
||||||
},
|
},
|
||||||
sync::{self, FlushError, GpuFuture},
|
sync::{self, FlushError, GpuFuture},
|
||||||
VulkanLibrary,
|
VulkanLibrary,
|
||||||
@ -341,22 +341,21 @@ fn main() {
|
|||||||
recreate_swapchain = true;
|
recreate_swapchain = true;
|
||||||
}
|
}
|
||||||
Event::RedrawEventsCleared => {
|
Event::RedrawEventsCleared => {
|
||||||
let dimensions = window.inner_size();
|
let image_extent: [u32; 2] = window.inner_size().into();
|
||||||
if dimensions.width == 0 || dimensions.height == 0 {
|
|
||||||
|
if image_extent.contains(&0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
previous_frame_end.as_mut().unwrap().cleanup_finished();
|
previous_frame_end.as_mut().unwrap().cleanup_finished();
|
||||||
|
|
||||||
if recreate_swapchain {
|
if recreate_swapchain {
|
||||||
let (new_swapchain, new_images) = match swapchain.recreate(SwapchainCreateInfo {
|
let (new_swapchain, new_images) = swapchain
|
||||||
image_extent: dimensions.into(),
|
.recreate(SwapchainCreateInfo {
|
||||||
..swapchain.create_info()
|
image_extent,
|
||||||
}) {
|
..swapchain.create_info()
|
||||||
Ok(r) => r,
|
})
|
||||||
Err(SwapchainCreationError::ImageExtentNotSupported { .. }) => return,
|
.expect("failed to recreate swapchain");
|
||||||
Err(e) => panic!("failed to recreate swapchain: {e}"),
|
|
||||||
};
|
|
||||||
|
|
||||||
swapchain = new_swapchain;
|
swapchain = new_swapchain;
|
||||||
framebuffers =
|
framebuffers =
|
||||||
|
@ -52,7 +52,7 @@ use vulkano::{
|
|||||||
shader::ShaderModule,
|
shader::ShaderModule,
|
||||||
swapchain::{
|
swapchain::{
|
||||||
acquire_next_image, AcquireError, Surface, Swapchain, SwapchainCreateInfo,
|
acquire_next_image, AcquireError, Surface, Swapchain, SwapchainCreateInfo,
|
||||||
SwapchainCreationError, SwapchainPresentInfo,
|
SwapchainPresentInfo,
|
||||||
},
|
},
|
||||||
sync::{self, FlushError, GpuFuture},
|
sync::{self, FlushError, GpuFuture},
|
||||||
VulkanLibrary,
|
VulkanLibrary,
|
||||||
@ -312,22 +312,21 @@ fn main() {
|
|||||||
recreate_swapchain = true;
|
recreate_swapchain = true;
|
||||||
}
|
}
|
||||||
Event::RedrawEventsCleared => {
|
Event::RedrawEventsCleared => {
|
||||||
let dimensions = window.inner_size();
|
let image_extent: [u32; 2] = window.inner_size().into();
|
||||||
if dimensions.width == 0 || dimensions.height == 0 {
|
|
||||||
|
if image_extent.contains(&0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
previous_frame_end.as_mut().unwrap().cleanup_finished();
|
previous_frame_end.as_mut().unwrap().cleanup_finished();
|
||||||
|
|
||||||
if recreate_swapchain {
|
if recreate_swapchain {
|
||||||
let (new_swapchain, new_images) = match swapchain.recreate(SwapchainCreateInfo {
|
let (new_swapchain, new_images) = swapchain
|
||||||
image_extent: dimensions.into(),
|
.recreate(SwapchainCreateInfo {
|
||||||
..swapchain.create_info()
|
image_extent,
|
||||||
}) {
|
..swapchain.create_info()
|
||||||
Ok(r) => r,
|
})
|
||||||
Err(SwapchainCreationError::ImageExtentNotSupported { .. }) => return,
|
.expect("failed to recreate swapchain");
|
||||||
Err(e) => panic!("failed to recreate swapchain: {e}"),
|
|
||||||
};
|
|
||||||
|
|
||||||
swapchain = new_swapchain;
|
swapchain = new_swapchain;
|
||||||
framebuffers =
|
framebuffers =
|
||||||
|
@ -47,7 +47,7 @@ use vulkano::{
|
|||||||
sampler::{Filter, Sampler, SamplerAddressMode, SamplerCreateInfo},
|
sampler::{Filter, Sampler, SamplerAddressMode, SamplerCreateInfo},
|
||||||
swapchain::{
|
swapchain::{
|
||||||
acquire_next_image, AcquireError, Surface, Swapchain, SwapchainCreateInfo,
|
acquire_next_image, AcquireError, Surface, Swapchain, SwapchainCreateInfo,
|
||||||
SwapchainCreationError, SwapchainPresentInfo,
|
SwapchainPresentInfo,
|
||||||
},
|
},
|
||||||
sync::{self, FlushError, GpuFuture},
|
sync::{self, FlushError, GpuFuture},
|
||||||
VulkanLibrary,
|
VulkanLibrary,
|
||||||
@ -455,22 +455,21 @@ fn main() {
|
|||||||
recreate_swapchain = true;
|
recreate_swapchain = true;
|
||||||
}
|
}
|
||||||
Event::RedrawEventsCleared => {
|
Event::RedrawEventsCleared => {
|
||||||
let dimensions = window.inner_size();
|
let image_extent: [u32; 2] = window.inner_size().into();
|
||||||
if dimensions.width == 0 || dimensions.height == 0 {
|
|
||||||
|
if image_extent.contains(&0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
previous_frame_end.as_mut().unwrap().cleanup_finished();
|
previous_frame_end.as_mut().unwrap().cleanup_finished();
|
||||||
|
|
||||||
if recreate_swapchain {
|
if recreate_swapchain {
|
||||||
let (new_swapchain, new_images) = match swapchain.recreate(SwapchainCreateInfo {
|
let (new_swapchain, new_images) = swapchain
|
||||||
image_extent: dimensions.into(),
|
.recreate(SwapchainCreateInfo {
|
||||||
..swapchain.create_info()
|
image_extent,
|
||||||
}) {
|
..swapchain.create_info()
|
||||||
Ok(r) => r,
|
})
|
||||||
Err(SwapchainCreationError::ImageExtentNotSupported { .. }) => return,
|
.expect("failed to recreate swapchain");
|
||||||
Err(e) => panic!("failed to recreate swapchain: {e}"),
|
|
||||||
};
|
|
||||||
|
|
||||||
swapchain = new_swapchain;
|
swapchain = new_swapchain;
|
||||||
framebuffers =
|
framebuffers =
|
||||||
|
@ -524,8 +524,9 @@ fn main() {
|
|||||||
*control_flow = ControlFlow::Exit;
|
*control_flow = ControlFlow::Exit;
|
||||||
}
|
}
|
||||||
Event::RedrawEventsCleared => {
|
Event::RedrawEventsCleared => {
|
||||||
let dimensions = window.inner_size();
|
let image_extent: [u32; 2] = window.inner_size().into();
|
||||||
if dimensions.width == 0 || dimensions.height == 0 {
|
|
||||||
|
if image_extent.contains(&0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ use vulkano::{
|
|||||||
shader::EntryPoint,
|
shader::EntryPoint,
|
||||||
swapchain::{
|
swapchain::{
|
||||||
acquire_next_image, AcquireError, Surface, Swapchain, SwapchainCreateInfo,
|
acquire_next_image, AcquireError, Surface, Swapchain, SwapchainCreateInfo,
|
||||||
SwapchainCreationError, SwapchainPresentInfo,
|
SwapchainPresentInfo,
|
||||||
},
|
},
|
||||||
sync::{self, FlushError, GpuFuture},
|
sync::{self, FlushError, GpuFuture},
|
||||||
VulkanLibrary,
|
VulkanLibrary,
|
||||||
@ -276,23 +276,21 @@ fn main() {
|
|||||||
recreate_swapchain = true;
|
recreate_swapchain = true;
|
||||||
}
|
}
|
||||||
Event::RedrawEventsCleared => {
|
Event::RedrawEventsCleared => {
|
||||||
let dimensions = window.inner_size();
|
let image_extent: [u32; 2] = window.inner_size().into();
|
||||||
if dimensions.width == 0 || dimensions.height == 0 {
|
|
||||||
|
if image_extent.contains(&0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
previous_frame_end.as_mut().unwrap().cleanup_finished();
|
previous_frame_end.as_mut().unwrap().cleanup_finished();
|
||||||
|
|
||||||
if recreate_swapchain {
|
if recreate_swapchain {
|
||||||
let (new_swapchain, new_images) =
|
let (new_swapchain, new_images) = swapchain
|
||||||
match swapchain.recreate(SwapchainCreateInfo {
|
.recreate(SwapchainCreateInfo {
|
||||||
image_extent: dimensions.into(),
|
image_extent,
|
||||||
..swapchain.create_info()
|
..swapchain.create_info()
|
||||||
}) {
|
})
|
||||||
Ok(r) => r,
|
.expect("failed to recreate swapchain");
|
||||||
Err(SwapchainCreationError::ImageExtentNotSupported { .. }) => return,
|
|
||||||
Err(e) => panic!("failed to recreate swapchain: {e}"),
|
|
||||||
};
|
|
||||||
|
|
||||||
swapchain = new_swapchain;
|
swapchain = new_swapchain;
|
||||||
let (new_pipeline, new_framebuffers) = window_size_dependent_setup(
|
let (new_pipeline, new_framebuffers) = window_size_dependent_setup(
|
||||||
|
@ -52,7 +52,7 @@ use vulkano::{
|
|||||||
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
|
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
|
||||||
swapchain::{
|
swapchain::{
|
||||||
acquire_next_image, AcquireError, Surface, Swapchain, SwapchainCreateInfo,
|
acquire_next_image, AcquireError, Surface, Swapchain, SwapchainCreateInfo,
|
||||||
SwapchainCreationError, SwapchainPresentInfo,
|
SwapchainPresentInfo,
|
||||||
},
|
},
|
||||||
sync::{self, FlushError, GpuFuture},
|
sync::{self, FlushError, GpuFuture},
|
||||||
VulkanLibrary,
|
VulkanLibrary,
|
||||||
@ -424,22 +424,21 @@ fn main() {
|
|||||||
recreate_swapchain = true;
|
recreate_swapchain = true;
|
||||||
}
|
}
|
||||||
Event::RedrawEventsCleared => {
|
Event::RedrawEventsCleared => {
|
||||||
let dimensions = window.inner_size();
|
let image_extent: [u32; 2] = window.inner_size().into();
|
||||||
if dimensions.width == 0 || dimensions.height == 0 {
|
|
||||||
|
if image_extent.contains(&0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
previous_frame_end.as_mut().unwrap().cleanup_finished();
|
previous_frame_end.as_mut().unwrap().cleanup_finished();
|
||||||
|
|
||||||
if recreate_swapchain {
|
if recreate_swapchain {
|
||||||
let (new_swapchain, new_images) = match swapchain.recreate(SwapchainCreateInfo {
|
let (new_swapchain, new_images) = swapchain
|
||||||
image_extent: dimensions.into(),
|
.recreate(SwapchainCreateInfo {
|
||||||
..swapchain.create_info()
|
image_extent,
|
||||||
}) {
|
..swapchain.create_info()
|
||||||
Ok(r) => r,
|
})
|
||||||
Err(SwapchainCreationError::ImageExtentNotSupported { .. }) => return,
|
.expect("failed to recreate swapchain");
|
||||||
Err(e) => panic!("failed to recreate swapchain: {e}"),
|
|
||||||
};
|
|
||||||
|
|
||||||
swapchain = new_swapchain;
|
swapchain = new_swapchain;
|
||||||
framebuffers =
|
framebuffers =
|
||||||
|
@ -46,7 +46,7 @@ use vulkano::{
|
|||||||
sampler::{Sampler, SamplerCreateInfo},
|
sampler::{Sampler, SamplerCreateInfo},
|
||||||
swapchain::{
|
swapchain::{
|
||||||
acquire_next_image, AcquireError, Surface, Swapchain, SwapchainCreateInfo,
|
acquire_next_image, AcquireError, Surface, Swapchain, SwapchainCreateInfo,
|
||||||
SwapchainCreationError, SwapchainPresentInfo,
|
SwapchainPresentInfo,
|
||||||
},
|
},
|
||||||
sync::{self, FlushError, GpuFuture},
|
sync::{self, FlushError, GpuFuture},
|
||||||
VulkanLibrary,
|
VulkanLibrary,
|
||||||
@ -352,22 +352,21 @@ fn main() {
|
|||||||
recreate_swapchain = true;
|
recreate_swapchain = true;
|
||||||
}
|
}
|
||||||
Event::RedrawEventsCleared => {
|
Event::RedrawEventsCleared => {
|
||||||
let dimensions = window.inner_size();
|
let image_extent: [u32; 2] = window.inner_size().into();
|
||||||
if dimensions.width == 0 || dimensions.height == 0 {
|
|
||||||
|
if image_extent.contains(&0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
previous_frame_end.as_mut().unwrap().cleanup_finished();
|
previous_frame_end.as_mut().unwrap().cleanup_finished();
|
||||||
|
|
||||||
if recreate_swapchain {
|
if recreate_swapchain {
|
||||||
let (new_swapchain, new_images) = match swapchain.recreate(SwapchainCreateInfo {
|
let (new_swapchain, new_images) = swapchain
|
||||||
image_extent: dimensions.into(),
|
.recreate(SwapchainCreateInfo {
|
||||||
..swapchain.create_info()
|
image_extent,
|
||||||
}) {
|
..swapchain.create_info()
|
||||||
Ok(r) => r,
|
})
|
||||||
Err(SwapchainCreationError::ImageExtentNotSupported { .. }) => return,
|
.expect("failed to recreate swapchain");
|
||||||
Err(e) => panic!("failed to recreate swapchain: {e}"),
|
|
||||||
};
|
|
||||||
|
|
||||||
swapchain = new_swapchain;
|
swapchain = new_swapchain;
|
||||||
framebuffers =
|
framebuffers =
|
||||||
|
@ -52,7 +52,7 @@ use vulkano::{
|
|||||||
render_pass::{AttachmentLoadOp, AttachmentStoreOp},
|
render_pass::{AttachmentLoadOp, AttachmentStoreOp},
|
||||||
swapchain::{
|
swapchain::{
|
||||||
acquire_next_image, AcquireError, Surface, Swapchain, SwapchainCreateInfo,
|
acquire_next_image, AcquireError, Surface, Swapchain, SwapchainCreateInfo,
|
||||||
SwapchainCreationError, SwapchainPresentInfo,
|
SwapchainPresentInfo,
|
||||||
},
|
},
|
||||||
sync::{self, FlushError, GpuFuture},
|
sync::{self, FlushError, GpuFuture},
|
||||||
Version, VulkanLibrary,
|
Version, VulkanLibrary,
|
||||||
@ -527,8 +527,9 @@ fn main() {
|
|||||||
Event::RedrawEventsCleared => {
|
Event::RedrawEventsCleared => {
|
||||||
// Do not draw the frame when the screen dimensions are zero. On Windows, this can
|
// Do not draw the frame when the screen dimensions are zero. On Windows, this can
|
||||||
// occur when minimizing the application.
|
// occur when minimizing the application.
|
||||||
let dimensions = window.inner_size();
|
let image_extent: [u32; 2] = window.inner_size().into();
|
||||||
if dimensions.width == 0 || dimensions.height == 0 {
|
|
||||||
|
if image_extent.contains(&0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -542,18 +543,12 @@ fn main() {
|
|||||||
// window size. In this example that includes the swapchain, the framebuffers and
|
// window size. In this example that includes the swapchain, the framebuffers and
|
||||||
// the dynamic state viewport.
|
// the dynamic state viewport.
|
||||||
if recreate_swapchain {
|
if recreate_swapchain {
|
||||||
let (new_swapchain, new_images) =
|
let (new_swapchain, new_images) = swapchain
|
||||||
match swapchain.recreate(SwapchainCreateInfo {
|
.recreate(SwapchainCreateInfo {
|
||||||
image_extent: dimensions.into(),
|
image_extent,
|
||||||
..swapchain.create_info()
|
..swapchain.create_info()
|
||||||
}) {
|
})
|
||||||
Ok(r) => r,
|
.expect("failed to recreate swapchain");
|
||||||
// This error tends to happen when the user is manually resizing the
|
|
||||||
// window. Simply restarting the loop is the easiest way to fix this
|
|
||||||
// issue.
|
|
||||||
Err(SwapchainCreationError::ImageExtentNotSupported { .. }) => return,
|
|
||||||
Err(e) => panic!("failed to recreate swapchain: {e}"),
|
|
||||||
};
|
|
||||||
|
|
||||||
swapchain = new_swapchain;
|
swapchain = new_swapchain;
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ use vulkano::{
|
|||||||
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
|
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
|
||||||
swapchain::{
|
swapchain::{
|
||||||
acquire_next_image, AcquireError, Surface, Swapchain, SwapchainCreateInfo,
|
acquire_next_image, AcquireError, Surface, Swapchain, SwapchainCreateInfo,
|
||||||
SwapchainCreationError, SwapchainPresentInfo,
|
SwapchainPresentInfo,
|
||||||
},
|
},
|
||||||
sync::{self, FlushError, GpuFuture},
|
sync::{self, FlushError, GpuFuture},
|
||||||
VulkanLibrary,
|
VulkanLibrary,
|
||||||
@ -522,8 +522,9 @@ fn main() {
|
|||||||
Event::RedrawEventsCleared => {
|
Event::RedrawEventsCleared => {
|
||||||
// Do not draw the frame when the screen dimensions are zero. On Windows, this can
|
// Do not draw the frame when the screen dimensions are zero. On Windows, this can
|
||||||
// occur when minimizing the application.
|
// occur when minimizing the application.
|
||||||
let dimensions = window.inner_size();
|
let image_extent: [u32; 2] = window.inner_size().into();
|
||||||
if dimensions.width == 0 || dimensions.height == 0 {
|
|
||||||
|
if image_extent.contains(&0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -539,18 +540,12 @@ fn main() {
|
|||||||
if recreate_swapchain {
|
if recreate_swapchain {
|
||||||
// Use the new dimensions of the window.
|
// Use the new dimensions of the window.
|
||||||
|
|
||||||
let (new_swapchain, new_images) =
|
let (new_swapchain, new_images) = swapchain
|
||||||
match swapchain.recreate(SwapchainCreateInfo {
|
.recreate(SwapchainCreateInfo {
|
||||||
image_extent: dimensions.into(),
|
image_extent,
|
||||||
..swapchain.create_info()
|
..swapchain.create_info()
|
||||||
}) {
|
})
|
||||||
Ok(r) => r,
|
.expect("failed to recreate swapchain");
|
||||||
// This error tends to happen when the user is manually resizing the
|
|
||||||
// window. Simply restarting the loop is the easiest way to fix this
|
|
||||||
// issue.
|
|
||||||
Err(SwapchainCreationError::ImageExtentNotSupported { .. }) => return,
|
|
||||||
Err(e) => panic!("failed to recreate swapchain: {e}"),
|
|
||||||
};
|
|
||||||
|
|
||||||
swapchain = new_swapchain;
|
swapchain = new_swapchain;
|
||||||
|
|
||||||
|
@ -18,8 +18,7 @@ use vulkano::{
|
|||||||
},
|
},
|
||||||
memory::allocator::StandardMemoryAllocator,
|
memory::allocator::StandardMemoryAllocator,
|
||||||
swapchain::{
|
swapchain::{
|
||||||
self, AcquireError, Surface, Swapchain, SwapchainCreateInfo, SwapchainCreationError,
|
self, AcquireError, Surface, Swapchain, SwapchainCreateInfo, SwapchainPresentInfo,
|
||||||
SwapchainPresentInfo,
|
|
||||||
},
|
},
|
||||||
sync::{self, FlushError, GpuFuture},
|
sync::{self, FlushError, GpuFuture},
|
||||||
};
|
};
|
||||||
@ -337,17 +336,21 @@ impl VulkanoWindowRenderer {
|
|||||||
|
|
||||||
/// Recreates swapchain images and image views which follow the window size.
|
/// Recreates swapchain images and image views which follow the window size.
|
||||||
fn recreate_swapchain_and_views(&mut self) {
|
fn recreate_swapchain_and_views(&mut self) {
|
||||||
let dimensions: [u32; 2] = self.window().inner_size().into();
|
let image_extent: [u32; 2] = self.window().inner_size().into();
|
||||||
let (new_swapchain, new_images) = match self.swapchain.recreate(SwapchainCreateInfo {
|
|
||||||
image_extent: dimensions,
|
if image_extent.contains(&0) {
|
||||||
// Use present mode from current state
|
return;
|
||||||
present_mode: self.present_mode,
|
}
|
||||||
..self.swapchain.create_info()
|
|
||||||
}) {
|
let (new_swapchain, new_images) = self
|
||||||
Ok(r) => r,
|
.swapchain
|
||||||
Err(SwapchainCreationError::ImageExtentNotSupported { .. }) => return,
|
.recreate(SwapchainCreateInfo {
|
||||||
Err(e) => panic!("failed to recreate swapchain: {e}"),
|
image_extent,
|
||||||
};
|
// Use present mode from current state
|
||||||
|
present_mode: self.present_mode,
|
||||||
|
..self.swapchain.create_info()
|
||||||
|
})
|
||||||
|
.expect("failed to recreate swapchain");
|
||||||
|
|
||||||
self.swapchain = new_swapchain;
|
self.swapchain = new_swapchain;
|
||||||
let new_images = new_images
|
let new_images = new_images
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
`Surface::from_window` instead"
|
`Surface::from_window` instead"
|
||||||
)]
|
)]
|
||||||
#![doc(html_logo_url = "https://raw.githubusercontent.com/vulkano-rs/vulkano/master/logo.png")]
|
#![doc(html_logo_url = "https://raw.githubusercontent.com/vulkano-rs/vulkano/master/logo.png")]
|
||||||
#![allow(clippy::missing_safety_doc)]
|
#![allow(clippy::missing_safety_doc, clippy::result_large_err)]
|
||||||
#![warn(rust_2018_idioms, rust_2021_compatibility)]
|
#![warn(rust_2018_idioms, rust_2021_compatibility)]
|
||||||
|
|
||||||
#[cfg(feature = "raw-window-handle")]
|
#[cfg(feature = "raw-window-handle")]
|
||||||
|
@ -6,17 +6,14 @@ use raw_window_handle::{
|
|||||||
HasRawDisplayHandle, HasRawWindowHandle, RawDisplayHandle, RawWindowHandle,
|
HasRawDisplayHandle, HasRawWindowHandle, RawDisplayHandle, RawWindowHandle,
|
||||||
};
|
};
|
||||||
use std::{any::Any, sync::Arc};
|
use std::{any::Any, sync::Arc};
|
||||||
use vulkano::{
|
use vulkano::{instance::Instance, swapchain::Surface, VulkanError};
|
||||||
instance::Instance,
|
|
||||||
swapchain::{Surface, SurfaceCreationError},
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Creates a Vulkan surface from a generic window which implements `HasRawWindowHandle` and thus
|
/// Creates a Vulkan surface from a generic window which implements `HasRawWindowHandle` and thus
|
||||||
/// can reveal the OS-dependent handle.
|
/// can reveal the OS-dependent handle.
|
||||||
pub fn create_surface_from_handle(
|
pub fn create_surface_from_handle(
|
||||||
window: Arc<impl Any + Send + Sync + HasRawWindowHandle + HasRawDisplayHandle>,
|
window: Arc<impl Any + Send + Sync + HasRawWindowHandle + HasRawDisplayHandle>,
|
||||||
instance: Arc<Instance>,
|
instance: Arc<Instance>,
|
||||||
) -> Result<Arc<Surface>, SurfaceCreationError> {
|
) -> Result<Arc<Surface>, VulkanError> {
|
||||||
unsafe {
|
unsafe {
|
||||||
match window.raw_window_handle() {
|
match window.raw_window_handle() {
|
||||||
RawWindowHandle::AndroidNdk(h) => {
|
RawWindowHandle::AndroidNdk(h) => {
|
||||||
@ -85,7 +82,7 @@ pub fn create_surface_from_handle(
|
|||||||
pub unsafe fn create_surface_from_handle_ref(
|
pub unsafe fn create_surface_from_handle_ref(
|
||||||
window: &(impl HasRawWindowHandle + HasRawDisplayHandle),
|
window: &(impl HasRawWindowHandle + HasRawDisplayHandle),
|
||||||
instance: Arc<Instance>,
|
instance: Arc<Instance>,
|
||||||
) -> Result<Arc<Surface>, SurfaceCreationError> {
|
) -> Result<Arc<Surface>, VulkanError> {
|
||||||
unsafe {
|
unsafe {
|
||||||
match window.raw_window_handle() {
|
match window.raw_window_handle() {
|
||||||
RawWindowHandle::AndroidNdk(h) => {
|
RawWindowHandle::AndroidNdk(h) => {
|
||||||
|
@ -5,8 +5,8 @@ use std::{
|
|||||||
};
|
};
|
||||||
use vulkano::{
|
use vulkano::{
|
||||||
instance::{Instance, InstanceExtensions},
|
instance::{Instance, InstanceExtensions},
|
||||||
swapchain::{Surface, SurfaceCreationError},
|
swapchain::Surface,
|
||||||
VulkanLibrary,
|
VulkanError, VulkanLibrary,
|
||||||
};
|
};
|
||||||
use winit::{
|
use winit::{
|
||||||
error::OsError as WindowCreationError,
|
error::OsError as WindowCreationError,
|
||||||
@ -37,7 +37,7 @@ pub fn required_extensions(library: &VulkanLibrary) -> InstanceExtensions {
|
|||||||
pub fn create_surface_from_winit(
|
pub fn create_surface_from_winit(
|
||||||
window: Arc<Window>,
|
window: Arc<Window>,
|
||||||
instance: Arc<Instance>,
|
instance: Arc<Instance>,
|
||||||
) -> Result<Arc<Surface>, SurfaceCreationError> {
|
) -> Result<Arc<Surface>, VulkanError> {
|
||||||
unsafe { winit_to_surface(instance, window) }
|
unsafe { winit_to_surface(instance, window) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,7 +65,8 @@ impl<E> VkSurfaceBuild<E> for WindowBuilder {
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum CreationError {
|
pub enum CreationError {
|
||||||
/// Error when creating the surface.
|
/// Error when creating the surface.
|
||||||
SurfaceCreationError(SurfaceCreationError),
|
VulkanError(VulkanError),
|
||||||
|
|
||||||
/// Error when creating the window.
|
/// Error when creating the window.
|
||||||
WindowCreationError(WindowCreationError),
|
WindowCreationError(WindowCreationError),
|
||||||
}
|
}
|
||||||
@ -73,7 +74,7 @@ pub enum CreationError {
|
|||||||
impl Error for CreationError {
|
impl Error for CreationError {
|
||||||
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
||||||
match self {
|
match self {
|
||||||
CreationError::SurfaceCreationError(err) => Some(err),
|
CreationError::VulkanError(err) => Some(err),
|
||||||
CreationError::WindowCreationError(err) => Some(err),
|
CreationError::WindowCreationError(err) => Some(err),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -85,16 +86,16 @@ impl Display for CreationError {
|
|||||||
f,
|
f,
|
||||||
"{}",
|
"{}",
|
||||||
match self {
|
match self {
|
||||||
CreationError::SurfaceCreationError(_) => "error while creating the surface",
|
CreationError::VulkanError(_) => "error while creating the surface",
|
||||||
CreationError::WindowCreationError(_) => "error while creating the window",
|
CreationError::WindowCreationError(_) => "error while creating the window",
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<SurfaceCreationError> for CreationError {
|
impl From<VulkanError> for CreationError {
|
||||||
fn from(err: SurfaceCreationError) -> CreationError {
|
fn from(err: VulkanError) -> CreationError {
|
||||||
CreationError::SurfaceCreationError(err)
|
CreationError::VulkanError(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,7 +109,7 @@ impl From<WindowCreationError> for CreationError {
|
|||||||
unsafe fn winit_to_surface(
|
unsafe fn winit_to_surface(
|
||||||
instance: Arc<Instance>,
|
instance: Arc<Instance>,
|
||||||
window: Arc<Window>,
|
window: Arc<Window>,
|
||||||
) -> Result<Arc<Surface>, SurfaceCreationError> {
|
) -> Result<Arc<Surface>, VulkanError> {
|
||||||
use raw_window_handle::HasRawWindowHandle;
|
use raw_window_handle::HasRawWindowHandle;
|
||||||
use raw_window_handle::RawWindowHandle::AndroidNdk;
|
use raw_window_handle::RawWindowHandle::AndroidNdk;
|
||||||
if let AndroidNdk(handle) = window.raw_window_handle() {
|
if let AndroidNdk(handle) = window.raw_window_handle() {
|
||||||
@ -127,7 +128,7 @@ unsafe fn winit_to_surface(
|
|||||||
unsafe fn winit_to_surface(
|
unsafe fn winit_to_surface(
|
||||||
instance: Arc<Instance>,
|
instance: Arc<Instance>,
|
||||||
window: Arc<Window>,
|
window: Arc<Window>,
|
||||||
) -> Result<Arc<Surface>, SurfaceCreationError> {
|
) -> Result<Arc<Surface>, VulkanError> {
|
||||||
use winit::platform::{wayland::WindowExtWayland, x11::WindowExtX11};
|
use winit::platform::{wayland::WindowExtWayland, x11::WindowExtX11};
|
||||||
|
|
||||||
match (window.wayland_display(), window.wayland_surface()) {
|
match (window.wayland_display(), window.wayland_surface()) {
|
||||||
@ -193,7 +194,7 @@ pub(crate) unsafe fn get_metal_layer_macos(view: *mut std::ffi::c_void) -> *mut
|
|||||||
unsafe fn winit_to_surface(
|
unsafe fn winit_to_surface(
|
||||||
instance: Arc<Instance>,
|
instance: Arc<Instance>,
|
||||||
window: Arc<Window>,
|
window: Arc<Window>,
|
||||||
) -> Result<Arc<Surface>, SurfaceCreationError> {
|
) -> Result<Arc<Surface>, VulkanError> {
|
||||||
use winit::platform::macos::WindowExtMacOS;
|
use winit::platform::macos::WindowExtMacOS;
|
||||||
let layer = get_metal_layer_macos(window.ns_view());
|
let layer = get_metal_layer_macos(window.ns_view());
|
||||||
Surface::from_mac_os(instance, layer as *const (), Some(window))
|
Surface::from_mac_os(instance, layer as *const (), Some(window))
|
||||||
@ -224,7 +225,7 @@ pub(crate) unsafe fn get_metal_layer_ios(view: *mut std::ffi::c_void) -> IOSMeta
|
|||||||
unsafe fn winit_to_surface(
|
unsafe fn winit_to_surface(
|
||||||
instance: Arc<Instance>,
|
instance: Arc<Instance>,
|
||||||
window: Arc<Window>,
|
window: Arc<Window>,
|
||||||
) -> Result<Arc<Surface>, SurfaceCreationError> {
|
) -> Result<Arc<Surface>, VulkanError> {
|
||||||
use winit::platform::ios::WindowExtIOS;
|
use winit::platform::ios::WindowExtIOS;
|
||||||
let layer = get_metal_layer_ios(window.ui_view());
|
let layer = get_metal_layer_ios(window.ui_view());
|
||||||
Surface::from_ios(instance, layer, Some(window))
|
Surface::from_ios(instance, layer, Some(window))
|
||||||
@ -234,7 +235,7 @@ unsafe fn winit_to_surface(
|
|||||||
unsafe fn winit_to_surface(
|
unsafe fn winit_to_surface(
|
||||||
instance: Arc<Instance>,
|
instance: Arc<Instance>,
|
||||||
window: Arc<Window>,
|
window: Arc<Window>,
|
||||||
) -> Result<Arc<Surface>, SurfaceCreationError> {
|
) -> Result<Arc<Surface>, VulkanError> {
|
||||||
use winit::platform::windows::WindowExtWindows;
|
use winit::platform::windows::WindowExtWindows;
|
||||||
|
|
||||||
Surface::from_win32(
|
Surface::from_win32(
|
||||||
|
@ -1387,11 +1387,31 @@ impl PhysicalDevice {
|
|||||||
.map_err(|err| err.add_context("surface_info"))?;
|
.map_err(|err| err.add_context("surface_info"))?;
|
||||||
|
|
||||||
let &SurfaceInfo {
|
let &SurfaceInfo {
|
||||||
|
present_mode,
|
||||||
full_screen_exclusive,
|
full_screen_exclusive,
|
||||||
win32_monitor,
|
win32_monitor,
|
||||||
_ne: _,
|
_ne: _,
|
||||||
} = surface_info;
|
} = surface_info;
|
||||||
|
|
||||||
|
if let Some(present_mode) = present_mode {
|
||||||
|
let mut present_modes = unsafe {
|
||||||
|
self.surface_present_modes_unchecked(surface)
|
||||||
|
.map_err(|_err| ValidationError {
|
||||||
|
context: "PhysicalDevice::surface_present_modes".into(),
|
||||||
|
problem: "returned an error".into(),
|
||||||
|
..Default::default()
|
||||||
|
})?
|
||||||
|
};
|
||||||
|
|
||||||
|
if !present_modes.any(|mode| mode == present_mode) {
|
||||||
|
return Err(ValidationError {
|
||||||
|
problem: "`surface_info.present_mode` is not supported for `surface`".into(),
|
||||||
|
vuids: &["VUID-VkSurfacePresentModeEXT-presentMode-07780"],
|
||||||
|
..Default::default()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
match (
|
match (
|
||||||
surface.api() == SurfaceApi::Win32
|
surface.api() == SurfaceApi::Win32
|
||||||
&& full_screen_exclusive == FullScreenExclusive::ApplicationControlled,
|
&& full_screen_exclusive == FullScreenExclusive::ApplicationControlled,
|
||||||
@ -1433,6 +1453,7 @@ impl PhysicalDevice {
|
|||||||
/* Input */
|
/* Input */
|
||||||
|
|
||||||
let SurfaceInfo {
|
let SurfaceInfo {
|
||||||
|
present_mode,
|
||||||
full_screen_exclusive,
|
full_screen_exclusive,
|
||||||
win32_monitor,
|
win32_monitor,
|
||||||
_ne: _,
|
_ne: _,
|
||||||
@ -1442,10 +1463,21 @@ impl PhysicalDevice {
|
|||||||
surface: surface.handle(),
|
surface: surface.handle(),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
let mut present_mode_vk = None;
|
||||||
let mut full_screen_exclusive_info_vk = None;
|
let mut full_screen_exclusive_info_vk = None;
|
||||||
let mut full_screen_exclusive_win32_info_vk = None;
|
let mut full_screen_exclusive_win32_info_vk = None;
|
||||||
|
|
||||||
if self.supported_extensions().ext_full_screen_exclusive && win32_monitor.is_some() {
|
if let Some(present_mode) = present_mode {
|
||||||
|
let next = present_mode_vk.insert(ash::vk::SurfacePresentModeEXT {
|
||||||
|
present_mode: present_mode.into(),
|
||||||
|
..Default::default()
|
||||||
|
});
|
||||||
|
|
||||||
|
next.p_next = info_vk.p_next as *mut _;
|
||||||
|
info_vk.p_next = next as *const _ as *const _;
|
||||||
|
}
|
||||||
|
|
||||||
|
if full_screen_exclusive != FullScreenExclusive::Default {
|
||||||
let next =
|
let next =
|
||||||
full_screen_exclusive_info_vk.insert(ash::vk::SurfaceFullScreenExclusiveInfoEXT {
|
full_screen_exclusive_info_vk.insert(ash::vk::SurfaceFullScreenExclusiveInfoEXT {
|
||||||
full_screen_exclusive: full_screen_exclusive.into(),
|
full_screen_exclusive: full_screen_exclusive.into(),
|
||||||
@ -1472,7 +1504,11 @@ impl PhysicalDevice {
|
|||||||
|
|
||||||
let mut capabilities_vk = ash::vk::SurfaceCapabilities2KHR::default();
|
let mut capabilities_vk = ash::vk::SurfaceCapabilities2KHR::default();
|
||||||
let mut capabilities_full_screen_exclusive_vk = None;
|
let mut capabilities_full_screen_exclusive_vk = None;
|
||||||
let mut protected_capabilities_vk = None;
|
let mut capabilities_present_modes_vk =
|
||||||
|
[ash::vk::PresentModeKHR::default(); PresentMode::COUNT];
|
||||||
|
let mut capabilities_present_mode_compatibility_vk = None;
|
||||||
|
let mut capabilities_present_scaling_vk = None;
|
||||||
|
let mut capabilities_protected_vk = None;
|
||||||
|
|
||||||
if full_screen_exclusive_info_vk.is_some() {
|
if full_screen_exclusive_info_vk.is_some() {
|
||||||
let next = capabilities_full_screen_exclusive_vk
|
let next = capabilities_full_screen_exclusive_vk
|
||||||
@ -1482,12 +1518,35 @@ impl PhysicalDevice {
|
|||||||
capabilities_vk.p_next = next as *mut _ as *mut _;
|
capabilities_vk.p_next = next as *mut _ as *mut _;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if present_mode.is_some() {
|
||||||
|
{
|
||||||
|
let next = capabilities_present_mode_compatibility_vk.insert(
|
||||||
|
ash::vk::SurfacePresentModeCompatibilityEXT {
|
||||||
|
present_mode_count: capabilities_present_modes_vk.len() as u32,
|
||||||
|
p_present_modes: capabilities_present_modes_vk.as_mut_ptr(),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
next.p_next = capabilities_vk.p_next as *mut _;
|
||||||
|
capabilities_vk.p_next = next as *mut _ as *mut _;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
let next = capabilities_present_scaling_vk
|
||||||
|
.insert(ash::vk::SurfacePresentScalingCapabilitiesEXT::default());
|
||||||
|
|
||||||
|
next.p_next = capabilities_vk.p_next as *mut _;
|
||||||
|
capabilities_vk.p_next = next as *mut _ as *mut _;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if self
|
if self
|
||||||
.instance
|
.instance
|
||||||
.enabled_extensions()
|
.enabled_extensions()
|
||||||
.khr_surface_protected_capabilities
|
.khr_surface_protected_capabilities
|
||||||
{
|
{
|
||||||
let next = protected_capabilities_vk
|
let next = capabilities_protected_vk
|
||||||
.insert(ash::vk::SurfaceProtectedCapabilitiesKHR::default());
|
.insert(ash::vk::SurfaceProtectedCapabilitiesKHR::default());
|
||||||
|
|
||||||
next.p_next = capabilities_vk.p_next as *mut _;
|
next.p_next = capabilities_vk.p_next as *mut _;
|
||||||
@ -1521,22 +1580,19 @@ impl PhysicalDevice {
|
|||||||
|
|
||||||
Ok(SurfaceCapabilities {
|
Ok(SurfaceCapabilities {
|
||||||
min_image_count: capabilities_vk.surface_capabilities.min_image_count,
|
min_image_count: capabilities_vk.surface_capabilities.min_image_count,
|
||||||
max_image_count: if capabilities_vk.surface_capabilities.max_image_count == 0 {
|
max_image_count: (capabilities_vk.surface_capabilities.max_image_count != 0)
|
||||||
None
|
.then_some(capabilities_vk.surface_capabilities.max_image_count),
|
||||||
} else {
|
current_extent: (!matches!(
|
||||||
Some(capabilities_vk.surface_capabilities.max_image_count)
|
capabilities_vk.surface_capabilities.current_extent,
|
||||||
},
|
ash::vk::Extent2D {
|
||||||
current_extent: if capabilities_vk.surface_capabilities.current_extent.width
|
width: u32::MAX,
|
||||||
== 0xffffffff
|
height: u32::MAX
|
||||||
&& capabilities_vk.surface_capabilities.current_extent.height == 0xffffffff
|
}
|
||||||
{
|
))
|
||||||
None
|
.then_some([
|
||||||
} else {
|
capabilities_vk.surface_capabilities.current_extent.width,
|
||||||
Some([
|
capabilities_vk.surface_capabilities.current_extent.height,
|
||||||
capabilities_vk.surface_capabilities.current_extent.width,
|
]),
|
||||||
capabilities_vk.surface_capabilities.current_extent.height,
|
|
||||||
])
|
|
||||||
},
|
|
||||||
min_image_extent: [
|
min_image_extent: [
|
||||||
capabilities_vk.surface_capabilities.min_image_extent.width,
|
capabilities_vk.surface_capabilities.min_image_extent.width,
|
||||||
capabilities_vk.surface_capabilities.min_image_extent.height,
|
capabilities_vk.surface_capabilities.min_image_extent.height,
|
||||||
@ -1561,14 +1617,75 @@ impl PhysicalDevice {
|
|||||||
.surface_capabilities
|
.surface_capabilities
|
||||||
.supported_composite_alpha
|
.supported_composite_alpha
|
||||||
.into(),
|
.into(),
|
||||||
supported_usage_flags: {
|
supported_usage_flags: ImageUsage::from(
|
||||||
let usage =
|
capabilities_vk.surface_capabilities.supported_usage_flags,
|
||||||
ImageUsage::from(capabilities_vk.surface_capabilities.supported_usage_flags);
|
),
|
||||||
debug_assert!(usage.intersects(ImageUsage::COLOR_ATTACHMENT)); // specs say that this must be true
|
|
||||||
usage
|
|
||||||
},
|
|
||||||
|
|
||||||
supports_protected: protected_capabilities_vk
|
compatible_present_modes: capabilities_present_mode_compatibility_vk.map_or_else(
|
||||||
|
Default::default,
|
||||||
|
|capabilities_present_mode_compatibility_vk| {
|
||||||
|
capabilities_present_modes_vk
|
||||||
|
[..capabilities_present_mode_compatibility_vk.present_mode_count as usize]
|
||||||
|
.iter()
|
||||||
|
.copied()
|
||||||
|
.map(PresentMode::try_from)
|
||||||
|
.filter_map(Result::ok)
|
||||||
|
.collect()
|
||||||
|
},
|
||||||
|
),
|
||||||
|
|
||||||
|
supported_present_scaling: capabilities_present_scaling_vk
|
||||||
|
.as_ref()
|
||||||
|
.map_or_else(Default::default, |c| c.supported_present_scaling.into()),
|
||||||
|
supported_present_gravity: capabilities_present_scaling_vk.as_ref().map_or_else(
|
||||||
|
Default::default,
|
||||||
|
|c| {
|
||||||
|
[
|
||||||
|
c.supported_present_gravity_x.into(),
|
||||||
|
c.supported_present_gravity_y.into(),
|
||||||
|
]
|
||||||
|
},
|
||||||
|
),
|
||||||
|
min_scaled_image_extent: capabilities_present_scaling_vk.as_ref().map_or(
|
||||||
|
Some([
|
||||||
|
capabilities_vk.surface_capabilities.min_image_extent.width,
|
||||||
|
capabilities_vk.surface_capabilities.min_image_extent.height,
|
||||||
|
]),
|
||||||
|
|c| {
|
||||||
|
(!matches!(
|
||||||
|
c.min_scaled_image_extent,
|
||||||
|
ash::vk::Extent2D {
|
||||||
|
width: u32::MAX,
|
||||||
|
height: u32::MAX,
|
||||||
|
}
|
||||||
|
))
|
||||||
|
.then_some([
|
||||||
|
c.min_scaled_image_extent.width,
|
||||||
|
c.min_scaled_image_extent.height,
|
||||||
|
])
|
||||||
|
},
|
||||||
|
),
|
||||||
|
max_scaled_image_extent: capabilities_present_scaling_vk.as_ref().map_or(
|
||||||
|
Some([
|
||||||
|
capabilities_vk.surface_capabilities.max_image_extent.width,
|
||||||
|
capabilities_vk.surface_capabilities.max_image_extent.height,
|
||||||
|
]),
|
||||||
|
|c| {
|
||||||
|
(!matches!(
|
||||||
|
c.max_scaled_image_extent,
|
||||||
|
ash::vk::Extent2D {
|
||||||
|
width: u32::MAX,
|
||||||
|
height: u32::MAX,
|
||||||
|
}
|
||||||
|
))
|
||||||
|
.then_some([
|
||||||
|
c.max_scaled_image_extent.width,
|
||||||
|
c.max_scaled_image_extent.height,
|
||||||
|
])
|
||||||
|
},
|
||||||
|
),
|
||||||
|
|
||||||
|
supports_protected: capabilities_protected_vk
|
||||||
.map_or(false, |c| c.supports_protected != 0),
|
.map_or(false, |c| c.supports_protected != 0),
|
||||||
|
|
||||||
full_screen_exclusive_supported: capabilities_full_screen_exclusive_vk
|
full_screen_exclusive_supported: capabilities_full_screen_exclusive_vk
|
||||||
@ -1630,12 +1747,36 @@ impl PhysicalDevice {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
surface_info
|
||||||
|
.validate(self)
|
||||||
|
.map_err(|err| err.add_context("surface_info"))?;
|
||||||
|
|
||||||
let &SurfaceInfo {
|
let &SurfaceInfo {
|
||||||
|
present_mode,
|
||||||
full_screen_exclusive,
|
full_screen_exclusive,
|
||||||
win32_monitor,
|
win32_monitor,
|
||||||
_ne: _,
|
_ne: _,
|
||||||
} = surface_info;
|
} = surface_info;
|
||||||
|
|
||||||
|
if let Some(present_mode) = present_mode {
|
||||||
|
let mut present_modes = unsafe {
|
||||||
|
self.surface_present_modes_unchecked(surface)
|
||||||
|
.map_err(|_err| ValidationError {
|
||||||
|
context: "PhysicalDevice::surface_present_modes".into(),
|
||||||
|
problem: "returned an error".into(),
|
||||||
|
..Default::default()
|
||||||
|
})?
|
||||||
|
};
|
||||||
|
|
||||||
|
if !present_modes.any(|mode| mode == present_mode) {
|
||||||
|
return Err(ValidationError {
|
||||||
|
problem: "`surface_info.present_mode` is not supported for `surface`".into(),
|
||||||
|
vuids: &["VUID-VkSurfacePresentModeEXT-presentMode-07780"],
|
||||||
|
..Default::default()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if !self
|
if !self
|
||||||
.instance
|
.instance
|
||||||
.enabled_extensions()
|
.enabled_extensions()
|
||||||
@ -1706,46 +1847,52 @@ impl PhysicalDevice {
|
|||||||
(self.handle, surface_info),
|
(self.handle, surface_info),
|
||||||
|(_, surface_info)| {
|
|(_, surface_info)| {
|
||||||
let &SurfaceInfo {
|
let &SurfaceInfo {
|
||||||
|
present_mode,
|
||||||
full_screen_exclusive,
|
full_screen_exclusive,
|
||||||
win32_monitor,
|
win32_monitor,
|
||||||
_ne: _,
|
_ne: _,
|
||||||
} = surface_info;
|
} = surface_info;
|
||||||
|
|
||||||
let mut surface_full_screen_exclusive_info = (full_screen_exclusive
|
let mut info_vk = ash::vk::PhysicalDeviceSurfaceInfo2KHR {
|
||||||
!= FullScreenExclusive::Default)
|
|
||||||
.then(|| ash::vk::SurfaceFullScreenExclusiveInfoEXT {
|
|
||||||
full_screen_exclusive: full_screen_exclusive.into(),
|
|
||||||
..Default::default()
|
|
||||||
});
|
|
||||||
|
|
||||||
let mut surface_full_screen_exclusive_win32_info =
|
|
||||||
win32_monitor.map(|win32_monitor| {
|
|
||||||
ash::vk::SurfaceFullScreenExclusiveWin32InfoEXT {
|
|
||||||
hmonitor: win32_monitor.0,
|
|
||||||
..Default::default()
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
let mut surface_info2 = ash::vk::PhysicalDeviceSurfaceInfo2KHR {
|
|
||||||
surface: surface.handle(),
|
surface: surface.handle(),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
let mut present_mode_vk = None;
|
||||||
|
let mut full_screen_exclusive_info_vk = None;
|
||||||
|
let mut full_screen_exclusive_win32_info_vk = None;
|
||||||
|
|
||||||
if let Some(surface_full_screen_exclusive_info) =
|
if let Some(present_mode) = present_mode {
|
||||||
surface_full_screen_exclusive_info.as_mut()
|
let next = present_mode_vk.insert(ash::vk::SurfacePresentModeEXT {
|
||||||
{
|
present_mode: present_mode.into(),
|
||||||
surface_full_screen_exclusive_info.p_next = surface_info2.p_next as *mut _;
|
..Default::default()
|
||||||
surface_info2.p_next =
|
});
|
||||||
surface_full_screen_exclusive_info as *const _ as *const _;
|
|
||||||
|
next.p_next = info_vk.p_next as *mut _;
|
||||||
|
info_vk.p_next = next as *const _ as *const _;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(surface_full_screen_exclusive_win32_info) =
|
if full_screen_exclusive != FullScreenExclusive::Default {
|
||||||
surface_full_screen_exclusive_win32_info.as_mut()
|
let next = full_screen_exclusive_info_vk.insert(
|
||||||
{
|
ash::vk::SurfaceFullScreenExclusiveInfoEXT {
|
||||||
surface_full_screen_exclusive_win32_info.p_next =
|
full_screen_exclusive: full_screen_exclusive.into(),
|
||||||
surface_info2.p_next as *mut _;
|
..Default::default()
|
||||||
surface_info2.p_next =
|
},
|
||||||
surface_full_screen_exclusive_win32_info as *const _ as *const _;
|
);
|
||||||
|
|
||||||
|
next.p_next = info_vk.p_next as *mut _;
|
||||||
|
info_vk.p_next = next as *const _ as *const _;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(win32_monitor) = win32_monitor {
|
||||||
|
let next = full_screen_exclusive_win32_info_vk.insert(
|
||||||
|
ash::vk::SurfaceFullScreenExclusiveWin32InfoEXT {
|
||||||
|
hmonitor: win32_monitor.0,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
next.p_next = info_vk.p_next as *mut _;
|
||||||
|
info_vk.p_next = next as *const _ as *const _;
|
||||||
}
|
}
|
||||||
|
|
||||||
let fns = self.instance.fns();
|
let fns = self.instance.fns();
|
||||||
@ -1755,40 +1902,40 @@ impl PhysicalDevice {
|
|||||||
.enabled_extensions()
|
.enabled_extensions()
|
||||||
.khr_get_surface_capabilities2
|
.khr_get_surface_capabilities2
|
||||||
{
|
{
|
||||||
let surface_format2s = loop {
|
let surface_format2s_vk = loop {
|
||||||
let mut count = 0;
|
let mut count = 0;
|
||||||
(fns.khr_get_surface_capabilities2
|
(fns.khr_get_surface_capabilities2
|
||||||
.get_physical_device_surface_formats2_khr)(
|
.get_physical_device_surface_formats2_khr)(
|
||||||
self.handle(),
|
self.handle(),
|
||||||
&surface_info2,
|
&info_vk,
|
||||||
&mut count,
|
&mut count,
|
||||||
ptr::null_mut(),
|
ptr::null_mut(),
|
||||||
)
|
)
|
||||||
.result()
|
.result()
|
||||||
.map_err(RuntimeError::from)?;
|
.map_err(RuntimeError::from)?;
|
||||||
|
|
||||||
let mut surface_format2s =
|
let mut surface_format2s_vk =
|
||||||
vec![ash::vk::SurfaceFormat2KHR::default(); count as usize];
|
vec![ash::vk::SurfaceFormat2KHR::default(); count as usize];
|
||||||
let result = (fns
|
let result = (fns
|
||||||
.khr_get_surface_capabilities2
|
.khr_get_surface_capabilities2
|
||||||
.get_physical_device_surface_formats2_khr)(
|
.get_physical_device_surface_formats2_khr)(
|
||||||
self.handle(),
|
self.handle(),
|
||||||
&surface_info2,
|
&info_vk,
|
||||||
&mut count,
|
&mut count,
|
||||||
surface_format2s.as_mut_ptr(),
|
surface_format2s_vk.as_mut_ptr(),
|
||||||
);
|
);
|
||||||
|
|
||||||
match result {
|
match result {
|
||||||
ash::vk::Result::SUCCESS => {
|
ash::vk::Result::SUCCESS => {
|
||||||
surface_format2s.set_len(count as usize);
|
surface_format2s_vk.set_len(count as usize);
|
||||||
break surface_format2s;
|
break surface_format2s_vk;
|
||||||
}
|
}
|
||||||
ash::vk::Result::INCOMPLETE => (),
|
ash::vk::Result::INCOMPLETE => (),
|
||||||
err => return Err(RuntimeError::from(err)),
|
err => return Err(RuntimeError::from(err)),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(surface_format2s
|
Ok(surface_format2s_vk
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter_map(|surface_format2| {
|
.filter_map(|surface_format2| {
|
||||||
(surface_format2.surface_format.format.try_into().ok())
|
(surface_format2.surface_format.format.try_into().ok())
|
||||||
|
@ -529,8 +529,8 @@ impl<'a> QueueGuard<'a> {
|
|||||||
states: &mut States<'_>,
|
states: &mut States<'_>,
|
||||||
) -> Result<impl ExactSizeIterator<Item = Result<bool, RuntimeError>>, RuntimeError> {
|
) -> Result<impl ExactSizeIterator<Item = Result<bool, RuntimeError>>, RuntimeError> {
|
||||||
let PresentInfo {
|
let PresentInfo {
|
||||||
ref wait_semaphores,
|
wait_semaphores,
|
||||||
ref swapchain_infos,
|
swapchain_infos,
|
||||||
_ne: _,
|
_ne: _,
|
||||||
} = present_info;
|
} = present_info;
|
||||||
|
|
||||||
@ -542,11 +542,13 @@ impl<'a> QueueGuard<'a> {
|
|||||||
let mut swapchains_vk: SmallVec<[_; 4]> = SmallVec::with_capacity(swapchain_infos.len());
|
let mut swapchains_vk: SmallVec<[_; 4]> = SmallVec::with_capacity(swapchain_infos.len());
|
||||||
let mut image_indices_vk: SmallVec<[_; 4]> = SmallVec::with_capacity(swapchain_infos.len());
|
let mut image_indices_vk: SmallVec<[_; 4]> = SmallVec::with_capacity(swapchain_infos.len());
|
||||||
let mut present_ids_vk: SmallVec<[_; 4]> = SmallVec::with_capacity(swapchain_infos.len());
|
let mut present_ids_vk: SmallVec<[_; 4]> = SmallVec::with_capacity(swapchain_infos.len());
|
||||||
|
let mut present_modes_vk: SmallVec<[_; 4]> = SmallVec::with_capacity(swapchain_infos.len());
|
||||||
let mut present_regions_vk: SmallVec<[_; 4]> =
|
let mut present_regions_vk: SmallVec<[_; 4]> =
|
||||||
SmallVec::with_capacity(swapchain_infos.len());
|
SmallVec::with_capacity(swapchain_infos.len());
|
||||||
let mut rectangles_vk: SmallVec<[_; 4]> = SmallVec::with_capacity(swapchain_infos.len());
|
let mut rectangles_vk: SmallVec<[_; 4]> = SmallVec::with_capacity(swapchain_infos.len());
|
||||||
|
|
||||||
let mut has_present_ids = false;
|
let mut has_present_ids = false;
|
||||||
|
let mut has_present_modes = false;
|
||||||
let mut has_present_regions = false;
|
let mut has_present_regions = false;
|
||||||
|
|
||||||
for swapchain_info in swapchain_infos {
|
for swapchain_info in swapchain_infos {
|
||||||
@ -554,6 +556,7 @@ impl<'a> QueueGuard<'a> {
|
|||||||
ref swapchain,
|
ref swapchain,
|
||||||
image_index,
|
image_index,
|
||||||
present_id,
|
present_id,
|
||||||
|
present_mode,
|
||||||
ref present_regions,
|
ref present_regions,
|
||||||
_ne: _,
|
_ne: _,
|
||||||
} = swapchain_info;
|
} = swapchain_info;
|
||||||
@ -561,6 +564,7 @@ impl<'a> QueueGuard<'a> {
|
|||||||
swapchains_vk.push(swapchain.handle());
|
swapchains_vk.push(swapchain.handle());
|
||||||
image_indices_vk.push(image_index);
|
image_indices_vk.push(image_index);
|
||||||
present_ids_vk.push(present_id.map_or(0, u64::from));
|
present_ids_vk.push(present_id.map_or(0, u64::from));
|
||||||
|
present_modes_vk.push(present_mode.map_or_else(Default::default, Into::into));
|
||||||
present_regions_vk.push(ash::vk::PresentRegionKHR::default());
|
present_regions_vk.push(ash::vk::PresentRegionKHR::default());
|
||||||
rectangles_vk.push(
|
rectangles_vk.push(
|
||||||
present_regions
|
present_regions
|
||||||
@ -573,6 +577,10 @@ impl<'a> QueueGuard<'a> {
|
|||||||
has_present_ids = true;
|
has_present_ids = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if present_mode.is_some() {
|
||||||
|
has_present_modes = true;
|
||||||
|
}
|
||||||
|
|
||||||
if !present_regions.is_empty() {
|
if !present_regions.is_empty() {
|
||||||
has_present_regions = true;
|
has_present_regions = true;
|
||||||
}
|
}
|
||||||
@ -589,6 +597,7 @@ impl<'a> QueueGuard<'a> {
|
|||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
let mut present_id_info_vk = None;
|
let mut present_id_info_vk = None;
|
||||||
|
let mut present_mode_info_vk = None;
|
||||||
let mut present_region_info_vk = None;
|
let mut present_region_info_vk = None;
|
||||||
|
|
||||||
if has_present_ids {
|
if has_present_ids {
|
||||||
@ -602,6 +611,17 @@ impl<'a> QueueGuard<'a> {
|
|||||||
info_vk.p_next = next as *const _ as *const _;
|
info_vk.p_next = next as *const _ as *const _;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if has_present_modes {
|
||||||
|
let next = present_mode_info_vk.insert(ash::vk::SwapchainPresentModeInfoEXT {
|
||||||
|
swapchain_count: present_modes_vk.len() as u32,
|
||||||
|
p_present_modes: present_modes_vk.as_ptr(),
|
||||||
|
..Default::default()
|
||||||
|
});
|
||||||
|
|
||||||
|
next.p_next = info_vk.p_next as _;
|
||||||
|
info_vk.p_next = next as *const _ as *const _;
|
||||||
|
}
|
||||||
|
|
||||||
if has_present_regions {
|
if has_present_regions {
|
||||||
for (present_regions_vk, rectangles_vk) in
|
for (present_regions_vk, rectangles_vk) in
|
||||||
(present_regions_vk.iter_mut()).zip(rectangles_vk.iter())
|
(present_regions_vk.iter_mut()).zip(rectangles_vk.iter())
|
||||||
|
@ -15,7 +15,6 @@ use super::{
|
|||||||
use crate::{
|
use crate::{
|
||||||
device::{Device, DeviceOwned},
|
device::{Device, DeviceOwned},
|
||||||
swapchain::Swapchain,
|
swapchain::Swapchain,
|
||||||
OomError,
|
|
||||||
};
|
};
|
||||||
use std::{
|
use std::{
|
||||||
hash::{Hash, Hasher},
|
hash::{Hash, Hasher},
|
||||||
@ -45,10 +44,10 @@ impl SwapchainImage {
|
|||||||
handle: ash::vk::Image,
|
handle: ash::vk::Image,
|
||||||
swapchain: Arc<Swapchain>,
|
swapchain: Arc<Swapchain>,
|
||||||
image_index: u32,
|
image_index: u32,
|
||||||
) -> Result<Arc<SwapchainImage>, OomError> {
|
) -> Arc<SwapchainImage> {
|
||||||
Ok(Arc::new(SwapchainImage {
|
Arc::new(SwapchainImage {
|
||||||
inner: Arc::new(Image::from_swapchain(handle, swapchain, image_index)),
|
inner: Arc::new(Image::from_swapchain(handle, swapchain, image_index)),
|
||||||
}))
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the swapchain this image belongs to.
|
/// Returns the swapchain this image belongs to.
|
||||||
|
@ -591,11 +591,16 @@ macro_rules! vulkan_enum {
|
|||||||
)+
|
)+
|
||||||
}
|
}
|
||||||
|
|
||||||
$(
|
impl $ty {
|
||||||
impl $ty {
|
#[allow(dead_code)]
|
||||||
|
pub(crate) const COUNT: usize = [
|
||||||
|
$(ash::vk::$ty_ffi::$flag_name_ffi.as_raw()),+
|
||||||
|
].len();
|
||||||
|
|
||||||
|
$(
|
||||||
$($impls)*
|
$($impls)*
|
||||||
}
|
)?
|
||||||
)?
|
}
|
||||||
|
|
||||||
impl From<$ty> for ash::vk::$ty_ffi {
|
impl From<$ty> for ash::vk::$ty_ffi {
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -653,6 +658,11 @@ macro_rules! vulkan_enum {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl $ty {
|
impl $ty {
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub(crate) const COUNT: usize = [
|
||||||
|
$(ash::vk::$ty_ffi::$flag_name_ffi.as_raw()),+
|
||||||
|
].len();
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate) fn validate_device(
|
pub(crate) fn validate_device(
|
||||||
|
@ -521,13 +521,13 @@ impl From<&Viewport> for ash::vk::Viewport {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// State of a single scissor box.
|
/// A two-dimensional subregion.
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||||
pub struct Scissor {
|
pub struct Scissor {
|
||||||
/// Coordinates in pixels of the top-left hand corner of the box.
|
/// Coordinates of the top-left hand corner of the box.
|
||||||
pub offset: [u32; 2],
|
pub offset: [u32; 2],
|
||||||
|
|
||||||
/// Dimensions in pixels of the box.
|
/// Dimensions of the box.
|
||||||
pub extent: [u32; 2],
|
pub extent: [u32; 2],
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -565,3 +565,13 @@ impl From<&Scissor> for ash::vk::Rect2D {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<ash::vk::Rect2D> for Scissor {
|
||||||
|
#[inline]
|
||||||
|
fn from(val: ash::vk::Rect2D) -> Self {
|
||||||
|
Scissor {
|
||||||
|
offset: [val.offset.x as u32, val.offset.y as u32],
|
||||||
|
extent: [val.extent.width, val.extent.height],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
1025
vulkano/src/swapchain/acquire_present.rs
Normal file
1025
vulkano/src/swapchain/acquire_present.rs
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -7,7 +7,7 @@
|
|||||||
// notice may not be copied, modified, or distributed except
|
// notice may not be copied, modified, or distributed except
|
||||||
// according to those terms.
|
// according to those terms.
|
||||||
|
|
||||||
use super::{FullScreenExclusive, Win32Monitor};
|
use super::{FullScreenExclusive, PresentGravityFlags, PresentScalingFlags, Win32Monitor};
|
||||||
use crate::{
|
use crate::{
|
||||||
cache::OnceCache,
|
cache::OnceCache,
|
||||||
device::physical::PhysicalDevice,
|
device::physical::PhysicalDevice,
|
||||||
@ -15,25 +15,23 @@ use crate::{
|
|||||||
image::ImageUsage,
|
image::ImageUsage,
|
||||||
instance::{Instance, InstanceExtensions},
|
instance::{Instance, InstanceExtensions},
|
||||||
macros::{impl_id_counter, vulkan_bitflags_enum, vulkan_enum},
|
macros::{impl_id_counter, vulkan_bitflags_enum, vulkan_enum},
|
||||||
swapchain::{
|
swapchain::display::{DisplayMode, DisplayPlane},
|
||||||
display::{DisplayMode, DisplayPlane},
|
Requires, RequiresAllOf, RequiresOneOf, RuntimeError, ValidationError, VulkanError,
|
||||||
SurfaceSwapchainLock,
|
VulkanObject,
|
||||||
},
|
|
||||||
OomError, Requires, RequiresAllOf, RequiresOneOf, RuntimeError, ValidationError, VulkanObject,
|
|
||||||
};
|
};
|
||||||
#[cfg(any(target_os = "macos", target_os = "ios"))]
|
#[cfg(any(target_os = "macos", target_os = "ios"))]
|
||||||
use objc::{class, msg_send, runtime::Object, sel, sel_impl};
|
use objc::{class, msg_send, runtime::Object, sel, sel_impl};
|
||||||
use raw_window_handle::{
|
use raw_window_handle::{
|
||||||
HasRawDisplayHandle, HasRawWindowHandle, RawDisplayHandle, RawWindowHandle,
|
HasRawDisplayHandle, HasRawWindowHandle, RawDisplayHandle, RawWindowHandle,
|
||||||
};
|
};
|
||||||
|
use smallvec::SmallVec;
|
||||||
use std::{
|
use std::{
|
||||||
any::Any,
|
any::Any,
|
||||||
error::Error,
|
fmt::{Debug, Error as FmtError, Formatter},
|
||||||
fmt::{Debug, Display, Error as FmtError, Formatter},
|
|
||||||
mem::MaybeUninit,
|
mem::MaybeUninit,
|
||||||
num::NonZeroU64,
|
num::NonZeroU64,
|
||||||
ptr,
|
ptr,
|
||||||
sync::{atomic::AtomicBool, Arc},
|
sync::Arc,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Represents a surface on the screen.
|
/// Represents a surface on the screen.
|
||||||
@ -45,9 +43,6 @@ pub struct Surface {
|
|||||||
id: NonZeroU64,
|
id: NonZeroU64,
|
||||||
api: SurfaceApi,
|
api: SurfaceApi,
|
||||||
object: Option<Arc<dyn Any + Send + Sync>>,
|
object: Option<Arc<dyn Any + Send + Sync>>,
|
||||||
// If true, a swapchain has been associated to this surface, and that any new swapchain
|
|
||||||
// creation should be forbidden.
|
|
||||||
has_swapchain: AtomicBool,
|
|
||||||
// FIXME: This field is never set.
|
// FIXME: This field is never set.
|
||||||
#[cfg(target_os = "ios")]
|
#[cfg(target_os = "ios")]
|
||||||
metal_layer: IOSMetalLayer,
|
metal_layer: IOSMetalLayer,
|
||||||
@ -88,7 +83,7 @@ impl Surface {
|
|||||||
pub fn from_window(
|
pub fn from_window(
|
||||||
instance: Arc<Instance>,
|
instance: Arc<Instance>,
|
||||||
window: Arc<impl HasRawWindowHandle + HasRawDisplayHandle + Any + Send + Sync>,
|
window: Arc<impl HasRawWindowHandle + HasRawDisplayHandle + Any + Send + Sync>,
|
||||||
) -> Result<Arc<Self>, SurfaceCreationError> {
|
) -> Result<Arc<Self>, VulkanError> {
|
||||||
let mut surface = unsafe { Self::from_window_ref(instance, &*window) }?;
|
let mut surface = unsafe { Self::from_window_ref(instance, &*window) }?;
|
||||||
Arc::get_mut(&mut surface).unwrap().object = Some(window);
|
Arc::get_mut(&mut surface).unwrap().object = Some(window);
|
||||||
|
|
||||||
@ -104,7 +99,7 @@ impl Surface {
|
|||||||
pub unsafe fn from_window_ref(
|
pub unsafe fn from_window_ref(
|
||||||
instance: Arc<Instance>,
|
instance: Arc<Instance>,
|
||||||
window: &(impl HasRawWindowHandle + HasRawDisplayHandle),
|
window: &(impl HasRawWindowHandle + HasRawDisplayHandle),
|
||||||
) -> Result<Arc<Self>, SurfaceCreationError> {
|
) -> Result<Arc<Self>, VulkanError> {
|
||||||
match (window.raw_window_handle(), window.raw_display_handle()) {
|
match (window.raw_window_handle(), window.raw_display_handle()) {
|
||||||
(RawWindowHandle::AndroidNdk(window), RawDisplayHandle::Android(_display)) => {
|
(RawWindowHandle::AndroidNdk(window), RawDisplayHandle::Android(_display)) => {
|
||||||
Self::from_android(instance, window.a_native_window, None)
|
Self::from_android(instance, window.a_native_window, None)
|
||||||
@ -159,7 +154,6 @@ impl Surface {
|
|||||||
id: Self::next_id(),
|
id: Self::next_id(),
|
||||||
api,
|
api,
|
||||||
object,
|
object,
|
||||||
has_swapchain: AtomicBool::new(false),
|
|
||||||
#[cfg(target_os = "ios")]
|
#[cfg(target_os = "ios")]
|
||||||
metal_layer: IOSMetalLayer::new(std::ptr::null_mut(), std::ptr::null_mut()),
|
metal_layer: IOSMetalLayer::new(std::ptr::null_mut(), std::ptr::null_mut()),
|
||||||
surface_formats: OnceCache::new(),
|
surface_formats: OnceCache::new(),
|
||||||
@ -175,19 +169,19 @@ impl Surface {
|
|||||||
pub fn headless(
|
pub fn headless(
|
||||||
instance: Arc<Instance>,
|
instance: Arc<Instance>,
|
||||||
object: Option<Arc<dyn Any + Send + Sync>>,
|
object: Option<Arc<dyn Any + Send + Sync>>,
|
||||||
) -> Result<Arc<Self>, SurfaceCreationError> {
|
) -> Result<Arc<Self>, VulkanError> {
|
||||||
Self::validate_headless(&instance)?;
|
Self::validate_headless(&instance)?;
|
||||||
|
|
||||||
unsafe { Ok(Self::headless_unchecked(instance, object)?) }
|
unsafe { Ok(Self::headless_unchecked(instance, object)?) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn validate_headless(instance: &Instance) -> Result<(), SurfaceCreationError> {
|
fn validate_headless(instance: &Instance) -> Result<(), ValidationError> {
|
||||||
if !instance.enabled_extensions().ext_headless_surface {
|
if !instance.enabled_extensions().ext_headless_surface {
|
||||||
return Err(SurfaceCreationError::RequirementNotMet {
|
return Err(ValidationError {
|
||||||
required_for: "`Surface::headless`",
|
|
||||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::InstanceExtension(
|
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::InstanceExtension(
|
||||||
"ext_headless_surface",
|
"ext_headless_surface",
|
||||||
)])]),
|
)])]),
|
||||||
|
..Default::default()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -235,7 +229,7 @@ impl Surface {
|
|||||||
pub fn from_display_plane(
|
pub fn from_display_plane(
|
||||||
display_mode: &DisplayMode,
|
display_mode: &DisplayMode,
|
||||||
plane: &DisplayPlane,
|
plane: &DisplayPlane,
|
||||||
) -> Result<Arc<Self>, SurfaceCreationError> {
|
) -> Result<Arc<Self>, VulkanError> {
|
||||||
Self::validate_from_display_plane(display_mode, plane)?;
|
Self::validate_from_display_plane(display_mode, plane)?;
|
||||||
|
|
||||||
unsafe { Ok(Self::from_display_plane_unchecked(display_mode, plane)?) }
|
unsafe { Ok(Self::from_display_plane_unchecked(display_mode, plane)?) }
|
||||||
@ -244,7 +238,7 @@ impl Surface {
|
|||||||
fn validate_from_display_plane(
|
fn validate_from_display_plane(
|
||||||
display_mode: &DisplayMode,
|
display_mode: &DisplayMode,
|
||||||
plane: &DisplayPlane,
|
plane: &DisplayPlane,
|
||||||
) -> Result<(), SurfaceCreationError> {
|
) -> Result<(), ValidationError> {
|
||||||
if !display_mode
|
if !display_mode
|
||||||
.display()
|
.display()
|
||||||
.physical_device()
|
.physical_device()
|
||||||
@ -252,11 +246,11 @@ impl Surface {
|
|||||||
.enabled_extensions()
|
.enabled_extensions()
|
||||||
.khr_display
|
.khr_display
|
||||||
{
|
{
|
||||||
return Err(SurfaceCreationError::RequirementNotMet {
|
return Err(ValidationError {
|
||||||
required_for: "`Surface::from_display_plane`",
|
|
||||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::InstanceExtension(
|
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::InstanceExtension(
|
||||||
"khr_display",
|
"khr_display",
|
||||||
)])]),
|
)])]),
|
||||||
|
..Default::default()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -325,7 +319,7 @@ impl Surface {
|
|||||||
instance: Arc<Instance>,
|
instance: Arc<Instance>,
|
||||||
window: *const W,
|
window: *const W,
|
||||||
object: Option<Arc<dyn Any + Send + Sync>>,
|
object: Option<Arc<dyn Any + Send + Sync>>,
|
||||||
) -> Result<Arc<Self>, SurfaceCreationError> {
|
) -> Result<Arc<Self>, VulkanError> {
|
||||||
Self::validate_from_android(&instance, window)?;
|
Self::validate_from_android(&instance, window)?;
|
||||||
|
|
||||||
Ok(Self::from_android_unchecked(instance, window, object)?)
|
Ok(Self::from_android_unchecked(instance, window, object)?)
|
||||||
@ -334,13 +328,13 @@ impl Surface {
|
|||||||
fn validate_from_android<W>(
|
fn validate_from_android<W>(
|
||||||
instance: &Instance,
|
instance: &Instance,
|
||||||
_window: *const W,
|
_window: *const W,
|
||||||
) -> Result<(), SurfaceCreationError> {
|
) -> Result<(), ValidationError> {
|
||||||
if !instance.enabled_extensions().khr_android_surface {
|
if !instance.enabled_extensions().khr_android_surface {
|
||||||
return Err(SurfaceCreationError::RequirementNotMet {
|
return Err(ValidationError {
|
||||||
required_for: "`Surface::from_android`",
|
|
||||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::InstanceExtension(
|
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::InstanceExtension(
|
||||||
"khr_android_surface",
|
"khr_android_surface",
|
||||||
)])]),
|
)])]),
|
||||||
|
..Default::default()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -397,7 +391,7 @@ impl Surface {
|
|||||||
dfb: *const D,
|
dfb: *const D,
|
||||||
surface: *const S,
|
surface: *const S,
|
||||||
object: Option<Arc<dyn Any + Send + Sync>>,
|
object: Option<Arc<dyn Any + Send + Sync>>,
|
||||||
) -> Result<Arc<Self>, SurfaceCreationError> {
|
) -> Result<Arc<Self>, VulkanError> {
|
||||||
Self::validate_from_directfb(&instance, dfb, surface)?;
|
Self::validate_from_directfb(&instance, dfb, surface)?;
|
||||||
|
|
||||||
Ok(Self::from_directfb_unchecked(
|
Ok(Self::from_directfb_unchecked(
|
||||||
@ -409,13 +403,13 @@ impl Surface {
|
|||||||
instance: &Instance,
|
instance: &Instance,
|
||||||
_dfb: *const D,
|
_dfb: *const D,
|
||||||
_surface: *const S,
|
_surface: *const S,
|
||||||
) -> Result<(), SurfaceCreationError> {
|
) -> Result<(), ValidationError> {
|
||||||
if !instance.enabled_extensions().ext_directfb_surface {
|
if !instance.enabled_extensions().ext_directfb_surface {
|
||||||
return Err(SurfaceCreationError::RequirementNotMet {
|
return Err(ValidationError {
|
||||||
required_for: "`Surface::from_directfb`",
|
|
||||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::InstanceExtension(
|
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::InstanceExtension(
|
||||||
"ext_directfb_surface",
|
"ext_directfb_surface",
|
||||||
)])]),
|
)])]),
|
||||||
|
..Default::default()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -475,7 +469,7 @@ impl Surface {
|
|||||||
instance: Arc<Instance>,
|
instance: Arc<Instance>,
|
||||||
image_pipe_handle: ash::vk::zx_handle_t,
|
image_pipe_handle: ash::vk::zx_handle_t,
|
||||||
object: Option<Arc<dyn Any + Send + Sync>>,
|
object: Option<Arc<dyn Any + Send + Sync>>,
|
||||||
) -> Result<Arc<Self>, SurfaceCreationError> {
|
) -> Result<Arc<Self>, VulkanError> {
|
||||||
Self::validate_from_fuchsia_image_pipe(&instance, image_pipe_handle)?;
|
Self::validate_from_fuchsia_image_pipe(&instance, image_pipe_handle)?;
|
||||||
|
|
||||||
Ok(Self::from_fuchsia_image_pipe_unchecked(
|
Ok(Self::from_fuchsia_image_pipe_unchecked(
|
||||||
@ -488,13 +482,13 @@ impl Surface {
|
|||||||
fn validate_from_fuchsia_image_pipe(
|
fn validate_from_fuchsia_image_pipe(
|
||||||
instance: &Instance,
|
instance: &Instance,
|
||||||
_image_pipe_handle: ash::vk::zx_handle_t,
|
_image_pipe_handle: ash::vk::zx_handle_t,
|
||||||
) -> Result<(), SurfaceCreationError> {
|
) -> Result<(), ValidationError> {
|
||||||
if !instance.enabled_extensions().fuchsia_imagepipe_surface {
|
if !instance.enabled_extensions().fuchsia_imagepipe_surface {
|
||||||
return Err(SurfaceCreationError::RequirementNotMet {
|
return Err(ValidationError {
|
||||||
required_for: "`Surface::from_fuchsia_image_pipe`",
|
|
||||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::InstanceExtension(
|
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::InstanceExtension(
|
||||||
"fuchsia_imagepipe_surface",
|
"fuchsia_imagepipe_surface",
|
||||||
)])]),
|
)])]),
|
||||||
|
..Default::default()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -550,7 +544,7 @@ impl Surface {
|
|||||||
instance: Arc<Instance>,
|
instance: Arc<Instance>,
|
||||||
stream_descriptor: ash::vk::GgpStreamDescriptor,
|
stream_descriptor: ash::vk::GgpStreamDescriptor,
|
||||||
object: Option<Arc<dyn Any + Send + Sync>>,
|
object: Option<Arc<dyn Any + Send + Sync>>,
|
||||||
) -> Result<Arc<Self>, SurfaceCreationError> {
|
) -> Result<Arc<Self>, VulkanError> {
|
||||||
Self::validate_from_ggp_stream_descriptor(&instance, stream_descriptor)?;
|
Self::validate_from_ggp_stream_descriptor(&instance, stream_descriptor)?;
|
||||||
|
|
||||||
Ok(Self::from_ggp_stream_descriptor_unchecked(
|
Ok(Self::from_ggp_stream_descriptor_unchecked(
|
||||||
@ -563,13 +557,13 @@ impl Surface {
|
|||||||
fn validate_from_ggp_stream_descriptor(
|
fn validate_from_ggp_stream_descriptor(
|
||||||
instance: &Instance,
|
instance: &Instance,
|
||||||
_stream_descriptor: ash::vk::GgpStreamDescriptor,
|
_stream_descriptor: ash::vk::GgpStreamDescriptor,
|
||||||
) -> Result<(), SurfaceCreationError> {
|
) -> Result<(), ValidationError> {
|
||||||
if !instance.enabled_extensions().ggp_stream_descriptor_surface {
|
if !instance.enabled_extensions().ggp_stream_descriptor_surface {
|
||||||
return Err(SurfaceCreationError::RequirementNotMet {
|
return Err(ValidationError {
|
||||||
required_for: "`Surface::from_ggp_stream_descriptor`",
|
|
||||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::InstanceExtension(
|
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::InstanceExtension(
|
||||||
"ggp_stream_descriptor_surface",
|
"ggp_stream_descriptor_surface",
|
||||||
)])]),
|
)])]),
|
||||||
|
..Default::default()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -627,7 +621,7 @@ impl Surface {
|
|||||||
instance: Arc<Instance>,
|
instance: Arc<Instance>,
|
||||||
metal_layer: IOSMetalLayer,
|
metal_layer: IOSMetalLayer,
|
||||||
object: Option<Arc<dyn Any + Send + Sync>>,
|
object: Option<Arc<dyn Any + Send + Sync>>,
|
||||||
) -> Result<Arc<Self>, SurfaceCreationError> {
|
) -> Result<Arc<Self>, VulkanError> {
|
||||||
Self::validate_from_ios(&instance, &metal_layer)?;
|
Self::validate_from_ios(&instance, &metal_layer)?;
|
||||||
|
|
||||||
Ok(Self::from_ios_unchecked(instance, metal_layer, object)?)
|
Ok(Self::from_ios_unchecked(instance, metal_layer, object)?)
|
||||||
@ -637,13 +631,13 @@ impl Surface {
|
|||||||
fn validate_from_ios(
|
fn validate_from_ios(
|
||||||
instance: &Instance,
|
instance: &Instance,
|
||||||
_metal_layer: &IOSMetalLayer,
|
_metal_layer: &IOSMetalLayer,
|
||||||
) -> Result<(), SurfaceCreationError> {
|
) -> Result<(), ValidationError> {
|
||||||
if !instance.enabled_extensions().mvk_ios_surface {
|
if !instance.enabled_extensions().mvk_ios_surface {
|
||||||
return Err(SurfaceCreationError::RequirementNotMet {
|
return Err(ValidationError {
|
||||||
required_for: "`Surface::from_ios`",
|
|
||||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::InstanceExtension(
|
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::InstanceExtension(
|
||||||
"mvk_ios_surface",
|
"mvk_ios_surface",
|
||||||
)])]),
|
)])]),
|
||||||
|
..Default::default()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -704,7 +698,7 @@ impl Surface {
|
|||||||
instance: Arc<Instance>,
|
instance: Arc<Instance>,
|
||||||
view: *const V,
|
view: *const V,
|
||||||
object: Option<Arc<dyn Any + Send + Sync>>,
|
object: Option<Arc<dyn Any + Send + Sync>>,
|
||||||
) -> Result<Arc<Self>, SurfaceCreationError> {
|
) -> Result<Arc<Self>, VulkanError> {
|
||||||
Self::validate_from_mac_os(&instance, view)?;
|
Self::validate_from_mac_os(&instance, view)?;
|
||||||
|
|
||||||
Ok(Self::from_mac_os_unchecked(instance, view, object)?)
|
Ok(Self::from_mac_os_unchecked(instance, view, object)?)
|
||||||
@ -714,13 +708,13 @@ impl Surface {
|
|||||||
fn validate_from_mac_os<V>(
|
fn validate_from_mac_os<V>(
|
||||||
instance: &Instance,
|
instance: &Instance,
|
||||||
_view: *const V,
|
_view: *const V,
|
||||||
) -> Result<(), SurfaceCreationError> {
|
) -> Result<(), ValidationError> {
|
||||||
if !instance.enabled_extensions().mvk_macos_surface {
|
if !instance.enabled_extensions().mvk_macos_surface {
|
||||||
return Err(SurfaceCreationError::RequirementNotMet {
|
return Err(ValidationError {
|
||||||
required_for: "`Surface::from_mac_os`",
|
|
||||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::InstanceExtension(
|
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::InstanceExtension(
|
||||||
"mvk_macos_surface",
|
"mvk_macos_surface",
|
||||||
)])]),
|
)])]),
|
||||||
|
..Default::default()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -779,7 +773,7 @@ impl Surface {
|
|||||||
instance: Arc<Instance>,
|
instance: Arc<Instance>,
|
||||||
layer: *const L,
|
layer: *const L,
|
||||||
object: Option<Arc<dyn Any + Send + Sync>>,
|
object: Option<Arc<dyn Any + Send + Sync>>,
|
||||||
) -> Result<Arc<Self>, SurfaceCreationError> {
|
) -> Result<Arc<Self>, VulkanError> {
|
||||||
Self::validate_from_metal(&instance, layer)?;
|
Self::validate_from_metal(&instance, layer)?;
|
||||||
|
|
||||||
Ok(Self::from_metal_unchecked(instance, layer, object)?)
|
Ok(Self::from_metal_unchecked(instance, layer, object)?)
|
||||||
@ -788,13 +782,13 @@ impl Surface {
|
|||||||
fn validate_from_metal<L>(
|
fn validate_from_metal<L>(
|
||||||
instance: &Instance,
|
instance: &Instance,
|
||||||
_layer: *const L,
|
_layer: *const L,
|
||||||
) -> Result<(), SurfaceCreationError> {
|
) -> Result<(), ValidationError> {
|
||||||
if !instance.enabled_extensions().ext_metal_surface {
|
if !instance.enabled_extensions().ext_metal_surface {
|
||||||
return Err(SurfaceCreationError::RequirementNotMet {
|
return Err(ValidationError {
|
||||||
required_for: "`Surface::from_metal`",
|
|
||||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::InstanceExtension(
|
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::InstanceExtension(
|
||||||
"ext_metal_surface",
|
"ext_metal_surface",
|
||||||
)])]),
|
)])]),
|
||||||
|
..Default::default()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -848,7 +842,7 @@ impl Surface {
|
|||||||
context: *const C,
|
context: *const C,
|
||||||
window: *const W,
|
window: *const W,
|
||||||
object: Option<Arc<dyn Any + Send + Sync>>,
|
object: Option<Arc<dyn Any + Send + Sync>>,
|
||||||
) -> Result<Arc<Self>, SurfaceCreationError> {
|
) -> Result<Arc<Self>, VulkanError> {
|
||||||
Self::validate_from_qnx_screen(&instance, context, window)?;
|
Self::validate_from_qnx_screen(&instance, context, window)?;
|
||||||
|
|
||||||
Ok(Self::from_qnx_screen_unchecked(
|
Ok(Self::from_qnx_screen_unchecked(
|
||||||
@ -860,13 +854,13 @@ impl Surface {
|
|||||||
instance: &Instance,
|
instance: &Instance,
|
||||||
_context: *const C,
|
_context: *const C,
|
||||||
_window: *const W,
|
_window: *const W,
|
||||||
) -> Result<(), SurfaceCreationError> {
|
) -> Result<(), ValidationError> {
|
||||||
if !instance.enabled_extensions().qnx_screen_surface {
|
if !instance.enabled_extensions().qnx_screen_surface {
|
||||||
return Err(SurfaceCreationError::RequirementNotMet {
|
return Err(ValidationError {
|
||||||
required_for: "`Surface::from_qnx_screen`",
|
|
||||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::InstanceExtension(
|
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::InstanceExtension(
|
||||||
"qnx_screen_surface",
|
"qnx_screen_surface",
|
||||||
)])]),
|
)])]),
|
||||||
|
..Default::default()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -926,22 +920,19 @@ impl Surface {
|
|||||||
instance: Arc<Instance>,
|
instance: Arc<Instance>,
|
||||||
window: *const W,
|
window: *const W,
|
||||||
object: Option<Arc<dyn Any + Send + Sync>>,
|
object: Option<Arc<dyn Any + Send + Sync>>,
|
||||||
) -> Result<Arc<Self>, SurfaceCreationError> {
|
) -> Result<Arc<Self>, VulkanError> {
|
||||||
Self::validate_from_vi(&instance, window)?;
|
Self::validate_from_vi(&instance, window)?;
|
||||||
|
|
||||||
Ok(Self::from_vi_unchecked(instance, window, object)?)
|
Ok(Self::from_vi_unchecked(instance, window, object)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn validate_from_vi<W>(
|
fn validate_from_vi<W>(instance: &Instance, _window: *const W) -> Result<(), ValidationError> {
|
||||||
instance: &Instance,
|
|
||||||
_window: *const W,
|
|
||||||
) -> Result<(), SurfaceCreationError> {
|
|
||||||
if !instance.enabled_extensions().nn_vi_surface {
|
if !instance.enabled_extensions().nn_vi_surface {
|
||||||
return Err(SurfaceCreationError::RequirementNotMet {
|
return Err(ValidationError {
|
||||||
required_for: "`Surface::from_vi`",
|
|
||||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::InstanceExtension(
|
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::InstanceExtension(
|
||||||
"nn_vi_surface",
|
"nn_vi_surface",
|
||||||
)])]),
|
)])]),
|
||||||
|
..Default::default()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1000,7 +991,7 @@ impl Surface {
|
|||||||
display: *const D,
|
display: *const D,
|
||||||
surface: *const S,
|
surface: *const S,
|
||||||
object: Option<Arc<dyn Any + Send + Sync>>,
|
object: Option<Arc<dyn Any + Send + Sync>>,
|
||||||
) -> Result<Arc<Self>, SurfaceCreationError> {
|
) -> Result<Arc<Self>, VulkanError> {
|
||||||
Self::validate_from_wayland(&instance, display, surface)?;
|
Self::validate_from_wayland(&instance, display, surface)?;
|
||||||
|
|
||||||
Ok(Self::from_wayland_unchecked(
|
Ok(Self::from_wayland_unchecked(
|
||||||
@ -1012,13 +1003,13 @@ impl Surface {
|
|||||||
instance: &Instance,
|
instance: &Instance,
|
||||||
_display: *const D,
|
_display: *const D,
|
||||||
_surface: *const S,
|
_surface: *const S,
|
||||||
) -> Result<(), SurfaceCreationError> {
|
) -> Result<(), ValidationError> {
|
||||||
if !instance.enabled_extensions().khr_wayland_surface {
|
if !instance.enabled_extensions().khr_wayland_surface {
|
||||||
return Err(SurfaceCreationError::RequirementNotMet {
|
return Err(ValidationError {
|
||||||
required_for: "`Surface::from_wayland`",
|
|
||||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::InstanceExtension(
|
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::InstanceExtension(
|
||||||
"khr_wayland_surface",
|
"khr_wayland_surface",
|
||||||
)])]),
|
)])]),
|
||||||
|
..Default::default()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1082,7 +1073,7 @@ impl Surface {
|
|||||||
hinstance: *const I,
|
hinstance: *const I,
|
||||||
hwnd: *const W,
|
hwnd: *const W,
|
||||||
object: Option<Arc<dyn Any + Send + Sync>>,
|
object: Option<Arc<dyn Any + Send + Sync>>,
|
||||||
) -> Result<Arc<Self>, SurfaceCreationError> {
|
) -> Result<Arc<Self>, VulkanError> {
|
||||||
Self::validate_from_win32(&instance, hinstance, hwnd)?;
|
Self::validate_from_win32(&instance, hinstance, hwnd)?;
|
||||||
|
|
||||||
Ok(Self::from_win32_unchecked(
|
Ok(Self::from_win32_unchecked(
|
||||||
@ -1094,13 +1085,13 @@ impl Surface {
|
|||||||
instance: &Instance,
|
instance: &Instance,
|
||||||
_hinstance: *const I,
|
_hinstance: *const I,
|
||||||
_hwnd: *const W,
|
_hwnd: *const W,
|
||||||
) -> Result<(), SurfaceCreationError> {
|
) -> Result<(), ValidationError> {
|
||||||
if !instance.enabled_extensions().khr_win32_surface {
|
if !instance.enabled_extensions().khr_win32_surface {
|
||||||
return Err(SurfaceCreationError::RequirementNotMet {
|
return Err(ValidationError {
|
||||||
required_for: "`Surface::from_win32`",
|
|
||||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::InstanceExtension(
|
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::InstanceExtension(
|
||||||
"khr_win32_surface",
|
"khr_win32_surface",
|
||||||
)])]),
|
)])]),
|
||||||
|
..Default::default()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1164,7 +1155,7 @@ impl Surface {
|
|||||||
connection: *const C,
|
connection: *const C,
|
||||||
window: ash::vk::xcb_window_t,
|
window: ash::vk::xcb_window_t,
|
||||||
object: Option<Arc<dyn Any + Send + Sync>>,
|
object: Option<Arc<dyn Any + Send + Sync>>,
|
||||||
) -> Result<Arc<Self>, SurfaceCreationError> {
|
) -> Result<Arc<Self>, VulkanError> {
|
||||||
Self::validate_from_xcb(&instance, connection, window)?;
|
Self::validate_from_xcb(&instance, connection, window)?;
|
||||||
|
|
||||||
Ok(Self::from_xcb_unchecked(
|
Ok(Self::from_xcb_unchecked(
|
||||||
@ -1176,13 +1167,13 @@ impl Surface {
|
|||||||
instance: &Instance,
|
instance: &Instance,
|
||||||
_connection: *const C,
|
_connection: *const C,
|
||||||
_window: ash::vk::xcb_window_t,
|
_window: ash::vk::xcb_window_t,
|
||||||
) -> Result<(), SurfaceCreationError> {
|
) -> Result<(), ValidationError> {
|
||||||
if !instance.enabled_extensions().khr_xcb_surface {
|
if !instance.enabled_extensions().khr_xcb_surface {
|
||||||
return Err(SurfaceCreationError::RequirementNotMet {
|
return Err(ValidationError {
|
||||||
required_for: "`Surface::from_xcb`",
|
|
||||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::InstanceExtension(
|
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::InstanceExtension(
|
||||||
"khr_xcb_surface",
|
"khr_xcb_surface",
|
||||||
)])]),
|
)])]),
|
||||||
|
..Default::default()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1246,7 +1237,7 @@ impl Surface {
|
|||||||
display: *const D,
|
display: *const D,
|
||||||
window: ash::vk::Window,
|
window: ash::vk::Window,
|
||||||
object: Option<Arc<dyn Any + Send + Sync>>,
|
object: Option<Arc<dyn Any + Send + Sync>>,
|
||||||
) -> Result<Arc<Self>, SurfaceCreationError> {
|
) -> Result<Arc<Self>, VulkanError> {
|
||||||
Self::validate_from_xlib(&instance, display, window)?;
|
Self::validate_from_xlib(&instance, display, window)?;
|
||||||
|
|
||||||
Ok(Self::from_xlib_unchecked(
|
Ok(Self::from_xlib_unchecked(
|
||||||
@ -1258,13 +1249,13 @@ impl Surface {
|
|||||||
instance: &Instance,
|
instance: &Instance,
|
||||||
_display: *const D,
|
_display: *const D,
|
||||||
_window: ash::vk::Window,
|
_window: ash::vk::Window,
|
||||||
) -> Result<(), SurfaceCreationError> {
|
) -> Result<(), ValidationError> {
|
||||||
if !instance.enabled_extensions().khr_xlib_surface {
|
if !instance.enabled_extensions().khr_xlib_surface {
|
||||||
return Err(SurfaceCreationError::RequirementNotMet {
|
return Err(ValidationError {
|
||||||
required_for: "`Surface::from_xlib`",
|
|
||||||
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::InstanceExtension(
|
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::InstanceExtension(
|
||||||
"khr_xlib_surface",
|
"khr_xlib_surface",
|
||||||
)])]),
|
)])]),
|
||||||
|
..Default::default()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1379,7 +1370,6 @@ impl Debug for Surface {
|
|||||||
instance,
|
instance,
|
||||||
api,
|
api,
|
||||||
object: _,
|
object: _,
|
||||||
has_swapchain,
|
|
||||||
..
|
..
|
||||||
} = self;
|
} = self;
|
||||||
|
|
||||||
@ -1388,18 +1378,10 @@ impl Debug for Surface {
|
|||||||
.field("instance", instance)
|
.field("instance", instance)
|
||||||
.field("api", api)
|
.field("api", api)
|
||||||
.field("window", &())
|
.field("window", &())
|
||||||
.field("has_swapchain", &has_swapchain)
|
|
||||||
.finish()
|
.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl SurfaceSwapchainLock for Surface {
|
|
||||||
#[inline]
|
|
||||||
fn flag(&self) -> &AtomicBool {
|
|
||||||
&self.has_swapchain
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get sublayer from iOS main view (ui_view). The sublayer is created as `CAMetalLayer`.
|
/// Get sublayer from iOS main view (ui_view). The sublayer is created as `CAMetalLayer`.
|
||||||
#[cfg(target_os = "ios")]
|
#[cfg(target_os = "ios")]
|
||||||
unsafe fn get_metal_layer_ios(ui_view: *mut std::ffi::c_void) -> IOSMetalLayer {
|
unsafe fn get_metal_layer_ios(ui_view: *mut std::ffi::c_void) -> IOSMetalLayer {
|
||||||
@ -1447,63 +1429,6 @@ unsafe fn get_metal_layer_macos(ns_view: *mut std::ffi::c_void) -> *mut Object {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Error that can happen when creating a surface.
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
|
||||||
pub enum SurfaceCreationError {
|
|
||||||
/// Not enough memory.
|
|
||||||
OomError(OomError),
|
|
||||||
|
|
||||||
RequirementNotMet {
|
|
||||||
required_for: &'static str,
|
|
||||||
requires_one_of: RequiresOneOf,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Error for SurfaceCreationError {
|
|
||||||
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
|
||||||
match self {
|
|
||||||
SurfaceCreationError::OomError(err) => Some(err),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Display for SurfaceCreationError {
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
|
||||||
match self {
|
|
||||||
Self::OomError(_) => write!(f, "not enough memory available"),
|
|
||||||
Self::RequirementNotMet {
|
|
||||||
required_for,
|
|
||||||
requires_one_of,
|
|
||||||
} => write!(
|
|
||||||
f,
|
|
||||||
"a requirement was not met for: {}; requires one of: {}",
|
|
||||||
required_for, requires_one_of,
|
|
||||||
),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<OomError> for SurfaceCreationError {
|
|
||||||
fn from(err: OomError) -> SurfaceCreationError {
|
|
||||||
SurfaceCreationError::OomError(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<RuntimeError> for SurfaceCreationError {
|
|
||||||
fn from(err: RuntimeError) -> SurfaceCreationError {
|
|
||||||
match err {
|
|
||||||
err @ RuntimeError::OutOfHostMemory => {
|
|
||||||
SurfaceCreationError::OomError(OomError::from(err))
|
|
||||||
}
|
|
||||||
err @ RuntimeError::OutOfDeviceMemory => {
|
|
||||||
SurfaceCreationError::OomError(OomError::from(err))
|
|
||||||
}
|
|
||||||
_ => panic!("unexpected error: {:?}", err),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The windowing API that was used to construct a surface.
|
/// The windowing API that was used to construct a surface.
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
@ -1882,8 +1807,21 @@ vulkan_enum! {
|
|||||||
/// [`PhysicalDevice::surface_formats`]: crate::device::physical::PhysicalDevice::surface_formats
|
/// [`PhysicalDevice::surface_formats`]: crate::device::physical::PhysicalDevice::surface_formats
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||||
pub struct SurfaceInfo {
|
pub struct SurfaceInfo {
|
||||||
|
/// If this is `Some`, the
|
||||||
|
/// [`ext_surface_maintenance1`](crate::instance::InstanceExtensions::ext_surface_maintenance1)
|
||||||
|
/// extension must be enabled on the instance.
|
||||||
|
pub present_mode: Option<PresentMode>,
|
||||||
|
|
||||||
|
/// If this is not [`FullScreenExclusive::Default`], the
|
||||||
|
/// [`ext_full_screen_exclusive`](crate::device::DeviceExtensions::ext_full_screen_exclusive)
|
||||||
|
/// extension must be supported by the physical device.
|
||||||
pub full_screen_exclusive: FullScreenExclusive,
|
pub full_screen_exclusive: FullScreenExclusive,
|
||||||
|
|
||||||
|
/// If `full_screen_exclusive` is [`FullScreenExclusive::ApplicationControlled`], and the
|
||||||
|
/// surface being queried is a Win32 surface, then this must be `Some`. Otherwise, it must be
|
||||||
|
/// `None`.
|
||||||
pub win32_monitor: Option<Win32Monitor>,
|
pub win32_monitor: Option<Win32Monitor>,
|
||||||
|
|
||||||
pub _ne: crate::NonExhaustive,
|
pub _ne: crate::NonExhaustive,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1891,6 +1829,7 @@ impl Default for SurfaceInfo {
|
|||||||
#[inline]
|
#[inline]
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
present_mode: None,
|
||||||
full_screen_exclusive: FullScreenExclusive::Default,
|
full_screen_exclusive: FullScreenExclusive::Default,
|
||||||
win32_monitor: None,
|
win32_monitor: None,
|
||||||
_ne: crate::NonExhaustive(()),
|
_ne: crate::NonExhaustive(()),
|
||||||
@ -1901,15 +1840,41 @@ impl Default for SurfaceInfo {
|
|||||||
impl SurfaceInfo {
|
impl SurfaceInfo {
|
||||||
pub(crate) fn validate(&self, physical_device: &PhysicalDevice) -> Result<(), ValidationError> {
|
pub(crate) fn validate(&self, physical_device: &PhysicalDevice) -> Result<(), ValidationError> {
|
||||||
let &Self {
|
let &Self {
|
||||||
|
present_mode,
|
||||||
full_screen_exclusive,
|
full_screen_exclusive,
|
||||||
win32_monitor: _,
|
win32_monitor: _,
|
||||||
_ne: _,
|
_ne: _,
|
||||||
} = self;
|
} = self;
|
||||||
|
|
||||||
if !physical_device
|
if let Some(present_mode) = present_mode {
|
||||||
.supported_extensions()
|
if !physical_device
|
||||||
.ext_full_screen_exclusive
|
.instance()
|
||||||
&& full_screen_exclusive != FullScreenExclusive::Default
|
.enabled_extensions()
|
||||||
|
.ext_surface_maintenance1
|
||||||
|
{
|
||||||
|
return Err(ValidationError {
|
||||||
|
context: "present_mode".into(),
|
||||||
|
problem: "is `Some`".into(),
|
||||||
|
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[
|
||||||
|
Requires::InstanceExtension("ext_surface_maintenance1"),
|
||||||
|
])]),
|
||||||
|
..Default::default()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
present_mode
|
||||||
|
.validate_physical_device(physical_device)
|
||||||
|
.map_err(|err| ValidationError {
|
||||||
|
context: "present_mode".into(),
|
||||||
|
vuids: &["VUID-VkSurfacePresentModeEXT-presentMode-parameter"],
|
||||||
|
..ValidationError::from_requirement(err)
|
||||||
|
})?;
|
||||||
|
}
|
||||||
|
|
||||||
|
if full_screen_exclusive != FullScreenExclusive::Default
|
||||||
|
&& !physical_device
|
||||||
|
.supported_extensions()
|
||||||
|
.ext_full_screen_exclusive
|
||||||
{
|
{
|
||||||
return Err(ValidationError {
|
return Err(ValidationError {
|
||||||
context: "full_screen_exclusive".into(),
|
context: "full_screen_exclusive".into(),
|
||||||
@ -1972,8 +1937,9 @@ pub struct SurfaceCapabilities {
|
|||||||
/// you may still get out of memory errors.
|
/// you may still get out of memory errors.
|
||||||
pub max_image_count: Option<u32>,
|
pub max_image_count: Option<u32>,
|
||||||
|
|
||||||
/// The current dimensions of the surface. `None` means that the surface's dimensions will
|
/// The current dimensions of the surface.
|
||||||
/// depend on the dimensions of the swapchain that you are going to create.
|
///
|
||||||
|
/// `None` means that the surface's dimensions will depend on the dimensions of the swapchain.
|
||||||
pub current_extent: Option<[u32; 2]>,
|
pub current_extent: Option<[u32; 2]>,
|
||||||
|
|
||||||
/// Minimum width and height of a swapchain that uses this surface.
|
/// Minimum width and height of a swapchain that uses this surface.
|
||||||
@ -1998,6 +1964,49 @@ pub struct SurfaceCapabilities {
|
|||||||
/// the `color_attachment` usage is guaranteed to be supported.
|
/// the `color_attachment` usage is guaranteed to be supported.
|
||||||
pub supported_usage_flags: ImageUsage,
|
pub supported_usage_flags: ImageUsage,
|
||||||
|
|
||||||
|
/// When [`SurfaceInfo::present_mode`] is provided,
|
||||||
|
/// lists that present mode and any modes that are compatible with that present mode.
|
||||||
|
///
|
||||||
|
/// If [`SurfaceInfo::present_mode`] was not provided, the value will be empty.
|
||||||
|
pub compatible_present_modes: SmallVec<[PresentMode; PresentMode::COUNT]>,
|
||||||
|
|
||||||
|
/// When [`SurfaceInfo::present_mode`] is provided,
|
||||||
|
/// the supported present scaling modes for the queried present mode.
|
||||||
|
///
|
||||||
|
/// If [`SurfaceInfo::present_mode`] was not provided, the value will be empty.
|
||||||
|
pub supported_present_scaling: PresentScalingFlags,
|
||||||
|
|
||||||
|
/// When [`SurfaceInfo::present_mode`] is provided,
|
||||||
|
/// the supported present gravity modes, horizontally and vertically,
|
||||||
|
/// for the queried present mode.
|
||||||
|
///
|
||||||
|
/// If [`SurfaceInfo::present_mode`] was not provided, both values will be empty.
|
||||||
|
pub supported_present_gravity: [PresentGravityFlags; 2],
|
||||||
|
|
||||||
|
/// When [`SurfaceInfo::present_mode`] is provided,
|
||||||
|
/// the smallest allowed extent for a swapchain, if it uses the queried present mode, and
|
||||||
|
/// one of the scaling modes in `supported_present_scaling`.
|
||||||
|
///
|
||||||
|
/// This is never greater than [`SurfaceCapabilities::min_image_extent`].
|
||||||
|
///
|
||||||
|
/// `None` means that the surface's dimensions will depend on the dimensions of the swapchain.
|
||||||
|
///
|
||||||
|
/// If [`SurfaceInfo::present_mode`] was not provided, this is will be equal to
|
||||||
|
/// `min_image_extent`.
|
||||||
|
pub min_scaled_image_extent: Option<[u32; 2]>,
|
||||||
|
|
||||||
|
/// When [`SurfaceInfo::present_mode`] is provided,
|
||||||
|
/// the largest allowed extent for a swapchain, if it uses the queried present mode, and
|
||||||
|
/// one of the scaling modes in `supported_present_scaling`.
|
||||||
|
///
|
||||||
|
/// This is never less than [`SurfaceCapabilities::max_image_extent`].
|
||||||
|
///
|
||||||
|
/// `None` means that the surface's dimensions will depend on the dimensions of the swapchain.
|
||||||
|
///
|
||||||
|
/// If [`SurfaceInfo::present_mode`] was not provided, this is will be equal to
|
||||||
|
/// `max_image_extent`.
|
||||||
|
pub max_scaled_image_extent: Option<[u32; 2]>,
|
||||||
|
|
||||||
/// Whether creating a protected swapchain is supported.
|
/// Whether creating a protected swapchain is supported.
|
||||||
pub supports_protected: bool,
|
pub supports_protected: bool,
|
||||||
|
|
||||||
@ -2008,8 +2017,7 @@ pub struct SurfaceCapabilities {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::{
|
use crate::{
|
||||||
swapchain::{Surface, SurfaceCreationError},
|
swapchain::Surface, Requires, RequiresAllOf, RequiresOneOf, ValidationError, VulkanError,
|
||||||
Requires, RequiresAllOf, RequiresOneOf,
|
|
||||||
};
|
};
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
|
|
||||||
@ -2017,11 +2025,11 @@ mod tests {
|
|||||||
fn khr_win32_surface_ext_missing() {
|
fn khr_win32_surface_ext_missing() {
|
||||||
let instance = instance!();
|
let instance = instance!();
|
||||||
match unsafe { Surface::from_win32(instance, ptr::null::<u8>(), ptr::null::<u8>(), None) } {
|
match unsafe { Surface::from_win32(instance, ptr::null::<u8>(), ptr::null::<u8>(), None) } {
|
||||||
Err(SurfaceCreationError::RequirementNotMet {
|
Err(VulkanError::ValidationError(ValidationError {
|
||||||
requires_one_of:
|
requires_one_of:
|
||||||
RequiresOneOf([RequiresAllOf([Requires::InstanceExtension("khr_win32_surface")])]),
|
RequiresOneOf([RequiresAllOf([Requires::InstanceExtension("khr_win32_surface")])]),
|
||||||
..
|
..
|
||||||
}) => (),
|
})) => (),
|
||||||
_ => panic!(),
|
_ => panic!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2030,11 +2038,11 @@ mod tests {
|
|||||||
fn khr_xcb_surface_ext_missing() {
|
fn khr_xcb_surface_ext_missing() {
|
||||||
let instance = instance!();
|
let instance = instance!();
|
||||||
match unsafe { Surface::from_xcb(instance, ptr::null::<u8>(), 0, None) } {
|
match unsafe { Surface::from_xcb(instance, ptr::null::<u8>(), 0, None) } {
|
||||||
Err(SurfaceCreationError::RequirementNotMet {
|
Err(VulkanError::ValidationError(ValidationError {
|
||||||
requires_one_of:
|
requires_one_of:
|
||||||
RequiresOneOf([RequiresAllOf([Requires::InstanceExtension("khr_xcb_surface")])]),
|
RequiresOneOf([RequiresAllOf([Requires::InstanceExtension("khr_xcb_surface")])]),
|
||||||
..
|
..
|
||||||
}) => (),
|
})) => (),
|
||||||
_ => panic!(),
|
_ => panic!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2043,11 +2051,11 @@ mod tests {
|
|||||||
fn khr_xlib_surface_ext_missing() {
|
fn khr_xlib_surface_ext_missing() {
|
||||||
let instance = instance!();
|
let instance = instance!();
|
||||||
match unsafe { Surface::from_xlib(instance, ptr::null::<u8>(), 0, None) } {
|
match unsafe { Surface::from_xlib(instance, ptr::null::<u8>(), 0, None) } {
|
||||||
Err(SurfaceCreationError::RequirementNotMet {
|
Err(VulkanError::ValidationError(ValidationError {
|
||||||
requires_one_of:
|
requires_one_of:
|
||||||
RequiresOneOf([RequiresAllOf([Requires::InstanceExtension("khr_xlib_surface")])]),
|
RequiresOneOf([RequiresAllOf([Requires::InstanceExtension("khr_xlib_surface")])]),
|
||||||
..
|
..
|
||||||
}) => (),
|
})) => (),
|
||||||
_ => panic!(),
|
_ => panic!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2057,11 +2065,11 @@ mod tests {
|
|||||||
let instance = instance!();
|
let instance = instance!();
|
||||||
match unsafe { Surface::from_wayland(instance, ptr::null::<u8>(), ptr::null::<u8>(), None) }
|
match unsafe { Surface::from_wayland(instance, ptr::null::<u8>(), ptr::null::<u8>(), None) }
|
||||||
{
|
{
|
||||||
Err(SurfaceCreationError::RequirementNotMet {
|
Err(VulkanError::ValidationError(ValidationError {
|
||||||
requires_one_of:
|
requires_one_of:
|
||||||
RequiresOneOf([RequiresAllOf([Requires::InstanceExtension("khr_wayland_surface")])]),
|
RequiresOneOf([RequiresAllOf([Requires::InstanceExtension("khr_wayland_surface")])]),
|
||||||
..
|
..
|
||||||
}) => (),
|
})) => (),
|
||||||
_ => panic!(),
|
_ => panic!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2070,11 +2078,11 @@ mod tests {
|
|||||||
fn khr_android_surface_ext_missing() {
|
fn khr_android_surface_ext_missing() {
|
||||||
let instance = instance!();
|
let instance = instance!();
|
||||||
match unsafe { Surface::from_android(instance, ptr::null::<u8>(), None) } {
|
match unsafe { Surface::from_android(instance, ptr::null::<u8>(), None) } {
|
||||||
Err(SurfaceCreationError::RequirementNotMet {
|
Err(VulkanError::ValidationError(ValidationError {
|
||||||
requires_one_of:
|
requires_one_of:
|
||||||
RequiresOneOf([RequiresAllOf([Requires::InstanceExtension("khr_android_surface")])]),
|
RequiresOneOf([RequiresAllOf([Requires::InstanceExtension("khr_android_surface")])]),
|
||||||
..
|
..
|
||||||
}) => (),
|
})) => (),
|
||||||
_ => panic!(),
|
_ => panic!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -310,8 +310,12 @@ where
|
|||||||
.map_err(|err| OutcomeErr::Full(err.into()))
|
.map_err(|err| OutcomeErr::Full(err.into()))
|
||||||
}
|
}
|
||||||
SubmitAnyBuilder::QueuePresent(present_info) => {
|
SubmitAnyBuilder::QueuePresent(present_info) => {
|
||||||
let intermediary_result = if partially_flushed {
|
if partially_flushed {
|
||||||
Ok(())
|
queue
|
||||||
|
.with(|mut q| {
|
||||||
|
q.submit_unchecked([Default::default()], Some(new_fence.clone()))
|
||||||
|
})
|
||||||
|
.map_err(|err| OutcomeErr::Partial(err.into()))
|
||||||
} else {
|
} else {
|
||||||
// VUID-VkPresentIdKHR-presentIds-04999
|
// VUID-VkPresentIdKHR-presentIds-04999
|
||||||
for swapchain_info in &present_info.swapchain_infos {
|
for swapchain_info in &present_info.swapchain_infos {
|
||||||
@ -334,19 +338,22 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
queue
|
let intermediary_result = queue
|
||||||
.with(|mut q| q.present_unchecked(present_info))?
|
.with(|mut q| q.present_unchecked(present_info))?
|
||||||
.map(|r| r.map(|_| ()))
|
.map(|r| r.map(|_| ()))
|
||||||
.fold(Ok(()), Result::and)
|
.fold(Ok(()), Result::and);
|
||||||
};
|
|
||||||
|
|
||||||
match intermediary_result {
|
match intermediary_result {
|
||||||
Ok(()) => queue
|
Ok(()) => queue
|
||||||
.with(|mut q| {
|
.with(|mut q| {
|
||||||
q.submit_unchecked([Default::default()], Some(new_fence.clone()))
|
q.submit_unchecked(
|
||||||
})
|
[Default::default()],
|
||||||
.map_err(|err| OutcomeErr::Partial(err.into())),
|
Some(new_fence.clone()),
|
||||||
Err(err) => Err(OutcomeErr::Full(err.into())),
|
)
|
||||||
|
})
|
||||||
|
.map_err(|err| OutcomeErr::Partial(err.into())),
|
||||||
|
Err(err) => Err(OutcomeErr::Full(err.into())),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -597,6 +597,10 @@ pub enum FlushError {
|
|||||||
/// for the same swapchain.
|
/// for the same swapchain.
|
||||||
PresentIdLessThanOrEqual,
|
PresentIdLessThanOrEqual,
|
||||||
|
|
||||||
|
/// A new present mode was provided, but this mode was not one of the valid present modes
|
||||||
|
/// that the swapchain was created with.
|
||||||
|
PresentModeNotValid,
|
||||||
|
|
||||||
/// Access to a resource has been denied.
|
/// Access to a resource has been denied.
|
||||||
ResourceAccessError {
|
ResourceAccessError {
|
||||||
error: AccessError,
|
error: AccessError,
|
||||||
@ -615,9 +619,9 @@ pub enum FlushError {
|
|||||||
impl Error for FlushError {
|
impl Error for FlushError {
|
||||||
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
||||||
match self {
|
match self {
|
||||||
FlushError::AccessError(err) => Some(err),
|
Self::AccessError(err) => Some(err),
|
||||||
FlushError::OomError(err) => Some(err),
|
Self::OomError(err) => Some(err),
|
||||||
FlushError::ResourceAccessError { error, .. } => Some(error),
|
Self::ResourceAccessError { error, .. } => Some(error),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -629,27 +633,31 @@ impl Display for FlushError {
|
|||||||
f,
|
f,
|
||||||
"{}",
|
"{}",
|
||||||
match self {
|
match self {
|
||||||
FlushError::AccessError(_) => "access to a resource has been denied",
|
Self::AccessError(_) => "access to a resource has been denied",
|
||||||
FlushError::OomError(_) => "not enough memory",
|
Self::OomError(_) => "not enough memory",
|
||||||
FlushError::DeviceLost => "the connection to the device has been lost",
|
Self::DeviceLost => "the connection to the device has been lost",
|
||||||
FlushError::SurfaceLost => "the surface of this swapchain is no longer valid",
|
Self::SurfaceLost => "the surface of this swapchain is no longer valid",
|
||||||
FlushError::OutOfDate => "the swapchain needs to be recreated",
|
Self::OutOfDate => "the swapchain needs to be recreated",
|
||||||
FlushError::FullScreenExclusiveModeLost => {
|
Self::FullScreenExclusiveModeLost => {
|
||||||
"the swapchain no longer has full screen exclusivity"
|
"the swapchain no longer has full screen exclusivity"
|
||||||
}
|
}
|
||||||
FlushError::Timeout => {
|
Self::Timeout => {
|
||||||
"the flush operation needed to block, but the timeout has elapsed"
|
"the flush operation needed to block, but the timeout has elapsed"
|
||||||
}
|
}
|
||||||
FlushError::PresentIdLessThanOrEqual => {
|
Self::PresentIdLessThanOrEqual => {
|
||||||
"present id is less than or equal to previous"
|
"present id is less than or equal to previous"
|
||||||
}
|
}
|
||||||
FlushError::ResourceAccessError { .. } => "access to a resource has been denied",
|
Self::PresentModeNotValid => {
|
||||||
FlushError::OneTimeSubmitAlreadySubmitted => {
|
"a new present mode was provided, but this mode was not one of the valid \
|
||||||
|
present modes that the swapchain was created with"
|
||||||
|
}
|
||||||
|
Self::ResourceAccessError { .. } => "access to a resource has been denied",
|
||||||
|
Self::OneTimeSubmitAlreadySubmitted => {
|
||||||
"the command buffer or one of the secondary command buffers it executes was \
|
"the command buffer or one of the secondary command buffers it executes was \
|
||||||
created with the \"one time submit\" flag, but has already been submitted in \
|
created with the \"one time submit\" flag, but has already been submitted in \
|
||||||
the past"
|
the past"
|
||||||
}
|
}
|
||||||
FlushError::ExclusiveAlreadyInUse => {
|
Self::ExclusiveAlreadyInUse => {
|
||||||
"the command buffer or one of the secondary command buffers it executes is \
|
"the command buffer or one of the secondary command buffers it executes is \
|
||||||
already in use was not created with the \"concurrent\" flag"
|
already in use was not created with the \"concurrent\" flag"
|
||||||
}
|
}
|
||||||
@ -660,7 +668,7 @@ impl Display for FlushError {
|
|||||||
|
|
||||||
impl From<AccessError> for FlushError {
|
impl From<AccessError> for FlushError {
|
||||||
fn from(err: AccessError) -> FlushError {
|
fn from(err: AccessError) -> FlushError {
|
||||||
FlushError::AccessError(err)
|
Self::AccessError(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -682,9 +690,9 @@ impl From<RuntimeError> for FlushError {
|
|||||||
impl From<FenceError> for FlushError {
|
impl From<FenceError> for FlushError {
|
||||||
fn from(err: FenceError) -> FlushError {
|
fn from(err: FenceError) -> FlushError {
|
||||||
match err {
|
match err {
|
||||||
FenceError::OomError(err) => FlushError::OomError(err),
|
FenceError::OomError(err) => Self::OomError(err),
|
||||||
FenceError::Timeout => FlushError::Timeout,
|
FenceError::Timeout => Self::Timeout,
|
||||||
FenceError::DeviceLost => FlushError::DeviceLost,
|
FenceError::DeviceLost => Self::DeviceLost,
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user