Closed robojeb closed 6 months ago
Very interesting: I've seen this issue reported for Linux before, but this is by far the best investigation I've seen. Not entirely sure what should be done to fix this though 🤔
The issue does reproduce with multi_threaded
removed from the project features.
I grabbed a single threaded stack trace from gdb
:
#0 0x00007fcd5f7564ae in ?? () from /usr/lib/libc.so.6
#1 0x00007fcd5f761980 in ?? () from /usr/lib/libc.so.6
#2 0x00007fcd5acbe750 in ?? () from /usr/lib/amdvlk64.so
#3 0x00007fcd5abb201e in ?? () from /usr/lib/amdvlk64.so
#4 0x00007fcd5a9856ab in ?? () from /usr/lib/amdvlk64.so
#5 0x00007fcd4de797fe in DispatchDestroySwapchainKHR (device=device@entry=0x564b0f065d60, swapchain=<optimized out>, swapchain@entry=0xfef35a00000000a0,
pAllocator=pAllocator@entry=0x0)
at /usr/src/debug/vulkan-validation-layers/Vulkan-ValidationLayers-sdk-1.3.261.1/layers/layer_chassis_dispatch_manual.cpp:393
#6 0x00007fcd4dd840ef in vulkan_layer_chassis::DestroySwapchainKHR (device=0x564b0f065d60, swapchain=0xfef35a00000000a0, pAllocator=0x0)
at /usr/src/debug/vulkan-validation-layers/Vulkan-ValidationLayers-sdk-1.3.261.1/layers/vulkan/generated/chassis.cpp:5689
#7 0x00007fcd61b5eeb7 in ash::extensions::khr::swapchain::Swapchain::destroy_swapchain ()
at /home/jeb/.local/share/cargo/registry/src/index.crates.io-6f17d22bba15001f/ash-0.37.3+1.3.251/src/extensions/khr/swapchain.rs:70
#8 wgpu_hal::vulkan::instance::{impl#5}::unconfigure (self=<optimized out>, device=<optimized out>) at src/vulkan/instance.rs:808
#9 0x00007fcd619c2c26 in wgpu_core::hub::Hub<wgpu_hal::vulkan::Api, wgpu_core::identity::IdentityManagerFactory>::surface_unconfigure<wgpu_hal::vulkan::Api, wgpu_core::identity::IdentityManagerFactory> (self=<optimized out>, device_id=..., surface=0x7fff77597ec0)
at /home/jeb/.local/share/cargo/registry/src/index.crates.io-6f17d22bba15001f/wgpu-core-0.17.1/src/hub.rs:659
#10 0x00007fcd61a48803 in wgpu_core::instance::{impl#6}::surface_drop::unconfigure<wgpu_core::identity::IdentityManagerFactory, wgpu_hal::vulkan::Api> (
global=<optimized out>, surface=<optimized out>, present=<optimized out>)
at /home/jeb/.local/share/cargo/registry/src/index.crates.io-6f17d22bba15001f/wgpu-core-0.17.1/src/instance.rs:653
#11 wgpu_core::global::Global<wgpu_core::identity::IdentityManagerFactory>::surface_drop<wgpu_core::identity::IdentityManagerFactory> (self=0x564b0f0045f0,
id=...) at /home/jeb/.local/share/cargo/registry/src/index.crates.io-6f17d22bba15001f/wgpu-core-0.17.1/src/instance.rs:659
#12 0x00007fcd614e9db1 in core::ptr::drop_in_place<wgpu::Surface> () at /rustc/49691b1f70d71dd7b8349c332b7f277ee527bf08/library/core/src/ptr/mod.rs:498
#13 0x00007fcd61504062 in core::ptr::drop_in_place<bevy_render::view::window::SurfaceData> ()
at /rustc/49691b1f70d71dd7b8349c332b7f277ee527bf08/library/core/src/ptr/mod.rs:498
#14 core::ptr::drop_in_place<core::option::Option<bevy_render::view::window::SurfaceData>> ()
at /rustc/49691b1f70d71dd7b8349c332b7f277ee527bf08/library/core/src/ptr/mod.rs:498
#15 bevy_render::view::window::WindowSurfaces::remove (self=0x564b0f171570, window=<optimized out>) at src/view/window/mod.rs:209
#16 0x00007fcd614d579b in bevy_render::view::window::extract_windows (extracted_windows=..., screenshot_manager=..., closed=..., windows=..., removed=...,
window_surfaces=...) at src/view/window/mod.rs:173
#17 core::ops::function::FnMut::call_mut<fn(bevy_ecs::change_detection::ResMut<bevy_render::view::window::ExtractedWindows>, bevy_render::extract_param::Extract<bevy_ecs::change_detection::Res<bevy_render::view::window::screenshot::ScreenshotManager>>, bevy_render::extract_param::Extract<bevy_ecs::event::EventReader<bevy_window::event::WindowClosed>>, bevy_render::extract_param::Extract<bevy_ecs::system::query::Query<(bevy_ecs::entity::Entity, &bevy_window::window::Window, &bevy_window::raw_handle::RawHandleWrapper, core::option::Option<&bevy_window::window::PrimaryWindow>), ()>>, bevy_render::extract_param::Extract<bevy_ecs::removal_detection::RemovedComponents<bevy_window::raw_handle::RawHandleWrapper>>, bevy_ecs::change_detection::ResMut<bevy_render::view::window::WindowSurfaces>), (bevy_ecs::change_detection::ResMut<bevy_render::view::window::ExtractedWindows>, bevy_render::extract_param::Extract<bevy_ecs::change_detection::Res<bevy_render::view::window::screenshot::ScreenshotManager>>, bevy_render::extract_param::Extract<bevy_ecs::event::EventReader<bevy_window::event::WindowClosed>>, bevy_render::extract_param::Extract<bevy_ecs::system::query::Query<(bevy_ecs::entity::Entity, &bevy_window::window::Window, &bevy_window::raw_handle::RawHandleWrapper, core::option::Option<&bevy_window::window::PrimaryWindow>), ()>>, bevy_render::extract_param::Extract<bevy_ecs::removal_detection::RemovedComponents<bevy_window::raw_handle::RawHandleWrapper>>, bevy_ecs::change_detection::ResMut<bevy_render::view::window::WindowSurfaces>)> ()
at /rustc/49691b1f70d71dd7b8349c332b7f277ee527bf08/library/core/src/ops/function.rs:166
#18 core::ops::function::impls::{impl#3}::call_mut<(bevy_ecs::change_detection::ResMut<bevy_render::view::window::ExtractedWindows>, bevy_render::extract_param::Extract<bevy_ecs::change_detection::Res<bevy_render::view::window::screenshot::ScreenshotManager>>, bevy_render::extract_param::Extract<bevy_ecs::event::EventReader<bevy_window::event::WindowClosed>>, bevy_render::extract_param::Extract<bevy_ecs::system::query::Query<(bevy_ecs::entity::Entity, &bevy_window::window::Window, &bevy_window::raw_handle::RawHandleWrapper, core::option::Option<&bevy_window::window::PrimaryWindow>), ()>>, bevy_render::extract_param::Extract<bevy_ecs::removal_detection::RemovedComponents<bevy_window::raw_handle::RawHandleWrapper>>, bevy_ecs::change_detection::ResMut<bevy_render::view::window::WindowSurfaces>), fn(bevy_ecs::change_detection::ResMut<bevy_render::view::window::ExtractedWindows>, bevy_render::extract_param::Extract<bevy_ecs::change_detection::Res<bevy_render::view::window::screenshot::ScreenshotManager>>, bevy_render::extract_param::Extract<bevy_ecs::event::EventReader<bevy_window::event::WindowClosed>>, bevy_render::extract_param::Extract<bevy_ecs::system::query::Query<(bevy_ecs::entity::Entity, &bevy_window::window::Window, &bevy_window::raw_handle::RawHandleWrapper, core::option::Option<&bevy_window::window::PrimaryWindow>), ()>>, bevy_render::extract_param::Extract<bevy_ecs::removal_detection::RemovedComponents<bevy_window::raw_handle::RawHandleWrapper>>, bevy_ecs::change_detection::ResMut<bevy_render::view::window::WindowSurfaces>)> (
self=<optimized out>, args=...) at /rustc/49691b1f70d71dd7b8349c332b7f277ee527bf08/library/core/src/ops/function.rs:294
#19 bevy_ecs::system::function_system::{impl#21}::run::call_inner<(), bevy_ecs::change_detection::ResMut<bevy_render::view::window::ExtractedWindows>, bevy_render::extract_param::Extract<bevy_ecs::change_detection::Res<bevy_render::view::window::screenshot::ScreenshotManager>>, bevy_render::extract_param::Extract<bevy_ecs::event::EventReader<bevy_window::event::WindowClosed>>, bevy_render::extract_param::Extract<bevy_ecs::system::query::Query<(bevy_ecs::entity::Entity, &bevy_window::window::Window, &bevy_window::raw_handle::RawHandleWrapper, core::option::Option<&bevy_window::window::PrimaryWindow>), ()>>, bevy_render::extract_param::Extract<bevy_ecs::removal_detection::RemovedComponents<bevy_window::raw_handle::RawHandleWrapper>>, bevy_ecs::change_detection::ResMut<bevy_render::view::window::WindowSurfaces>, &mut fn(bevy_ecs::change_detection::ResMut<bevy_render::view::window::ExtractedWindows>, bevy_render::extract_param::Extract<bevy_ecs::change_detection::Res<bevy_render::view::window::screenshot::ScreenshotManager>>, bevy_render::extract_param::Extract<bevy_ecs::event::EventReader<bevy_window::event::WindowClosed>>, bevy_render::extract_param::Extract<bevy_ecs::system::query::Query<(bevy_ecs::entity::Entity, &bevy_window::window::Window, &bevy_window::raw_handle::RawHandleWrapper, core::option::Option<&bevy_window::window::PrimaryWindow>), ()>>, bevy_render::extract_param::Extract<bevy_ecs::removal_detection::RemovedComponents<bevy_window::raw_handle::RawHandleWrapper>>, bevy_ecs::change_detection::ResMut<bevy_render::view::window::WindowSurfaces>)> (f=<optimized out>, F0=..., F1=..., F2=..., F3=..., F4=..., F5=...)
at /home/jeb/.local/share/cargo/git/checkouts/bevy-f7ffde730c324c74/66f72dd/crates/bevy_ecs/src/system/function_system.rs:641
#20 bevy_ecs::system::function_system::{impl#21}::run<(), fn(bevy_ecs::change_detection::ResMut<bevy_render::view::window::ExtractedWindows>, bevy_render::extract_param::Extract<bevy_ecs::change_detection::Res<bevy_render::view::window::screenshot::ScreenshotManager>>, bevy_render::extract_param::Extract<bevy_ecs::event::EventReader<bevy_window::event::WindowClosed>>, bevy_render::extract_param::Extract<bevy_ecs::system::query::Query<(bevy_ecs::entity::Entity, &bevy_window::window::Window, &bevy_window::raw_handle::RawHandleWrapper, core::option::Option<&bevy_window::window::PrimaryWindow>), ()>>, bevy_render::extract_param::Extract<bevy_ecs::removal_detection::RemovedComponents<bevy_window::raw_handle::RawHandleWrapper>>, bevy_ecs::change_detection::ResMut<bevy_render::view::window::WindowSurfaces>), bevy_ecs::change_detection::ResMut<bevy_render::view::window::ExtractedWindows>, bevy_render::extract_param::Extract<bevy_ecs::change_detection::Res<bevy_render::view::window::screenshot::ScreenshotManager>>, bevy_render::extract_param::Extract<bevy_ecs::event::EventReader<bevy_window::event::WindowClosed>>, bevy_render::extract_param::Extract<bevy_ecs::system::query::Query<(bevy_ecs::entity::Entity, &bevy_window::window::Window, &bevy_window::raw_handle::RawHandleWrapper, core::option::Option<&bevy_window::window::PrimaryWindow>), ()>>, bevy_render::extract_param::Extract<bevy_ecs::removal_detection::--Type <RET> for more, q to quit, c to continue without paging--
RemovedComponents<bevy_window::raw_handle::RawHandleWrapper>>, bevy_ecs::change_detection::ResMut<bevy_render::view::window::WindowSurfaces>> (
self=<optimized out>, param_value=...)
at /home/jeb/.local/share/cargo/git/checkouts/bevy-f7ffde730c324c74/66f72dd/crates/bevy_ecs/src/system/function_system.rs:644
#21 bevy_ecs::system::function_system::{impl#6}::run_unsafe<fn(bevy_ecs::change_detection::ResMut<bevy_render::view::window::ExtractedWindows>, bevy_render::extract_param::Extract<bevy_ecs::change_detection::Res<bevy_render::view::window::screenshot::ScreenshotManager>>, bevy_render::extract_param::Extract<bevy_ecs::event::EventReader<bevy_window::event::WindowClosed>>, bevy_render::extract_param::Extract<bevy_ecs::system::query::Query<(bevy_ecs::entity::Entity, &bevy_window::window::Window, &bevy_window::raw_handle::RawHandleWrapper, core::option::Option<&bevy_window::window::PrimaryWindow>), ()>>, bevy_render::extract_param::Extract<bevy_ecs::removal_detection::RemovedComponents<bevy_window::raw_handle::RawHandleWrapper>>, bevy_ecs::change_detection::ResMut<bevy_render::view::window::WindowSurfaces>), fn(bevy_ecs::change_detection::ResMut<bevy_render::view::window::ExtractedWindows>, bevy_render::extract_param::Extract<bevy_ecs::change_detection::Res<bevy_render::view::window::screenshot::ScreenshotManager>>, bevy_render::extract_param::Extract<bevy_ecs::event::EventReader<bevy_window::event::WindowClosed>>, bevy_render::extract_param::Extract<bevy_ecs::system::query::Query<(bevy_ecs::entity::Entity, &bevy_window::window::Window, &bevy_window::raw_handle::RawHandleWrapper, core::option::Option<&bevy_window::window::PrimaryWindow>), ()>>, bevy_render::extract_param::Extract<bevy_ecs::removal_detection::RemovedComponents<bevy_window::raw_handle::RawHandleWrapper>>, bevy_ecs::change_detection::ResMut<bevy_render::view::window::WindowSurfaces>)> (
self=0x564b0f3369c0, input=<optimized out>, world=...)
at /home/jeb/.local/share/cargo/git/checkouts/bevy-f7ffde730c324c74/66f72dd/crates/bevy_ecs/src/system/function_system.rs:484
#22 0x00007fcd6230cfe0 in bevy_ecs::schedule::executor::single_threaded::{impl#0}::run::{closure#0} () at src/schedule/executor/single_threaded.rs:92
#23 core::ops::function::FnOnce::call_once<bevy_ecs::schedule::executor::single_threaded::{impl#0}::run::{closure_env#0}, ()> ()
at /rustc/49691b1f70d71dd7b8349c332b7f277ee527bf08/library/core/src/ops/function.rs:250
#24 core::panic::unwind_safe::{impl#23}::call_once<(), bevy_ecs::schedule::executor::single_threaded::{impl#0}::run::{closure_env#0}> (self=...)
at /rustc/49691b1f70d71dd7b8349c332b7f277ee527bf08/library/core/src/panic/unwind_safe.rs:271
#25 std::panicking::try::do_call<core::panic::unwind_safe::AssertUnwindSafe<bevy_ecs::schedule::executor::single_threaded::{impl#0}::run::{closure_env#0}>, ()> (data=<optimized out>) at /rustc/49691b1f70d71dd7b8349c332b7f277ee527bf08/library/std/src/panicking.rs:504
#26 std::panicking::try<(), core::panic::unwind_safe::AssertUnwindSafe<bevy_ecs::schedule::executor::single_threaded::{impl#0}::run::{closure_env#0}>> (
f=...) at /rustc/49691b1f70d71dd7b8349c332b7f277ee527bf08/library/std/src/panicking.rs:468
#27 std::panic::catch_unwind<core::panic::unwind_safe::AssertUnwindSafe<bevy_ecs::schedule::executor::single_threaded::{impl#0}::run::{closure_env#0}>, ()> (
f=...) at /rustc/49691b1f70d71dd7b8349c332b7f277ee527bf08/library/std/src/panic.rs:142
#28 bevy_ecs::schedule::executor::single_threaded::{impl#0}::run (self=0x564b0f04d910, schedule=0x7fff775991a0, world=0x564b0f222350)
at src/schedule/executor/single_threaded.rs:91
#29 0x00007fcd6172766e in bevy_ecs::world::{impl#3}::run_schedule::{closure#0}<bevy_render::ExtractSchedule> (world=0x564b0f222350, sched=0x7fff77599180)
at /home/jeb/.local/share/cargo/git/checkouts/bevy-f7ffde730c324c74/66f72dd/crates/bevy_ecs/src/world/mod.rs:2088
#30 bevy_ecs::world::World::try_schedule_scope<(), bevy_render::ExtractSchedule, bevy_ecs::world::{impl#3}::run_schedule::{closure_env#0}<bevy_render::ExtractSchedule>> (self=0x564b0f222350, label=..., f=...)
at /home/jeb/.local/share/cargo/git/checkouts/bevy-f7ffde730c324c74/66f72dd/crates/bevy_ecs/src/world/mod.rs:2007
#31 bevy_ecs::world::World::schedule_scope<(), bevy_render::ExtractSchedule, bevy_ecs::world::{impl#3}::run_schedule::{closure_env#0}<bevy_render::ExtractSchedule>> (self=0x564b0f222350, label=..., f=...)
at /home/jeb/.local/share/cargo/git/checkouts/bevy-f7ffde730c324c74/66f72dd/crates/bevy_ecs/src/world/mod.rs:2059
#32 0x00007fcd615724d3 in bevy_ecs::world::World::run_schedule<bevy_render::ExtractSchedule> (self=<optimized out>)
at /home/jeb/.local/share/cargo/git/checkouts/bevy-f7ffde730c324c74/66f72dd/crates/bevy_ecs/src/world/mod.rs:2088
#33 bevy_render::extract (main_world=0x7fff7759b718, render_app=0x564b0f222350) at src/lib.rs:396
#34 0x00007fcd622a443b in alloc::boxed::{impl#49}::call<(&mut bevy_ecs::world::World, &mut bevy_app::app::App), (dyn core::ops::function::Fn<(&mut bevy_ecs::world::World, &mut bevy_app::app::App), Output=()> + core::marker::Send), alloc::alloc::Global> (self=0x564b0f222340, args=...)
at /rustc/49691b1f70d71dd7b8349c332b7f277ee527bf08/library/alloc/src/boxed.rs:2021
#35 bevy_app::app::SubApp::extract (self=0x564b0f222340, main_world=0x7fff7759b718) at src/app.rs:166
#36 bevy_app::app::App::update (self=0x7fff7759b718) at src/app.rs:264
#37 0x00007fcd60592720 in bevy_winit::winit_runner::{closure#0} (event=..., event_loop=0x564b0d97cea0, control_flow=0x7fff7759a740) at src/lib.rs:818
#38 0x00007fcd605c887e in winit::platform_impl::platform::sticky_exit_callback<(), bevy_winit::winit_runner::{closure_env#0}> (evt=..., target=0x0,
control_flow=0x7fff7759a740, callback=0x7fff7759afd0)
at /home/jeb/.local/share/cargo/registry/src/index.crates.io-6f17d22bba15001f/winit-0.28.7/src/platform_impl/linux/mod.rs:884
#39 winit::platform_impl::platform::x11::{impl#2}::run_return::single_iteration<(), bevy_winit::winit_runner::{closure_env#0}> (this=0x7fff7759ab80,
control_flow=0x7fff7759a740, cause=0x7fff7759a7f0, callback=0x7fff7759afd0)
at /home/jeb/.local/share/cargo/registry/src/index.crates.io-6f17d22bba15001f/winit-0.28.7/src/platform_impl/linux/x11/mod.rs:358
#40 0x00007fcd605c8ea8 in winit::platform_impl::platform::x11::EventLoop<()>::run_return<(), bevy_winit::winit_runner::{closure_env#0}> (
self=0x7fff7759ab80, callback=...)
at /home/jeb/.local/share/cargo/registry/src/index.crates.io-6f17d22bba15001f/winit-0.28.7/src/platform_impl/linux/x11/mod.rs:483
#41 0x00007fcd605ca98d in winit::platform_impl::platform::x11::EventLoop<()>::run<(), bevy_winit::winit_runner::{closure_env#0}> (self=...,
callback=<error reading variable: Cannot access memory at address 0x1a1>)
at /home/jeb/.local/share/cargo/registry/src/index.crates.io-6f17d22bba15001f/winit-0.28.7/src/platform_impl/linux/x11/mod.rs:498
#42 0x00007fcd60584368 in winit::platform_impl::platform::EventLoop<()>::run<(), bevy_winit::winit_runner::{closure_env#0}> (
self=<error reading variable: Cannot access memory at address 0x0>, callback=<error reading variable: Cannot access memory at address 0x18>)
at /home/jeb/.local/share/cargo/registry/src/index.crates.io-6f17d22bba15001f/winit-0.28.7/src/platform_impl/linux/mod.rs:792
#43 winit::event_loop::EventLoop<()>::run<(), bevy_winit::winit_runner::{closure_env#0}> (
event_handler=<error reading variable: Cannot access memory at address 0x18>)
at /home/jeb/.local/share/cargo/registry/src/index.crates.io-6f17d22bba15001f/winit-0.28.7/src/event_loop.rs:305
#44 bevy_winit::run<bevy_winit::winit_runner::{closure_env#0}, ()> (event_handler=<error reading variable: Cannot access memory at address 0x18>)
at src/lib.rs:235
#45 bevy_winit::winit_runner (app=...) at src/lib.rs:902
#46 0x00007fcd60575902 in core::ops::function::FnOnce::call_once<fn(bevy_app::app::App), (bevy_app::app::App)> ()
at /rustc/49691b1f70d71dd7b8349c332b7f277ee527bf08/library/core/src/ops/function.rs:250
#47 core::ops::function::FnOnce::call_once<fn(bevy_app::app::App), (bevy_app::app::App)> ()
at /rustc/49691b1f70d71dd7b8349c332b7f277ee527bf08/library/core/src/ops/function.rs:250
#48 0x00007fcd622a45f9 in alloc::boxed::{impl#47}::call_once<(bevy_app::app::App), (dyn core::ops::function::FnOnce<(bevy_app::app::App), Output=()> + core::marker::Send), alloc::alloc::Global> (self=..., args=...) at /rustc/49691b1f70d71dd7b8349c332b7f277ee527bf08/library/alloc/src/boxed.rs:2007
--Type <RET> for more, q to quit, c to continue without paging--
#49 bevy_app::app::App::run (self=<optimized out>) at src/app.rs:315
#50 0x0000564b0be29272 in general_logistics::main () at src/bin/general_logistics.rs:5
Its getting stuck deep in the AMDVLK code, so it might be their issue? Unless wgpu is doing something "non conforming" when destroying the swapchain, that other drivers handle better.
For now I will probably just go back to using radeon-vulkan
, I only installed AMDVLK
for some raytracing tests and I don't need to keep it installed.
I created a minimal example that can control the issue by changing the window PresentMode
use bevy::{prelude::*, window::PresentMode};
fn main() {
App::new()
.add_plugins(DefaultPlugins.set(WindowPlugin {
primary_window: Some(Window {
present_mode: PresentMode::AutoNoVsync, /* Works */
..default()
}),
..default()
}))
.run();
}
The issue only reproduces with PresentMode::AutoVsync
and PresentMode::Fifo
(which I think is the default in AutoVsync
mode).
The issue also doesn't appear to reproduce if the WinitSettings::desktop_app()
resource is provided.
Interestingly, the issue does not reproduce running wgpu
boids or cube examples, even though they should be using PresentMode::Fifo
as well.
I checked on both wgpu
0.17.1 and trunk.
I haven't been able to narrow down what Bevy is doing that causes FIFO mode to apparently deadlock when the swap-chain is destroyed.
@alice-i-cecile I think I have narrowed the issue.
In PresentMode::Fifo
when the winit::window::Window
structure is dropped before wgpu::Surface
, then the AMDVLK driver will hang while trying to destroy the SwapChain.
If I skip dropping (or leak) the winit::window::Window
, the hang does not occur.
I think that Bevy might be violating the WGPU surface docs on this, from here
raw_window_handle must remain valid until after the returned Surface is dropped.
But Bevy will always destroy the winit
Window before destroying the Surface.
It isn't clear why other drivers handle this more gracefully.
Known issue. I've tried several times to solve it, but stopped, since for me, since the pipelined rendering change, it stopped happening altogether. See the already opened issues:
If it is really what you describe, I'm hyped. All I can say.
Thanks for bringing together all the prior issues.
It heartens me that #839 and #1908 have stack-traces which show the stall occurring during swap-chain destruction. It makes it more likely we are actually looking at the same issue across all these machines. (It looks like it may even affect the intel driver as well).
I built and installed the amdvlk
driver with debug symbols to see if I could dig further.
The issue is most definitely caused by closing the winit
Window prior to shutting down the wgpu
Surface in the renderer.
Internally the amdvlk
driver spawns a background thread to handle presenting images to whatever the display back-end happens to be.
In FIFO mode, after every frame presented this background thread will wait for the X-server to send an XCB_PRESENT_COMPLETE_NOTIFY
by calling xcb_wait_for_special_event()
.
Because the window was closed, this never happens (see similar issue here).
Because the background thread never advances in its loop, it fails to process a Notify
event that the Bevy render thread sends while tearing down the Swap-chain which sets a timeout for UINT32_MAX seconds (so technically Bevy will eventually close... in 136 years).
So the root cause is:
Bevy --[blocks on]--> amdvlk worker --[waiting for event from]--> Xorg
While it could be argued that the amdvlk
driver is doing something not very resilient, I do think that Bevy should fix the Window-Surface close order. This will make Bevy more resilient, and will comply with the wgpu
documentation.
I put together a prototype which stores an Atomic token in the main app World to back-channel information from the Render World about the state of the wgpu
Surface.
This is the most minimal change that I could think of, but is somewhat of a hack. If someone knows a better way to back-channel information from the Render World, or can move ownership of the Surface to the Main App World that might be a better solution, but I couldn't think of a way that didn't involve introducing heavy new dependencies into one of the crates.
Edit: I think this issue should be tagged with S-Needs-Design
Bevy version
Mainline Bevy
git+https://github.com/bevyengine/bevy.git#66f72dd25bb9e3f3d035f2f14dcbcd25674f968c
[Optional] Relevant system information
EndeavourOS
Rust: 1.75-nightly
Broken adapter info:
What you did
Ran Bevy with the
AMDVLK
Vulkan driver, and closed the game window.What went wrong
The game window closes, but the application continues to run until
ctrl+c
Additional information
Forcing the
vulkan-radeon
driver using environment variables makes the issue go away.So this issue appears to only be related to the
AMDVLK
driver option.