Commit cc9e947
committed
METAL: Route texture load through video thread when threaded video active
The Metal driver had a narrow threading issue when used with the
threaded video wrapper. Unlike the other graphics APIs where
both load and unload have races, Metal's case is specifically
about the shared blit command buffer used during mipmapped
texture creation.
The race
========
When metal_load_texture is called with a TEXTURE_FILTER_MIPMAP_*
filter, the execution path reaches:
- [self newTexture:image mipmapped:YES] in metal_renderer.m
- which creates an MTLTexture (thread-safe on MTLDevice)
- calls replaceRegion: (thread-safe)
- accesses self.blitCommandBuffer (a lazily-created
MTLCommandBuffer stored on the shared Context instance)
- encodes mipmap generation via [cb blitCommandEncoder]
MTLCommandBuffer and MTLCommandEncoder are documented as
single-thread-only. The blit command buffer is committed and
nulled at frame end, on the video thread:
- (void)end { ... [_blitCommandBuffer commit];
_blitCommandBuffer = nil; ... }
If the main thread calls metal_load_texture mid-frame and
encodes mipmap commands on the same blit command buffer that
the video thread is about to commit, this is undefined
behaviour per Apple's Metal threading rules.
Other Metal paths are already safe
==================================
Most of the Metal driver operations are fine:
- [_device newTextureWithDescriptor:] is thread-safe
- [texture replaceRegion:] is thread-safe and synchronous
- metal_unload_texture releases an ARC-retained handle; Metal
command buffers retain their referenced resources, so the
underlying MTLTexture stays alive until the GPU is done.
No cross-thread race on unload (unlike D3D12/Vulkan where
command buffers don't refcount resources).
The only remaining race is the blit command buffer sharing
during mipmapped load.
The fix
=======
Route metal_load_texture through video_thread_texture_handle
when threaded video is active, matching the pattern established
in the D3D10/11/12 and Vulkan patches. This serialises all
Context.blitCommandBuffer access on the video thread.
Implementation:
- Split metal_load_texture into an internal function that does
the actual texture creation, and an outer function that
dispatches.
- metal_texture_cmd_t carries video_data (as void* to avoid
ARC issues with Obj-C refs in C structs), image, filter_type,
and handle (output).
- Handle is passed back via cmd->handle rather than the int
return channel of custom_command_method_t to avoid truncation
on 64-bit Apple platforms.
- The dispatch happens unconditionally for any threaded load,
not just mipmapped ones -- consistent with other drivers and
avoids branching on filter type.
- metal_unload_texture is left unchanged (ARC refcounting is
sufficient).
Depends on: 8d55232 (VIDEO/THREAD: barrier + wrapper hardening),
which hardens video_thread_texture_handle to be safe when the
wrapper is inactive.
Cost: texture load now blocks briefly while the video thread
processes the dispatched command. Texture loads happen during
menu navigation, not frame-critical paths, so latency is
imperceptible.
No behavioural change on non-threaded video.1 parent 0306e17 commit cc9e947
1 file changed
Lines changed: 73 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
49 | 49 | | |
50 | 50 | | |
51 | 51 | | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
52 | 55 | | |
53 | 56 | | |
54 | 57 | | |
| |||
2568 | 2571 | | |
2569 | 2572 | | |
2570 | 2573 | | |
2571 | | - | |
2572 | | - | |
| 2574 | + | |
| 2575 | + | |
| 2576 | + | |
| 2577 | + | |
| 2578 | + | |
| 2579 | + | |
| 2580 | + | |
| 2581 | + | |
| 2582 | + | |
| 2583 | + | |
| 2584 | + | |
| 2585 | + | |
| 2586 | + | |
| 2587 | + | |
| 2588 | + | |
| 2589 | + | |
| 2590 | + | |
| 2591 | + | |
| 2592 | + | |
| 2593 | + | |
| 2594 | + | |
| 2595 | + | |
| 2596 | + | |
| 2597 | + | |
| 2598 | + | |
2573 | 2599 | | |
2574 | 2600 | | |
2575 | 2601 | | |
| |||
2581 | 2607 | | |
2582 | 2608 | | |
2583 | 2609 | | |
| 2610 | + | |
| 2611 | + | |
| 2612 | + | |
| 2613 | + | |
| 2614 | + | |
| 2615 | + | |
| 2616 | + | |
| 2617 | + | |
| 2618 | + | |
| 2619 | + | |
| 2620 | + | |
| 2621 | + | |
| 2622 | + | |
| 2623 | + | |
| 2624 | + | |
| 2625 | + | |
| 2626 | + | |
| 2627 | + | |
| 2628 | + | |
| 2629 | + | |
| 2630 | + | |
| 2631 | + | |
| 2632 | + | |
| 2633 | + | |
| 2634 | + | |
| 2635 | + | |
| 2636 | + | |
| 2637 | + | |
| 2638 | + | |
| 2639 | + | |
| 2640 | + | |
| 2641 | + | |
| 2642 | + | |
| 2643 | + | |
| 2644 | + | |
| 2645 | + | |
| 2646 | + | |
| 2647 | + | |
| 2648 | + | |
2584 | 2649 | | |
2585 | 2650 | | |
2586 | 2651 | | |
2587 | 2652 | | |
2588 | 2653 | | |
| 2654 | + | |
| 2655 | + | |
| 2656 | + | |
| 2657 | + | |
| 2658 | + | |
| 2659 | + | |
2589 | 2660 | | |
2590 | 2661 | | |
2591 | 2662 | | |
| |||
0 commit comments