Skip to content

fix(video): keep a slow movie's pictures and survive Intel's compiler - #2849

Draft
yeetbot90 wants to merge 5 commits into
NotRexed:mainfrom
yeetbot90:fix/windows-movie-and-first-scene
Draft

yeetbot90 wants to merge 5 commits into
NotRexed:mainfrom
yeetbot90:fix/windows-movie-and-first-scene

Conversation

@yeetbot90

@yeetbot90 yeetbot90 commented Nov 12, 2026 •

Copy link
Copy Markdown
Contributor

��What this is for: a Windows PC with Intel UHD Graphics can play the opening movie instead of skipping almost every picture, and can get into the first scene without the process dying inside Intel's compiler. What is measured: game-free checks on Windows, including the movie check run against this branch and against the source from before the movie change. Not measured: the reporter's game was not run again, on that UHD or on any other GPU. No pictures.

This branch is current main (b157c3e8). #2827 is already merged there, so it is not repeated here.

Problem

From one Windows log, build v2.1.0-rc.3-256-g51da0464, Intel UHD Graphics, Vulkan 1.4, driver 0x195bb0 / Intel Corporation 101.7088, 4 logical processors, shaders not prepared at the build.

  • dec_acquire (host/nn_video.c) waits about 100 ms for the first picture, then hands the buffer out black. The first decode took 426.1 ms. The log says the first buffer went out before the first picture was decoded (shown black) twice.
  • The same function, when the picture in hand is late and it is the only one queued, decodes the next packet so it can skip it. The movie clock is the wall clock, so that decode makes the next acquire later. Mean decode was 19.5 ms and pictures are 16.7 ms apart, and 1933 of 2221 pictures were skipped. A decoder that is already faster than the pictures still needs to decode ahead and drop late ones (issues 146 and 179).
  • The linear movie upscale did run (movie upscaling uses the linear compute path). The coop-matrix movie networks stayed left out. That is unchanged.
  • The first 3D scene compiled shaders on the spot (the shaders' preparation was skipped at the build). One submit was slow submit: 109326.6 ms (draw 108018.5 ms, pipelines 7.1 ms). Later: 134.8 draws left out (not ready), skips at vk_draw.cpp 6756 and 6752, 312 pipelines (203441 ms). Those draws are the mesh fallback waiting on compute pipelines. They are not what killed the process.
  • The process then died: CRASH: exception 0xc0000005 (read 0x170, guest 0xfffff00000000170) at igvk64.dll+0x14d102, backtrace igvk64.dll+0x14d102 igvk64.dll+0x134aaf igvk64.dll+0x7f23a igvk64.dll+0x322ef hookshot_vk.dll+0x21d861 hookshot_vk.dll+0x23467d ucrtbase.dll+0x2cd30 KERNEL32.DLL+0x2dda7 ntdll.dll+0x7ee4c. The log has no driver faulted compiling line, so the fault was not inside guarded_graphics or guarded_compute. vkCreateShaderModule and gpl_link's pipeline create were not guarded, and graphics pipelines were still built side by side.
  • Colour stretch of network 0775215f8da720e6 (512x288 -> 1536x864) squares the decoded sqrt values on purpose. That math is unchanged. An unbound storage buffer reported as reading zeros is unchanged.

What changed

  • host/nn_video.c dec_acquire: the first acquire waits ~500 ms for a picture, by the same clock as fix(host): a movie's end no longer waits ~250 ms for a picture that is not coming #2682's later ~100 ms wait. A Stop or Flush with nothing submitted since still does not wait. HOS_VIDEO_ACQUIRE_TRIES=1 is still 50 tries. If the mean decode time is already longer than the gap between pictures, the late picture is shown instead of decoding another one in order to drop it. Pictures already queued are still dropped. HOS_VIDEO_NO_CATCHUP=1 still skips nothing.
  • gpu/vk/vk_internal.h IntelDriverGate: on Windows, vendor 0x8086 only, one thread enters vkCreateShaderModule and vkCreate*Pipelines. RX_VK_NO_INTEL_SERIAL leaves them side by side. NVIDIA, AMD, and Intel on other systems take no lock.
  • guarded_shader_module (gpu/vk/vk_draw.cpp): a fault comes back as result -77 and that program is left out. gpl_link, the movie and upscale helpers, a masked clear's modules, and the compute warm pass call it in this file. make_module and the temporal pipelines call the same functions through extern_guarded_*, because a header declaration of guarded_* itself was a second function and the Windows build rejected every call as ambiguous. A masked clear does not hold the gate across cached_graphics, which takes the same lock.
  • readme.md and docs/development.md say what the movie does now and name RX_VK_NO_INTEL_SERIAL, HOS_VIDEO_NO_CATCHUP and HOS_VIDEO_ACQUIRE_TRIES.

How it was tested

Windows, clang 22.1.5 (x86_64-pc-windows-msvc), 2026-11-12. No game window. Rebased onto main b157c3e8.

  • python -I -B tests/test_video_catchup.py: printed ok. The same test against host/nn_video.c from before this movie change printed FAIL: the first acquire waits ~500 ms for a picture, FAIL: an acquire after the first waits ~100 ms, and FAIL: a decoder slower than the pictures shows the late one instead of decoding in order to skip it, then exited 1. The fast-decoder case still passed on that old source.
  • python -I -B tests/test_vcore_video_acquire.py: printed ok. The first acquire waits ~500 ms, an acquire after that ~100 ms even when a sleep takes 5 ms, and a stopped decoder does not wait.
  • python -I -B tests/test_intel_compiler_gate.py: printed Intel's compiler on Windows is entered by one thread, and a fault leaves that shader out: ok.
  • python -I -B tests/test_shader_module_guard.py: the extracted guarded_shader_module, with a stand-in that raises an access violation after writing a handle, printed a fault creating a shader module leaves that program out: ok.
  • Also passed here after the rebase: test_opening_skip.py, test_driver_faults.py, test_masked_clear_failure.py, test_program_cache_cleanup.py, test_upscale_fallback.py, test_precompile_compute_guard.py.
  • The first Windows build failed: declaring guarded_compute and guarded_shader_module in the header made a second function, and llvm-mingw reported the calls ambiguous. The wrappers are the fix. tests/run_all.py was not run as a whole.

Not tested

  • The reporter's Windows Intel UHD was not run again. Nothing here shows that the opening plays or that the first scene survives on that PC.
  • NVIDIA, AMD, and Linux Intel were not run.
  • A movie whose decoder is faster than the pictures was not played; only the game-free stand-in covers that path.
  • The first visit will still hitch while shaders compile, because preparation was skipped and this GPU has no mesh shaders.

Risks

Overlaps

@yeetbot90
yeetbot90 force-pushed the fix/windows-movie-and-first-scene branch from 395059c to 36f7b20 Compare November 12, 2026 16:45
yeetbot90 and others added 5 commits November 12, 2026 17:47
A decoder slower than the gap between pictures was asked to decode the next one so it could be dropped. The clock gained every decode, and the opening skipped 1933 of 2221 pictures. The first acquire waits about 500 ms, by the same clock as the later 100 ms wait, and a stopped decoder still does not wait.

Co-authored-by: Cursor <cursoragent@cursor.com>
Intel's compiler on Windows was entered by several threads, and vkCreateShaderModule had no guard. A read of address 0x170 in igvk64 ended the process during the first scene. On that driver one thread enters the compiler, and a fault drops the shader instead of the process. Other vendors, and Intel on other systems, are unchanged.

Co-authored-by: Cursor <cursoragent@cursor.com>
Declaring them in the header made a second function beside the ones in the unnamed namespace, so every call in vk_draw.cpp was ambiguous and the Windows build stopped. Other files call the same functions through a wrapper.

Co-authored-by: Cursor <cursoragent@cursor.com>
…a tenth

The stopped-decoder check was still counting a decoder that had already acquired once.

Co-authored-by: Cursor <cursoragent@cursor.com>
…ered one thread at a time

Co-authored-by: Cursor <cursoragent@cursor.com>
@yeetbot90
yeetbot90 force-pushed the fix/windows-movie-and-first-scene branch from 36f7b20 to 285f2b9 Compare November 12, 2026 16:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant