-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add an example to test small window sizes (#3597)
# Objective We keep getting issues where things break at small window sizes, e.g #3368 (caused by #3153), #3596 ('caused' by #3545) ## Solution - Add a test that we can make small windows. Currently, this fails on my machine with some quite scary vulkan errors: ``` 2022-01-08T22:55:13.770261Z ERROR wgpu_hal::vulkan::instance: VALIDATION [VUID-VkSwapchainCreateInfoKHR-imageExtent-01274 (0x7cd0911d)] Validation Error: [ VUID-VkSwapchainCreateInfoKHR-imageExtent-01274 ] Object 0: handle = 0x1adbd410a60, type = VK_OBJECT_TYPE_DEVICE; | MessageID = 0x7cd0911d | vkCreateSwapchainKHR() called with imageExtent = (225,60), which is outside the bounds returned by vkGetPhysicalDeviceSurfaceCapabilitiesKHR(): currentExtent = (225,56), minImageExtent = (225,56), maxImageExtent = (225,56). The Vulkan spec states: imageExtent must be between minImageExtent and maxImageExtent, inclusive, where minImageExtent and maxImageExtent are members of the VkSurfaceCapabilitiesKHR structure returned by vkGetPhysicalDeviceSurfaceCapabilitiesKHR for the surface (https://vulkan.lunarg.com/doc/view/1.2.198.1/windows/1.2-extensions/vkspec.html#VUID-VkSwapchainCreateInfoKHR-imageExtent-01274) 2022-01-08T22:55:13.770808Z ERROR wgpu_hal::vulkan::instance: objects: (type: DEVICE, hndl: 0x1adbd410a60, name: ?) 2022-01-08T22:55:13.787403Z ERROR wgpu_hal::vulkan::instance: VALIDATION [VUID-VkSwapchainCreateInfoKHR-imageExtent-01274 (0x7cd0911d)] Validation Error: [ VUID-VkSwapchainCreateInfoKHR-imageExtent-01274 ] Object 0: handle = 0x1adbd410a60, type = VK_OBJECT_TYPE_DEVICE; | MessageID = 0x7cd0911d | vkCreateSwapchainKHR() called with imageExtent = (225,56), which is outside the bounds returned by vkGetPhysicalDeviceSurfaceCapabilitiesKHR(): currentExtent = (225,52), minImageExtent = (225,52), maxImageExtent = (225,52). The Vulkan spec states: imageExtent must be between minImageExtent and maxImageExtent, inclusive, where minImageExtent and maxImageExtent are members of the VkSurfaceCapabilitiesKHR structure returned by vkGetPhysicalDeviceSurfaceCapabilitiesKHR for the surface (https://vulkan.lunarg.com/doc/view/1.2.198.1/windows/1.2-extensions/vkspec.html#VUID-VkSwapchainCreateInfoKHR-imageExtent-01274) ``` etc. This might be a new issue here, although I'm surprised it's vulkan giving this error; wgpu should stop it if this is illegal.
- Loading branch information
Showing
5 changed files
with
244 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
( | ||
exit_after: Some(90) | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
( | ||
// Ensures that the full cycle will run | ||
exit_after: Some(410) | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
//! A test to confirm that `bevy` allows minimising the window | ||
//! This is run in CI to ensure that this doesn't regress again. | ||
use bevy::prelude::*; | ||
|
||
fn main() { | ||
// TODO: Combine this with `resizing` once multiple_windows is simpler than | ||
// it is currently. | ||
App::new() | ||
.insert_resource(WindowDescriptor { | ||
title: "Minimising".into(), | ||
..Default::default() | ||
}) | ||
.add_plugins(DefaultPlugins) | ||
.add_system(minimise_automatically) | ||
.add_startup_system(setup_3d) | ||
.add_startup_system(setup_2d) | ||
.run(); | ||
} | ||
|
||
fn minimise_automatically(mut windows: ResMut<Windows>, mut frames: Local<u32>) { | ||
if *frames == 60 { | ||
windows.get_primary_mut().unwrap().set_minimized(true); | ||
} else { | ||
*frames += 1; | ||
} | ||
} | ||
|
||
/// A simple 3d scene, taken from the `3d_scene` example | ||
fn setup_3d( | ||
mut commands: Commands, | ||
mut meshes: ResMut<Assets<Mesh>>, | ||
mut materials: ResMut<Assets<StandardMaterial>>, | ||
) { | ||
// plane | ||
commands.spawn_bundle(PbrBundle { | ||
mesh: meshes.add(Mesh::from(shape::Plane { size: 5.0 })), | ||
material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()), | ||
..default() | ||
}); | ||
// cube | ||
commands.spawn_bundle(PbrBundle { | ||
mesh: meshes.add(Mesh::from(shape::Cube { size: 1.0 })), | ||
material: materials.add(Color::rgb(0.8, 0.7, 0.6).into()), | ||
transform: Transform::from_xyz(0.0, 0.5, 0.0), | ||
..default() | ||
}); | ||
// light | ||
commands.spawn_bundle(PointLightBundle { | ||
point_light: PointLight { | ||
intensity: 1500.0, | ||
shadows_enabled: true, | ||
..default() | ||
}, | ||
transform: Transform::from_xyz(4.0, 8.0, 4.0), | ||
..default() | ||
}); | ||
// camera | ||
commands.spawn_bundle(PerspectiveCameraBundle { | ||
transform: Transform::from_xyz(-2.0, 2.5, 5.0).looking_at(Vec3::ZERO, Vec3::Y), | ||
..default() | ||
}); | ||
} | ||
|
||
/// A simple 2d scene, taken from the `rect` example | ||
fn setup_2d(mut commands: Commands) { | ||
commands.spawn_bundle(OrthographicCameraBundle::new_2d()); | ||
commands.spawn_bundle(SpriteBundle { | ||
sprite: Sprite { | ||
color: Color::rgb(0.25, 0.25, 0.75), | ||
custom_size: Some(Vec2::new(50.0, 50.0)), | ||
..default() | ||
}, | ||
..default() | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
//! A test to confirm that `bevy` allows setting the window to arbitrary small sizes | ||
//! This is run in CI to ensure that this doesn't regress again. | ||
|
||
use bevy::{input::system::exit_on_esc_system, prelude::*}; | ||
|
||
// The smallest size reached is 1x1, as X11 doesn't support windows with a 0 dimension | ||
// TODO: Add a check for platforms other than X11 for 0xk and kx0, despite those currently unsupported on CI. | ||
const MAX_WIDTH: u16 = 401; | ||
const MAX_HEIGHT: u16 = 401; | ||
const MIN_WIDTH: u16 = 1; | ||
const MIN_HEIGHT: u16 = 1; | ||
const RESIZE_STEP: u16 = 4; | ||
|
||
struct Dimensions { | ||
width: u16, | ||
height: u16, | ||
} | ||
|
||
fn main() { | ||
App::new() | ||
.insert_resource(WindowDescriptor { | ||
width: MAX_WIDTH.try_into().unwrap(), | ||
height: MAX_HEIGHT.try_into().unwrap(), | ||
scale_factor_override: Some(1.), | ||
title: "Resizing".into(), | ||
..Default::default() | ||
}) | ||
.insert_resource(Dimensions { | ||
width: MAX_WIDTH, | ||
height: MAX_HEIGHT, | ||
}) | ||
.add_plugins(DefaultPlugins) | ||
.insert_resource(Phase::ContractingY) | ||
.add_system(change_window_size) | ||
.add_system(sync_dimensions) | ||
.add_system(exit_on_esc_system) | ||
.add_startup_system(setup_3d) | ||
.add_startup_system(setup_2d) | ||
.run(); | ||
} | ||
|
||
enum Phase { | ||
ContractingY, | ||
ContractingX, | ||
ExpandingY, | ||
ExpandingX, | ||
} | ||
|
||
use Phase::*; | ||
|
||
fn change_window_size( | ||
mut windows: ResMut<Dimensions>, | ||
mut phase: ResMut<Phase>, | ||
mut first_complete: Local<bool>, | ||
) { | ||
// Put off rendering for one frame, as currently for a frame where | ||
// resizing happens, nothing is presented. | ||
// TODO: Debug and fix this if feasible | ||
if !*first_complete { | ||
*first_complete = true; | ||
return; | ||
} | ||
let height = windows.height; | ||
let width = windows.width; | ||
match *phase { | ||
Phase::ContractingY => { | ||
if height <= MIN_HEIGHT { | ||
*phase = ContractingX; | ||
} else { | ||
windows.height -= RESIZE_STEP; | ||
} | ||
} | ||
Phase::ContractingX => { | ||
if width <= MIN_WIDTH { | ||
*phase = ExpandingY; | ||
} else { | ||
windows.width -= RESIZE_STEP; | ||
} | ||
} | ||
Phase::ExpandingY => { | ||
if height >= MAX_HEIGHT { | ||
*phase = ExpandingX; | ||
} else { | ||
windows.height += RESIZE_STEP; | ||
} | ||
} | ||
Phase::ExpandingX => { | ||
if width >= MAX_WIDTH { | ||
*phase = ContractingY; | ||
} else { | ||
windows.width += RESIZE_STEP; | ||
} | ||
} | ||
} | ||
} | ||
|
||
fn sync_dimensions(dim: Res<Dimensions>, mut windows: ResMut<Windows>) { | ||
if dim.is_changed() { | ||
windows.get_primary_mut().unwrap().set_resolution( | ||
dim.width.try_into().unwrap(), | ||
dim.height.try_into().unwrap(), | ||
); | ||
} | ||
} | ||
|
||
/// A simple 3d scene, taken from the `3d_scene` example | ||
fn setup_3d( | ||
mut commands: Commands, | ||
mut meshes: ResMut<Assets<Mesh>>, | ||
mut materials: ResMut<Assets<StandardMaterial>>, | ||
) { | ||
// plane | ||
commands.spawn_bundle(PbrBundle { | ||
mesh: meshes.add(Mesh::from(shape::Plane { size: 5.0 })), | ||
material: materials.add(Color::rgb(0.3, 0.5, 0.3).into()), | ||
..default() | ||
}); | ||
// cube | ||
commands.spawn_bundle(PbrBundle { | ||
mesh: meshes.add(Mesh::from(shape::Cube { size: 1.0 })), | ||
material: materials.add(Color::rgb(0.8, 0.7, 0.6).into()), | ||
transform: Transform::from_xyz(0.0, 0.5, 0.0), | ||
..default() | ||
}); | ||
// light | ||
commands.spawn_bundle(PointLightBundle { | ||
point_light: PointLight { | ||
intensity: 1500.0, | ||
shadows_enabled: true, | ||
..default() | ||
}, | ||
transform: Transform::from_xyz(4.0, 8.0, 4.0), | ||
..default() | ||
}); | ||
// camera | ||
commands.spawn_bundle(PerspectiveCameraBundle { | ||
transform: Transform::from_xyz(-2.0, 2.5, 5.0).looking_at(Vec3::ZERO, Vec3::Y), | ||
..default() | ||
}); | ||
} | ||
|
||
/// A simple 2d scene, taken from the `rect` example | ||
fn setup_2d(mut commands: Commands) { | ||
commands.spawn_bundle(OrthographicCameraBundle::new_2d()); | ||
commands.spawn_bundle(SpriteBundle { | ||
sprite: Sprite { | ||
color: Color::rgb(0.25, 0.25, 0.75), | ||
custom_size: Some(Vec2::new(50.0, 50.0)), | ||
..default() | ||
}, | ||
..default() | ||
}); | ||
} |