Image extent zero length (#1893)

* Updating examples and SwapchainCreationError enum to resolve #1892 and related discussion

* Slightly better documentation
This commit is contained in:
Ryan Andersen 2022-05-09 05:25:26 -07:00 committed by GitHub
parent 5c6bbe0be4
commit a89359007b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 143 additions and 24 deletions

View File

@ -234,12 +234,17 @@ fn main() {
recreate_swapchain = true;
}
Event::RedrawEventsCleared => {
let dimensions = surface.window().inner_size();
if dimensions.width == 0 || dimensions.height == 0 {
return;
}
previous_frame_end.as_mut().unwrap().cleanup_finished();
if recreate_swapchain {
let (new_swapchain, new_images) =
match swapchain.recreate(SwapchainCreateInfo {
image_extent: surface.window().inner_size().into(),
image_extent: dimensions.into(),
..swapchain.create_info()
}) {
Ok(r) => r,

View File

@ -195,11 +195,16 @@ fn main() {
recreate_swapchain = true;
}
Event::RedrawEventsCleared => {
let dimensions = surface.window().inner_size();
if dimensions.width == 0 || dimensions.height == 0 {
return;
}
previous_frame_end.as_mut().unwrap().cleanup_finished();
if recreate_swapchain {
let (new_swapchain, new_images) = match swapchain.recreate(SwapchainCreateInfo {
image_extent: surface.window().inner_size().into(),
image_extent: dimensions.into(),
..swapchain.create_info()
}) {
Ok(r) => r,

View File

@ -163,11 +163,16 @@ fn main() {
recreate_swapchain = true;
}
Event::RedrawEventsCleared => {
let dimensions = surface.window().inner_size();
if dimensions.width == 0 || dimensions.height == 0 {
return;
}
previous_frame_end.as_mut().unwrap().cleanup_finished();
if recreate_swapchain {
let (new_swapchain, new_images) = match swapchain.recreate(SwapchainCreateInfo {
image_extent: surface.window().inner_size().into(),
image_extent: dimensions.into(),
..swapchain.create_info()
}) {
Ok(r) => r,

View File

@ -346,11 +346,16 @@ fn main() {
recreate_swapchain = true;
}
Event::RedrawEventsCleared => {
let dimensions = surface.window().inner_size();
if dimensions.width == 0 || dimensions.height == 0 {
return;
}
previous_frame_end.as_mut().unwrap().cleanup_finished();
if recreate_swapchain {
let (new_swapchain, new_images) = match swapchain.recreate(SwapchainCreateInfo {
image_extent: surface.window().inner_size().into(),
image_extent: dimensions.into(),
..swapchain.create_info()
}) {
Ok(r) => r,

View File

@ -266,11 +266,16 @@ fn main() {
recreate_swapchain = true;
}
Event::RedrawEventsCleared => {
let dimensions = surface.window().inner_size();
if dimensions.width == 0 || dimensions.height == 0 {
return;
}
previous_frame_end.as_mut().unwrap().cleanup_finished();
if recreate_swapchain {
let (new_swapchain, new_images) = match swapchain.recreate(SwapchainCreateInfo {
image_extent: surface.window().inner_size().into(),
image_extent: dimensions.into(),
..swapchain.create_info()
}) {
Ok(r) => r,

View File

@ -275,11 +275,16 @@ fn main() {
recreate_swapchain = true;
}
Event::RedrawEventsCleared => {
let dimensions = surface.window().inner_size();
if dimensions.width == 0 || dimensions.height == 0 {
return;
}
previous_frame_end.as_mut().unwrap().cleanup_finished();
if recreate_swapchain {
let (new_swapchain, new_images) = match swapchain.recreate(SwapchainCreateInfo {
image_extent: surface.window().inner_size().into(),
image_extent: dimensions.into(),
..swapchain.create_info()
}) {
Ok(r) => r,

View File

@ -297,12 +297,17 @@ fn main() {
recreate_swapchain = true;
}
Event::RedrawEventsCleared => {
let dimensions = surface.window().inner_size();
if dimensions.width == 0 || dimensions.height == 0 {
return;
}
previous_frame_end.as_mut().unwrap().cleanup_finished();
if recreate_swapchain {
let (new_swapchain, new_images) =
match swapchain.recreate(SwapchainCreateInfo {
image_extent: surface.window().inner_size().into(),
image_extent: dimensions.into(),
..swapchain.create_info()
}) {
Ok(r) => r,

View File

@ -293,12 +293,17 @@ fn main() {
recreate_swapchain = true;
}
Event::RedrawEventsCleared => {
let dimensions = surface.window().inner_size();
if dimensions.width == 0 || dimensions.height == 0 {
return;
}
previous_frame_end.as_mut().unwrap().cleanup_finished();
if recreate_swapchain {
let (new_swapchain, new_images) =
match swapchain.recreate(SwapchainCreateInfo {
image_extent: surface.window().inner_size().into(),
image_extent: dimensions.into(),
..swapchain.create_info()
}) {
Ok(r) => r,

View File

@ -63,6 +63,16 @@ fn main() {
if !handle_events(&mut event_loop, &mut renderer, &mut app) {
break;
}
match renderer.window_size() {
[w, h] => {
// Skip this frame when minimized
if w == 0 || h == 0 {
continue;
}
}
}
app.update_state_after_inputs(&mut renderer);
compute_then_render(&mut renderer, &mut app, render_target_id);
app.reset_input_state();

View File

@ -271,7 +271,6 @@ impl Renderer {
}
/// Winit window size
#[allow(unused)]
pub fn window_size(&self) -> [u32; 2] {
let size = self.window().inner_size();
[size.width, size.height]

View File

@ -352,11 +352,16 @@ fn main() {
ref mut previous_frame_end,
} = window_surfaces.get_mut(&window_id).unwrap();
let dimensions = surface.window().inner_size();
if dimensions.width == 0 || dimensions.height == 0 {
return;
}
previous_frame_end.as_mut().unwrap().cleanup_finished();
if *recreate_swapchain {
let (new_swapchain, new_images) = match swapchain.recreate(SwapchainCreateInfo {
image_extent: surface.window().inner_size().into(),
image_extent: dimensions.into(),
..swapchain.create_info()
}) {
Ok(r) => r,

View File

@ -197,6 +197,15 @@ fn compute_then_render(
life_color: [f32; 4],
dead_color: [f32; 4],
) {
// Skip this window when minimized
match vulkano_window.window_size() {
[w, h] => {
if w == 0 || h == 0 {
return;
}
}
}
// Start frame
let before_pipeline_future = match vulkano_window.start_frame() {
Err(e) => {

View File

@ -312,11 +312,16 @@ fn main() {
recreate_swapchain = true;
}
Event::RedrawEventsCleared => {
let dimensions = surface.window().inner_size();
if dimensions.width == 0 || dimensions.height == 0 {
return;
}
previous_frame_end.as_mut().unwrap().cleanup_finished();
if recreate_swapchain {
let (new_swapchain, new_images) = match swapchain.recreate(SwapchainCreateInfo {
image_extent: surface.window().inner_size().into(),
image_extent: dimensions.into(),
..swapchain.create_info()
}) {
Ok(r) => r,

View File

@ -258,11 +258,16 @@ fn main() {
recreate_swapchain = true;
}
Event::RedrawEventsCleared => {
let dimensions = surface.window().inner_size();
if dimensions.width == 0 || dimensions.height == 0 {
return;
}
previous_frame_end.as_mut().unwrap().cleanup_finished();
if recreate_swapchain {
let (new_swapchain, new_images) = match swapchain.recreate(SwapchainCreateInfo {
image_extent: surface.window().inner_size().into(),
image_extent: dimensions.into(),
..swapchain.create_info()
}) {
Ok(r) => r,

View File

@ -243,11 +243,16 @@ fn main() {
recreate_swapchain = true;
}
Event::RedrawEventsCleared => {
let dimensions = surface.window().inner_size();
if dimensions.width == 0 || dimensions.height == 0 {
return;
}
previous_frame_end.as_mut().unwrap().cleanup_finished();
if recreate_swapchain {
let (new_swapchain, new_images) = match swapchain.recreate(SwapchainCreateInfo {
image_extent: surface.window().inner_size().into(),
image_extent: dimensions.into(),
..swapchain.create_info()
}) {
Ok(r) => r,

View File

@ -395,11 +395,16 @@ fn main() {
recreate_swapchain = true;
}
Event::RedrawEventsCleared => {
let dimensions = surface.window().inner_size();
if dimensions.width == 0 || dimensions.height == 0 {
return;
}
previous_frame_end.as_mut().unwrap().cleanup_finished();
if recreate_swapchain {
let (new_swapchain, new_images) = match swapchain.recreate(SwapchainCreateInfo {
image_extent: surface.window().inner_size().into(),
image_extent: dimensions.into(),
..swapchain.create_info()
}) {
Ok(r) => r,

View File

@ -412,8 +412,8 @@ fn main() {
}
Event::RedrawEventsCleared => {
let dimensions = surface.window().inner_size();
if dimensions.width == 0 && dimensions.height == 0 {
return; // On Windows, minimizing sets surface to 0x0. Do not draw frame.
if dimensions.width == 0 || dimensions.height == 0 {
return;
}
// Update per-frame variables.

View File

@ -189,12 +189,17 @@ fn main() {
recreate_swapchain = true;
}
Event::RedrawEventsCleared => {
let dimensions = surface.window().inner_size();
if dimensions.width == 0 || dimensions.height == 0 {
return;
}
previous_frame_end.as_mut().unwrap().cleanup_finished();
if recreate_swapchain {
let (new_swapchain, new_images) =
match swapchain.recreate(SwapchainCreateInfo {
image_extent: surface.window().inner_size().into(),
image_extent: dimensions.into(),
..swapchain.create_info()
}) {
Ok(r) => r,

View File

@ -349,11 +349,16 @@ fn main() {
recreate_swapchain = true;
}
Event::RedrawEventsCleared => {
let dimensions = surface.window().inner_size();
if dimensions.width == 0 || dimensions.height == 0 {
return;
}
previous_frame_end.as_mut().unwrap().cleanup_finished();
if recreate_swapchain {
let (new_swapchain, new_images) = match swapchain.recreate(SwapchainCreateInfo {
image_extent: surface.window().inner_size().into(),
image_extent: dimensions.into(),
..swapchain.create_info()
}) {
Ok(r) => r,

View File

@ -267,11 +267,16 @@ fn main() {
recreate_swapchain = true;
}
Event::RedrawEventsCleared => {
let dimensions = surface.window().inner_size();
if dimensions.width == 0 || dimensions.height == 0 {
return;
}
previous_frame_end.as_mut().unwrap().cleanup_finished();
if recreate_swapchain {
let (new_swapchain, new_images) = match swapchain.recreate(SwapchainCreateInfo {
image_extent: surface.window().inner_size().into(),
image_extent: dimensions.into(),
..swapchain.create_info()
}) {
Ok(r) => r,

View File

@ -416,6 +416,13 @@ fn main() {
recreate_swapchain = true;
}
Event::RedrawEventsCleared => {
// Do not draw frame when screen dimensions are zero.
// On Windows, this can occur from minimizing the application.
let dimensions = surface.window().inner_size();
if dimensions.width == 0 || dimensions.height == 0 {
return;
}
// It is important to call this function from time to time, otherwise resources will keep
// accumulating and you will eventually reach an out of memory error.
// Calling this function polls various fences in order to determine what the GPU has
@ -425,11 +432,11 @@ fn main() {
// Whenever the window resizes we need to recreate everything dependent on the window size.
// In this example that includes the swapchain, the framebuffers and the dynamic state viewport.
if recreate_swapchain {
// Get the new dimensions of the window.
// Use the new dimensions of the window.
let (new_swapchain, new_images) =
match swapchain.recreate(SwapchainCreateInfo {
image_extent: surface.window().inner_size().into(),
image_extent: dimensions.into(),
..swapchain.create_info()
}) {
Ok(r) => r,

View File

@ -392,8 +392,10 @@ impl<W> Swapchain<W> {
}
// VUID-VkSwapchainCreateInfoKHR-imageExtent-01689
// Shouldn't be possible with a properly behaving device
assert!(image_extent[0] != 0 || image_extent[1] != 0);
// On some platforms, dimensions of zero-length can occur by minimizing the surface.
if image_extent.contains(&0) {
return Err(SwapchainCreationError::ImageExtentZeroLengthDimensions);
}
// VUID-VkSwapchainCreateInfoKHR-imageArrayLayers-01275
if image_array_layers == 0
@ -1056,6 +1058,14 @@ pub enum SwapchainCreationError {
max_supported: [u32; 2],
},
/// The provided `image_extent` contained at least one dimension of zero length.
/// This is prohibited by [VUID-VkSwapchainCreateInfoKHR-imageExtent-01689](https://khronos.org/registry/vulkan/specs/1.3-extensions/man/html/VkSwapchainCreateInfoKHR.html#VUID-VkSwapchainCreateInfoKHR-imageExtent-01689)
/// which requires both the width and height be non-zero.
///
/// This error is distinct from `ImageExtentNotSupported` because a surface's minimum supported
/// length may not enforce this rule.
ImageExtentZeroLengthDimensions,
/// The provided image parameters are not supported as queried from `image_format_properties`.
ImageFormatPropertiesNotSupported,
@ -1139,9 +1149,13 @@ impl fmt::Display for SwapchainCreationError {
),
Self::ImageExtentNotSupported { provided, min_supported, max_supported } => write!(
fmt,
"the provided `min_image_count` ({:?}) is not within the range (min: {:?}, max: {:?}) supported by the surface for this device",
"the provided `image_extent` ({:?}) is not within the range (min: {:?}, max: {:?}) supported by the surface for this device",
provided, min_supported, max_supported,
),
Self::ImageExtentZeroLengthDimensions => write!(
fmt,
"the provided `image_extent` contained at least one dimension of zero length",
),
Self::ImageFormatPropertiesNotSupported => write!(
fmt,
"the provided image parameters are not supported as queried from `image_format_properties`",