Commit b762cd1
committed
GFX/FONT: Route font_driver_free through video thread when threaded video active
font_driver_free calls renderer->free (e.g. d3d12_font_free,
gl2_raster_font_free, d3d11_font_free) directly on the calling
thread. Menu drivers call this from context_destroy or
context_reset_internal on the main thread, while the video
thread is still rendering frames.
This produces driver-specific races:
GL1/GL2/GL3: The GL context can only be current on one
thread. gl2_raster_font_free calls make_current(true) to
steal the context from the video thread, then calls
glDeleteTextures. If the video thread is mid-frame, its
subsequent GL calls are invalid until context is restored.
D3D11: The ImmediateContext is explicitly not thread-safe
per Microsoft's docs. d3d11_font_free calls Release on
the font texture's COM objects while the video thread draws
with the same context — undefined behaviour.
D3D10: Same as D3D11, though slightly less severe because
D3D10's device has an internal mutex. Release still races
with pending GPU draws.
D3D12: d3d12_font_free uses a GPU fence wait with
++fenceValue. The non-atomic increment from the main
thread races with the video thread's own fence signalling,
potentially skipping or duplicating fence values.
Vulkan: vulkan_destroy_texture (called from font free) uses
vkQueueWaitIdle under queue_lock, which drains submitted
work but not command buffers currently being recorded on the
video thread.
Metal: Blit command buffer access can race (same as texture
load). However, font glyph textures in the Metal driver use
replaceRegion: (thread-safe) rather than the blit command
encoder, so this is lower risk.
Fix: in font_driver_free, when threaded video is active,
dispatch the renderer->free call to the video thread via
video_thread_texture_handle. This serialises the font
resource destruction with the video thread's frame rendering,
the same pattern used for texture load/unload.
This is a single-point fix in font_driver.c that covers ALL
video driver backends at once, rather than patching each
driver's font_free individually. The font_driver_free
function is the natural place for this because it already
checks is_threaded and is the single entry point for all font
destruction.
Implementation:
- font_free_cmd_t packages the renderer pointer, renderer_data,
and is_threaded flag.
- font_driver_free_wrap is the CMD_CUSTOM_COMMAND callback.
Calls renderer->free on the video thread.
- When is_threaded is true and renderer->free exists, dispatch
via video_thread_texture_handle. The font_data_t struct
itself (renderer/renderer_data pointers + malloc'd memory)
is cleaned up on the main thread after the dispatch returns
-- only the GPU-touching renderer->free needs serialisation.
- video_thread_texture_handle is self-safe (falls back to
direct call when the wrapper is not active, and handles
same-thread calls without deadlock).
- Non-threaded path is unchanged.
This fixes the mid-session font scale change crash on D3D12
that was previously only mitigated by XMB's
pending_context_reset counter. It also eliminates the GL
context-stealing race in gl2_raster_font_free.
Depends on: 8d55232 (VIDEO/THREAD: barrier + wrapper
hardening).
No behavioural change on non-threaded video.1 parent ee3eae3 commit b762cd1
1 file changed
Lines changed: 60 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
901 | 901 | | |
902 | 902 | | |
903 | 903 | | |
| 904 | + | |
| 905 | + | |
| 906 | + | |
| 907 | + | |
| 908 | + | |
| 909 | + | |
| 910 | + | |
| 911 | + | |
| 912 | + | |
| 913 | + | |
| 914 | + | |
| 915 | + | |
| 916 | + | |
| 917 | + | |
| 918 | + | |
| 919 | + | |
| 920 | + | |
904 | 921 | | |
905 | 922 | | |
906 | 923 | | |
| |||
913 | 930 | | |
914 | 931 | | |
915 | 932 | | |
| 933 | + | |
| 934 | + | |
| 935 | + | |
| 936 | + | |
| 937 | + | |
| 938 | + | |
| 939 | + | |
| 940 | + | |
| 941 | + | |
| 942 | + | |
| 943 | + | |
| 944 | + | |
| 945 | + | |
| 946 | + | |
| 947 | + | |
| 948 | + | |
| 949 | + | |
| 950 | + | |
| 951 | + | |
| 952 | + | |
| 953 | + | |
| 954 | + | |
| 955 | + | |
| 956 | + | |
| 957 | + | |
| 958 | + | |
| 959 | + | |
| 960 | + | |
| 961 | + | |
| 962 | + | |
| 963 | + | |
| 964 | + | |
| 965 | + | |
| 966 | + | |
| 967 | + | |
| 968 | + | |
| 969 | + | |
| 970 | + | |
| 971 | + | |
| 972 | + | |
| 973 | + | |
| 974 | + | |
| 975 | + | |
916 | 976 | | |
917 | 977 | | |
918 | 978 | | |
| |||
0 commit comments