gfx-rs / gfx

[maintenance mode] A low-overhead Vulkan-like GPU API for Rust.
http://gfx-rs.github.io/
Apache License 2.0
5.36k stars 547 forks source link

Intel: Panic when acquirng swapchain image #3141

Closed freqmod closed 4 years ago

freqmod commented 4 years ago

Short info header:

Also tested on another machine, Linux with NVIDIA Geforce RTX 2060. There the same code works flawlessly, i can open 50 windows without any problems.

I have a program with 2 threads. One thread is running the event loop with winit, the other is handling graphics and interfacing wgpu (etc.). They are connected using a crossbeam.

When clicking a button the gpu thread gets the mouse event over crossbeam, reports a user event back to the winit thread, which creates a window & a corresponding surface. The surface is passed to the graphics thread to set up the rendering.

It seems to me like the swapchain tries to render in the old window while the new one is created. This causes the intel driver to return a strange texture index, and not an error. Thus rust panics. This happens every time.

I have made a workaround (attached) that sanitises the texture indices, and this seems to work. (i could create 10-20 windows without panic now)

Possible workaround:

diff --git a/src/backend/vulkan/src/window.rs b/src/backend/vulkan/src/window.rs index 6e852e51..420d8a15 100644 --- a/src/backend/vulkan/src/window.rs +++ b/src/backend/vulkan/src/window.rs @@ -501,6 +501,11 @@ impl w::PresentationSurface<Backend> for Surface { timeout_ns = timeout_ns.saturating_sub(moment.elapsed().as_nanos() as u64); let fences = &[ssc.fence.0]; + if(!(index < ssc.frames.len() as u32)) + { + return Err(w::AcquireError::OutOfDate); + } + match ssc.device.0.wait_for_fences(fences, true, timeout_ns) { Ok(()) => { ssc.device.0.reset_fences(fences).unwrap(); `

Panic:

thread '<unnamed>' panicked at 'index out of bounds: the len is 3 but the index is 32767', /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8/src/libcore/slice/mod.rs:2806:10 note: run with RUST_BACKTRACE=1 environment variable to display a backtrace. [Switching to Thread 0x7ffff79ef700 (LWP 6198)] Thread 2 "customcode" hit Breakpoint 1, rust_panic () at src/libstd/panicking.rs:521 521 src/libstd/panicking.rs: No such file or directory. (gdb) bt #0 rust_panic () at src/libstd/panicking.rs:521 #1 0x0000555555db15a6 in std::panicking::rust_panic_with_hook () at src/libstd/panicking.rs:491 #2 0x0000555555db104e in rust_begin_unwind () at src/libstd/panicking.rs:375 #3 0x0000555555dcc2de in core::panicking::panic_fmt () at src/libcore/panicking.rs:84 #4 0x0000555555dcc2a5 in core::panicking::panic_bounds_check () at src/libcore/panicking.rs:62 #5 0x0000555555a17937 in <usize as core::slice::SliceIndex<[T]>>::index (self=32767, slice=...) at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8/src/libcore/slice/mod.rs:2806 #6 0x0000555555a19628 in core::slice::<impl core::ops::index::Index for [T]>::index (self=..., index=32767) at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8/src/libcore/slice/mod.rs:2657 #7 0x00005555559e57fb in <alloc::vec::Vec as core::ops::index::Index>::index (self=0x55555629b6b0, index=32767) at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8/src/liballoc/vec.rs:1871 #8 0x00005555559b8716 in <gfx_backend_vulkan::window::Surface as gfx_hal::window::PresentationSurface>::acquire_image (self=0x55555629b638, timeout_ns=999910700) at /home/freqmod/Downloads/gfx/src/backend/vulkan/src/window.rs:512 #9 0x0000555555833fec in wgpu_core::swap_chain::<impl wgpu_core::hub::Global>::swap_chain_get_next_texture (self=0x5555560ff860, swap_chain_id=..., view_id_in=...) at /home/freqmod/Downloads/wgpu/wgpu-core/src/swap_chain.rs:148 #10 0x00005555558995a2 in wgpu_swap_chain_get_next_texture (swap_chain_id=...) at /home/freqmod/Downloads/wgpu/wgpu-native/src/device.rs:410 #11 0x00005555556df5d7 in wgpu::SwapChain::get_next_texture (self=0x7ffff012aec0) at /home/freqmod/Downloads/wgpu-rs/src/lib.rs:1480 #12 0x0000555555629eef in customcode::RenderingPipeline::redraw (self=0x7ffff79ee960, win_idx=...) at src/main.rs:454 #13 0x000055555562ada2 in customcode::RenderingPipeline::handle_event (self=0x7ffff79ee960, event=...) at src/main.rs:553 #14 0x000055555562b67e in customcode::RenderingPipeline::listen_for_events (self=..., event_receiver=...) at src/main.rs:612 #15 0x000055555562da9d in customcode::main::{{closure}} () at src/main.rs:633 #16 0x000055555562366d in std::sys_common::backtrace::rust_begin_short_backtrace (f=...) at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8/src/libstd/sys_common/backtrace.rs:136 #17 0x000055555565ad5d in std::thread::Builder::spawn_unchecked::{{closure}}::{{closure}} () at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8/src/libstd/thread/mod.rs:469 #18 0x00005555556575cb in <std::panic::AssertUnwindSafe as core::ops::function::FnOnce<()>>::call_once (self=..., _args=()) at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8/src/libstd/panic.rs:318 #19 0x000055555568a78e in std::panicking::try::do_call (data=0x7ffff79eeb60 "\000") at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8/src/libstd/panicking.rs:292 `#20 0x0000555555db4e3a in rust_maybe_catch_panic () at src/libpanic_unwind/lib.rs:78 --Type <RET> for more, q to quit, c to continue without paging-- #21 0x0000555555689daa in std::panicking::try (f=...) at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8/src/libstd/panicking.rs:270 #22 0x000055555565766d in std::panic::catch_unwind (f=...) at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8/src/libstd/panic.rs:394 #23 0x000055555565ab5a in std::thread::Builder::spawn_unchecked::{{closure}} () at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8/src/libstd/thread/mod.rs:468 #24 0x000055555566fec3 in core::ops::function::FnOnce::call_once{{vtable-shim}} () at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8/src/libcore/ops/function.rs:232 #25 0x0000555555da5b9f in <alloc::boxed::Box as core::ops::function::FnOnce>::call_once () at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8/src/liballoc/boxed.rs:1022 #26 0x0000555555db4270 in <alloc::boxed::Box<F> as core::ops::function::FnOnce<A>>::call_once () at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8/src/liballoc/boxed.rs:1022 #27 std::sys_common::thread::start_thread () at src/libstd/sys_common/thread.rs:13 #28 std::sys::unix::thread::Thread::new::thread_start () at src/libstd/sys/unix/thread.rs:80 #29 0x00007ffff7d58669 in start_thread (arg=) at pthread_create.c:479 `#30 0x00007ffff7c66323 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

vulkaninfo:

========== VULKANINFO ========== Vulkan Instance Version: 1.1.114 Instance Extensions: ==================== Instance Extensions count = 18 VK_EXT_acquire_xlib_display : extension revision 1 VK_EXT_debug_report : extension revision 9 VK_EXT_debug_utils : extension revision 1 VK_EXT_direct_mode_display : extension revision 1 VK_EXT_display_surface_counter : extension revision 1 VK_KHR_device_group_creation : extension revision 1 VK_KHR_display : extension revision 23 VK_KHR_external_fence_capabilities : extension revision 1 VK_KHR_external_memory_capabilities : extension revision 1 VK_KHR_external_semaphore_capabilities: extension revision 1 VK_KHR_get_display_properties2 : extension revision 1 VK_KHR_get_physical_device_properties2: extension revision 1 VK_KHR_get_surface_capabilities2 : extension revision 1 VK_KHR_surface : extension revision 25 VK_KHR_surface_protected_capabilities: extension revision 1 VK_KHR_wayland_surface : extension revision 6 VK_KHR_xcb_surface : extension revision 6 VK_KHR_xlib_surface : extension revision 6 Layers: count = 4 ======= VK_LAYER_LUNARG_standard_validation (LunarG Standard Validation Layer) Vulkan version 1.0.114, layer version 1 Layer Extensions count = 0 Devices count = 1 GPU id : 0 (Intel(R) HD Graphics 515 (Skylake GT2)) Layer-Device Extensions count = 0 VK_LAYER_MESA_overlay (Mesa Overlay layer) Vulkan version 1.1.73, layer version 1 Layer Extensions count = 0 Devices count = 1 GPU id : 0 (Intel(R) HD Graphics 515 (Skylake GT2)) Layer-Device Extensions count = 0 VK_LAYER_VALVE_steam_overlay_32 (Steam Overlay Layer) Vulkan version 1.0.3, layer version 1 Layer Extensions count = 0 Devices count = 1 GPU id : 0 (Intel(R) HD Graphics 515 (Skylake GT2)) Layer-Device Extensions count = 0 VK_LAYER_VALVE_steam_overlay_64 (Steam Overlay Layer) Vulkan version 1.0.3, layer version 1 Layer Extensions count = 0 Devices count = 1 GPU id : 0 (Intel(R) HD Graphics 515 (Skylake GT2)) Layer-Device Extensions count = 0 Presentable Surfaces: ===================== GPU id : 0 (Intel(R) HD Graphics 515 (Skylake GT2)) Surface type : VK_KHR_xlib_surface Formats: count = 2 B8G8R8A8_SRGB B8G8R8A8_UNORM Present Modes: count = 3 IMMEDIATE_KHR MAILBOX_KHR FIFO_KHR VkSurfaceCapabilitiesKHR: minImageCount = 3 maxImageCount = 0 currentExtent: width = 256 height = 256 minImageExtent: width = 256 height = 256 maxImageExtent: width = 256 height = 256 maxImageArrayLayers = 1 supportedTransform: VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR currentTransform: VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR supportedCompositeAlpha: VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR supportedUsageFlags: VK_IMAGE_USAGE_TRANSFER_SRC_BIT VK_IMAGE_USAGE_TRANSFER_DST_BIT VK_IMAGE_USAGE_SAMPLED_BIT VK_IMAGE_USAGE_STORAGE_BIT VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT VkSurfaceCapabilities2EXT: supportedSurfaceCounters: None GPU id : 0 (Intel(R) HD Graphics 515 (Skylake GT2)) Surface type : VK_KHR_xcb_surface Formats: count = 2 B8G8R8A8_SRGB B8G8R8A8_UNORM Present Modes: count = 3 IMMEDIATE_KHR MAILBOX_KHR FIFO_KHR VkSurfaceCapabilitiesKHR: minImageCount = 3 maxImageCount = 0 currentExtent: width = 256 height = 256 minImageExtent: width = 256 height = 256 maxImageExtent: width = 256 height = 256 maxImageArrayLayers = 1 supportedTransform: VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR currentTransform: VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR supportedCompositeAlpha: VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR supportedUsageFlags: VK_IMAGE_USAGE_TRANSFER_SRC_BIT VK_IMAGE_USAGE_TRANSFER_DST_BIT VK_IMAGE_USAGE_SAMPLED_BIT VK_IMAGE_USAGE_STORAGE_BIT VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT VkSurfaceCapabilities2EXT: supportedSurfaceCounters: None Groups : ======== Device Group Properties (Group 0) : physicalDeviceCount = 1 Intel(R) HD Graphics 515 (Skylake GT2) (ID: 0) subsetAllocation = 0 Device Group Present Capabilities (Group 0) : Intel(R) HD Graphics 515 (Skylake GT2) (ID: 0) Can present images from the following devices: Intel(R) HD Graphics 515 (Skylake GT2) (ID: 0) Present modes: VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR Device Properties and Extensions : ================================== GPU0 VkPhysicalDeviceProperties: =========================== apiVersion = 0x401066 (1.1.102) driverVersion = 79699976 (0x4c02008) vendorID = 0x8086 deviceID = 0x191e deviceType = INTEGRATED_GPU ` deviceName = Intel(R) HD Graphics 515 (Skylake GT2) ...

kvark commented 4 years ago

The returned index appears to be -1, which hints on invalid usage or some kind of invalid internal state in the driver and/or the surface. Do you have validation layers installed? If you do, you should see some output when running the application in debug, and it may tell us what's going wrong.

kvark commented 4 years ago

At the very least, we could check if the index is specifically -1 and issue a warning in this case, as a workaround for this unspecified driver behavior.

freqmod commented 4 years ago

I recompiled, and had to update winit (from version 20 to version 21), now i can't reproduce the error anymore. (I had to rewrite some stuff as i couldn't clone events anymore, so that can affect races).

I suggest closing this for now and see if anybody else has this problem in the future. (or possibly validate the indices of the textures as a preventive measure).

nical commented 4 years ago

I have the same issue when resizing a window with wgpu-rs. For example clone the lyon repo and run the wgpu example https://github.com/nical/lyon/tree/master/examples/wgpu (cargo build in the examples/wgpu folder). I've also had this with other wgpu related things but this one is probably the simplest.