Skip to content

PR684 - Intel GPU crash fixes, fixed overexposed image on intel, pipeline cache crash mitigation for intel GPUs - #754

Merged
kraibse merged 7 commits into
nx2-experimentalfrom
pr684
Nov 7, 2026
Merged

kraibse merged 7 commits into
nx2-experimentalfrom
pr684

Conversation

@kraibse

@kraibse kraibse commented Nov 7, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Intel Arc dGPUs lost the device soon after boot in Mario Kart World, and also showed banding and crashed on shutdown. This PR fixes those.

  • Task shaders: payload word 1 was never set, so a task that culls all its threads launched a garbage number of mesh workgroups. It is now zeroed at the start of the task program, followed by a barrier, as the mesh prologue already does.
  • Banding: shaders that lost a conditional barrier raced on Intel's Windows driver. Those shaders now require the guest warp size (32). This is a workaround, not a real barrier. Shader::Info::UsesWarpOps() holds the warp-op condition so compute and graphics can't drift apart.
  • Pipeline cache: Intel's Windows driver crashes in vkGetPipelineCacheData while pipelines build. The periodic flush is skipped, and queued builds are dropped and running ones drained before the final save, on that driver only.
  • Shutdown: the state tracker kept a stale pointer to the channel's dirty flags. ClearChannel() resets it when the bound channel is released and when the rasterizer is destroyed.
  • Mesh/task subgroup size: applies vulkan: Fix shaders that assume 32 wide warps when running on hardware with natively 16 wide warps like Intel #745's change (graphics mesh and task stages that use warp ops require the guest warp size). It uses the shared helper, so shaders that lost a conditional barrier are covered there too.

Vendor reach

