Skip to content

Recompiler: "packed pixel ancillary input has an unsupported live use" for a plain v_bfe_u32 of the render target index #1903

Closed

Description

@fisherjoey

Stray (PPSA02100 v1.05, Unreal Engine 4) aborts a few minutes into start-up on a pixel shader:

what():  ShaderRecompiler::Recompile: shader info collection failed: packed pixel ancillary input has an unsupported live use

Setup: Linux (Nobara 44, kernel 7.2), RTX 5070 Ti, NVIDIA 595.91.07. Base is main 1be6f9f + #861 + #1836 + #1893.

The shader (0x200e360000) reads the render target index with the usual extract, v_bfe_u32 v4, v4, 16, 11. In IR that becomes BitFieldUExtract(ancillary, And(16, 31), UMin(And(11, 31), Sub(32, And(16, 31)))). lowerPackedAncillary only runs when ConstantFolder visits the GetBuiltin, and at that point the extract's offset and count are not constants yet. They fold later in the same pass, so the ancillary value is never lowered and shader info collection rejects it. The existing pixel_ancillary test builds the extract with immediate operands, so it doesn't cover this shape.

Fix: lower the ancillary from the BitFieldUExtract / BitFieldSExtract fold case too, once that extract's own operands have folded. Replaying Stray's 32 deferred ancillary shaders through the recompiler, 6 compile with the fix. The other 26 use the raw ancillary value in a SelectU32 and are a separate case. The PR has a test that fails on main and passes with the fix. PR: #____

AI-assisted: yes

Activity

  1. oneandonlydean commented on Oct 10, 2026

    @oneandonlydean
    Collaborator

    Could you retest Stray on current main? #1179 now lowers the packed ancillary after the whole fold pass (its LateFold test is this And(16, 31) shape), which should cover the v_bfe_u32 case here.

  2. fisherjoey commented on Oct 10, 2026

    @fisherjoey
    ContributorAuthor

    I tested #1179's code on Stray before it merged, at b4e02e2 (the later rebase to d8b1ad7 only touched a TechnicalDebt line). It didn't cover these shaders: 0 of the 4 replayable ones compiled (0x200e360000, 0x200e3b0000, 0x200e3c0000, 0x200e8b0000), and in game all 6 stayed deferred and the draw failed.

    The late fold handles the And(16, 31) shape, but in the real shaders the ancillary word also has an exec-masked SelectU32 copy. That copy still counts as a reader when the check runs, because MaskedSelectEliminator only removes it later, so #1179 refuses the whole word. #1904 covers that case, with an ExtractVectorMaskedCopy test in pixel_ancillary, and with it all 4 compile.

    A different set of 26 Stray shaders reads the whole word after the VGPR is reused, which neither PR covers. That's #2548.

    I can rerun Stray on current main to confirm, and will post the result here.

    AI-assisted: yes

  3. fisherjoey commented on Oct 10, 2026

    @fisherjoey
    ContributorAuthor

    Retested on current main (bc40a6b, #1179 included), offline, with the real ShaderRecompiler::Recompile on the requests Stray logged for these shaders:

    • main: 0 of 4. All four fail in shader info collection with packed pixel ancillary input has an unsupported live use. 0x200e360000 and 0x200e3c0000 report (used by BitFieldUExtract 16 11, SelectU32 ? ?), and 0x200e3b0000 and 0x200e8b0000 report (used by BitFieldUExtract 16 11).
    • main + fix(shader): lower the packed pixel ancillary when its extract operands fold after it #1904 (6b41cf4, merges cleanly): 2 of 4. 0x200e3b0000 and 0x200e8b0000 compile. 0x200e360000 and 0x200e3c0000 still fail, now with (used by SelectU32 ? ?).

    That's lower than the 4 of 4 I reported earlier. That test ran on an older base that didn't include #2083, and #2083 is the difference. Bisecting main with the #1179 + #1904 code applied at each step, f145139 gives 4 of 4 and the #2083 merge (a8b032b) gives 2 of 4. Reverting #2083 on top of main + #1904 brings it back to 4 of 4. #2083 picks f32 NaN results on the bits with a select, which adds another SelectU32 reader of the packed ancillary word in two of these shaders, and #1904's lowering doesn't accept that reader. So either #1904 needs to handle that select, or #2083's select should skip the ancillary input. I can update #1904 to accept that select if that's where you'd like it handled.

    The other two Stray shaders in this group (0x200e4d0000, 0x200e680000) still can't be replayed offline because the SRT walk needs guest memory, so they aren't counted.

    Setup: Linux, CPU-only replay (no game run), Release build with ANYPS5_ENABLE_SPIRV_TOOLS=ON, fresh shader disk cache for each run. The requests are serialization version 13, which current main reads as-is, and re-serializing them reproduces the input byte for byte.

    AI-assisted: yes

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions