hakolao / egui_winit_vulkano

Egui gui integration with winit and vulkano
Apache License 2.0
78 stars 36 forks source link

Failed to signal fence and flush on draw_on_image #66

Open RA3236 opened 5 months ago

RA3236 commented 5 months ago
Failed to signal fence and flush: a validation error occurred

Caused by:
    access to a resource has been denied (resource use: Some(ResourceUseRef { command_index: 0, command_name: "begin_rendering", resource_in_command: DepthStencilAttachment, secondary_use_ref: None }), error: the resource is already in use, and there is no tracking of concurrent usages)

I’m not so clear on why this happens, but this is fixed by heading to line 671 (line 673 for #53) in renderer.rs and replacing:

let future =
        after_main_cb.then_signal_fence_and_flush().expect("Failed to signal fence and flush");
// Return our future
Box::new(future)

with

Box::new(after_main_cb)

i.e. not signalling and flushing. I'm not enough of a Vulkan expert to understand why this works - I think it has something to do with how the swapchain is set up. I don't know if this happens on the main branch here, but it definitely occurs on #53, and there aren't code changes that would suggest otherwise.

My submission code is as follows:

let buffer = command_buffer.end()?;
let future = self
    .previous_frame_end
    .take()
    .unwrap()
    .join(self.acquire_future.take().unwrap())
    .then_execute(self.queue.clone(), buffer)?;
let future = self.gui.draw_on_image(future, self.egui_image_views[self.image_index as usize].clone())
    .then_swapchain_present(
        self.queue.clone(),
        SwapchainPresentInfo::swapchain_image_index(
            self.swapchain.clone(),
            self.image_index,
        ),
    )
    .then_signal_fence_and_flush();

match future {
    Ok(future) => {
        info!("Frame submitted successfully");
        self.previous_frame_end = Some(future.boxed());
    }
    Err(Validated::Error(VulkanError::OutOfDate)) => {
        info!("Swapchain out of date");
        self.recreate_swapchain = true;
        self.previous_frame_end = Some(vulkano::sync::now(self.device.clone()).boxed());
    }
    Err(e) => {
        error!("Failed to flush future: {:?}", e);
        self.previous_frame_end = Some(vulkano::sync::now(self.device.clone()).boxed());
    }
}
hakolao commented 5 months ago

It should be better to let the user control then_signal_fence_and_flush, and to get rid of that line. I don't think it's needed anymore, or if it ever was...

I'm also not sure what goes wrong in the synchronization, and would probably need more debugging.

hakolao commented 5 months ago

67 implementing the fix...