winit event loop suppressing Vulkan validation output at shutdown

Viewed 191

Lately, I have been following the classic Vulkan tutorial and have successfully enabled the validation layer features and loaded the VK_EXT_debug_utils extension. I confirmed the latter when I forced an error during the instance creation and my registered callback was invoked as expected. Finally I wanted to test the error detection during cleanup and followed the suggestion of the tutorial to comment out destroying the debug utils messenger handle. To my surprise no errors have been reported.

Eventually I was able to track this issue down to winit and the run method. The way that method hijacks the main thread apparently makes it impossible for the Vulkan debug utils to report any diagnostics at shutdown. For testing purposes I replaced the call to EventLoop::run with EventLoop::run_return which returns the control flow. With the latter I got the expected error message about the extension leak when the application exits.

I'd like to know how I may reconcile the use of the EventLoop::run method with the debug utils.

1 Answers

After further trial and error and looking through the documentation I finally found a fix for this issue which is still baffling me due to its awful behavior with regards to the implementation details of winit.

The documentation for the EventLoop::run method mentions that

Any values not passed to this function will not be dropped.

This means that the struct I wrapped the method call in is not getting dropped and thus the Vulkan instance wasn't destroyed and therefore the debug utils weren't triggered whatsoever.

Since my event loop is currently pretty concise as it does not contain anything yet I had to pass self into the closure as follows:

fn run(mut self) {
    self.event_loop
        .take()
        .unwrap()
        .run(move |event, _, control_flow| {
            *control_flow = ControlFlow::Poll;

            let Self { .. } = self;

            match event {
                Event::WindowEvent {
                    event: WindowEvent::CloseRequested,
                    ..
                } => *control_flow = ControlFlow::Exit,
                _ => (),
            }
        });
}
Related