vulkano: Radv leading to panicked main thread in triangle example

Running the triangle example code gives me:

WARNING: radv is not a conformant vulkan implementation, testing use only. Using device: AMD RADV POLARIS10 (type: DiscreteGpu) thread 'main' panicked at 'called Result::unwrap()on anErrvalue: Timeout', /buildslave/rust-buildbot/slave/stable-dist-rustc-linux/build/src/libcore/result.rs:837 note: Run withRUST_BACKTRACE=1for a backtrace.

I am not sure whether this is a RADV bug or one I could fix. Any ideas here? Will you test with Mesa/Radv as well?

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Comments: 19 (9 by maintainers)

Most upvoted comments

Ah, so I can stop the hang by either switching to FIFO presentation, or setting the timeout to u64::max_value(). Using a finite timeout seems to result in some sort of deadlock in radv. I’m not sure if there’s something else we’re doing wrong, but I can reproduce it in my C program, so I’m leaning toward a bug in radv.

I’m also using radv, and have this problem with the triangle/teapot example. You can match on the error instead of unwrapping (as well as handle recreating the swapchain):

match swapchain.acquire_next_image(Duration::from_millis(1)) {
    Result::Ok(image_num) => {
        // Present triangle/teapot/etc.
    },
    Result::Err(err) => {
        vulkano::swapchain::AcquireError::OutOfDate => {
            recreate_swapchain = true;
        },
        err => println!("Swapchain acquire error: {}", err)
    }
}

However, this leads to a different panic:

Swapchain acquire error: no image is available for acquiring yet
dt: 0.334312 ms
Swapchain acquire error: no image is available for acquiring yet
dt: 0.560813 ms
Swapchain acquire error: no image is available for acquiring yet
dt: 0.455526 ms
thread 'main' panicked at 'assertion failed: index < len', /buildslave/rust-buildbot/slave/beta-dist-rustc-linux/build/src/libcollections/vec.rs:762
stack backtrace:
   1:     0x55697b246f8c - std::sys::imp::backtrace::tracing::imp::write::h23bcdb89e70c5bbf
                        at /buildslave/rust-buildbot/slave/beta-dist-rustc-linux/build/src/libstd/sys/unix/backtrace/tracing/gcc_s.rs:42
   2:     0x55697b2494be - std::panicking::default_hook::{{closure}}::he7b82439fd2d2bb6
                        at /buildslave/rust-buildbot/slave/beta-dist-rustc-linux/build/src/libstd/panicking.rs:351
   3:     0x55697b2490c4 - std::panicking::default_hook::he1cd4269c1558f23
                        at /buildslave/rust-buildbot/slave/beta-dist-rustc-linux/build/src/libstd/panicking.rs:367
   4:     0x55697b24995b - std::panicking::rust_panic_with_hook::h006b37e36b7c8982
                        at /buildslave/rust-buildbot/slave/beta-dist-rustc-linux/build/src/libstd/panicking.rs:555
   5:     0x55697b2497a4 - std::panicking::begin_panic::h043cddfdd3933cc4
                        at /buildslave/rust-buildbot/slave/beta-dist-rustc-linux/build/src/libstd/panicking.rs:517
   6:     0x55697b249719 - std::panicking::begin_panic_fmt::h34e588bba6b8a2c2
                        at /buildslave/rust-buildbot/slave/beta-dist-rustc-linux/build/src/libstd/panicking.rs:501
   7:     0x55697b2496a7 - rust_begin_unwind
                        at /buildslave/rust-buildbot/slave/beta-dist-rustc-linux/build/src/libstd/panicking.rs:477
   8:     0x55697b273dbd - core::panicking::panic_fmt::he52644573ecd78ff
                        at /buildslave/rust-buildbot/slave/beta-dist-rustc-linux/build/src/libcore/panicking.rs:69
   9:     0x55697b273cf4 - core::panicking::panic::hab2712470c117667
                        at /buildslave/rust-buildbot/slave/beta-dist-rustc-linux/build/src/libcore/panicking.rs:49
  10:     0x55697b166432 - <collections::vec::Vec<T>>::remove::h212820e650179e10
                        at /home/***/workspace/rs/vulkano/examples/<panic macros>:4
  11:     0x55697b1ca10d - vulkano::swapchain::swapchain::Swapchain::acquire_next_image::h31c02d06bbb4d191
                        at /home/***/workspace/rs/vulkano/vulkano/src/swapchain/swapchain.rs:285
  12:     0x55697b0a1563 - teapot::main::h988c9674ea919c4f
                        at /home/***/workspace/rs/vulkano/examples/src/bin/teapot.rs:345
  13:     0x55697b2503ea - __rust_maybe_catch_panic
                        at /buildslave/rust-buildbot/slave/beta-dist-rustc-linux/build/src/libpanic_unwind/lib.rs:98
  14:     0x55697b249e66 - std::rt::lang_start::h1ef940195e3c010e
                        at /buildslave/rust-buildbot/slave/beta-dist-rustc-linux/build/src/libstd/panicking.rs:436
                        at /buildslave/rust-buildbot/slave/beta-dist-rustc-linux/build/src/libstd/panic.rs:361
                        at /buildslave/rust-buildbot/slave/beta-dist-rustc-linux/build/src/libstd/rt.rs:57
  15:     0x55697b0ac7f2 - main
  16:     0x7f3f95b68f0f - __libc_start_main
  17:     0x55697af718b8 - _start
  18:                0x0 - <unknown>

It looks like in https://github.com/tomaka/vulkano/blob/master/vulkano/src/swapchain/swapchain.rs :285 a semaphore is removed form the pool, but never put back in if acquiring the image fails for any reason.

I don’t know if this is a proper solution, but for messing around on amdgpu+radv, the semaphore can just be put back in:

    pub fn acquire_next_image(&self, timeout: Duration) -> Result<usize, AcquireError> {
        unsafe {
            let stale = self.stale.lock().unwrap();
            if *stale {
                return Err(AcquireError::OutOfDate);
            }

            let vk = self.device.pointers();

            let semaphore = self.semaphores_pool.lock().unwrap().remove(0);

            let timeout_ns = timeout.as_secs().saturating_mul(1_000_000_000)
                                              .saturating_add(timeout.subsec_nanos() as u64);

            let mut out = mem::uninitialized();
            let r = try!(check_errors(vk.AcquireNextImageKHR(self.device.internal_object(),
                                                             self.swapchain, timeout_ns,
                                                             semaphore.internal_object(), 0,     // TODO: timeout
                                                             &mut out)));

            let id = match r {
                Success::Success => out as usize,
                Success::Suboptimal => out as usize,        // TODO: give that info to the user
                Success::NotReady | Success::Timeout => {
                    self.semaphores_pool.lock().unwrap().push(semaphore);
                    return Err(AcquireError::Timeout)
                },
                s => panic!("unexpected success value: {:?}", s)
            };

            let mut images_semaphores = self.images_semaphores.lock().unwrap();
            images_semaphores[id] = Some(semaphore);

            Ok(id)
        }
    }