Change Applies to
Subgroup-32 for lost conditional barriers Intel proprietary Windows only. The pass that sets the flag only runs there.
Pipeline cache flush skip and drain Intel proprietary Windows only.
Task payload zero plus barrier All vendors.
ClearChannel() All vendors.
Mesh/task required subgroup size (#745) Where requiredSubgroupSizeStages includes the stage: ANV, RADV on GFX10+, others per driver.

Checked against Mesa (ANV, RADV) and the Vulkan spec. ANV reports subgroup sizes 8 to 32 and lists compute, task and mesh as required-size stages. RADV on GFX10+ reports 32 to 64 and accepts 32 or 64.

#541 sets supports_conditional_barriers = true. On my A770 keeping those barriers on Windows causes device loss. I am not doing that here and will revisit it separately.

Assisted-by: Claude Opus 5.5 (debugging, code, testing, review)

Type of change

  • Bug fix
  • Game compatibility / game-support
  • Performance
  • New feature
  • Refactor / cleanup
  • CI / build
  • Documentation

Testing

  • Tested on Windows
  • Tested on Linux
  • Tested on macOS
  • Tested on NVIDIA
  • Tested on AMD (9600X iGPU)
  • Tested on Intel (Arc A770 16gb)

Cross-testing on NVIDIA/Linux, Intel/Linux and AMD/Linux is in progress. Results will be posted here. The change most worth watching on other vendors is the task prologue.

Games tested:

Mario Kart World 1.8.0: no more crash on startup or banding
Donkey Kong Bananza 3.2.0: black screen with these changes and with the stock build

Checklist

  • I built it locally and it compiles without new warnings
  • I did not add any copyrighted game data, keys or firmware
  • Docs updated if needed
  • I added AI Disclosure if one was used

Related to #130, #706, #66, #745

Fix these before you post it:

Summary by CodeRabbit

  • Bug Fixes
    • Improved Vulkan pipeline handling for task and mesh shaders that use warp-wide operations, helping ensure shader stages run with compatible execution settings.
    • Improved pipeline-cache handling on systems where the graphics driver cannot safely read the cache while builds are in progress.
    • Improved cleanup of queued work and graphics state when channels are released, reducing the risk of stale work or state being reused.
    • Added safer handling for shader barriers in conditional control flow.

Before these changes, intel dGPU device loss would occur soon after
boot. These changes also fix several intel dGPU crashes and banding.

Task shaders: payload word 1 was never set which caused Intel device
loss. Now zeroed at start, followed by a barrier.
Banding: shaders that previously lost a conditional barrier raced on
Intel dGPU, those shaders are now forced to subgroup size 32.
Pipeline cache: Intel driver crashed when cache was read during pipeline
builds. Flush is now skipped for the driver.
Closing the game: state tracker kept stale pointer to channel state
which crashed on shutdown. ClearChannel() resets it.

Size 32 is a workaround, not a real barrier

Tested A770, driver 32.0.101.9150, Windows, MKW

Assisted-by: Claude Opus 5.5 (debugging, code, testing)
Pipeline Cache now waits for shader build workers before saving cache on
drivers where CanReadPipelineCacheDuringBuilds() is false.

Tested on A770, MKW. Closing during shader builds closed cleanly.

Assisted-by: Claude Opus 5.5 (debugging, code, testing)
New ClearRequests() in ThreadWorker, close waits only for running builds

Tested A770, MKW, closing during shader builds

Assisted-by: Claude Opus 5.5 (debugging, code, testing)
Info::UsesWarpOps() replaces the copy in the compute pipeline so graphics
mesh/task stages can use the same condition, including shaders that lost a
conditional barrier.
Graphics pipelines built the required-subgroup-size struct but never attached it (it was [[maybe_unused]]). Compute pipelines already require 32 when they use warp ops. Mainly applies to intel, because there we have 16-wide pipelines.
Foliage rendered as glowing white on Intel ANV. Its leaf mesh shaders compact visible leaves with Ballot + BitCount(ballot & LtMask). ANV compiled the large colour-pass shader 16-wide, so the two halves of each workgroup wrote the same slots, while the small pre-pass shader ran 32-wide. The colour pass then failed its depth-EQUAL test against the pre-pass, and the sky showed through.

Signed-off-by: Andreas Heider <andreas@heider.io>
Assisted-by: Claude Opus 5.5 (debugging with RenderDoc, fix)
Shaders that lost a conditional barrier now get the guest warp size on
mesh and task stages too, matching compute.
@github-actions
github-actions Bot changed the base branch from nx2 to nx2-experimental November 7, 2026 16:17
@github-actions

github-actions Bot commented Nov 7, 2026

Copy link
Copy Markdown

Retargeted to nx2-experimental for pre-build testing. It will be promoted to nx2 after validation.

@coderabbitai

coderabbitai Bot commented Nov 7, 2026

Copy link
Copy Markdown
Contributor

Explain Change →

Note

CodeRabbit ASCII loading animation

Currently processing new changes in this PR. This may take a few minutes, please wait...

Review info

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 5b690628-a4a0-4282-b571-4f22d7757d90
Commits

Reviewing files that changed from the base of the PR and between aff8b25 and 0e82056.

Files selected for processing: 11

  • src/common/thread_worker.h
  • src/shader_recompiler/backend/spirv/emit_spirv_mesh.cpp
  • src/shader_recompiler/ir_opt/conditional_barrier_pass.cpp
  • src/shader_recompiler/shader_info.h
  • src/video_core/renderer_vulkan/vk_compute_pipeline.cpp
  • src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp
  • src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
  • src/video_core/renderer_vulkan/vk_rasterizer.cpp
  • src/video_core/renderer_vulkan/vk_rasterizer.h
  • src/video_core/renderer_vulkan/vk_state_tracker.h
  • src/video_core/vulkan_common/vulkan_device.h

@kraibse

kraibse commented Nov 7, 2026

Copy link
Copy Markdown
Collaborator Author

Test results

Intel GPU users

  • Can now boot the game and don't crash from any of the previously occurring crashes described in vulkan: intel arc fixes for MKW #684
  • Visual artifacts remain but the before and after comparison showed these issues already existing. Will be tackled in another PR.

Before
image
After
image
image

Remaining visual artifacts include:

  • Blocky shadows under the player character
  • Pink structures and landscape

AMD/NVIDIA users

  • Report no regression as expected. Changes are guarded and solely limited to intel GPUs.

@kraibse kraibse mentioned this pull request Nov 7, 2026
12 of 21 tasks
@kraibse
kraibse merged commit db093d7 into nx2-experimental Nov 7, 2026
5 checks passed
GoatTech-42 added a commit to GoatTech-42/Lichii that referenced this pull request Nov 7, 2026
…e (ports Eglantine #754)

Port of Djihads80/Eglantine#754 commit 8e87cf5. A task that culls all threads left the payload undefined; Intel garbage there launches enough workgroups to lose the device (Intel Windows device loss in Mario Kart World).
EddieRicobom pushed a commit to EddieRicobom/eggcellent that referenced this pull request Nov 8, 2026
…e (ports Eglantine #754)

Port of Eglantine-Community/Eglantine#754 commit 8e87cf5. A task that culls all threads left the payload undefined; Intel garbage there launches enough workgroups to lose the device (Intel Windows device loss in Mario Kart World).

(cherry picked from commit a2721909d26671f84e6796257cea6f76c9199879)
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.

3 participants