Description
Assertion failure when running wgpu with commit 35b163ebc861cae808ca168cdd5edf4ec91456f9 or later.
Repro steps
The easiest thing is probably to use the attached trace (below). But you should also be able to reproduce the bug running terra directly.
Clone...
git clone https://github.com/fintelia/terra && cd terra
git checkout 9ac9d598f23065543df14a8b1051faf918065c41
patch Cargo.toml...
[replace]
"https://github.com/gfx-rs/wgpu#wgpu-core:0.6.0" = { git = "https://github.com/gfx-rs/wgpu", rev = "b82482f31c6fa30fcb27188b561a3eb6ee056580" }
"https://github.com/gfx-rs/wgpu#wgpu-types:0.6.0" = { git = "https://github.com/gfx-rs/wgpu", rev = "b82482f31c6fa30fcb27188b561a3eb6ee056580" }
Run...
RUST_BACKTRACE=1 cargo run --release
Uninstall...
rm -r ~/.cache/terra
Expected vs observed behavior
I would expect the program to run normally, as it does without the patched wgpu-core version. Instead it crashes with an assertion failure:
thread 'main' panicked at 'assertion failed: `(left == right)`
left: `1`,
right: `2`', /home/jonathan/.cargo/git/checkouts/wgpu-53e70f8674b08dd4/b82482f/wgpu-core/src/track/mod.rs:373:21
stack backtrace:
0: rust_begin_unwind
at /rustc/7f9c43cf98cfe1c369045399929cb098155b8374/library/std/src/panicking.rs:493:5
1: core::panicking::panic_fmt
at /rustc/7f9c43cf98cfe1c369045399929cb098155b8374/library/core/src/panicking.rs:92:14
2: wgpu_core::track::ResourceTracker<S>::merge_extend
3: wgpu_core::command::CommandBuffer<B>::insert_barriers
at /home/jonathan/.cargo/git/checkouts/wgpu-53e70f8674b08dd4/b82482f/wgpu-core/src/command/mod.rs:98:9
4: wgpu_core::device::queue::<impl wgpu_core::hub::Global<G>>::queue_submit
at /home/jonathan/.cargo/git/checkouts/wgpu-53e70f8674b08dd4/b82482f/wgpu-core/src/device/queue.rs:603:25
5: <wgpu::backend::direct::Context as wgpu::Context>::queue_submit
at /home/jonathan/.cargo/git/checkouts/wgpu-rs-40ea39809c03c5d8/3d60546/src/backend/direct.rs:1698:15
6: wgpu::Queue::submit
at /home/jonathan/.cargo/git/checkouts/wgpu-rs-40ea39809c03c5d8/3d60546/src/lib.rs:2605:9
7: terra::Terrain::render
at ./src/lib.rs:476:9
Extra materials
Platform
Ubuntu 20.10
AMD RX 580
wgpu 35b163ebc861cae808ca168cdd5edf4ec91456f9
Could be related to #1116 , needs to be retested.
Unfortunately, the API trace doesn't reveal the problem and instead fails on a different issue, which I'm looking at:
thread 'main' panicked at 'range end index 1 out of range for slice of length 0', /hub/moz/wgpu/wgpu-core/src/command/render.rs:1047:45
note: run withRUST_BACKTRACE=1environment variable to display a backtrace
The issue still happens for me on 29cb9e687dfc102ca50e4a0046879ef096be1f19: trace.zip
@fintelia could you try running in debug and providing a trace from it?
My only suspect so far (about being unable to replay the capture) is explained in #1125, which is on its way to landing.
debug trace: trace.zip
debug trace from 35a2c8c474983f19d166683133b171505e0def32: trace.zip
@fintelia note that the repro steps are incomplete. First, there is a nightly requirement:
error[E0554]:
#![feature]may not be used on the stable release channel
--> src/lib.rs:2:1
|
2 | #![feature(test)]
Secondly, last time I tried there was an error about missing resources. Trying again now.
Able to reproduce now, working on it
@fintelia ok I think I figured out everything now.
First of all, thank you for greatly detailed issues, repro cases, and attached API traces! It's a pleasure to work on this :)
First problem I saw was with API tracing - I wasn't able to replay the stuff you provided. This is now fixed in #1127
Second problem was that a swapchain frame was used after it was presented, and we didn't detect this in a very robust way. Now #1126 produces an actual error for this case. This means you are getting an error now instead of an internal panic, so it still needs to be fixed on your side.
After some debugging, I was able to fix the issue on my end by merging the two render passes which were using the swapchain frame. Based on the comment at the top of swap_chain.rs I'm not sure it should have been possible to use the frame in two render passes to begin with, but perhaps doing so might mess with the reference counting and make wgpu think the frame is still in use even after dropping it?
2 render passes should be fine, unless one uses one swapchain frame and another uses the next (i.e. the frame gets dropped after first one is recorded). Are you sure that in your case the frame isn't dropped in-between?
I don't think that is possible with the scopes in play. The full function is here, but the general shape of the code is:
```rust
pub fn render(
frame: &wgpu::TextureView,
...
) {
{
let mut rpass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
color_attachments: &[wgpu::RenderPassColorAttachmentDescriptor { attachment: frame, ... },
...
});
}
{
let mut rpass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
color_attachments: &[wgpu::RenderPassColorAttachmentDescriptor { attachment: frame, ... },
...
});
}
}
Weird. We should be able to reproduce this on wgpu-rs examples then (and last time I tried, it worked fine).
I was able to reproduce with the hello-triangle example: https://github.com/fintelia/wgpu-rs/blob/double-renderpass/examples/hello-triangle/main.rs
However, this patch prevents the crash. So it seems that it isn't enough to create two render passes, but that they both must be recorded onto the same CommandEncoder.
I'm looking into this