fix(vk): Intel Windows runtime fixes (pipeline cache saves, alpha to coverage) #2456
Open
hckrman101 wants to merge 6 commits from
hckrman101/fix/intel-runtime into main
pull from: hckrman101/fix/intel-runtime
merge into: MagicBeanDev:main
MagicBeanDev:main
MagicBeanDev:github/pr/2893
MagicBeanDev:github/pr/2890
MagicBeanDev:github/pr/2887
MagicBeanDev:github/pr/2878
MagicBeanDev:github/pr/2875
MagicBeanDev:github/pr/2874
MagicBeanDev:github/pr/2873
MagicBeanDev:github/pr/2871
MagicBeanDev:github/pr/2756
MagicBeanDev:github/pr/2897
MagicBeanDev:github/pr/2896
MagicBeanDev:github/pr/2718
MagicBeanDev:github/pr/2842
MagicBeanDev:github/pr/2691
MagicBeanDev:github/pr/2895
MagicBeanDev:github/pr/2743
MagicBeanDev:github/pr/2765
MagicBeanDev:github/pr/2708
MagicBeanDev:github/pr/2732
MagicBeanDev:github/pr/2755
MagicBeanDev:github/pr/2817
MagicBeanDev:github/pr/2876
MagicBeanDev:release-please--branches--main
MagicBeanDev:release-please--branches--main--release-notes
MagicBeanDev:github/pr/2778
MagicBeanDev:github/pr/2888
MagicBeanDev:github/pr/2866
MagicBeanDev:github/pr/2877
MagicBeanDev:github/pr/2800
MagicBeanDev:github/pr/2829
MagicBeanDev:github/pr/2850
MagicBeanDev:github/pr/2889
MagicBeanDev:github/pr/2882
MagicBeanDev:github/pr/2860
MagicBeanDev:github/pr/2849
MagicBeanDev:github/pr/2886
MagicBeanDev:github/pr/2794
MagicBeanDev:github/pr/2840
MagicBeanDev:github/pr/2830
MagicBeanDev:github/pr/2834
MagicBeanDev:github/pr/2719
MagicBeanDev:github/pr/2742
MagicBeanDev:github/pr/2741
MagicBeanDev:github/pr/2820
MagicBeanDev:github/pr/2771
MagicBeanDev:github/pr/2859
MagicBeanDev:github/pr/2858
MagicBeanDev:github/pr/2823
MagicBeanDev:github/pr/2757
MagicBeanDev:github/pr/2769
MagicBeanDev:github/pr/2844
MagicBeanDev:github/pr/2843
MagicBeanDev:github/pr/2673
MagicBeanDev:github/pr/2855
MagicBeanDev:github/pr/2739
MagicBeanDev:github/pr/2807
MagicBeanDev:github/pr/2851
MagicBeanDev:github/pr/2789
MagicBeanDev:github/pr/2814
MagicBeanDev:github/pr/2818
MagicBeanDev:github/pr/2774
MagicBeanDev:github/pr/2772
MagicBeanDev:github/pr/2750
MagicBeanDev:github/pr/2786
MagicBeanDev:github/pr/2785
MagicBeanDev:github/pr/2782
MagicBeanDev:github/pr/2779
MagicBeanDev:github/pr/2775
MagicBeanDev:github/pr/2706
MagicBeanDev:github/pr/2766
MagicBeanDev:github/pr/2747
MagicBeanDev:github/pr/2759
MagicBeanDev:github/pr/2745
MagicBeanDev:github/pr/2740
MagicBeanDev:github/pr/2733
MagicBeanDev:github/pr/2725
MagicBeanDev:github/pr/2727
MagicBeanDev:github/pr/2728
MagicBeanDev:github/pr/2729
MagicBeanDev:github/pr/2721
MagicBeanDev:github/pr/2722
MagicBeanDev:github/pr/2715
MagicBeanDev:github/pr/2714
MagicBeanDev:github/pr/2707
MagicBeanDev:github/pr/2703
MagicBeanDev:github/pr/2705
MagicBeanDev:github/pr/2697
MagicBeanDev:github/pr/2679
MagicBeanDev:github/pr/2676
MagicBeanDev:github/pr/2669
MagicBeanDev:docs/what-hookshot-connects-to
MagicBeanDev:fix/hdr-encode-test
MagicBeanDev:fix/main-tests
MagicBeanDev:fix/play-cache-files
MagicBeanDev:perf/game-barrier-order
MagicBeanDev:feat/heap-lazy
MagicBeanDev:feat/texture-detail
MagicBeanDev:perf/astc-opaque-bc1
MagicBeanDev:fix/fs-dir-lock
MagicBeanDev:fix/framegen-native-kept
MagicBeanDev:fix/update-no-downgrade
MagicBeanDev:port/k10-gcn-f16-mirrors
MagicBeanDev:fix/framegen-mult-cap
MagicBeanDev:chore/release-as-2.1.1
MagicBeanDev:perf/pcache-load-switch
MagicBeanDev:fix/prepare-progress-log
MagicBeanDev:fix/update-closes-stale-game
MagicBeanDev:fix/hdr-scaled-sampled
MagicBeanDev:perf/first-start-preset
MagicBeanDev:perf/zero-upload
MagicBeanDev:fix/vcore-escape-2s
MagicBeanDev:test/fake-gh-atomic
MagicBeanDev:perf/batch-idle-flush
MagicBeanDev:test/finish-stub-a
MagicBeanDev:chore/record-2.1.0
MagicBeanDev:fix/main-red-tests
MagicBeanDev:fix/test-display-startup-driver-cache
MagicBeanDev:feat/mesh-shader-mode
MagicBeanDev:fix/menu-probes-at-startup
MagicBeanDev:fix/fps-counter-classic
MagicBeanDev:fix/test-log-batch-flake
MagicBeanDev:fix/narrow-screen-hud
MagicBeanDev:ci/prereleases
MagicBeanDev:release/v2.0.15
MagicBeanDev:hotfix/v2.0.15
MagicBeanDev:fix/present-ahead-replay
MagicBeanDev:release/v2.0.13
MagicBeanDev:fix/bracket-paths-2013
MagicBeanDev:fix/hdr-overlays-2013
MagicBeanDev:fix/fps-counter-scale-2013
MagicBeanDev:fix/stick-seen-at-rest
MagicBeanDev:hotfix/menu-fits-screen
MagicBeanDev:fix/f1-always-opens-menu
MagicBeanDev:fix/ini-keep-lines
MagicBeanDev:claude/cranky-pike-7cf247
MagicBeanDev:perf/texture-answer-flat
MagicBeanDev:fix/stamp-test-modules
MagicBeanDev:fix/appimage-fonts
MagicBeanDev:fix/display-awake
MagicBeanDev:release/v2.0.12
MagicBeanDev:fix/discord-windows
MagicBeanDev:rc/v2.0.12-tests
MagicBeanDev:fix/dlss-keep-feature
MagicBeanDev:rc/v2.0.12
MagicBeanDev:button-icons
No reviewers
Labels
Clear labels
accessibility
Barrier affecting people with disabilities
autorelease: pending
autorelease: tagged
bug
Something isn't working
dependencies
Pull requests that update a dependency file
documentation
Improvements or additions to documentation
duplicate
This issue or pull request already exists
enhancement
New feature or request
github_actions
Pull requests that update GitHub Actions code
good first issue
Good for newcomers
help wanted
Extra attention is needed
invalid
This doesn't seem right
question
Further information is requested
testing wanted
wontfix
This will not be worked on
No labels
accessibility
autorelease: pending
autorelease: tagged
bug
dependencies
documentation
duplicate
enhancement
github_actions
good first issue
help wanted
invalid
question
testing wanted
wontfix
Milestone
Clear milestone
No items
No milestone
Assignees
Clear assignees
No assignees
2 participants
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".
No due date set.
Dependencies
No dependencies set
Reference
MagicBeanDev/Hookshot!2456
Loading…
Reference in a new issue
No description provided.
Delete branch "hckrman101/fix/intel-runtime"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Intel's Windows driver crashes when the pipeline cache is saved while pipelines are being built, and on Intel's integrated GPUs it draws coloured noise on foliage with dynamic alpha to coverage. This PR works around both, on that driver only. Every other driver, NVIDIA's included, runs exactly as before, and nothing in shader translation changes, so players don't need to prepare shaders again.
What changed
Which workarounds a GPU gets is decided once, from its Vulkan properties, in
gpu/vk/vk_vendor.h. The log prints the result as onevk: vendor fixesline. Each workaround has anRX_VK_switch that forces it on or off on any GPU (listed in docs/development.md).RX_VK_PCACHE_APART=0/1RX_VK_DYN_A2C=0/1(0turns the fix on)igvk64.dllafter the owl intro, and the black screens on Intel. Those rows have no logs yet, so this is not confirmed. An Arc B580 report (discrete) gets the pipeline-cache fix but not the alpha-to-coverage one.RX_VK_GPLstage libraries (opt-in) need alpha to coverage to be dynamic, so they stay off on the GPUs that get the second fix.VK_EXT_vertex_input_dynamic_state.gpu/vk/vk_vendor.h, thevk: vendor fixesblock in vk_main.cpp, its switches row in docs/development.md andtests/test_vendor_fixes.py. Each carries only its own fixes, so either can merge first. Whichever merges second gets a trivial conflict in those four files, resolved by keeping both sets of fields, lines and test rows.Credit
These are reimplementations in Hookshot's own code, not copies. Their authors are credited in the code comments and in the commit.
Verified on NVIDIA (RTX 3090, Linux, driver 620.70.06)
tests/test_vendor_fixes.pygives 15 sets of device properties to the realvendor_fixes(): NVIDIA on Windows and Linux, NVK, AMD's Windows driver in both branches, RADV, AMDVLK, Intel Windows on integrated and Arc, ANV, and llvmpipe.tests/test_pipeline_cache_save.pyhas two new cases.tests/test_pipeline_play_cache.pypasses with the play files' copy inside the gate. It has two new cases. With a compile stuck in a generation, the save returns after its bound without writing it, and a later save writes it once the compile has ended. A play file's copy tries once in play and gets the forced wait at the window's close and with a forced save.tests/test_vendor_fixes.pyalso checks the close path and that only forced copies hold builds back.RX_VK_PCACHE_APART=1 RX_VK_DYN_A2C=0. It drew 2,434 draws a frame with 0 skipped, at ~49 fps headless. The pipeline cache was saved twice during play through the lock, with no stall, fault or lost device. The picture was normal: foliage, ground haze and characters, nothing missing.tests/run_all.pypasses, apart from checks that fail on this PC without the change too (nozstandardortkinterhere).Not tested: please help if you have an Intel GPU on Windows
I have no Intel GPU, so neither fix has been seen working on the hardware it is for. Reports with
hookshot_log.txtare very welcome.igvk64.dllor the black screen go away? The log should saypipeline cache saves apart from builds 1. Is there any new stutter when the cache is saved during play? A save that had to wait logs "save put off".RX_VK_DYN_A2C=1.I will try to build the pr #2456 and will report back. I'm using the Intel Arc 7 cores + Intel Core Ultra 5 125h and there are a lot of issues. Managed to get to in game and saved the game but now it always crashes from that point. I have to use an older driver ( 31.0.101.5334 ), thats the only one that works.
Read through the whole change. The gating looks right to me: every build that takes a cache goes through
apart_graphics/apart_compute(no nested shared lock, sincecreate_cachedcallscreateone at a time), everyvkGetPipelineCacheDataafter start-up is inside the gate, the gate only ever usestry_lock, so a stuck compile can't wedge a writer-preferringshared_mutex, and the SEH-caught driver faults return throughapart_*, so the shared lock is always released. On non-Intel drivers bothcache_use_beginandcache_copy_beginreturn before touching the lock, so NVIDIA/AMD behave exactly as before. The static A2C side is also sound: the feature bit is cleared beforevkCreateDevice, and witheds3_a2cfalse the pipeline key,alphaToCoverageEnableand the dynamic-state list already handle it, andgpl_wanteddrops GPL as described. Bounding the old unboundedusersdrain inplay_cache_saveis a nice side fix too.CI is green and the branch merges cleanly with main.
Two things worth a look, neither blocking:
play_file_writealways useskCopyWaitStart, and it runs on the save thread during play. While it waits,copy_pendingmakes every new build wait up to 1 s incache_use_begin, and that includes the build a draw is waiting on. So on Intel a long compile in flight can cost a visible hitch of up to 1 s at a save point. The description says "A save during play tries once", which only holds for pcache. Maybe a single try for play files in play too (the generation is kept and retried anyway), or skip the hold-back when the copy's own wait is short? At least worth asking Intel testers to watch for it, as the description already does.pipeline_cache_close->play_cache_save), the play file also only gets 2 s, not the 30 s a forced save gets. If builds are still running then, this run's last generation is dropped. It's minor (it gets recompiled next run), but it doesn't quite match the description's "a forced save (exit ...) tries for up to 30 s".Nit:
create_devicenow queriesVkPhysicalDeviceDriverPropertiestwice (the new block and the subgroup block, which setsdev.driver_id). One query could feed both.@Andrade2244, thanks for offering to test. Your Core Ultra 5 125H (Meteor Lake Arc Graphics) is reported as integrated, so it should get both fixes. If you can, please attach
hookshot_log.txtfrom a run on the current driver. Thevk: vendor fixesline will show what was applied, and the log should also show whether the crash after your save is still theigvk64.dllone.This runs in play too (from the save thread via
play_cache_save), so play files get the 2 s wait plus thecopy_pendinghold-back on builds, unlike pcache's single try in play. See point 1 in the review body.This hold-back also applies to the replay thread's draw-time builds. If an in-flight compile keeps the copy waiting, a draw can stall here for up to 1 s. That's bounded and Intel-only, but it might show up as a hitch at save points.
@hckrman101 Glad to help. I will attach the log.
The logs on the latest release version showed "VK_ERROR_DEVICE_LOST" crash. I had a igvk64.dll related crash on the latest drivers (32.0.101.9175) but it was even before reaching the main menu. For some reason, on this setup, the only drivers that seem to work when using vulkan are the ones i have mentioned ( for other games/ports as well ).
I've tested the build and attached the log. It still crashes in the igvk64.dll. It dosent crash immediately like the latest release build tho. Its possible to run it for a while until it eventually crashes.

