Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

If semaphore is not VK_NULL_HANDLE it must be unsignaled #2229

Open
jimmieW opened this issue Jun 15, 2023 · 4 comments
Open

If semaphore is not VK_NULL_HANDLE it must be unsignaled #2229

jimmieW opened this issue Jun 15, 2023 · 4 comments

Comments

@jimmieW
Copy link

jimmieW commented Jun 15, 2023

Vulkano version: 0.33
OS: windows 11
Device: Intel(R) UHD Graphics (type: IntegratedGpu)
Driver: Intel Corporation - Intel driver - 1656188
Vulkan:
Api version: 1.2.204
Enabled layers: ["VK_LAYER_KHRONOS_validation"]

We are currently testing our Vulkano based system on Intel GPUs and we have have been experiencing some issues that I was hoping someone in the community could help us shed some light on.

Basically we are seeing issues like this:

Failed to flush future: ResourceAccessError { error: AlreadyInUse, use_ref: Some(ResourceUseRef { command_index: 0, command_name: "begin_render_pass", resource_in_command: FramebufferAttachment { index: 2 }, secondary_use_ref: None }) }

Validation Error: [ VUID-vkAcquireNextImageKHR-semaphore-01286 ] Object 0: handle = 0x1395ad0000004261, type = VK_OBJECT_TYPE_SEMAPHORE; | MessageID = 0xe9e4b2a9 | vkAcquireNextImageKHR: Semaphore must not be currently signaled. The Vulkan spec states: If semaphore is not VK_NULL_HANDLE it must be unsignaled (https://vulkan.lunarg.com/doc/view/1.3.243.0/windows/1.3-extensions/vkspec.html#VUID-vkAcquireNextImageKHR-semaphore-01286)

After going a bit deeper I saw that we are allocating a new Semaphore from a pool.

swapchain.rs

pub fn acquire_next_image(
    swapchain: Arc<Swapchain>,
    timeout: Option<Duration>,
) -> Result<(u32, bool, SwapchainAcquireFuture), AcquireError> {
    let semaphore = Arc::new(Semaphore::from_pool(swapchain.device.clone())?);
    let fence = Fence::from_pool(swapchain.device.clone())?;

It is then given back to the pool on Drop.

Now, if I remove the usage of the pool the error disappears. Basically I make sure we use:

must_put_in_pool: false

This leads me to believe that either:

  • The semaphore is signaled when it re-enters the pool.
    Or
  • The semaphore is signaled after it has re-entered the pool.

I understand it might be hard to reason about this without a repro, but maybe you can verify that a semphore has a "clean state" when re-entering the pool somehow?

Oh and finally, thanks for the hard work you put into this API!

@Rua
Copy link
Contributor

Rua commented Jun 15, 2023

There is unfortunately no way to check the state of a semaphore, nor is there a way to make it be in a particular state. All Vulkano can do is ensure that the semaphores have been signalled and waited before putting them back in the pool. That seems to have gone wrong here.

@jimmieW
Copy link
Author

jimmieW commented Jun 15, 2023

Thanks for replying so fast!

The Semphore struct seems to have the necessary information to forbid it from going back to the pool if it for instance is waiting to be signaled:

#[derive(Debug)]
pub struct Semaphore {
    handle: ash::vk::Semaphore,
    device: Arc<Device>,
    id: NonZeroU64,
    must_put_in_pool: bool,

    export_handle_types: ExternalSemaphoreHandleTypes,

    state: Mutex<SemaphoreState>,
}

#[derive(Debug, Default)]
pub(crate) struct SemaphoreState {
    is_signaled: bool,
    pending_signal: Option<SignalType>,
    pending_wait: Option<Weak<Queue>>,

    reference_exported: bool,
    exported_handle_types: ExternalSemaphoreHandleTypes,
    current_import: Option<ImportType>,
    permanent_import: Option<ExternalSemaphoreHandleType>,
}

But maybe that should be handled before Drop(..) is called.. That is Drop(..) should not be called if we are waiting for it to be signaled.

It seems to me that the necessary information is there to protect against the Vulkan error I am seeing, but I might be wrong. :)

@Rua
Copy link
Contributor

Rua commented Jun 15, 2023

You can't prevent drop from being called. It happens automatically when there are no more references to the object.

@Rua
Copy link
Contributor

Rua commented Jun 15, 2023

As far as I can tell, the validation layer error is a direct result of the ResourceAccessError that comes before it. I suspect that because that error is returned, some things that should have been used are discarded instead, including that semaphore.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants