[mtl surface] fix crash on exit when metal GPU frame capture is enabled. Apparently, if we release resources (on exit) before all GPU work is completed, libMetalCapture crashes on bad access. To work around that, in mg_mtl_surface_destroy(), we enqueue a last (empty) command buffer and call waitUntilCompleted on it, to ensure all previous command buffers are also completed
This commit is contained in:
parent
5ce53001e2
commit
0c74e997ae
|
@ -103,7 +103,7 @@ void mg_mtl_canvas_begin(mg_canvas_backend* interface, mg_color clearColor)
|
||||||
}
|
}
|
||||||
@autoreleasepool
|
@autoreleasepool
|
||||||
{
|
{
|
||||||
if(surface->commandBuffer == nil || surface->commandBuffer == nil)
|
if(surface->commandBuffer == nil)
|
||||||
{
|
{
|
||||||
mg_mtl_surface_acquire_drawable_and_command_buffer(surface);
|
mg_mtl_surface_acquire_drawable_and_command_buffer(surface);
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,6 +42,13 @@ void mg_mtl_surface_destroy(mg_surface_data* interface)
|
||||||
|
|
||||||
@autoreleasepool
|
@autoreleasepool
|
||||||
{
|
{
|
||||||
|
//NOTE: when GPU frame capture is enabled, if we release resources before all work is completed,
|
||||||
|
// libMetalCapture crashes... the following hack avoids this crash by enqueuing a last (empty)
|
||||||
|
// command buffer and waiting for it to complete, ensuring all previous buffers have completed
|
||||||
|
id<MTLCommandBuffer> endBuffer = [surface->commandQueue commandBuffer];
|
||||||
|
[endBuffer commit];
|
||||||
|
[endBuffer waitUntilCompleted];
|
||||||
|
|
||||||
[surface->commandQueue release];
|
[surface->commandQueue release];
|
||||||
[surface->mtlLayer removeFromSuperlayer];
|
[surface->mtlLayer removeFromSuperlayer];
|
||||||
[surface->mtlLayer release];
|
[surface->mtlLayer release];
|
||||||
|
@ -107,13 +114,14 @@ void mg_mtl_surface_present(mg_surface_data* interface)
|
||||||
//NOTE(martin): present drawable and commit command buffer
|
//NOTE(martin): present drawable and commit command buffer
|
||||||
[surface->commandBuffer presentDrawable: surface->drawable];
|
[surface->commandBuffer presentDrawable: surface->drawable];
|
||||||
[surface->commandBuffer commit];
|
[surface->commandBuffer commit];
|
||||||
[surface->commandBuffer waitUntilCompleted];
|
// [surface->commandBuffer waitUntilCompleted];
|
||||||
|
|
||||||
//NOTE(martin): acquire next frame resources
|
//TODO: do we really need this?
|
||||||
[surface->commandBuffer release];
|
|
||||||
surface->commandBuffer = nil;
|
|
||||||
[surface->drawable release];
|
[surface->drawable release];
|
||||||
surface->drawable = nil;
|
surface->drawable = nil;
|
||||||
|
|
||||||
|
[surface->commandBuffer release];
|
||||||
|
surface->commandBuffer = nil;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue