ValidationError-ify futures (#2271)

* ValidationError-ify sync primitives

* Fix Windows error

* Return timeouts as errors instead

* Simplify a bit

* ValidationError-ify futures

* Update vulkano/src/sync/future/semaphore_signal.rs

Co-authored-by: marc0246 <40955683+marc0246@users.noreply.github.com>

* Update vulkano/src/swapchain/acquire_present.rs

Co-authored-by: marc0246 <40955683+marc0246@users.noreply.github.com>

* Update vulkano/src/sync/future/fence_signal.rs

Co-authored-by: marc0246 <40955683+marc0246@users.noreply.github.com>

---------

Co-authored-by: marc0246 <40955683+marc0246@users.noreply.github.com>
This commit is contained in:
Rua 2023-08-04 22:02:45 +02:00 committed by GitHub
parent 12dc95c6ec
commit b7c79acb77
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
32 changed files with 391 additions and 593 deletions

View File

@ -85,11 +85,10 @@ use vulkano::{
},
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
swapchain::{
acquire_next_image, AcquireError, Surface, Swapchain, SwapchainCreateInfo,
SwapchainPresentInfo,
acquire_next_image, Surface, Swapchain, SwapchainCreateInfo, SwapchainPresentInfo,
},
sync::{self, FlushError, GpuFuture},
VulkanLibrary,
sync::{self, GpuFuture},
Validated, VulkanError, VulkanLibrary,
};
use winit::{
event::{ElementState, Event, KeyboardInput, VirtualKeyCode, WindowEvent},
@ -570,9 +569,9 @@ fn main() {
}
let (image_index, suboptimal, acquire_future) =
match acquire_next_image(swapchain.clone(), None) {
match acquire_next_image(swapchain.clone(), None).map_err(Validated::unwrap) {
Ok(r) => r,
Err(AcquireError::OutOfDate) => {
Err(VulkanError::OutOfDate) => {
recreate_swapchain = true;
return;
}
@ -666,11 +665,11 @@ fn main() {
)
.then_signal_fence_and_flush();
match future {
match future.map_err(Validated::unwrap) {
Ok(future) => {
previous_frame_end = Some(future.boxed());
}
Err(FlushError::OutOfDate) => {
Err(VulkanError::OutOfDate) => {
recreate_swapchain = true;
previous_frame_end = Some(sync::now(device.clone()).boxed());
}

View File

@ -44,11 +44,10 @@ use vulkano::{
},
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
swapchain::{
acquire_next_image, AcquireError, Surface, Swapchain, SwapchainCreateInfo,
SwapchainPresentInfo,
acquire_next_image, Surface, Swapchain, SwapchainCreateInfo, SwapchainPresentInfo,
},
sync::{self, FlushError, GpuFuture},
VulkanLibrary,
sync::{self, GpuFuture},
Validated, VulkanError, VulkanLibrary,
};
use winit::{
event::{Event, WindowEvent},
@ -318,9 +317,9 @@ fn main() {
}
let (image_index, suboptimal, acquire_future) =
match acquire_next_image(swapchain.clone(), None) {
match acquire_next_image(swapchain.clone(), None).map_err(Validated::unwrap) {
Ok(r) => r,
Err(AcquireError::OutOfDate) => {
Err(VulkanError::OutOfDate) => {
recreate_swapchain = true;
return;
}
@ -409,11 +408,11 @@ fn main() {
)
.then_signal_fence_and_flush();
match future {
match future.map_err(Validated::unwrap) {
Ok(future) => {
previous_frame_end = Some(Box::new(future) as Box<_>);
}
Err(FlushError::OutOfDate) => {
Err(VulkanError::OutOfDate) => {
recreate_swapchain = true;
previous_frame_end = Some(Box::new(sync::now(device.clone())) as Box<_>);
}

View File

@ -21,11 +21,10 @@ use vulkano::{
instance::{Instance, InstanceCreateFlags, InstanceCreateInfo},
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass},
swapchain::{
acquire_next_image, AcquireError, Surface, Swapchain, SwapchainCreateInfo,
SwapchainPresentInfo,
acquire_next_image, Surface, Swapchain, SwapchainCreateInfo, SwapchainPresentInfo,
},
sync::{self, FlushError, GpuFuture},
VulkanLibrary,
sync::{self, GpuFuture},
Validated, VulkanError, VulkanLibrary,
};
use winit::{
event::{Event, WindowEvent},
@ -196,9 +195,9 @@ fn main() {
}
let (image_index, suboptimal, acquire_future) =
match acquire_next_image(swapchain.clone(), None) {
match acquire_next_image(swapchain.clone(), None).map_err(Validated::unwrap) {
Ok(r) => r,
Err(AcquireError::OutOfDate) => {
Err(VulkanError::OutOfDate) => {
recreate_swapchain = true;
return;
}
@ -276,11 +275,11 @@ fn main() {
)
.then_signal_fence_and_flush();
match future {
match future.map_err(Validated::unwrap) {
Ok(future) => {
previous_frame_end = Some(future.boxed());
}
Err(FlushError::OutOfDate) => {
Err(VulkanError::OutOfDate) => {
recreate_swapchain = true;
previous_frame_end = Some(sync::now(device.clone()).boxed());
}

View File

@ -41,11 +41,10 @@ use vulkano::{
instance::{Instance, InstanceCreateFlags, InstanceCreateInfo},
memory::allocator::StandardMemoryAllocator,
swapchain::{
acquire_next_image, AcquireError, Surface, Swapchain, SwapchainCreateInfo,
SwapchainPresentInfo,
acquire_next_image, Surface, Swapchain, SwapchainCreateInfo, SwapchainPresentInfo,
},
sync::{self, FlushError, GpuFuture},
VulkanLibrary,
sync::{self, GpuFuture},
Validated, VulkanError, VulkanLibrary,
};
use winit::{
event::{Event, WindowEvent},
@ -222,9 +221,9 @@ fn main() {
}
let (image_index, suboptimal, acquire_future) =
match acquire_next_image(swapchain.clone(), None) {
match acquire_next_image(swapchain.clone(), None).map_err(Validated::unwrap) {
Ok(r) => r,
Err(AcquireError::OutOfDate) => {
Err(VulkanError::OutOfDate) => {
recreate_swapchain = true;
return;
}
@ -269,11 +268,11 @@ fn main() {
)
.then_signal_fence_and_flush();
match future {
match future.map_err(Validated::unwrap) {
Ok(future) => {
previous_frame_end = Some(future.boxed());
}
Err(FlushError::OutOfDate) => {
Err(VulkanError::OutOfDate) => {
recreate_swapchain = true;
previous_frame_end = Some(sync::now(device.clone()).boxed());
}

View File

@ -60,16 +60,18 @@ mod linux {
PipelineShaderStageCreateInfo,
},
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
swapchain::{AcquireError, Surface, Swapchain, SwapchainCreateInfo, SwapchainPresentInfo},
swapchain::{
acquire_next_image, Surface, Swapchain, SwapchainCreateInfo, SwapchainPresentInfo,
},
sync::{
now,
semaphore::{
ExternalSemaphoreHandleType, ExternalSemaphoreHandleTypes, Semaphore,
SemaphoreCreateInfo,
},
FlushError, GpuFuture,
GpuFuture,
},
VulkanLibrary,
Validated, VulkanError, VulkanLibrary,
};
use winit::{
event::{Event, WindowEvent},
@ -349,15 +351,19 @@ mod linux {
recreate_swapchain = false;
}
let (image_index, suboptimal, acquire_future) =
match vulkano::swapchain::acquire_next_image(swapchain.clone(), None) {
Ok(r) => r,
Err(AcquireError::OutOfDate) => {
recreate_swapchain = true;
return;
}
Err(e) => panic!("failed to acquire next image: {e}"),
};
let (image_index, suboptimal, acquire_future) = match acquire_next_image(
swapchain.clone(),
None,
)
.map_err(Validated::unwrap)
{
Ok(r) => r,
Err(VulkanError::OutOfDate) => {
recreate_swapchain = true;
return;
}
Err(e) => panic!("failed to acquire next image: {e}"),
};
if suboptimal {
recreate_swapchain = true;
@ -413,12 +419,12 @@ mod linux {
)
.then_signal_fence_and_flush();
match future {
match future.map_err(Validated::unwrap) {
Ok(future) => {
future.wait(None).unwrap();
previous_frame_end = Some(future.boxed());
}
Err(FlushError::OutOfDate) => {
Err(VulkanError::OutOfDate) => {
recreate_swapchain = true;
previous_frame_end = Some(vulkano::sync::now(device.clone()).boxed());
}

View File

@ -46,11 +46,10 @@ use vulkano::{
},
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
swapchain::{
acquire_next_image, AcquireError, Surface, Swapchain, SwapchainCreateInfo,
SwapchainPresentInfo,
acquire_next_image, Surface, Swapchain, SwapchainCreateInfo, SwapchainPresentInfo,
},
sync::{self, FlushError, GpuFuture},
DeviceSize, VulkanLibrary,
sync::{self, GpuFuture},
DeviceSize, Validated, VulkanError, VulkanLibrary,
};
use winit::{
event::{Event, WindowEvent},
@ -443,9 +442,9 @@ fn main() {
}
let (image_index, suboptimal, acquire_future) =
match acquire_next_image(swapchain.clone(), None) {
match acquire_next_image(swapchain.clone(), None).map_err(Validated::unwrap) {
Ok(r) => r,
Err(AcquireError::OutOfDate) => {
Err(VulkanError::OutOfDate) => {
recreate_swapchain = true;
return;
}
@ -504,11 +503,11 @@ fn main() {
)
.then_signal_fence_and_flush();
match future {
match future.map_err(Validated::unwrap) {
Ok(future) => {
previous_frame_end = Some(future.boxed());
}
Err(FlushError::OutOfDate) => {
Err(VulkanError::OutOfDate) => {
recreate_swapchain = true;
previous_frame_end = Some(sync::now(device.clone()).boxed());
}

View File

@ -45,11 +45,10 @@ use vulkano::{
},
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
swapchain::{
acquire_next_image, AcquireError, Surface, Swapchain, SwapchainCreateInfo,
SwapchainPresentInfo,
acquire_next_image, Surface, Swapchain, SwapchainCreateInfo, SwapchainPresentInfo,
},
sync::{self, FlushError, GpuFuture},
DeviceSize, VulkanLibrary,
sync::{self, GpuFuture},
DeviceSize, Validated, VulkanError, VulkanLibrary,
};
use winit::{
event::{Event, WindowEvent},
@ -391,9 +390,9 @@ fn main() {
}
let (image_index, suboptimal, acquire_future) =
match acquire_next_image(swapchain.clone(), None) {
match acquire_next_image(swapchain.clone(), None).map_err(Validated::unwrap) {
Ok(r) => r,
Err(AcquireError::OutOfDate) => {
Err(VulkanError::OutOfDate) => {
recreate_swapchain = true;
return;
}
@ -452,11 +451,11 @@ fn main() {
)
.then_signal_fence_and_flush();
match future {
match future.map_err(Validated::unwrap) {
Ok(future) => {
previous_frame_end = Some(future.boxed());
}
Err(FlushError::OutOfDate) => {
Err(VulkanError::OutOfDate) => {
recreate_swapchain = true;
previous_frame_end = Some(sync::now(device.clone()).boxed());
}

View File

@ -54,11 +54,10 @@ use vulkano::{
},
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
swapchain::{
acquire_next_image, AcquireError, Surface, Swapchain, SwapchainCreateInfo,
SwapchainPresentInfo,
acquire_next_image, Surface, Swapchain, SwapchainCreateInfo, SwapchainPresentInfo,
},
sync::{self, FlushError, GpuFuture},
DeviceSize, VulkanLibrary,
sync::{self, GpuFuture},
DeviceSize, Validated, VulkanError, VulkanLibrary,
};
use winit::{
event::{Event, WindowEvent},
@ -412,9 +411,9 @@ fn main() {
}
let (image_index, suboptimal, acquire_future) =
match acquire_next_image(swapchain.clone(), None) {
match acquire_next_image(swapchain.clone(), None).map_err(Validated::unwrap) {
Ok(r) => r,
Err(AcquireError::OutOfDate) => {
Err(VulkanError::OutOfDate) => {
recreate_swapchain = true;
return;
}
@ -473,11 +472,11 @@ fn main() {
)
.then_signal_fence_and_flush();
match future {
match future.map_err(Validated::unwrap) {
Ok(future) => {
previous_frame_end = Some(future.boxed());
}
Err(FlushError::OutOfDate) => {
Err(VulkanError::OutOfDate) => {
recreate_swapchain = true;
previous_frame_end = Some(sync::now(device.clone()).boxed());
}

View File

@ -61,11 +61,10 @@ use vulkano::{
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
single_pass_renderpass,
swapchain::{
acquire_next_image, AcquireError, Surface, Swapchain, SwapchainCreateInfo,
SwapchainPresentInfo,
acquire_next_image, Surface, Swapchain, SwapchainCreateInfo, SwapchainPresentInfo,
},
sync::{self, FlushError, GpuFuture},
VulkanLibrary,
sync::{self, GpuFuture},
Validated, VulkanError, VulkanLibrary,
};
use winit::{
event::{Event, WindowEvent},
@ -412,9 +411,9 @@ fn main() {
}
let (image_index, suboptimal, acquire_future) =
match acquire_next_image(swapchain.clone(), None) {
match acquire_next_image(swapchain.clone(), None).map_err(Validated::unwrap) {
Ok(r) => r,
Err(AcquireError::OutOfDate) => {
Err(VulkanError::OutOfDate) => {
recreate_swapchain = true;
return;
}
@ -520,11 +519,11 @@ fn main() {
)
.then_signal_fence_and_flush();
match future {
match future.map_err(Validated::unwrap) {
Ok(future) => {
previous_frame_end = Some(future.boxed());
}
Err(FlushError::OutOfDate) => {
Err(VulkanError::OutOfDate) => {
recreate_swapchain = true;
previous_frame_end = Some(sync::now(device.clone()).boxed());
}

View File

@ -42,11 +42,10 @@ use vulkano::{
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
single_pass_renderpass,
swapchain::{
acquire_next_image, AcquireError, Surface, Swapchain, SwapchainCreateInfo,
SwapchainPresentInfo,
acquire_next_image, Surface, Swapchain, SwapchainCreateInfo, SwapchainPresentInfo,
},
sync::{self, FlushError, GpuFuture},
VulkanLibrary,
sync::{self, GpuFuture},
Validated, VulkanError, VulkanLibrary,
};
use winit::{
event::{Event, WindowEvent},
@ -388,9 +387,9 @@ fn main() {
}
let (image_index, suboptimal, acquire_future) =
match acquire_next_image(swapchain.clone(), None) {
match acquire_next_image(swapchain.clone(), None).map_err(Validated::unwrap) {
Ok(r) => r,
Err(AcquireError::OutOfDate) => {
Err(VulkanError::OutOfDate) => {
recreate_swapchain = true;
return;
}
@ -448,11 +447,11 @@ fn main() {
)
.then_signal_fence_and_flush();
match future {
match future.map_err(Validated::unwrap) {
Ok(future) => {
previous_frame_end = Some(future.boxed());
}
Err(FlushError::OutOfDate) => {
Err(VulkanError::OutOfDate) => {
recreate_swapchain = true;
previous_frame_end = Some(sync::now(device.clone()).boxed());
}

View File

@ -45,11 +45,10 @@ use vulkano::{
},
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
swapchain::{
acquire_next_image, AcquireError, Surface, Swapchain, SwapchainCreateInfo,
SwapchainPresentInfo,
acquire_next_image, Surface, Swapchain, SwapchainCreateInfo, SwapchainPresentInfo,
},
sync::{self, FlushError, GpuFuture},
VulkanLibrary,
sync::{self, GpuFuture},
Validated, VulkanError, VulkanLibrary,
};
use winit::{
event::{ElementState, Event, KeyboardInput, WindowEvent},
@ -434,9 +433,9 @@ fn main() {
}
let (image_index, suboptimal, acquire_future) =
match acquire_next_image(swapchain.clone(), None) {
match acquire_next_image(swapchain.clone(), None).map_err(Validated::unwrap) {
Ok(r) => r,
Err(AcquireError::OutOfDate) => {
Err(VulkanError::OutOfDate) => {
*recreate_swapchain = true;
return;
}
@ -489,11 +488,11 @@ fn main() {
)
.then_signal_fence_and_flush();
match future {
match future.map_err(Validated::unwrap) {
Ok(future) => {
*previous_frame_end = Some(future.boxed());
}
Err(FlushError::OutOfDate) => {
Err(VulkanError::OutOfDate) => {
*recreate_swapchain = true;
*previous_frame_end = Some(sync::now(device.clone()).boxed());
}

View File

@ -43,11 +43,10 @@ use vulkano::{
query::{QueryControlFlags, QueryPool, QueryPoolCreateInfo, QueryResultFlags, QueryType},
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
swapchain::{
acquire_next_image, AcquireError, Surface, Swapchain, SwapchainCreateInfo,
SwapchainPresentInfo,
acquire_next_image, Surface, Swapchain, SwapchainCreateInfo, SwapchainPresentInfo,
},
sync::{self, FlushError, GpuFuture},
VulkanLibrary,
sync::{self, GpuFuture},
Validated, VulkanError, VulkanLibrary,
};
use winit::{
event::{Event, WindowEvent},
@ -408,9 +407,9 @@ fn main() {
}
let (image_index, suboptimal, acquire_future) =
match acquire_next_image(swapchain.clone(), None) {
match acquire_next_image(swapchain.clone(), None).map_err(Validated::unwrap) {
Ok(r) => r,
Err(AcquireError::OutOfDate) => {
Err(VulkanError::OutOfDate) => {
recreate_swapchain = true;
return;
}
@ -502,11 +501,11 @@ fn main() {
)
.then_signal_fence_and_flush();
match future {
match future.map_err(Validated::unwrap) {
Ok(future) => {
previous_frame_end = Some(future.boxed());
}
Err(FlushError::OutOfDate) => {
Err(VulkanError::OutOfDate) => {
recreate_swapchain = true;
previous_frame_end = Some(sync::now(device.clone()).boxed());
}

View File

@ -43,11 +43,10 @@ use vulkano::{
},
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
swapchain::{
acquire_next_image, AcquireError, Surface, Swapchain, SwapchainCreateInfo,
SwapchainPresentInfo,
acquire_next_image, Surface, Swapchain, SwapchainCreateInfo, SwapchainPresentInfo,
},
sync::{self, FlushError, GpuFuture},
DeviceSize, VulkanLibrary,
sync::{self, GpuFuture},
DeviceSize, Validated, VulkanError, VulkanLibrary,
};
use winit::{
event::{Event, WindowEvent},
@ -385,9 +384,9 @@ fn main() {
}
let (image_index, suboptimal, acquire_future) =
match acquire_next_image(swapchain.clone(), None) {
match acquire_next_image(swapchain.clone(), None).map_err(Validated::unwrap) {
Ok(r) => r,
Err(AcquireError::OutOfDate) => {
Err(VulkanError::OutOfDate) => {
recreate_swapchain = true;
return;
}
@ -448,11 +447,11 @@ fn main() {
)
.then_signal_fence_and_flush();
match future {
match future.map_err(Validated::unwrap) {
Ok(future) => {
previous_frame_end = Some(future.boxed());
}
Err(FlushError::OutOfDate) => {
Err(VulkanError::OutOfDate) => {
recreate_swapchain = true;
previous_frame_end = Some(sync::now(device.clone()).boxed());
}

View File

@ -51,11 +51,10 @@ use vulkano::{
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
shader::{ShaderModule, ShaderModuleCreateInfo},
swapchain::{
acquire_next_image, AcquireError, Surface, Swapchain, SwapchainCreateInfo,
SwapchainPresentInfo,
acquire_next_image, Surface, Swapchain, SwapchainCreateInfo, SwapchainPresentInfo,
},
sync::{self, FlushError, GpuFuture},
VulkanLibrary,
sync::{self, GpuFuture},
Validated, VulkanError, VulkanLibrary,
};
use winit::{
event::{Event, WindowEvent},
@ -330,9 +329,9 @@ fn main() {
}
let (image_index, suboptimal, acquire_future) =
match acquire_next_image(swapchain.clone(), None) {
match acquire_next_image(swapchain.clone(), None).map_err(Validated::unwrap) {
Ok(r) => r,
Err(AcquireError::OutOfDate) => {
Err(VulkanError::OutOfDate) => {
recreate_swapchain = true;
return;
}
@ -384,11 +383,11 @@ fn main() {
)
.then_signal_fence_and_flush();
match future {
match future.map_err(Validated::unwrap) {
Ok(future) => {
previous_frame_end = Some(future.boxed());
}
Err(FlushError::OutOfDate) => {
Err(VulkanError::OutOfDate) => {
recreate_swapchain = true;
previous_frame_end = Some(sync::now(device.clone()).boxed());
}

View File

@ -46,11 +46,10 @@ use vulkano::{
},
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
swapchain::{
acquire_next_image, AcquireError, Surface, Swapchain, SwapchainCreateInfo,
SwapchainPresentInfo,
acquire_next_image, Surface, Swapchain, SwapchainCreateInfo, SwapchainPresentInfo,
},
sync::{self, FlushError, GpuFuture},
DeviceSize, VulkanLibrary,
sync::{self, GpuFuture},
DeviceSize, Validated, VulkanError, VulkanLibrary,
};
use winit::{
event::{Event, WindowEvent},
@ -520,9 +519,9 @@ fn main() {
}
let (image_index, suboptimal, acquire_future) =
match acquire_next_image(swapchain.clone(), None) {
match acquire_next_image(swapchain.clone(), None).map_err(Validated::unwrap) {
Ok(r) => r,
Err(AcquireError::OutOfDate) => {
Err(VulkanError::OutOfDate) => {
recreate_swapchain = true;
return;
}
@ -581,11 +580,11 @@ fn main() {
)
.then_signal_fence_and_flush();
match future {
match future.map_err(Validated::unwrap) {
Ok(future) => {
previous_frame_end = Some(future.boxed());
}
Err(FlushError::OutOfDate) => {
Err(VulkanError::OutOfDate) => {
recreate_swapchain = true;
previous_frame_end = Some(sync::now(device.clone()).boxed());
}

View File

@ -50,7 +50,7 @@ use vulkano::{
SwapchainPresentInfo,
},
sync::{self, future::FenceSignalFuture, GpuFuture},
VulkanLibrary,
Validated, VulkanLibrary,
};
use winit::{
event::{Event, WindowEvent},
@ -627,7 +627,7 @@ fn main() {
.then_signal_fence_and_flush();
// Update this frame's future with current fence.
fences[image_index as usize] = match future {
fences[image_index as usize] = match future.map_err(Validated::unwrap) {
// Success, store result into vector.
Ok(future) => Some(Arc::new(future)),

View File

@ -48,11 +48,10 @@ use vulkano::{
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
shader::EntryPoint,
swapchain::{
acquire_next_image, AcquireError, Surface, Swapchain, SwapchainCreateInfo,
SwapchainPresentInfo,
acquire_next_image, Surface, Swapchain, SwapchainCreateInfo, SwapchainPresentInfo,
},
sync::{self, FlushError, GpuFuture},
VulkanLibrary,
sync::{self, GpuFuture},
Validated, VulkanError, VulkanLibrary,
};
use winit::{
event::{Event, WindowEvent},
@ -352,9 +351,9 @@ fn main() {
.unwrap();
let (image_index, suboptimal, acquire_future) =
match acquire_next_image(swapchain.clone(), None) {
match acquire_next_image(swapchain.clone(), None).map_err(Validated::unwrap) {
Ok(r) => r,
Err(AcquireError::OutOfDate) => {
Err(VulkanError::OutOfDate) => {
recreate_swapchain = true;
return;
}
@ -416,11 +415,11 @@ fn main() {
)
.then_signal_fence_and_flush();
match future {
match future.map_err(Validated::unwrap) {
Ok(future) => {
previous_frame_end = Some(future.boxed());
}
Err(FlushError::OutOfDate) => {
Err(VulkanError::OutOfDate) => {
recreate_swapchain = true;
previous_frame_end = Some(sync::now(device.clone()).boxed());
}

View File

@ -51,11 +51,10 @@ use vulkano::{
},
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
swapchain::{
acquire_next_image, AcquireError, Surface, Swapchain, SwapchainCreateInfo,
SwapchainPresentInfo,
acquire_next_image, Surface, Swapchain, SwapchainCreateInfo, SwapchainPresentInfo,
},
sync::{self, FlushError, GpuFuture},
VulkanLibrary,
sync::{self, GpuFuture},
Validated, VulkanError, VulkanLibrary,
};
use winit::{
event::{Event, WindowEvent},
@ -446,9 +445,9 @@ fn main() {
}
let (image_index, suboptimal, acquire_future) =
match acquire_next_image(swapchain.clone(), None) {
match acquire_next_image(swapchain.clone(), None).map_err(Validated::unwrap) {
Ok(r) => r,
Err(AcquireError::OutOfDate) => {
Err(VulkanError::OutOfDate) => {
recreate_swapchain = true;
return;
}
@ -500,11 +499,11 @@ fn main() {
)
.then_signal_fence_and_flush();
match future {
match future.map_err(Validated::unwrap) {
Ok(future) => {
previous_frame_end = Some(future.boxed());
}
Err(FlushError::OutOfDate) => {
Err(VulkanError::OutOfDate) => {
recreate_swapchain = true;
previous_frame_end = Some(sync::now(device.clone()).boxed());
}

View File

@ -45,11 +45,10 @@ use vulkano::{
},
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
swapchain::{
acquire_next_image, AcquireError, Surface, Swapchain, SwapchainCreateInfo,
SwapchainPresentInfo,
acquire_next_image, Surface, Swapchain, SwapchainCreateInfo, SwapchainPresentInfo,
},
sync::{self, FlushError, GpuFuture},
DeviceSize, VulkanLibrary,
sync::{self, GpuFuture},
DeviceSize, Validated, VulkanError, VulkanLibrary,
};
use winit::{
event::{Event, WindowEvent},
@ -402,9 +401,9 @@ fn main() {
}
let (image_index, suboptimal, acquire_future) =
match acquire_next_image(swapchain.clone(), None) {
match acquire_next_image(swapchain.clone(), None).map_err(Validated::unwrap) {
Ok(r) => r,
Err(AcquireError::OutOfDate) => {
Err(VulkanError::OutOfDate) => {
recreate_swapchain = true;
return;
}
@ -463,11 +462,11 @@ fn main() {
)
.then_signal_fence_and_flush();
match future {
match future.map_err(Validated::unwrap) {
Ok(future) => {
previous_frame_end = Some(future.boxed());
}
Err(FlushError::OutOfDate) => {
Err(VulkanError::OutOfDate) => {
recreate_swapchain = true;
previous_frame_end = Some(sync::now(device.clone()).boxed());
}

View File

@ -51,11 +51,10 @@ use vulkano::{
},
render_pass::{AttachmentLoadOp, AttachmentStoreOp},
swapchain::{
acquire_next_image, AcquireError, Surface, Swapchain, SwapchainCreateInfo,
SwapchainPresentInfo,
acquire_next_image, Surface, Swapchain, SwapchainCreateInfo, SwapchainPresentInfo,
},
sync::{self, FlushError, GpuFuture},
Version, VulkanLibrary,
sync::{self, GpuFuture},
Validated, Version, VulkanError, VulkanLibrary,
};
use winit::{
event::{Event, WindowEvent},
@ -569,9 +568,9 @@ fn main() {
// This function can block if no image is available. The parameter is an optional
// timeout after which the function call will return an error.
let (image_index, suboptimal, acquire_future) =
match acquire_next_image(swapchain.clone(), None) {
match acquire_next_image(swapchain.clone(), None).map_err(Validated::unwrap) {
Ok(r) => r,
Err(AcquireError::OutOfDate) => {
Err(VulkanError::OutOfDate) => {
recreate_swapchain = true;
return;
}
@ -670,11 +669,11 @@ fn main() {
)
.then_signal_fence_and_flush();
match future {
match future.map_err(Validated::unwrap) {
Ok(future) => {
previous_frame_end = Some(future.boxed());
}
Err(FlushError::OutOfDate) => {
Err(VulkanError::OutOfDate) => {
recreate_swapchain = true;
previous_frame_end = Some(sync::now(device.clone()).boxed());
}

View File

@ -45,11 +45,10 @@ use vulkano::{
},
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
swapchain::{
acquire_next_image, AcquireError, Surface, Swapchain, SwapchainCreateInfo,
SwapchainPresentInfo,
acquire_next_image, Surface, Swapchain, SwapchainCreateInfo, SwapchainPresentInfo,
},
sync::{self, FlushError, GpuFuture},
VulkanLibrary,
sync::{self, GpuFuture},
Validated, VulkanError, VulkanLibrary,
};
use winit::{
event::{Event, WindowEvent},
@ -569,9 +568,9 @@ fn main() {
// This function can block if no image is available. The parameter is an optional
// timeout after which the function call will return an error.
let (image_index, suboptimal, acquire_future) =
match acquire_next_image(swapchain.clone(), None) {
match acquire_next_image(swapchain.clone(), None).map_err(Validated::unwrap) {
Ok(r) => r,
Err(AcquireError::OutOfDate) => {
Err(VulkanError::OutOfDate) => {
recreate_swapchain = true;
return;
}
@ -667,11 +666,11 @@ fn main() {
)
.then_signal_fence_and_flush();
match future {
match future.map_err(Validated::unwrap) {
Ok(future) => {
previous_frame_end = Some(future.boxed());
}
Err(FlushError::OutOfDate) => {
Err(VulkanError::OutOfDate) => {
recreate_swapchain = true;
previous_frame_end = Some(sync::now(device.clone()).boxed());
}

View File

@ -15,11 +15,9 @@ use vulkano::{
format::Format,
image::{view::ImageView, Image, ImageCreateInfo, ImageType, ImageUsage},
memory::allocator::{AllocationCreateInfo, StandardMemoryAllocator},
swapchain::{
self, AcquireError, PresentMode, Surface, Swapchain, SwapchainCreateInfo,
SwapchainPresentInfo,
},
sync::{self, FlushError, GpuFuture},
swapchain::{self, PresentMode, Surface, Swapchain, SwapchainCreateInfo, SwapchainPresentInfo},
sync::{self, GpuFuture},
Validated, VulkanError,
};
use winit::window::Window;
@ -261,7 +259,7 @@ impl VulkanoWindowRenderer {
/// Execute your command buffers after calling this function and finish rendering by calling
/// [`VulkanoWindowRenderer::present`].
#[inline]
pub fn acquire(&mut self) -> Result<Box<dyn GpuFuture>, AcquireError> {
pub fn acquire(&mut self) -> Result<Box<dyn GpuFuture>, VulkanError> {
// Recreate swap chain if needed (when resizing of window occurs or swapchain is outdated)
// Also resize render views if needed
if self.recreate_swapchain {
@ -270,11 +268,13 @@ impl VulkanoWindowRenderer {
// Acquire next image in the swapchain
let (image_index, suboptimal, acquire_future) =
match swapchain::acquire_next_image(self.swapchain.clone(), None) {
match swapchain::acquire_next_image(self.swapchain.clone(), None)
.map_err(Validated::unwrap)
{
Ok(r) => r,
Err(AcquireError::OutOfDate) => {
Err(VulkanError::OutOfDate) => {
self.recreate_swapchain = true;
return Err(AcquireError::OutOfDate);
return Err(VulkanError::OutOfDate);
}
Err(e) => panic!("failed to acquire next image: {e}"),
};
@ -306,7 +306,7 @@ impl VulkanoWindowRenderer {
),
)
.then_signal_fence_and_flush();
match future {
match future.map_err(Validated::unwrap) {
Ok(mut future) => {
if wait_future {
match future.wait(None) {
@ -320,7 +320,7 @@ impl VulkanoWindowRenderer {
self.previous_frame_end = Some(future.boxed());
}
Err(FlushError::OutOfDate) => {
Err(VulkanError::OutOfDate) => {
self.recreate_swapchain = true;
self.previous_frame_end =
Some(sync::now(self.graphics_queue.device().clone()).boxed());

View File

@ -17,12 +17,10 @@ use crate::{
image::{Image, ImageLayout},
swapchain::Swapchain,
sync::{
future::{
now, AccessCheckError, AccessError, FlushError, GpuFuture, NowFuture, SubmitAnyBuilder,
},
future::{now, AccessCheckError, AccessError, GpuFuture, NowFuture, SubmitAnyBuilder},
PipelineStages,
},
DeviceSize, SafeDeref, ValidationError, VulkanObject,
DeviceSize, SafeDeref, Validated, ValidationError, VulkanError, VulkanObject,
};
use parking_lot::{Mutex, MutexGuard};
use std::{
@ -235,7 +233,7 @@ where
{
// Implementation of `build_submission`. Doesn't check whenever the future was already flushed.
// You must make sure to not submit same command buffer multiple times.
unsafe fn build_submission_impl(&self) -> Result<SubmitAnyBuilder, FlushError> {
unsafe fn build_submission_impl(&self) -> Result<SubmitAnyBuilder, Validated<VulkanError>> {
Ok(match self.previous.build_submission()? {
SubmitAnyBuilder::Empty => SubmitAnyBuilder::CommandBuffer(
SubmitInfo {
@ -289,7 +287,7 @@ where
self.previous.cleanup_finished();
}
unsafe fn build_submission(&self) -> Result<SubmitAnyBuilder, FlushError> {
unsafe fn build_submission(&self) -> Result<SubmitAnyBuilder, Validated<VulkanError>> {
if *self.submitted.lock() {
return Ok(SubmitAnyBuilder::Empty);
}
@ -297,7 +295,7 @@ where
self.build_submission_impl()
}
fn flush(&self) -> Result<(), FlushError> {
fn flush(&self) -> Result<(), Validated<VulkanError>> {
unsafe {
let mut submitted = self.submitted.lock();
if *submitted {

View File

@ -23,11 +23,11 @@ use crate::{
swapchain::{PresentInfo, SwapchainPresentInfo},
sync::{
fence::{Fence, FenceState},
future::{AccessCheckError, FlushError, GpuFuture},
future::{AccessCheckError, GpuFuture},
semaphore::SemaphoreState,
},
OomError, Requires, RequiresAllOf, RequiresOneOf, ValidationError, Version, VulkanError,
VulkanObject,
OomError, Requires, RequiresAllOf, RequiresOneOf, Validated, ValidationError, Version,
VulkanError, VulkanObject,
};
use ahash::HashMap;
use parking_lot::{Mutex, MutexGuard};
@ -694,7 +694,7 @@ impl<'a> QueueGuard<'a> {
fence: Option<Arc<Fence>>,
future: &dyn GpuFuture,
queue: &Queue,
) -> Result<(), FlushError> {
) -> Result<(), Validated<VulkanError>> {
let submit_infos: SmallVec<[_; 4]> = smallvec![submit_info];
let mut states = States::from_submit_infos(&submit_infos);
@ -707,15 +707,31 @@ impl<'a> QueueGuard<'a> {
match command_buffer.usage() {
CommandBufferUsage::OneTimeSubmit => {
// VUID-vkQueueSubmit2-commandBuffer-03874
if state.has_been_submitted() {
return Err(FlushError::OneTimeSubmitAlreadySubmitted);
return Err(Box::new(ValidationError {
problem: "a command buffer, or one of the secondary \
command buffers it executes, was created with the \
`CommandBufferUsage::OneTimeSubmit` usage, but \
it has already been submitted in the past"
.into(),
vuids: &["VUID-vkQueueSubmit2-commandBuffer-03874"],
..Default::default()
})
.into());
}
}
CommandBufferUsage::MultipleSubmit => {
// VUID-vkQueueSubmit2-commandBuffer-03875
if state.is_submit_pending() {
return Err(FlushError::ExclusiveAlreadyInUse);
return Err(Box::new(ValidationError {
problem: "a command buffer, or one of the secondary \
command buffers it executes, was not created with the \
`CommandBufferUsage::SimultaneousUse` usage, but \
it is already in use by the device"
.into(),
vuids: &["VUID-vkQueueSubmit2-commandBuffer-03875"],
..Default::default()
})
.into());
}
}
CommandBufferUsage::SimultaneousUse => (),
@ -739,10 +755,16 @@ impl<'a> QueueGuard<'a> {
queue,
) {
Err(AccessCheckError::Denied(error)) => {
return Err(FlushError::ResourceAccessError {
error,
use_ref: range_usage.first_use,
});
return Err(Box::new(ValidationError {
problem: format!(
"access to a resource has been denied \
(resource use: {:?}, error: {})",
range_usage.first_use, error
)
.into(),
..Default::default()
})
.into());
}
Err(AccessCheckError::Unknown) => {
let result = if range_usage.mutable {
@ -752,10 +774,16 @@ impl<'a> QueueGuard<'a> {
};
if let Err(error) = result {
return Err(FlushError::ResourceAccessError {
error,
use_ref: range_usage.first_use,
});
return Err(Box::new(ValidationError {
problem: format!(
"access to a resource has been denied \
(resource use: {:?}, error: {})",
range_usage.first_use, error
)
.into(),
..Default::default()
})
.into());
}
}
_ => (),
@ -775,10 +803,16 @@ impl<'a> QueueGuard<'a> {
queue,
) {
Err(AccessCheckError::Denied(error)) => {
return Err(FlushError::ResourceAccessError {
error,
use_ref: range_usage.first_use,
});
return Err(Box::new(ValidationError {
problem: format!(
"access to a resource has been denied \
(resource use: {:?}, error: {})",
range_usage.first_use, error
)
.into(),
..Default::default()
})
.into());
}
Err(AccessCheckError::Unknown) => {
let result = if range_usage.mutable {
@ -789,10 +823,16 @@ impl<'a> QueueGuard<'a> {
};
if let Err(error) = result {
return Err(FlushError::ResourceAccessError {
error,
use_ref: range_usage.first_use,
});
return Err(Box::new(ValidationError {
problem: format!(
"access to a resource has been denied \
(resource use: {:?}, error: {})",
range_usage.first_use, error
)
.into(),
..Default::default()
})
.into());
}
}
_ => (),

View File

@ -14,16 +14,15 @@ use crate::{
image::{Image, ImageLayout},
sync::{
fence::Fence,
future::{AccessCheckError, AccessError, FlushError, GpuFuture, SubmitAnyBuilder},
future::{AccessCheckError, AccessError, GpuFuture, SubmitAnyBuilder},
semaphore::Semaphore,
},
DeviceSize, OomError, RequirementNotMet, Requires, RequiresAllOf, RequiresOneOf, VulkanError,
DeviceSize, Requires, RequiresAllOf, RequiresOneOf, Validated, ValidationError, VulkanError,
VulkanObject,
};
use smallvec::smallvec;
use std::{
error::Error,
fmt::{Debug, Display, Error as FmtError, Formatter},
fmt::Debug,
mem::MaybeUninit,
num::NonZeroU64,
ops::Range,
@ -50,7 +49,7 @@ use std::{
pub fn acquire_next_image(
swapchain: Arc<Swapchain>,
timeout: Option<Duration>,
) -> Result<(u32, bool, SwapchainAcquireFuture), AcquireError> {
) -> Result<(u32, bool, SwapchainAcquireFuture), Validated<VulkanError>> {
let semaphore = Arc::new(Semaphore::from_pool(swapchain.device.clone())?);
let fence = Fence::from_pool(swapchain.device.clone())?;
@ -63,13 +62,16 @@ pub fn acquire_next_image(
// > VkSwapchainCreateInfoKHR::oldSwapchain value to vkCreateSwapchainKHR
let retired = swapchain.is_retired.lock();
if *retired {
return Err(AcquireError::OutOfDate);
return Err(VulkanError::OutOfDate.into());
}
let acquire_result =
unsafe { acquire_next_image_raw(&swapchain, timeout, Some(&semaphore), Some(&fence)) };
if let &Err(AcquireError::FullScreenExclusiveModeLost) = &acquire_result {
if matches!(
acquire_result,
Err(Validated::Error(VulkanError::FullScreenExclusiveModeLost))
) {
swapchain
.full_screen_exclusive_held
.store(false, Ordering::SeqCst);
@ -103,7 +105,7 @@ pub unsafe fn acquire_next_image_raw(
timeout: Option<Duration>,
semaphore: Option<&Semaphore>,
fence: Option<&Fence>,
) -> Result<AcquiredImage, AcquireError> {
) -> Result<AcquiredImage, Validated<VulkanError>> {
let fns = swapchain.device.fns();
let timeout_ns = if let Some(timeout) = timeout {
@ -130,8 +132,8 @@ pub unsafe fn acquire_next_image_raw(
let suboptimal = match result {
ash::vk::Result::SUCCESS => false,
ash::vk::Result::SUBOPTIMAL_KHR => true,
ash::vk::Result::NOT_READY => return Err(AcquireError::Timeout),
ash::vk::Result::TIMEOUT => return Err(AcquireError::Timeout),
ash::vk::Result::NOT_READY => return Err(VulkanError::NotReady.into()),
ash::vk::Result::TIMEOUT => return Err(VulkanError::Timeout.into()),
err => return Err(VulkanError::from(err).into()),
};
@ -197,7 +199,7 @@ impl SwapchainAcquireFuture {
unsafe impl GpuFuture for SwapchainAcquireFuture {
fn cleanup_finished(&mut self) {}
unsafe fn build_submission(&self) -> Result<SubmitAnyBuilder, FlushError> {
unsafe fn build_submission(&self) -> Result<SubmitAnyBuilder, Validated<VulkanError>> {
if let Some(ref semaphore) = self.semaphore {
let sem = smallvec![semaphore.clone()];
Ok(SubmitAnyBuilder::SemaphoresWait(sem))
@ -206,7 +208,7 @@ unsafe impl GpuFuture for SwapchainAcquireFuture {
}
}
fn flush(&self) -> Result<(), FlushError> {
fn flush(&self) -> Result<(), Validated<VulkanError>> {
Ok(())
}
@ -307,79 +309,6 @@ unsafe impl DeviceOwned for SwapchainAcquireFuture {
}
}
/// Error that can happen when calling `acquire_next_image`.
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[repr(u32)]
pub enum AcquireError {
/// Not enough memory.
OomError(OomError),
/// The connection to the device has been lost.
DeviceLost,
/// The timeout of the function has been reached before an image was available.
Timeout,
/// The surface is no longer accessible and must be recreated.
SurfaceLost,
/// The swapchain has lost or doesn't have full-screen exclusivity possibly for
/// implementation-specific reasons outside of the applications control.
FullScreenExclusiveModeLost,
/// The surface has changed in a way that makes the swapchain unusable. You must query the
/// surface's new properties and recreate a new swapchain if you want to continue drawing.
OutOfDate,
}
impl Error for AcquireError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self {
AcquireError::OomError(err) => Some(err),
_ => None,
}
}
}
impl Display for AcquireError {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
write!(
f,
"{}",
match self {
AcquireError::OomError(_) => "not enough memory",
AcquireError::DeviceLost => "the connection to the device has been lost",
AcquireError::Timeout => "no image is available for acquiring yet",
AcquireError::SurfaceLost => "the surface of this swapchain is no longer valid",
AcquireError::OutOfDate => "the swapchain needs to be recreated",
AcquireError::FullScreenExclusiveModeLost => {
"the swapchain no longer has full-screen exclusivity"
}
}
)
}
}
impl From<OomError> for AcquireError {
fn from(err: OomError) -> AcquireError {
AcquireError::OomError(err)
}
}
impl From<VulkanError> for AcquireError {
fn from(err: VulkanError) -> AcquireError {
match err {
err @ VulkanError::OutOfHostMemory => AcquireError::OomError(OomError::from(err)),
err @ VulkanError::OutOfDeviceMemory => AcquireError::OomError(OomError::from(err)),
VulkanError::DeviceLost => AcquireError::DeviceLost,
VulkanError::SurfaceLost => AcquireError::SurfaceLost,
VulkanError::OutOfDate => AcquireError::OutOfDate,
VulkanError::FullScreenExclusiveModeLost => AcquireError::FullScreenExclusiveModeLost,
_ => panic!("unexpected error: {:?}", err),
}
}
}
/// Presents an image on the screen.
///
/// The actual behavior depends on the present mode that you passed when creating the swapchain.
@ -596,7 +525,7 @@ where
self.previous.cleanup_finished();
}
unsafe fn build_submission(&self) -> Result<SubmitAnyBuilder, FlushError> {
unsafe fn build_submission(&self) -> Result<SubmitAnyBuilder, Validated<VulkanError>> {
if self.flushed.load(Ordering::SeqCst) {
return Ok(SubmitAnyBuilder::Empty);
}
@ -673,7 +602,7 @@ where
})
}
fn flush(&self) -> Result<(), FlushError> {
fn flush(&self) -> Result<(), Validated<VulkanError>> {
unsafe {
// If `flushed` already contains `true`, then `build_submission` will return `Empty`.
@ -693,7 +622,6 @@ where
.first()
.map_or(false, |first| first.present_mode.is_some());
// VUID-VkPresentIdKHR-presentIds-04999
for swapchain_info in swapchain_infos {
let &SwapchainPresentInfo {
ref swapchain,
@ -707,15 +635,30 @@ where
if present_id.map_or(false, |present_id| {
!swapchain.try_claim_present_id(present_id)
}) {
return Err(FlushError::PresentIdLessThanOrEqual);
return Err(Box::new(ValidationError {
problem: "the provided `present_id` was not greater than any \
`present_id` passed previously for the same swapchain"
.into(),
vuids: &["VUID-VkPresentIdKHR-presentIds-04999"],
..Default::default()
})
.into());
}
if let Some(present_mode) = present_mode {
assert!(has_present_mode);
// VUID-VkSwapchainPresentModeInfoEXT-pPresentModes-07761
if !swapchain.present_modes().contains(&present_mode) {
return Err(FlushError::PresentModeNotValid);
return Err(Box::new(ValidationError {
problem: "the requested present mode is not one of the modes \
in `swapchain.present_modes()`"
.into(),
vuids: &[
"VUID-VkSwapchainPresentModeInfoEXT-pPresentModes-07761",
],
..Default::default()
})
.into());
}
} else {
assert!(!has_present_mode);
@ -729,9 +672,19 @@ where
) {
Ok(_) => (),
Err(AccessCheckError::Unknown) => {
return Err(AccessError::SwapchainImageNotAcquired.into())
return Err(Box::new(ValidationError {
problem: AccessError::SwapchainImageNotAcquired.to_string().into(),
..Default::default()
})
.into());
}
Err(AccessCheckError::Denied(err)) => {
return Err(Box::new(ValidationError {
problem: err.to_string().into(),
..Default::default()
})
.into());
}
Err(AccessCheckError::Denied(e)) => return Err(e.into()),
}
Ok(self
@ -862,24 +815,30 @@ pub fn wait_for_present(
swapchain: Arc<Swapchain>,
present_id: u64,
timeout: Option<Duration>,
) -> Result<bool, PresentWaitError> {
) -> Result<bool, Validated<VulkanError>> {
if !swapchain.device.enabled_features().present_wait {
return Err(Box::new(ValidationError {
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature("present_wait")])]),
vuids: &["VUID-vkWaitForPresentKHR-presentWait-06234"],
..Default::default()
})
.into());
}
if present_id == 0 {
return Err(Box::new(ValidationError {
context: "present_id".into(),
problem: "is 0".into(),
..Default::default()
})
.into());
}
let retired = swapchain.is_retired.lock();
// VUID-vkWaitForPresentKHR-swapchain-04997
if *retired {
return Err(PresentWaitError::OutOfDate);
}
if present_id == 0 {
return Err(PresentWaitError::PresentIdZero);
}
// VUID-vkWaitForPresentKHR-presentWait-06234
if !swapchain.device.enabled_features().present_wait {
return Err(PresentWaitError::RequirementNotMet {
required_for: "`wait_for_present`",
requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::Feature("present_wait")])]),
});
return Err(VulkanError::OutOfDate.into());
}
let timeout_ns = timeout.map(|dur| dur.as_nanos() as u64).unwrap_or(0);
@ -896,112 +855,17 @@ pub fn wait_for_present(
match result {
ash::vk::Result::SUCCESS => Ok(false),
ash::vk::Result::SUBOPTIMAL_KHR => Ok(true),
ash::vk::Result::TIMEOUT => Err(PresentWaitError::Timeout),
ash::vk::Result::TIMEOUT => Err(VulkanError::Timeout.into()),
err => {
let err = VulkanError::from(err).into();
let err = VulkanError::from(err);
if let PresentWaitError::FullScreenExclusiveModeLost = &err {
if matches!(err, VulkanError::FullScreenExclusiveModeLost) {
swapchain
.full_screen_exclusive_held
.store(false, Ordering::SeqCst);
}
Err(err)
}
}
}
/// Error that can happen when calling `acquire_next_image`.
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[repr(u32)]
pub enum PresentWaitError {
/// Not enough memory.
OomError(OomError),
/// The connection to the device has been lost.
DeviceLost,
/// The surface has changed in a way that makes the swapchain unusable. You must query the
/// surface's new properties and recreate a new swapchain if you want to continue drawing.
OutOfDate,
/// The surface is no longer accessible and must be recreated.
SurfaceLost,
/// The swapchain has lost or doesn't have full-screen exclusivity possibly for
/// implementation-specific reasons outside of the applications control.
FullScreenExclusiveModeLost,
/// The timeout of the function has been reached before the present occured.
Timeout,
RequirementNotMet {
required_for: &'static str,
requires_one_of: RequiresOneOf,
},
/// Present id of zero is invalid.
PresentIdZero,
}
impl Error for PresentWaitError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self {
Self::OomError(err) => Some(err),
_ => None,
}
}
}
impl Display for PresentWaitError {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
match self {
Self::OomError(e) => write!(f, "{}", e),
Self::DeviceLost => write!(f, "the connection to the device has been lost"),
Self::Timeout => write!(f, "no image is available for acquiring yet"),
Self::SurfaceLost => write!(f, "the surface of this swapchain is no longer valid"),
Self::OutOfDate => write!(f, "the swapchain needs to be recreated"),
Self::FullScreenExclusiveModeLost => {
write!(f, "the swapchain no longer has full-screen exclusivity")
}
Self::RequirementNotMet {
required_for,
requires_one_of,
} => write!(
f,
"a requirement was not met for: {}; requires one of: {}",
required_for, requires_one_of,
),
Self::PresentIdZero => write!(f, "present id of zero is invalid"),
}
}
}
impl From<OomError> for PresentWaitError {
fn from(err: OomError) -> PresentWaitError {
Self::OomError(err)
}
}
impl From<RequirementNotMet> for PresentWaitError {
fn from(err: RequirementNotMet) -> Self {
Self::RequirementNotMet {
required_for: err.required_for,
requires_one_of: err.requires_one_of,
}
}
}
impl From<VulkanError> for PresentWaitError {
fn from(err: VulkanError) -> PresentWaitError {
match err {
err @ VulkanError::OutOfHostMemory => Self::OomError(OomError::from(err)),
err @ VulkanError::OutOfDeviceMemory => Self::OomError(OomError::from(err)),
VulkanError::DeviceLost => Self::DeviceLost,
VulkanError::SurfaceLost => Self::SurfaceLost,
VulkanError::OutOfDate => Self::OutOfDate,
VulkanError::FullScreenExclusiveModeLost => Self::FullScreenExclusiveModeLost,
_ => panic!("unexpected error: {:?}", err),
Err(err.into())
}
}
}

View File

@ -276,9 +276,10 @@
//! as last parameter the old swapchain.
//!
//! ```
//! use vulkano::swapchain;
//! use vulkano::swapchain::{AcquireError, SwapchainCreateInfo, SwapchainPresentInfo};
//! use vulkano::sync::GpuFuture;
//! use vulkano::{
//! swapchain::{self, SwapchainCreateInfo, SwapchainPresentInfo},
//! sync::GpuFuture, Validated, VulkanError,
//! };
//!
//! // let (swapchain, images) = Swapchain::new(...);
//! # let mut swapchain: ::std::sync::Arc<::vulkano::swapchain::Swapchain> = return;
@ -298,11 +299,12 @@
//! recreate_swapchain = false;
//! }
//!
//! let (image_index, suboptimal, acq_future) = match swapchain::acquire_next_image(swapchain.clone(), None) {
//! Ok(r) => r,
//! Err(AcquireError::OutOfDate) => { recreate_swapchain = true; continue; },
//! Err(err) => panic!("{:?}", err),
//! };
//! let (image_index, suboptimal, acq_future) =
//! match swapchain::acquire_next_image(swapchain.clone(), None).map_err(Validated::unwrap) {
//! Ok(r) => r,
//! Err(VulkanError::OutOfDate) => { recreate_swapchain = true; continue; },
//! Err(err) => panic!("{:?}", err),
//! };
//!
//! // ...
//!

View File

@ -7,7 +7,7 @@
// notice may not be copied, modified, or distributed except
// according to those terms.
use super::{AccessCheckError, FlushError, GpuFuture};
use super::{AccessCheckError, GpuFuture};
use crate::{
buffer::Buffer,
command_buffer::{SemaphoreSubmitInfo, SubmitInfo},
@ -19,7 +19,7 @@ use crate::{
future::{AccessError, SubmitAnyBuilder},
PipelineStages,
},
DeviceSize, VulkanError,
DeviceSize, Validated, ValidationError, VulkanError,
};
use parking_lot::{Mutex, MutexGuard};
use std::{
@ -160,7 +160,7 @@ where
///
/// If the wait is successful, this function also cleans any resource locked by previous
/// submissions.
pub fn wait(&self, timeout: Option<Duration>) -> Result<(), FlushError> {
pub fn wait(&self, timeout: Option<Duration>) -> Result<(), Validated<VulkanError>> {
let mut state = self.state.lock();
self.flush_impl(&mut state)?;
@ -211,7 +211,7 @@ where
fn flush_impl(
&self,
state: &mut MutexGuard<'_, FenceSignalFutureState<F>>,
) -> Result<(), FlushError> {
) -> Result<(), Validated<VulkanError>> {
unsafe {
// In this function we temporarily replace the current state with `Poisoned` at the
// beginning, and we take care to always put back a value into `state` before
@ -314,12 +314,18 @@ where
})
.map_err(|err| OutcomeErr::Partial(err.into()))
} else {
// VUID-VkPresentIdKHR-presentIds-04999
for swapchain_info in &present_info.swapchain_infos {
if swapchain_info.present_id.map_or(false, |present_id| {
!swapchain_info.swapchain.try_claim_present_id(present_id)
}) {
return Err(FlushError::PresentIdLessThanOrEqual);
return Err(Box::new(ValidationError {
problem: "the provided `present_id` was not greater than any \
`present_id` passed previously for the same swapchain"
.into(),
vuids: &["VUID-VkPresentIdKHR-presentIds-04999"],
..Default::default()
})
.into());
}
match previous.check_swapchain_image_acquired(
@ -329,9 +335,21 @@ where
) {
Ok(_) => (),
Err(AccessCheckError::Unknown) => {
return Err(AccessError::SwapchainImageNotAcquired.into())
return Err(Box::new(ValidationError {
problem: AccessError::SwapchainImageNotAcquired
.to_string()
.into(),
..Default::default()
})
.into());
}
Err(AccessCheckError::Denied(err)) => {
return Err(Box::new(ValidationError {
problem: err.to_string().into(),
..Default::default()
})
.into());
}
Err(AccessCheckError::Denied(e)) => return Err(e.into()),
}
}
@ -414,7 +432,7 @@ where
self.cleanup_finished_impl()
}
unsafe fn build_submission(&self) -> Result<SubmitAnyBuilder, FlushError> {
unsafe fn build_submission(&self) -> Result<SubmitAnyBuilder, Validated<VulkanError>> {
let mut state = self.state.lock();
self.flush_impl(&mut state)?;
@ -433,7 +451,7 @@ where
Ok(SubmitAnyBuilder::Empty)
}
fn flush(&self) -> Result<(), FlushError> {
fn flush(&self) -> Result<(), Validated<VulkanError>> {
let mut state = self.state.lock();
self.flush_impl(&mut state)
}
@ -569,13 +587,13 @@ where
self.cleanup_finished_impl()
}
unsafe fn build_submission(&self) -> Result<SubmitAnyBuilder, FlushError> {
unsafe fn build_submission(&self) -> Result<SubmitAnyBuilder, Validated<VulkanError>> {
// Note that this is sound because we always return `SubmitAnyBuilder::Empty`. See the
// documentation of `build_submission`.
(**self).build_submission()
}
fn flush(&self) -> Result<(), FlushError> {
fn flush(&self) -> Result<(), Validated<VulkanError>> {
(**self).flush()
}

View File

@ -7,13 +7,13 @@
// notice may not be copied, modified, or distributed except
// according to those terms.
use super::{AccessCheckError, FlushError, GpuFuture, SubmitAnyBuilder};
use super::{AccessCheckError, GpuFuture, SubmitAnyBuilder};
use crate::{
buffer::Buffer,
device::{Device, DeviceOwned, Queue},
image::{Image, ImageLayout},
swapchain::Swapchain,
DeviceSize, VulkanObject,
DeviceSize, Validated, VulkanError, VulkanObject,
};
use std::{ops::Range, sync::Arc};
@ -62,7 +62,7 @@ where
self.second.cleanup_finished();
}
fn flush(&self) -> Result<(), FlushError> {
fn flush(&self) -> Result<(), Validated<VulkanError>> {
// Since each future remembers whether it has been flushed, there's no safety issue here
// if we call this function multiple times.
self.first.flush()?;
@ -71,7 +71,7 @@ where
Ok(())
}
unsafe fn build_submission(&self) -> Result<SubmitAnyBuilder, FlushError> {
unsafe fn build_submission(&self) -> Result<SubmitAnyBuilder, Validated<VulkanError>> {
// TODO: review this function
let first = self.first.build_submission()?;
let second = self.second.build_submission()?;

View File

@ -100,14 +100,13 @@ use super::{fence::Fence, semaphore::Semaphore};
use crate::{
buffer::Buffer,
command_buffer::{
CommandBufferExecError, CommandBufferExecFuture, PrimaryCommandBufferAbstract,
ResourceUseRef, SubmitInfo,
CommandBufferExecError, CommandBufferExecFuture, PrimaryCommandBufferAbstract, SubmitInfo,
},
device::{DeviceOwned, Queue},
image::{Image, ImageLayout},
memory::BindSparseInfo,
swapchain::{self, PresentFuture, PresentInfo, Swapchain, SwapchainPresentInfo},
DeviceSize, OomError, VulkanError,
DeviceSize, Validated, VulkanError,
};
use smallvec::SmallVec;
use std::{
@ -158,14 +157,14 @@ pub unsafe trait GpuFuture: DeviceOwned {
/// Once the caller has submitted the submission and has determined that the GPU has finished
/// executing it, it should call `signal_finished`. Failure to do so will incur a large runtime
/// overhead, as the future will have to block to make sure that it is finished.
unsafe fn build_submission(&self) -> Result<SubmitAnyBuilder, FlushError>;
unsafe fn build_submission(&self) -> Result<SubmitAnyBuilder, Validated<VulkanError>>;
/// Flushes the future and submits to the GPU the actions that will permit this future to
/// occur.
///
/// The implementation must remember that it was flushed. If the function is called multiple
/// times, only the first time must result in a flush.
fn flush(&self) -> Result<(), FlushError>;
fn flush(&self) -> Result<(), Validated<VulkanError>>;
/// Sets the future to its "complete" state, meaning that it can safely be destroyed.
///
@ -297,7 +296,9 @@ pub unsafe trait GpuFuture: DeviceOwned {
/// on two different queues, then you would need two submits anyway and it is always
/// advantageous to submit A as soon as possible.
#[inline]
fn then_signal_semaphore_and_flush(self) -> Result<SemaphoreSignalFuture<Self>, FlushError>
fn then_signal_semaphore_and_flush(
self,
) -> Result<SemaphoreSignalFuture<Self>, Validated<VulkanError>>
where
Self: Sized,
{
@ -323,7 +324,7 @@ pub unsafe trait GpuFuture: DeviceOwned {
///
/// This is a just a shortcut for `then_signal_fence()` followed with `flush()`.
#[inline]
fn then_signal_fence_and_flush(self) -> Result<FenceSignalFuture<Self>, FlushError>
fn then_signal_fence_and_flush(self) -> Result<FenceSignalFuture<Self>, Validated<VulkanError>>
where
Self: Sized,
{
@ -405,11 +406,11 @@ where
(**self).cleanup_finished()
}
unsafe fn build_submission(&self) -> Result<SubmitAnyBuilder, FlushError> {
unsafe fn build_submission(&self) -> Result<SubmitAnyBuilder, Validated<VulkanError>> {
(**self).build_submission()
}
fn flush(&self) -> Result<(), FlushError> {
fn flush(&self) -> Result<(), Validated<VulkanError>> {
(**self).flush()
}
@ -478,9 +479,6 @@ impl SubmitAnyBuilder {
/// Access to a resource was denied.
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum AccessError {
/// Exclusive access is denied.
ExclusiveDenied,
/// The resource is already in use, and there is no tracking of concurrent usages.
AlreadyInUse,
@ -496,9 +494,6 @@ pub enum AccessError {
requested: ImageLayout,
},
/// Trying to use a buffer that still contains garbage data.
BufferNotInitialized,
/// Trying to use a swapchain image without depending on a corresponding acquire image future.
SwapchainImageNotAcquired,
}
@ -511,7 +506,6 @@ impl Display for AccessError {
f,
"{}",
match self {
AccessError::ExclusiveDenied => "only shared access is allowed for this resource",
AccessError::AlreadyInUse => {
"the resource is already in use, and there is no tracking of concurrent usages"
}
@ -522,9 +516,6 @@ impl Display for AccessError {
"trying to use an image without transitioning it from the undefined or \
preinitialized layouts first"
}
AccessError::BufferNotInitialized => {
"trying to use a buffer that still contains garbage data"
}
AccessError::SwapchainImageNotAcquired => {
"trying to use a swapchain image without depending on a corresponding acquire \
image future"
@ -563,123 +554,3 @@ impl From<AccessError> for AccessCheckError {
AccessCheckError::Denied(err)
}
}
/// Error that can happen when creating a graphics pipeline.
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum FlushError {
/// Access to a resource has been denied.
AccessError(AccessError),
/// Not enough memory.
OomError(OomError),
/// The connection to the device has been lost.
DeviceLost,
/// The surface is no longer accessible and must be recreated.
SurfaceLost,
/// The surface has changed in a way that makes the swapchain unusable. You must query the
/// surface's new properties and recreate a new swapchain if you want to continue drawing.
OutOfDate,
/// The swapchain has lost or doesn't have full screen exclusivity possibly for
/// implementation-specific reasons outside of the applications control.
FullScreenExclusiveModeLost,
/// The flush operation needed to block, but the timeout has elapsed.
Timeout,
/// A non-zero present_id must be greater than any non-zero present_id passed previously
/// for the same swapchain.
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.
ResourceAccessError {
error: AccessError,
use_ref: Option<ResourceUseRef>,
},
/// 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 it the past.
OneTimeSubmitAlreadySubmitted,
/// The command buffer or one of the secondary command buffers it executes is already in use by
/// the GPU and was not created with the "concurrent" flag.
ExclusiveAlreadyInUse,
}
impl Error for FlushError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self {
Self::AccessError(err) => Some(err),
Self::OomError(err) => Some(err),
Self::ResourceAccessError { error, .. } => Some(error),
_ => None,
}
}
}
impl Display for FlushError {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
write!(
f,
"{}",
match self {
Self::AccessError(_) => "access to a resource has been denied",
Self::OomError(_) => "not enough memory",
Self::DeviceLost => "the connection to the device has been lost",
Self::SurfaceLost => "the surface of this swapchain is no longer valid",
Self::OutOfDate => "the swapchain needs to be recreated",
Self::FullScreenExclusiveModeLost => {
"the swapchain no longer has full screen exclusivity"
}
Self::Timeout => {
"the flush operation needed to block, but the timeout has elapsed"
}
Self::PresentIdLessThanOrEqual => {
"present id is less than or equal to previous"
}
Self::PresentModeNotValid => {
"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 \
created with the \"one time submit\" flag, but has already been submitted in \
the past"
}
Self::ExclusiveAlreadyInUse => {
"the command buffer or one of the secondary command buffers it executes is \
already in use was not created with the \"concurrent\" flag"
}
}
)
}
}
impl From<AccessError> for FlushError {
fn from(err: AccessError) -> FlushError {
Self::AccessError(err)
}
}
impl From<VulkanError> for FlushError {
fn from(err: VulkanError) -> Self {
match err {
VulkanError::OutOfHostMemory | VulkanError::OutOfDeviceMemory => {
Self::OomError(err.into())
}
VulkanError::DeviceLost => Self::DeviceLost,
VulkanError::SurfaceLost => Self::SurfaceLost,
VulkanError::OutOfDate => Self::OutOfDate,
VulkanError::FullScreenExclusiveModeLost => Self::FullScreenExclusiveModeLost,
_ => panic!("unexpected error: {:?}", err),
}
}
}

View File

@ -7,13 +7,13 @@
// notice may not be copied, modified, or distributed except
// according to those terms.
use super::{AccessCheckError, FlushError, GpuFuture, SubmitAnyBuilder};
use super::{AccessCheckError, GpuFuture, SubmitAnyBuilder};
use crate::{
buffer::Buffer,
device::{Device, DeviceOwned, Queue},
image::{Image, ImageLayout},
swapchain::Swapchain,
DeviceSize,
DeviceSize, Validated, VulkanError,
};
use std::{ops::Range, sync::Arc};
@ -33,12 +33,12 @@ unsafe impl GpuFuture for NowFuture {
fn cleanup_finished(&mut self) {}
#[inline]
unsafe fn build_submission(&self) -> Result<SubmitAnyBuilder, FlushError> {
unsafe fn build_submission(&self) -> Result<SubmitAnyBuilder, Validated<VulkanError>> {
Ok(SubmitAnyBuilder::Empty)
}
#[inline]
fn flush(&self) -> Result<(), FlushError> {
fn flush(&self) -> Result<(), Validated<VulkanError>> {
Ok(())
}

View File

@ -7,7 +7,7 @@
// notice may not be copied, modified, or distributed except
// according to those terms.
use super::{AccessCheckError, FlushError, GpuFuture, SubmitAnyBuilder};
use super::{AccessCheckError, GpuFuture, SubmitAnyBuilder};
use crate::{
buffer::Buffer,
command_buffer::{SemaphoreSubmitInfo, SubmitInfo},
@ -15,7 +15,7 @@ use crate::{
image::{Image, ImageLayout},
swapchain::Swapchain,
sync::{future::AccessError, semaphore::Semaphore, PipelineStages},
DeviceSize,
DeviceSize, Validated, ValidationError, VulkanError,
};
use parking_lot::Mutex;
use smallvec::smallvec;
@ -69,7 +69,7 @@ where
self.previous.cleanup_finished();
}
unsafe fn build_submission(&self) -> Result<SubmitAnyBuilder, FlushError> {
unsafe fn build_submission(&self) -> Result<SubmitAnyBuilder, Validated<VulkanError>> {
// Flushing the signaling part, since it must always be submitted before the waiting part.
self.flush()?;
let sem = smallvec![self.semaphore.clone()];
@ -77,7 +77,7 @@ where
Ok(SubmitAnyBuilder::SemaphoresWait(sem))
}
fn flush(&self) -> Result<(), FlushError> {
fn flush(&self) -> Result<(), Validated<VulkanError>> {
unsafe {
let mut wait_submitted = self.wait_submitted.lock();
@ -142,12 +142,18 @@ where
builder.submit(&queue)?;*/
}
SubmitAnyBuilder::QueuePresent(present_info) => {
// VUID-VkPresentIdKHR-presentIds-04999
for swapchain_info in &present_info.swapchain_infos {
if swapchain_info.present_id.map_or(false, |present_id| {
!swapchain_info.swapchain.try_claim_present_id(present_id)
}) {
return Err(FlushError::PresentIdLessThanOrEqual);
return Err(Box::new(ValidationError {
problem: "the provided `present_id` was not greater than any \
`present_id` passed previously for the same swapchain"
.into(),
vuids: &["VUID-VkPresentIdKHR-presentIds-04999"],
..Default::default()
})
.into());
}
match self.previous.check_swapchain_image_acquired(
@ -157,9 +163,21 @@ where
) {
Ok(_) => (),
Err(AccessCheckError::Unknown) => {
return Err(AccessError::SwapchainImageNotAcquired.into())
return Err(Box::new(ValidationError {
problem: AccessError::SwapchainImageNotAcquired
.to_string()
.into(),
..Default::default()
})
.into());
}
Err(AccessCheckError::Denied(err)) => {
return Err(Box::new(ValidationError {
problem: err.to_string().into(),
..Default::default()
})
.into());
}
Err(AccessCheckError::Denied(e)) => return Err(e.into()),
}
}
@ -177,7 +195,7 @@ where
}],
None,
)?;
Ok::<_, FlushError>(())
Ok::<_, Validated<VulkanError>>(())
})?;
}
};

View File

@ -19,7 +19,7 @@
#[allow(unused)]
pub(crate) use self::pipeline::{PipelineStageAccess, PipelineStageAccessFlags};
pub use self::{
future::{now, FlushError, GpuFuture},
future::{now, GpuFuture},
pipeline::{
AccessFlags, BufferMemoryBarrier, DependencyFlags, DependencyInfo, ImageMemoryBarrier,
MemoryBarrier, PipelineStage, PipelineStages, QueueFamilyOwnershipTransfer,