mirror of
https://github.com/vulkano-rs/vulkano.git
synced 2024-10-29 21:42:26 +00:00
Impl Present Wait Feature (#1965)
* impl present_wait feature * handle timeout case * add missing doc * document the return type of wait_for_present * impl check for VUID-04999 * don't enforce gt if present_id is zero * impl PresentInfoExt * Remove NonZeroU64 from wait_for_present in favor of an error * fix gl-interop example * fix docs and fmt * PresentInfoExt -> PresentInfo, Added swapchain + index to info * fix doc test, didn't save file... * fix gl-interop * Remove Whitespace
This commit is contained in:
parent
e0af8af960
commit
8e8482016a
@ -45,7 +45,8 @@ use vulkano::{
|
||||
},
|
||||
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
|
||||
swapchain::{
|
||||
acquire_next_image, AcquireError, Swapchain, SwapchainCreateInfo, SwapchainCreationError,
|
||||
acquire_next_image, AcquireError, PresentInfo, Swapchain, SwapchainCreateInfo,
|
||||
SwapchainCreationError,
|
||||
},
|
||||
sync::{self, FlushError, GpuFuture},
|
||||
VulkanLibrary,
|
||||
@ -359,7 +360,13 @@ fn main() {
|
||||
.join(acquire_future)
|
||||
.then_execute(queue.clone(), command_buffer)
|
||||
.unwrap()
|
||||
.then_swapchain_present(queue.clone(), swapchain.clone(), image_num)
|
||||
.then_swapchain_present(
|
||||
queue.clone(),
|
||||
PresentInfo {
|
||||
index: image_num,
|
||||
..PresentInfo::swapchain(swapchain.clone())
|
||||
},
|
||||
)
|
||||
.then_signal_fence_and_flush();
|
||||
|
||||
match future {
|
||||
|
@ -20,7 +20,8 @@ use vulkano::{
|
||||
instance::{Instance, InstanceCreateInfo},
|
||||
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass},
|
||||
swapchain::{
|
||||
acquire_next_image, AcquireError, Swapchain, SwapchainCreateInfo, SwapchainCreationError,
|
||||
acquire_next_image, AcquireError, PresentInfo, Swapchain, SwapchainCreateInfo,
|
||||
SwapchainCreationError,
|
||||
},
|
||||
sync::{self, FlushError, GpuFuture},
|
||||
VulkanLibrary,
|
||||
@ -267,7 +268,13 @@ fn main() {
|
||||
.join(acquire_future)
|
||||
.then_execute(queue.clone(), command_buffer)
|
||||
.unwrap()
|
||||
.then_swapchain_present(queue.clone(), swapchain.clone(), image_num)
|
||||
.then_swapchain_present(
|
||||
queue.clone(),
|
||||
PresentInfo {
|
||||
index: image_num,
|
||||
..PresentInfo::swapchain(swapchain.clone())
|
||||
},
|
||||
)
|
||||
.then_signal_fence_and_flush();
|
||||
|
||||
match future {
|
||||
|
@ -37,7 +37,8 @@ use vulkano::{
|
||||
image::{view::ImageView, ImageUsage},
|
||||
instance::{Instance, InstanceCreateInfo},
|
||||
swapchain::{
|
||||
acquire_next_image, AcquireError, Swapchain, SwapchainCreateInfo, SwapchainCreationError,
|
||||
acquire_next_image, AcquireError, PresentInfo, Swapchain, SwapchainCreateInfo,
|
||||
SwapchainCreationError,
|
||||
},
|
||||
sync::{self, FlushError, GpuFuture},
|
||||
VulkanLibrary,
|
||||
@ -247,7 +248,13 @@ fn main() {
|
||||
|
||||
let future = after_future
|
||||
.unwrap()
|
||||
.then_swapchain_present(queue.clone(), swapchain.clone(), image_num)
|
||||
.then_swapchain_present(
|
||||
queue.clone(),
|
||||
PresentInfo {
|
||||
index: image_num,
|
||||
..PresentInfo::swapchain(swapchain.clone())
|
||||
},
|
||||
)
|
||||
.then_signal_fence_and_flush();
|
||||
|
||||
match future {
|
||||
|
@ -41,7 +41,9 @@ mod linux {
|
||||
},
|
||||
render_pass::{Framebuffer, RenderPass, Subpass},
|
||||
sampler::{Filter, Sampler, SamplerAddressMode, SamplerCreateInfo},
|
||||
swapchain::{AcquireError, Swapchain, SwapchainCreateInfo, SwapchainCreationError},
|
||||
swapchain::{
|
||||
AcquireError, PresentInfo, Swapchain, SwapchainCreateInfo, SwapchainCreationError,
|
||||
},
|
||||
sync::{
|
||||
now, ExternalSemaphoreHandleType, ExternalSemaphoreHandleTypes, FlushError, GpuFuture,
|
||||
PipelineStages, Semaphore, SemaphoreCreateInfo,
|
||||
@ -344,7 +346,13 @@ mod linux {
|
||||
let future = future
|
||||
.then_execute(queue.clone(), command_buffer)
|
||||
.unwrap()
|
||||
.then_swapchain_present(queue.clone(), swapchain.clone(), image_num)
|
||||
.then_swapchain_present(
|
||||
queue.clone(),
|
||||
PresentInfo {
|
||||
index: image_num,
|
||||
..PresentInfo::swapchain(swapchain.clone())
|
||||
},
|
||||
)
|
||||
.then_signal_fence_and_flush();
|
||||
|
||||
match future {
|
||||
|
@ -39,7 +39,8 @@ use vulkano::{
|
||||
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
|
||||
sampler::{Filter, Sampler, SamplerAddressMode, SamplerCreateInfo},
|
||||
swapchain::{
|
||||
acquire_next_image, AcquireError, Swapchain, SwapchainCreateInfo, SwapchainCreationError,
|
||||
acquire_next_image, AcquireError, PresentInfo, Swapchain, SwapchainCreateInfo,
|
||||
SwapchainCreationError,
|
||||
},
|
||||
sync::{self, FlushError, GpuFuture},
|
||||
VulkanLibrary,
|
||||
@ -440,7 +441,13 @@ fn main() {
|
||||
.join(acquire_future)
|
||||
.then_execute(queue.clone(), command_buffer)
|
||||
.unwrap()
|
||||
.then_swapchain_present(queue.clone(), swapchain.clone(), image_num)
|
||||
.then_swapchain_present(
|
||||
queue.clone(),
|
||||
PresentInfo {
|
||||
index: image_num,
|
||||
..PresentInfo::swapchain(swapchain.clone())
|
||||
},
|
||||
)
|
||||
.then_signal_fence_and_flush();
|
||||
|
||||
match future {
|
||||
|
@ -37,7 +37,8 @@ use vulkano::{
|
||||
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
|
||||
sampler::{Filter, Sampler, SamplerAddressMode, SamplerCreateInfo},
|
||||
swapchain::{
|
||||
acquire_next_image, AcquireError, Swapchain, SwapchainCreateInfo, SwapchainCreationError,
|
||||
acquire_next_image, AcquireError, PresentInfo, Swapchain, SwapchainCreateInfo,
|
||||
SwapchainCreationError,
|
||||
},
|
||||
sync::{self, FlushError, GpuFuture},
|
||||
VulkanLibrary,
|
||||
@ -357,7 +358,13 @@ fn main() {
|
||||
.join(acquire_future)
|
||||
.then_execute(queue.clone(), command_buffer)
|
||||
.unwrap()
|
||||
.then_swapchain_present(queue.clone(), swapchain.clone(), image_num)
|
||||
.then_swapchain_present(
|
||||
queue.clone(),
|
||||
PresentInfo {
|
||||
index: image_num,
|
||||
..PresentInfo::swapchain(swapchain.clone())
|
||||
},
|
||||
)
|
||||
.then_signal_fence_and_flush();
|
||||
|
||||
match future {
|
||||
|
@ -46,7 +46,8 @@ use vulkano::{
|
||||
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
|
||||
sampler::{Filter, Sampler, SamplerAddressMode, SamplerCreateInfo},
|
||||
swapchain::{
|
||||
acquire_next_image, AcquireError, Swapchain, SwapchainCreateInfo, SwapchainCreationError,
|
||||
acquire_next_image, AcquireError, PresentInfo, Swapchain, SwapchainCreateInfo,
|
||||
SwapchainCreationError,
|
||||
},
|
||||
sync::{self, FlushError, GpuFuture},
|
||||
VulkanLibrary,
|
||||
@ -368,7 +369,13 @@ fn main() {
|
||||
.join(acquire_future)
|
||||
.then_execute(queue.clone(), command_buffer)
|
||||
.unwrap()
|
||||
.then_swapchain_present(queue.clone(), swapchain.clone(), image_num)
|
||||
.then_swapchain_present(
|
||||
queue.clone(),
|
||||
PresentInfo {
|
||||
index: image_num,
|
||||
..PresentInfo::swapchain(swapchain.clone())
|
||||
},
|
||||
)
|
||||
.then_signal_fence_and_flush();
|
||||
|
||||
match future {
|
||||
|
@ -50,7 +50,8 @@ use vulkano::{
|
||||
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
|
||||
single_pass_renderpass,
|
||||
swapchain::{
|
||||
acquire_next_image, AcquireError, Swapchain, SwapchainCreateInfo, SwapchainCreationError,
|
||||
acquire_next_image, AcquireError, PresentInfo, Swapchain, SwapchainCreateInfo,
|
||||
SwapchainCreationError,
|
||||
},
|
||||
sync::{self, FlushError, GpuFuture},
|
||||
VulkanLibrary,
|
||||
@ -441,7 +442,13 @@ fn main() {
|
||||
.join(acquire_future)
|
||||
.then_execute(queue.clone(), command_buffer)
|
||||
.unwrap()
|
||||
.then_swapchain_present(queue.clone(), swapchain.clone(), image_num)
|
||||
.then_swapchain_present(
|
||||
queue.clone(),
|
||||
PresentInfo {
|
||||
index: image_num,
|
||||
..PresentInfo::swapchain(swapchain.clone())
|
||||
},
|
||||
)
|
||||
.then_signal_fence_and_flush();
|
||||
|
||||
match future {
|
||||
|
@ -36,7 +36,8 @@ use vulkano::{
|
||||
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
|
||||
single_pass_renderpass,
|
||||
swapchain::{
|
||||
acquire_next_image, AcquireError, Swapchain, SwapchainCreateInfo, SwapchainCreationError,
|
||||
acquire_next_image, AcquireError, PresentInfo, Swapchain, SwapchainCreateInfo,
|
||||
SwapchainCreationError,
|
||||
},
|
||||
sync::{self, FlushError, GpuFuture},
|
||||
VulkanLibrary,
|
||||
@ -405,7 +406,13 @@ fn main() {
|
||||
.join(acquire_future)
|
||||
.then_execute(queue.clone(), command_buffer)
|
||||
.unwrap()
|
||||
.then_swapchain_present(queue.clone(), swapchain.clone(), image_num)
|
||||
.then_swapchain_present(
|
||||
queue.clone(),
|
||||
PresentInfo {
|
||||
index: image_num,
|
||||
..PresentInfo::swapchain(swapchain.clone())
|
||||
},
|
||||
)
|
||||
.then_signal_fence_and_flush();
|
||||
|
||||
match future {
|
||||
|
@ -39,7 +39,7 @@ use vulkano::{
|
||||
},
|
||||
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
|
||||
swapchain::{
|
||||
acquire_next_image, AcquireError, Surface, Swapchain, SwapchainCreateInfo,
|
||||
acquire_next_image, AcquireError, PresentInfo, Surface, Swapchain, SwapchainCreateInfo,
|
||||
SwapchainCreationError,
|
||||
},
|
||||
sync::{self, FlushError, GpuFuture},
|
||||
@ -445,7 +445,13 @@ fn main() {
|
||||
.join(acquire_future)
|
||||
.then_execute(queue.clone(), command_buffer)
|
||||
.unwrap()
|
||||
.then_swapchain_present(queue.clone(), swapchain.clone(), image_num)
|
||||
.then_swapchain_present(
|
||||
queue.clone(),
|
||||
PresentInfo {
|
||||
index: image_num,
|
||||
..PresentInfo::swapchain(swapchain.clone())
|
||||
},
|
||||
)
|
||||
.then_signal_fence_and_flush();
|
||||
|
||||
match future {
|
||||
|
@ -38,7 +38,8 @@ use vulkano::{
|
||||
query::{QueryControlFlags, QueryPool, QueryPoolCreateInfo, QueryResultFlags, QueryType},
|
||||
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
|
||||
swapchain::{
|
||||
acquire_next_image, AcquireError, Swapchain, SwapchainCreateInfo, SwapchainCreationError,
|
||||
acquire_next_image, AcquireError, PresentInfo, Swapchain, SwapchainCreateInfo,
|
||||
SwapchainCreationError,
|
||||
},
|
||||
sync::{self, FlushError, GpuFuture},
|
||||
VulkanLibrary,
|
||||
@ -460,7 +461,13 @@ fn main() {
|
||||
.join(acquire_future)
|
||||
.then_execute(queue.clone(), command_buffer)
|
||||
.unwrap()
|
||||
.then_swapchain_present(queue.clone(), swapchain.clone(), image_num)
|
||||
.then_swapchain_present(
|
||||
queue.clone(),
|
||||
PresentInfo {
|
||||
index: image_num,
|
||||
..PresentInfo::swapchain(swapchain.clone())
|
||||
},
|
||||
)
|
||||
.then_signal_fence_and_flush();
|
||||
|
||||
match future {
|
||||
|
@ -37,7 +37,8 @@ use vulkano::{
|
||||
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
|
||||
sampler::{Filter, Sampler, SamplerAddressMode, SamplerCreateInfo},
|
||||
swapchain::{
|
||||
acquire_next_image, AcquireError, Swapchain, SwapchainCreateInfo, SwapchainCreationError,
|
||||
acquire_next_image, AcquireError, PresentInfo, Swapchain, SwapchainCreateInfo,
|
||||
SwapchainCreationError,
|
||||
},
|
||||
sync::{self, FlushError, GpuFuture},
|
||||
VulkanLibrary,
|
||||
@ -353,7 +354,13 @@ fn main() {
|
||||
.join(acquire_future)
|
||||
.then_execute(queue.clone(), command_buffer)
|
||||
.unwrap()
|
||||
.then_swapchain_present(queue.clone(), swapchain.clone(), image_num)
|
||||
.then_swapchain_present(
|
||||
queue.clone(),
|
||||
PresentInfo {
|
||||
index: image_num,
|
||||
..PresentInfo::swapchain(swapchain.clone())
|
||||
},
|
||||
)
|
||||
.then_signal_fence_and_flush();
|
||||
|
||||
match future {
|
||||
|
@ -44,7 +44,8 @@ use vulkano::{
|
||||
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
|
||||
shader::ShaderModule,
|
||||
swapchain::{
|
||||
acquire_next_image, AcquireError, Swapchain, SwapchainCreateInfo, SwapchainCreationError,
|
||||
acquire_next_image, AcquireError, PresentInfo, Swapchain, SwapchainCreateInfo,
|
||||
SwapchainCreationError,
|
||||
},
|
||||
sync::{self, FlushError, GpuFuture},
|
||||
VulkanLibrary,
|
||||
@ -336,7 +337,13 @@ fn main() {
|
||||
.join(acquire_future)
|
||||
.then_execute(queue.clone(), command_buffer)
|
||||
.unwrap()
|
||||
.then_swapchain_present(queue.clone(), swapchain.clone(), image_num)
|
||||
.then_swapchain_present(
|
||||
queue.clone(),
|
||||
PresentInfo {
|
||||
index: image_num,
|
||||
..PresentInfo::swapchain(swapchain.clone())
|
||||
},
|
||||
)
|
||||
.then_signal_fence_and_flush();
|
||||
|
||||
match future {
|
||||
|
@ -43,7 +43,8 @@ use vulkano::{
|
||||
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
|
||||
sampler::{Filter, Sampler, SamplerAddressMode, SamplerCreateInfo},
|
||||
swapchain::{
|
||||
acquire_next_image, AcquireError, Swapchain, SwapchainCreateInfo, SwapchainCreationError,
|
||||
acquire_next_image, AcquireError, PresentInfo, Swapchain, SwapchainCreateInfo,
|
||||
SwapchainCreationError,
|
||||
},
|
||||
sync::{self, FlushError, GpuFuture},
|
||||
VulkanLibrary,
|
||||
@ -491,7 +492,13 @@ fn main() {
|
||||
.join(acquire_future)
|
||||
.then_execute(queue.clone(), command_buffer)
|
||||
.unwrap()
|
||||
.then_swapchain_present(queue.clone(), swapchain.clone(), image_num)
|
||||
.then_swapchain_present(
|
||||
queue.clone(),
|
||||
PresentInfo {
|
||||
index: image_num,
|
||||
..PresentInfo::swapchain(swapchain.clone())
|
||||
},
|
||||
)
|
||||
.then_signal_fence_and_flush();
|
||||
|
||||
match future {
|
||||
|
@ -37,7 +37,7 @@ use vulkano::{
|
||||
GraphicsPipeline, PipelineBindPoint,
|
||||
},
|
||||
render_pass::{Framebuffer, FramebufferCreateInfo, Subpass},
|
||||
swapchain::{PresentMode, Swapchain, SwapchainCreateInfo},
|
||||
swapchain::{PresentInfo, PresentMode, Swapchain, SwapchainCreateInfo},
|
||||
sync::{FenceSignalFuture, GpuFuture},
|
||||
VulkanLibrary,
|
||||
};
|
||||
@ -534,7 +534,13 @@ fn main() {
|
||||
.join(acquire_future)
|
||||
.then_execute(queue.clone(), command_buffer)
|
||||
.unwrap()
|
||||
.then_swapchain_present(queue.clone(), swapchain.clone(), image_index)
|
||||
.then_swapchain_present(
|
||||
queue.clone(),
|
||||
PresentInfo {
|
||||
index: image_index,
|
||||
..PresentInfo::swapchain(swapchain.clone())
|
||||
},
|
||||
)
|
||||
.then_signal_fence_and_flush();
|
||||
|
||||
// Update this frame's future with current fence.
|
||||
|
@ -34,7 +34,8 @@ use vulkano::{
|
||||
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
|
||||
shader::ShaderModule,
|
||||
swapchain::{
|
||||
acquire_next_image, AcquireError, Swapchain, SwapchainCreateInfo, SwapchainCreationError,
|
||||
acquire_next_image, AcquireError, PresentInfo, Swapchain, SwapchainCreateInfo,
|
||||
SwapchainCreationError,
|
||||
},
|
||||
sync::{self, FlushError, GpuFuture},
|
||||
VulkanLibrary,
|
||||
@ -360,7 +361,13 @@ fn main() {
|
||||
.join(acquire_future)
|
||||
.then_execute(queue.clone(), command_buffer)
|
||||
.unwrap()
|
||||
.then_swapchain_present(queue.clone(), swapchain.clone(), image_num)
|
||||
.then_swapchain_present(
|
||||
queue.clone(),
|
||||
PresentInfo {
|
||||
index: image_num,
|
||||
..PresentInfo::swapchain(swapchain.clone())
|
||||
},
|
||||
)
|
||||
.then_signal_fence_and_flush();
|
||||
|
||||
match future {
|
||||
|
@ -44,7 +44,8 @@ use vulkano::{
|
||||
},
|
||||
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
|
||||
swapchain::{
|
||||
acquire_next_image, AcquireError, Swapchain, SwapchainCreateInfo, SwapchainCreationError,
|
||||
acquire_next_image, AcquireError, PresentInfo, Swapchain, SwapchainCreateInfo,
|
||||
SwapchainCreationError,
|
||||
},
|
||||
sync::{self, FlushError, GpuFuture},
|
||||
VulkanLibrary,
|
||||
@ -443,7 +444,13 @@ fn main() {
|
||||
.join(acquire_future)
|
||||
.then_execute(queue.clone(), command_buffer)
|
||||
.unwrap()
|
||||
.then_swapchain_present(queue.clone(), swapchain.clone(), image_num)
|
||||
.then_swapchain_present(
|
||||
queue.clone(),
|
||||
PresentInfo {
|
||||
index: image_num,
|
||||
..PresentInfo::swapchain(swapchain.clone())
|
||||
},
|
||||
)
|
||||
.then_signal_fence_and_flush();
|
||||
|
||||
match future {
|
||||
|
@ -37,7 +37,8 @@ use vulkano::{
|
||||
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
|
||||
sampler::{Sampler, SamplerCreateInfo},
|
||||
swapchain::{
|
||||
acquire_next_image, AcquireError, Swapchain, SwapchainCreateInfo, SwapchainCreationError,
|
||||
acquire_next_image, AcquireError, PresentInfo, Swapchain, SwapchainCreateInfo,
|
||||
SwapchainCreationError,
|
||||
},
|
||||
sync::{self, FlushError, GpuFuture},
|
||||
VulkanLibrary,
|
||||
@ -358,7 +359,13 @@ fn main() {
|
||||
.join(acquire_future)
|
||||
.then_execute(queue.clone(), command_buffer)
|
||||
.unwrap()
|
||||
.then_swapchain_present(queue.clone(), swapchain.clone(), image_num)
|
||||
.then_swapchain_present(
|
||||
queue.clone(),
|
||||
PresentInfo {
|
||||
index: image_num,
|
||||
..PresentInfo::swapchain(swapchain.clone())
|
||||
},
|
||||
)
|
||||
.then_signal_fence_and_flush();
|
||||
|
||||
match future {
|
||||
|
@ -46,7 +46,8 @@ use vulkano::{
|
||||
},
|
||||
render_pass::{LoadOp, StoreOp},
|
||||
swapchain::{
|
||||
acquire_next_image, AcquireError, Swapchain, SwapchainCreateInfo, SwapchainCreationError,
|
||||
acquire_next_image, AcquireError, PresentInfo, Swapchain, SwapchainCreateInfo,
|
||||
SwapchainCreationError,
|
||||
},
|
||||
sync::{self, FlushError, GpuFuture},
|
||||
Version, VulkanLibrary,
|
||||
@ -568,7 +569,13 @@ fn main() {
|
||||
// This function does not actually present the image immediately. Instead it submits a
|
||||
// present command at the end of the queue. This means that it will only be presented once
|
||||
// the GPU has finished executing the command buffer that draws the triangle.
|
||||
.then_swapchain_present(queue.clone(), swapchain.clone(), image_num)
|
||||
.then_swapchain_present(
|
||||
queue.clone(),
|
||||
PresentInfo {
|
||||
index: image_num,
|
||||
..PresentInfo::swapchain(swapchain.clone())
|
||||
},
|
||||
)
|
||||
.then_signal_fence_and_flush();
|
||||
|
||||
match future {
|
||||
|
@ -39,7 +39,8 @@ use vulkano::{
|
||||
},
|
||||
render_pass::{Framebuffer, FramebufferCreateInfo, RenderPass, Subpass},
|
||||
swapchain::{
|
||||
acquire_next_image, AcquireError, Swapchain, SwapchainCreateInfo, SwapchainCreationError,
|
||||
acquire_next_image, AcquireError, PresentInfo, Swapchain, SwapchainCreateInfo,
|
||||
SwapchainCreationError,
|
||||
},
|
||||
sync::{self, FlushError, GpuFuture},
|
||||
VulkanLibrary,
|
||||
@ -576,7 +577,13 @@ fn main() {
|
||||
// This function does not actually present the image immediately. Instead it submits a
|
||||
// present command at the end of the queue. This means that it will only be presented once
|
||||
// the GPU has finished executing the command buffer that draws the triangle.
|
||||
.then_swapchain_present(queue.clone(), swapchain.clone(), image_num)
|
||||
.then_swapchain_present(
|
||||
queue.clone(),
|
||||
PresentInfo {
|
||||
index: image_num,
|
||||
..PresentInfo::swapchain(swapchain.clone())
|
||||
},
|
||||
)
|
||||
.then_signal_fence_and_flush();
|
||||
|
||||
match future {
|
||||
|
@ -19,7 +19,9 @@ use vulkano::{
|
||||
format::Format,
|
||||
image::{view::ImageView, ImageAccess, ImageViewAbstract},
|
||||
swapchain,
|
||||
swapchain::{AcquireError, Surface, Swapchain, SwapchainCreateInfo, SwapchainCreationError},
|
||||
swapchain::{
|
||||
AcquireError, PresentInfo, Surface, Swapchain, SwapchainCreateInfo, SwapchainCreationError,
|
||||
},
|
||||
sync,
|
||||
sync::{FlushError, GpuFuture},
|
||||
};
|
||||
@ -279,8 +281,10 @@ impl VulkanoWindowRenderer {
|
||||
let future = after_future
|
||||
.then_swapchain_present(
|
||||
self.graphics_queue.clone(),
|
||||
self.swap_chain.clone(),
|
||||
self.image_index,
|
||||
PresentInfo {
|
||||
index: self.image_index,
|
||||
..PresentInfo::swapchain(self.swap_chain.clone())
|
||||
},
|
||||
)
|
||||
.then_signal_fence_and_flush();
|
||||
match future {
|
||||
|
@ -9,7 +9,7 @@
|
||||
|
||||
use crate::{
|
||||
device::{DeviceOwned, Queue},
|
||||
swapchain::{PresentRegion, Swapchain},
|
||||
swapchain::PresentInfo,
|
||||
sync::Semaphore,
|
||||
OomError, SynchronizedVulkanObject, VulkanError, VulkanObject,
|
||||
};
|
||||
@ -19,6 +19,7 @@ use std::{
|
||||
fmt::{Debug, Display, Error as FmtError, Formatter},
|
||||
marker::PhantomData,
|
||||
ptr,
|
||||
sync::atomic::{AtomicU64, Ordering},
|
||||
};
|
||||
|
||||
/// Prototype for a submission that presents a swapchain on the screen.
|
||||
@ -27,6 +28,8 @@ pub struct SubmitPresentBuilder<'a> {
|
||||
wait_semaphores: SmallVec<[ash::vk::Semaphore; 8]>,
|
||||
swapchains: SmallVec<[ash::vk::SwapchainKHR; 4]>,
|
||||
image_indices: SmallVec<[u32; 4]>,
|
||||
present_ids: SmallVec<[u64; 4]>,
|
||||
prev_present_ids: SmallVec<[&'a AtomicU64; 4]>,
|
||||
present_regions: SmallVec<[ash::vk::PresentRegionKHR; 4]>,
|
||||
rect_layers: SmallVec<[ash::vk::RectLayerKHR; 4]>,
|
||||
marker: PhantomData<&'a ()>,
|
||||
@ -40,6 +43,8 @@ impl<'a> SubmitPresentBuilder<'a> {
|
||||
wait_semaphores: SmallVec::new(),
|
||||
swapchains: SmallVec::new(),
|
||||
image_indices: SmallVec::new(),
|
||||
present_ids: SmallVec::new(),
|
||||
prev_present_ids: SmallVec::new(),
|
||||
present_regions: SmallVec::new(),
|
||||
rect_layers: SmallVec::new(),
|
||||
marker: PhantomData,
|
||||
@ -76,21 +81,25 @@ impl<'a> SubmitPresentBuilder<'a> {
|
||||
///
|
||||
/// If `VK_KHR_incremental_present` is not enabled, the `present_region` parameter is ignored.
|
||||
///
|
||||
/// If `present_id` feature is not enabled, then the `present_id` parameter is ignored.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// - If you submit this builder, the swapchain must be kept alive until you are
|
||||
/// guaranteed that the GPU has finished presenting.
|
||||
///
|
||||
/// - The swapchains and semaphores must all belong to the same device.
|
||||
///
|
||||
#[inline]
|
||||
pub unsafe fn add_swapchain<W>(
|
||||
&mut self,
|
||||
swapchain: &'a Swapchain<W>,
|
||||
image_num: u32,
|
||||
present_region: Option<&'a PresentRegion>,
|
||||
) {
|
||||
debug_assert!(image_num < swapchain.image_count());
|
||||
pub unsafe fn add_swapchain<W>(&mut self, info: &'a PresentInfo<W>) {
|
||||
let PresentInfo {
|
||||
swapchain,
|
||||
index,
|
||||
present_id,
|
||||
present_region,
|
||||
..
|
||||
} = info;
|
||||
|
||||
debug_assert!((*index as u32) < swapchain.image_count());
|
||||
|
||||
if swapchain
|
||||
.device()
|
||||
@ -117,8 +126,13 @@ impl<'a> SubmitPresentBuilder<'a> {
|
||||
self.present_regions.push(vk_present_region);
|
||||
}
|
||||
|
||||
if swapchain.device().enabled_features().present_id {
|
||||
self.present_ids.push(present_id.unwrap_or(0));
|
||||
self.prev_present_ids.push(swapchain.prev_present_id());
|
||||
}
|
||||
|
||||
self.swapchains.push(swapchain.internal_object());
|
||||
self.image_indices.push(image_num);
|
||||
self.image_indices.push(*index as u32);
|
||||
}
|
||||
|
||||
/// Submits the command. Calls `vkQueuePresentKHR`.
|
||||
@ -135,7 +149,7 @@ impl<'a> SubmitPresentBuilder<'a> {
|
||||
"Tried to submit a present command without any swapchain"
|
||||
);
|
||||
|
||||
let present_regions = {
|
||||
let mut present_regions = {
|
||||
if !self.present_regions.is_empty() {
|
||||
debug_assert!(queue.device().enabled_extensions().khr_incremental_present);
|
||||
debug_assert_eq!(self.swapchains.len(), self.present_regions.len());
|
||||
@ -154,16 +168,35 @@ impl<'a> SubmitPresentBuilder<'a> {
|
||||
}
|
||||
};
|
||||
|
||||
let mut results = vec![ash::vk::Result::SUCCESS; self.swapchains.len()];
|
||||
let mut present_ids = {
|
||||
if !self.present_ids.is_empty() {
|
||||
debug_assert!(queue.device().enabled_features().present_id);
|
||||
debug_assert_eq!(self.swapchains.len(), self.present_ids.len());
|
||||
|
||||
// VUID-VkPresentIdKHR-presentIds-04999
|
||||
for (id, prev_id) in self.present_ids.iter().zip(self.prev_present_ids.iter()) {
|
||||
if *id != 0 {
|
||||
if prev_id.fetch_max(*id, Ordering::SeqCst) >= *id {
|
||||
return Err(SubmitPresentError::PresentIdLessThanOrEqual);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Some(ash::vk::PresentIdKHR {
|
||||
swapchain_count: self.swapchains.len() as u32,
|
||||
p_present_ids: self.present_ids.as_ptr(),
|
||||
..Default::default()
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
};
|
||||
|
||||
let mut results = vec![ash::vk::Result::SUCCESS; self.swapchains.len()];
|
||||
let fns = queue.device().fns();
|
||||
let queue = queue.internal_object_guard();
|
||||
|
||||
let infos = ash::vk::PresentInfoKHR {
|
||||
p_next: present_regions
|
||||
.as_ref()
|
||||
.map(|pr| pr as *const ash::vk::PresentRegionsKHR as *const _)
|
||||
.unwrap_or(ptr::null()),
|
||||
let mut present_info = ash::vk::PresentInfoKHR {
|
||||
wait_semaphore_count: self.wait_semaphores.len() as u32,
|
||||
p_wait_semaphores: self.wait_semaphores.as_ptr(),
|
||||
swapchain_count: self.swapchains.len() as u32,
|
||||
@ -173,7 +206,17 @@ impl<'a> SubmitPresentBuilder<'a> {
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
(fns.khr_swapchain.queue_present_khr)(*queue, &infos)
|
||||
if let Some(present_regions) = present_regions.as_mut() {
|
||||
present_regions.p_next = present_info.p_next as *mut _;
|
||||
present_info.p_next = present_regions as *const _ as *const _;
|
||||
}
|
||||
|
||||
if let Some(present_ids) = present_ids.as_mut() {
|
||||
present_ids.p_next = present_info.p_next as *mut _;
|
||||
present_info.p_next = present_ids as *const _ as *const _;
|
||||
}
|
||||
|
||||
(fns.khr_swapchain.queue_present_khr)(*queue, &present_info)
|
||||
.result()
|
||||
.map_err(VulkanError::from)?;
|
||||
|
||||
@ -216,6 +259,10 @@ pub enum SubmitPresentError {
|
||||
/// 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,
|
||||
|
||||
/// A non-zero present_id must be greater than any non-zero present_id passed previously
|
||||
/// for the same swapchain.
|
||||
PresentIdLessThanOrEqual,
|
||||
}
|
||||
|
||||
impl Error for SubmitPresentError {
|
||||
@ -243,6 +290,9 @@ impl Display for SubmitPresentError {
|
||||
SubmitPresentError::FullScreenExclusiveModeLost => {
|
||||
"the swapchain no longer has full-screen exclusivity"
|
||||
}
|
||||
SubmitPresentError::PresentIdLessThanOrEqual => {
|
||||
"present id is less than or equal to previous"
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
@ -607,6 +607,7 @@ impl Device {
|
||||
/// # Safety
|
||||
///
|
||||
/// - `file` must be a handle to external memory that was created outside the Vulkan API.
|
||||
#[cfg_attr(not(unix), allow(unused_variables))]
|
||||
pub unsafe fn memory_fd_properties(
|
||||
&self,
|
||||
handle_type: ExternalMemoryHandleType,
|
||||
|
@ -243,7 +243,7 @@
|
||||
//! command to present the image on the screen after the draw operations are finished.
|
||||
//!
|
||||
//! ```
|
||||
//! use vulkano::swapchain;
|
||||
//! use vulkano::swapchain::{self, PresentInfo};
|
||||
//! use vulkano::sync::GpuFuture;
|
||||
//! # let queue: ::std::sync::Arc<::vulkano::device::Queue> = return;
|
||||
//! # let mut swapchain: ::std::sync::Arc<swapchain::Swapchain<()>> = return;
|
||||
@ -257,7 +257,13 @@
|
||||
//! // constructed from images[image_num]
|
||||
//! acquire_future
|
||||
//! .then_execute(queue.clone(), command_buffer).unwrap()
|
||||
//! .then_swapchain_present(queue.clone(), swapchain.clone(), image_num)
|
||||
//! .then_swapchain_present(
|
||||
//! queue.clone(),
|
||||
//! PresentInfo {
|
||||
//! index: image_num,
|
||||
//! .. PresentInfo::swapchain(swapchain.clone())
|
||||
//! },
|
||||
//! )
|
||||
//! .then_signal_fence_and_flush().unwrap();
|
||||
//! }
|
||||
//! ```
|
||||
@ -276,7 +282,7 @@
|
||||
//!
|
||||
//! ```
|
||||
//! use vulkano::swapchain;
|
||||
//! use vulkano::swapchain::{AcquireError, SwapchainCreateInfo};
|
||||
//! use vulkano::swapchain::{AcquireError, SwapchainCreateInfo, PresentInfo};
|
||||
//! use vulkano::sync::GpuFuture;
|
||||
//!
|
||||
//! // let (swapchain, images) = Swapchain::new(...);
|
||||
@ -307,7 +313,13 @@
|
||||
//!
|
||||
//! let final_future = acq_future
|
||||
//! // .then_execute(...)
|
||||
//! .then_swapchain_present(queue.clone(), swapchain.clone(), index)
|
||||
//! .then_swapchain_present(
|
||||
//! queue.clone(),
|
||||
//! PresentInfo {
|
||||
//! index,
|
||||
//! .. PresentInfo::swapchain(swapchain.clone())
|
||||
//! },
|
||||
//! )
|
||||
//! .then_signal_fence_and_flush().unwrap(); // TODO: PresentError?
|
||||
//!
|
||||
//! if suboptimal {
|
||||
@ -325,9 +337,10 @@ pub use self::{
|
||||
SurfaceInfo, SurfaceTransform,
|
||||
},
|
||||
swapchain::{
|
||||
acquire_next_image, acquire_next_image_raw, present, present_incremental, AcquireError,
|
||||
AcquiredImage, FullScreenExclusive, FullScreenExclusiveError, PresentFuture, Swapchain,
|
||||
SwapchainAcquireFuture, SwapchainCreateInfo, SwapchainCreationError, Win32Monitor,
|
||||
acquire_next_image, acquire_next_image_raw, present, wait_for_present, AcquireError,
|
||||
AcquiredImage, FullScreenExclusive, FullScreenExclusiveError, PresentFuture, PresentInfo,
|
||||
PresentWaitError, Swapchain, SwapchainAcquireFuture, SwapchainCreateInfo,
|
||||
SwapchainCreationError, Win32Monitor,
|
||||
},
|
||||
};
|
||||
#[cfg(target_os = "ios")]
|
||||
|
@ -12,7 +12,7 @@ use crate::swapchain::Swapchain;
|
||||
/// Represents a region on an image.
|
||||
///
|
||||
/// A region consists of an arbitrary amount of rectangles.
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct PresentRegion {
|
||||
pub rectangles: Vec<RectangleLayer>,
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ use std::{
|
||||
ops::Range,
|
||||
ptr,
|
||||
sync::{
|
||||
atomic::{AtomicBool, Ordering},
|
||||
atomic::{AtomicBool, AtomicU64, Ordering},
|
||||
Arc,
|
||||
},
|
||||
time::Duration,
|
||||
@ -69,6 +69,7 @@ pub struct Swapchain<W> {
|
||||
clipped: bool,
|
||||
full_screen_exclusive: FullScreenExclusive,
|
||||
win32_monitor: Option<Win32Monitor>,
|
||||
prev_present_id: AtomicU64,
|
||||
|
||||
// Whether full-screen exclusive is currently held.
|
||||
full_screen_exclusive_held: AtomicBool,
|
||||
@ -173,6 +174,7 @@ impl<W> Swapchain<W> {
|
||||
clipped,
|
||||
full_screen_exclusive,
|
||||
win32_monitor,
|
||||
prev_present_id: Default::default(),
|
||||
|
||||
full_screen_exclusive_held: AtomicBool::new(false),
|
||||
images,
|
||||
@ -267,6 +269,7 @@ impl<W> Swapchain<W> {
|
||||
clipped,
|
||||
full_screen_exclusive,
|
||||
win32_monitor,
|
||||
prev_present_id: Default::default(),
|
||||
|
||||
full_screen_exclusive_held: AtomicBool::new(full_screen_exclusive_held),
|
||||
images,
|
||||
@ -898,6 +901,10 @@ impl<W> Swapchain<W> {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn prev_present_id(&self) -> &AtomicU64 {
|
||||
&self.prev_present_id
|
||||
}
|
||||
}
|
||||
|
||||
impl<W> Drop for Swapchain<W> {
|
||||
@ -1491,23 +1498,54 @@ pub fn acquire_next_image<W>(
|
||||
))
|
||||
}
|
||||
|
||||
/// Parameters for
|
||||
/// [`swapchain::present`](crate::swapchain::present)
|
||||
/// and
|
||||
/// [`GpuFuture::then_swapchain_present`](crate::sync::GpuFuture::then_swapchain_present).
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct PresentInfo<W> {
|
||||
/// The `Swapchain` to present to.
|
||||
pub swapchain: Arc<Swapchain<W>>,
|
||||
/// The same index that `acquire_next_image` returned. The image must have been acquired first.
|
||||
pub index: usize,
|
||||
/// A present id used for this present call.
|
||||
///
|
||||
/// Must be greater than previously used.
|
||||
///
|
||||
/// If this value is zero it is equivalent to `None`.
|
||||
///
|
||||
/// If the `present_id` feature is not enabled on the device, the parameter will be ignored.
|
||||
pub present_id: Option<u64>,
|
||||
/// Areas outside the present region may be ignored by Vulkan in order to optimize presentation.
|
||||
///
|
||||
/// This is just an optimization hint, as the Vulkan driver is free to ignore the given present region.
|
||||
///
|
||||
/// If `khr_incremental_present` extension is not enabled on the device, the parameter will be ignored.
|
||||
pub present_region: Option<PresentRegion>,
|
||||
pub _ne: crate::NonExhaustive,
|
||||
}
|
||||
|
||||
impl<W> PresentInfo<W> {
|
||||
pub fn swapchain(swapchain: Arc<Swapchain<W>>) -> Self {
|
||||
Self {
|
||||
swapchain,
|
||||
index: 0,
|
||||
present_id: None,
|
||||
present_region: None,
|
||||
_ne: crate::NonExhaustive(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Presents an image on the screen.
|
||||
///
|
||||
/// The parameter is the same index as what `acquire_next_image` returned. The image must
|
||||
/// have been acquired first.
|
||||
///
|
||||
/// The actual behavior depends on the present mode that you passed when creating the
|
||||
/// swapchain.
|
||||
pub fn present<F, W>(
|
||||
swapchain: Arc<Swapchain<W>>,
|
||||
before: F,
|
||||
queue: Arc<Queue>,
|
||||
index: usize,
|
||||
) -> PresentFuture<F, W>
|
||||
pub fn present<F, W>(before: F, queue: Arc<Queue>, info: PresentInfo<W>) -> PresentFuture<F, W>
|
||||
where
|
||||
F: GpuFuture,
|
||||
{
|
||||
assert!(index < swapchain.images.len());
|
||||
assert!(info.index < info.swapchain.images.len());
|
||||
|
||||
// TODO: restore this check with a dummy ImageAccess implementation
|
||||
/*let swapchain_image = me.images.lock().unwrap().get(index).unwrap().0.upgrade().unwrap(); // TODO: return error instead
|
||||
@ -1519,47 +1557,69 @@ where
|
||||
PresentFuture {
|
||||
previous: before,
|
||||
queue,
|
||||
swapchain,
|
||||
image_id: index,
|
||||
present_region: None,
|
||||
info,
|
||||
flushed: AtomicBool::new(false),
|
||||
finished: AtomicBool::new(false),
|
||||
}
|
||||
}
|
||||
|
||||
/// Same as `swapchain::present`, except it allows specifying a present region.
|
||||
/// Areas outside the present region may be ignored by Vulkan in order to optimize presentation.
|
||||
/// Wait for an image to be presented to the user. Must be used with a `present_id` given to `present_with_id`.
|
||||
///
|
||||
/// This is just an optimization hint, as the Vulkan driver is free to ignore the given present region.
|
||||
///
|
||||
/// If `VK_KHR_incremental_present` is not enabled on the device, the parameter will be ignored.
|
||||
pub fn present_incremental<F, W>(
|
||||
/// Returns a bool to represent if the presentation was suboptimal. In this case the swapchain is still
|
||||
/// usable, but the swapchain should be recreated as the Surface's properties no longer match the swapchain.
|
||||
pub fn wait_for_present<W>(
|
||||
swapchain: Arc<Swapchain<W>>,
|
||||
before: F,
|
||||
queue: Arc<Queue>,
|
||||
index: usize,
|
||||
present_region: PresentRegion,
|
||||
) -> PresentFuture<F, W>
|
||||
where
|
||||
F: GpuFuture,
|
||||
{
|
||||
assert!(index < swapchain.images.len());
|
||||
present_id: u64,
|
||||
timeout: Option<Duration>,
|
||||
) -> Result<bool, PresentWaitError> {
|
||||
let retired = swapchain.retired.lock();
|
||||
|
||||
// TODO: restore this check with a dummy ImageAccess implementation
|
||||
/*let swapchain_image = me.images.lock().unwrap().get(index).unwrap().0.upgrade().unwrap(); // TODO: return error instead
|
||||
// Normally if `check_image_access` returns false we're supposed to call the `gpu_access`
|
||||
// function on the image instead. But since we know that this method on `SwapchainImage`
|
||||
// always returns false anyway (by design), we don't need to do it.
|
||||
assert!(before.check_image_access(&swapchain_image, ImageLayout::PresentSrc, true, &queue).is_ok()); // TODO: return error instead*/
|
||||
// VUID-vkWaitForPresentKHR-swapchain-04997
|
||||
if *retired {
|
||||
return Err(PresentWaitError::OutOfDate);
|
||||
}
|
||||
|
||||
PresentFuture {
|
||||
previous: before,
|
||||
queue,
|
||||
swapchain,
|
||||
image_id: index,
|
||||
present_region: Some(present_region),
|
||||
flushed: AtomicBool::new(false),
|
||||
finished: AtomicBool::new(false),
|
||||
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 {
|
||||
features: &["present_wait"],
|
||||
..Default::default()
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
let timeout_ns = timeout.map(|dur| dur.as_nanos() as u64).unwrap_or(0);
|
||||
|
||||
let result = unsafe {
|
||||
(swapchain.device.fns().khr_present_wait.wait_for_present_khr)(
|
||||
swapchain.device.internal_object(),
|
||||
swapchain.handle,
|
||||
present_id.into(),
|
||||
timeout_ns,
|
||||
)
|
||||
};
|
||||
|
||||
match result {
|
||||
ash::vk::Result::SUCCESS => Ok(false),
|
||||
ash::vk::Result::SUBOPTIMAL_KHR => Ok(true),
|
||||
ash::vk::Result::TIMEOUT => return Err(PresentWaitError::Timeout),
|
||||
err => {
|
||||
let err = VulkanError::from(err).into();
|
||||
|
||||
if let PresentWaitError::FullScreenExclusiveModeLost = &err {
|
||||
swapchain
|
||||
.full_screen_exclusive_held
|
||||
.store(false, Ordering::SeqCst);
|
||||
}
|
||||
|
||||
Err(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1790,6 +1850,106 @@ impl From<VulkanError> for AcquireError {
|
||||
}
|
||||
}
|
||||
|
||||
/// 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 application’s 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 {
|
||||
#[inline]
|
||||
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
||||
match *self {
|
||||
Self::OomError(ref err) => Some(err),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for PresentWaitError {
|
||||
#[inline]
|
||||
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 {
|
||||
#[inline]
|
||||
fn from(err: OomError) -> PresentWaitError {
|
||||
Self::OomError(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<RequirementNotMet> for PresentWaitError {
|
||||
#[inline]
|
||||
fn from(err: RequirementNotMet) -> Self {
|
||||
Self::RequirementNotMet {
|
||||
required_for: err.required_for,
|
||||
requires_one_of: err.requires_one_of,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<VulkanError> for PresentWaitError {
|
||||
#[inline]
|
||||
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),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents a swapchain image being presented on the screen.
|
||||
#[must_use = "Dropping this object will immediately block the thread until the GPU has finished processing the submission"]
|
||||
pub struct PresentFuture<P, W>
|
||||
@ -1798,9 +1958,7 @@ where
|
||||
{
|
||||
previous: P,
|
||||
queue: Arc<Queue>,
|
||||
swapchain: Arc<Swapchain<W>>,
|
||||
image_id: usize,
|
||||
present_region: Option<PresentRegion>,
|
||||
info: PresentInfo<W>,
|
||||
// True if `flush()` has been called on the future, which means that the present command has
|
||||
// been submitted.
|
||||
flushed: AtomicBool,
|
||||
@ -1816,13 +1974,13 @@ where
|
||||
/// Returns the index of the image in the list of images returned when creating the swapchain.
|
||||
#[inline]
|
||||
pub fn image_id(&self) -> usize {
|
||||
self.image_id
|
||||
self.info.index
|
||||
}
|
||||
|
||||
/// Returns the corresponding swapchain.
|
||||
#[inline]
|
||||
pub fn swapchain(&self) -> &Arc<Swapchain<W>> {
|
||||
&self.swapchain
|
||||
&self.info.swapchain
|
||||
}
|
||||
}
|
||||
|
||||
@ -1849,20 +2007,12 @@ where
|
||||
Ok(match self.previous.build_submission()? {
|
||||
SubmitAnyBuilder::Empty => {
|
||||
let mut builder = SubmitPresentBuilder::new();
|
||||
builder.add_swapchain(
|
||||
&self.swapchain,
|
||||
self.image_id as u32,
|
||||
self.present_region.as_ref(),
|
||||
);
|
||||
builder.add_swapchain(&self.info);
|
||||
SubmitAnyBuilder::QueuePresent(builder)
|
||||
}
|
||||
SubmitAnyBuilder::SemaphoresWait(sem) => {
|
||||
let mut builder: SubmitPresentBuilder = sem.into();
|
||||
builder.add_swapchain(
|
||||
&self.swapchain,
|
||||
self.image_id as u32,
|
||||
self.present_region.as_ref(),
|
||||
);
|
||||
builder.add_swapchain(&self.info);
|
||||
SubmitAnyBuilder::QueuePresent(builder)
|
||||
}
|
||||
SubmitAnyBuilder::CommandBuffer(_) => {
|
||||
@ -1871,11 +2021,7 @@ where
|
||||
self.previous.flush()?;
|
||||
|
||||
let mut builder = SubmitPresentBuilder::new();
|
||||
builder.add_swapchain(
|
||||
&self.swapchain,
|
||||
self.image_id as u32,
|
||||
self.present_region.as_ref(),
|
||||
);
|
||||
builder.add_swapchain(&self.info);
|
||||
SubmitAnyBuilder::QueuePresent(builder)
|
||||
}
|
||||
SubmitAnyBuilder::BindSparse(_) => {
|
||||
@ -1884,11 +2030,7 @@ where
|
||||
self.previous.flush()?;
|
||||
|
||||
let mut builder = SubmitPresentBuilder::new();
|
||||
builder.add_swapchain(
|
||||
&self.swapchain,
|
||||
self.image_id as u32,
|
||||
self.present_region.as_ref(),
|
||||
);
|
||||
builder.add_swapchain(&self.info);
|
||||
SubmitAnyBuilder::QueuePresent(builder)
|
||||
}
|
||||
SubmitAnyBuilder::QueuePresent(_present) => {
|
||||
@ -1910,7 +2052,8 @@ where
|
||||
self.flushed.store(true, Ordering::SeqCst);
|
||||
|
||||
if let &Err(FlushError::FullScreenExclusiveModeLost) = &build_submission_result {
|
||||
self.swapchain
|
||||
self.info
|
||||
.swapchain
|
||||
.full_screen_exclusive_held
|
||||
.store(false, Ordering::SeqCst);
|
||||
}
|
||||
@ -1921,7 +2064,8 @@ where
|
||||
let present_result = present.submit(&self.queue);
|
||||
|
||||
if let &Err(SubmitPresentError::FullScreenExclusiveModeLost) = &present_result {
|
||||
self.swapchain
|
||||
self.info
|
||||
.swapchain
|
||||
.full_screen_exclusive_held
|
||||
.store(false, Ordering::SeqCst);
|
||||
}
|
||||
@ -1978,7 +2122,8 @@ where
|
||||
expected_layout: ImageLayout,
|
||||
queue: &Queue,
|
||||
) -> Result<Option<(PipelineStages, AccessFlags)>, AccessCheckError> {
|
||||
let swapchain_image = self.swapchain.raw_image(self.image_id).unwrap();
|
||||
let swapchain_image = self.info.swapchain.raw_image(self.info.index).unwrap();
|
||||
|
||||
if swapchain_image.image.internal_object() == image.internal_object() {
|
||||
// This future presents the swapchain image, which "unlocks" it. Therefore any attempt
|
||||
// to use this swapchain image afterwards shouldn't get granted automatic access.
|
||||
|
@ -24,7 +24,7 @@ use crate::{
|
||||
},
|
||||
device::{DeviceOwned, Queue},
|
||||
image::{sys::UnsafeImage, ImageLayout},
|
||||
swapchain::{self, PresentFuture, PresentRegion, Swapchain},
|
||||
swapchain::{self, PresentFuture, PresentInfo},
|
||||
DeviceSize, OomError,
|
||||
};
|
||||
use std::{
|
||||
@ -257,30 +257,12 @@ pub unsafe trait GpuFuture: DeviceOwned {
|
||||
fn then_swapchain_present<W>(
|
||||
self,
|
||||
queue: Arc<Queue>,
|
||||
swapchain: Arc<Swapchain<W>>,
|
||||
image_index: usize,
|
||||
info: PresentInfo<W>,
|
||||
) -> PresentFuture<Self, W>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
swapchain::present(swapchain, self, queue, image_index)
|
||||
}
|
||||
|
||||
/// Same as `then_swapchain_present`, except it allows specifying a present region.
|
||||
///
|
||||
/// > **Note**: This is just a shortcut for the `Swapchain::present_incremental()` function.
|
||||
#[inline]
|
||||
fn then_swapchain_present_incremental<W>(
|
||||
self,
|
||||
queue: Arc<Queue>,
|
||||
swapchain: Arc<Swapchain<W>>,
|
||||
image_index: usize,
|
||||
present_region: PresentRegion,
|
||||
) -> PresentFuture<Self, W>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
swapchain::present_incremental(swapchain, self, queue, image_index, present_region)
|
||||
swapchain::present(self, queue, info)
|
||||
}
|
||||
|
||||
/// Turn the current future into a `Box<dyn GpuFuture>`.
|
||||
@ -499,6 +481,10 @@ pub enum FlushError {
|
||||
|
||||
/// 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,
|
||||
}
|
||||
|
||||
impl Error for FlushError {
|
||||
@ -531,6 +517,9 @@ impl Display for FlushError {
|
||||
"the flush operation needed to block, but the timeout has \
|
||||
elapsed"
|
||||
}
|
||||
FlushError::PresentIdLessThanOrEqual => {
|
||||
"present id is less than or equal to previous"
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
@ -554,6 +543,7 @@ impl From<SubmitPresentError> for FlushError {
|
||||
SubmitPresentError::FullScreenExclusiveModeLost => {
|
||||
FlushError::FullScreenExclusiveModeLost
|
||||
}
|
||||
SubmitPresentError::PresentIdLessThanOrEqual => FlushError::PresentIdLessThanOrEqual,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user