hookshot_log.2.txt
I'm investigating a related memory peak from #2206:
pcache_file_read,play_file_writeand full base-cache saves still allocate whole-cache vectors. Is anyone already covering file-backed mapped I/O for these paths?The scope would preserve the warm cache, existing file format, play-generation policy and atomic replacement. Your bounded Intel copy/build separation would remain authoritative: prepare the file view before the copy lock, keep the lock around the driver copy, then flush/publish after release. Page faults and flush costs need measurement; mapping alone is not a speedup claim. No production edits yet.
github-sync referenced this pull request2026-11-12 11:36:09 +00:00
Test request T-4RXC: mixed (the crash is gone; rendering on this iGPU is still unreliable)
Hardware: Intel UHD Graphics 770 (the i9-12900K's iGPU,
RX_VK_DEVICE=1; mesh shaders no), Intel driver 32.0.101.7088 (101.7088in the log), 64 GB RAM, Windows 11. An RTX 3080 is device 0 and drives the display. Builtef1ec66c(the PR head) and main51da0464, both standalone from source with llvm-mingw, default options, 1280x720 window.What I checked: whether the
igvk64.dllcrash goes away, and the foliage with and without the alpha-to-coverage fix. Each run: load the same save (adult, Kakariko), press A into play, teleport to Kokiri Forest, wait 60 s, take threehookshot_ctl.py shots 10 s apart, thenhookshot_ctl.py quit. Runs alternated main and PR.RX_VK_DYN_A2C=1All four main crashes are the same in the Windows event log:
The game's log just stops, with no message.
On the PR the log names the fix, and each run put off 2 to 4 saves at exactly the moments that would have overlapped builds:
With
RX_VK_DYN_A2C=1the line readsstatic alpha to coverage 0. Main's crashes all came in the minutes when pipelines were being built for this GPU (first visits), which fits the description's cause. I did not catch a crash inside a save itself.Pictures (from
shot; I can't attach images from here, so these are descriptions; ask if you want the PNGs):Kakariko, 10 s into play: normal on both main and the PR.
Kokiri Forest, PR (static alpha to coverage), two runs:
Kokiri Forest, PR with
RX_VK_DYN_A2C=1, one run:So on this UHD 770 and driver, in the one place I looked, I could not reproduce the noise the static setting is meant to clear, and the static setting looked coarser. One run each, so that is weak evidence.
In 2 of the 4 PR runs (the first two after building), the picture was badly wrong for the whole minute:
PR 3 and the
RX_VK_DYN_A2C=1run in the same places looked normal. Main crashed before it got that far, so I can't say whether this comes from the PR. It is more likely the Intel driver's first pipeline builds on this GPU, or the worklist's "Entire world is broken" Intel report, but that is a guess.Speed, for scale: 6.9-17.5 fps in Kokiri at 1280x720.
Not tested: Arc (discrete), Iris Xe, a forced save at window close while a build is stuck, and long play. Worklist: the
igvk64.dllaccess violation row (0.11, an i3-1115G4 UHD report) now has a reproduction with a log on a UHD 770, 4 of 4 on main.Follow-up to T-4RXC above: six more runs of the PR head
ef1ec66con the same UHD 770, the same route (Kakariko save, teleport to Kokiri Forest, three shots, quit).igvk64.dll+0x14d102. Each run still logs 2 put-off saves.hookshot_programs.bin,hookshot_pipelines.bin,hookshot_pipeline_states.bin,hookshot_computes.bin,mkw_vk_pipelines*.bin; the log shows0 program keys keptandpipeline cache ... (0 KB)). All six drew Kakariko and Kokiri normally, the same as the third run above.not translated: a network left out on this cardlines are in every run. Main can't be compared, because it crashes first. I'd treat it as a separate, intermittent Intel problem, not as something this PR causes; but it's unexplained.The pipeline-cache half now has evidence: dankman42's UHD 770 crashed in
igvk64.dll4 of 4 times on main and 0 of 10 on this head, with saves put off exactly where builds overlapped.0edc360calso covers the play-file waits raised in review.It conflicts with main in
gpu/vk/vk_main.cpponly: main addeddev.radv_gcn = drv.driverID == ...in the subgroup block, where this PR drops thedrvquery. Resolving it withdev.driver_idmakestests/test_fallback_size_policy.pyfail, since it looks for that exact line, so the rebase needs that test updated. With that,test_vendor_fixes.py,test_pipeline_cache_save.py,test_pipeline_play_cache.pyandtest_env_on.pypass.Static alpha to coverage is less clear. On the UHD 770 the noise didn't show with dynamic A2C either, and static A2C drew grass as coarse, blocky clumps, while
RX_VK_DYN_A2C=1looked finer. One GPU and one place, but the only report. I'd ship the cache fix and hold static A2C until an Iris Xe or Meteor Lake report shows the noise going away, or split it out.