Decode and SPIR-V emitter corrections this title's shaders need: image and
memory operand handling, scalar ALU forms, and the IR plumbing that goes with
them.
A shader the recompiler cannot translate is a gap in emulation, not a reason to
take the process down: skipping the draw or dispatch that wanted it costs some
rendering, while aborting costs the title.
CompileOptions gains non_fatal and CompileResult gains unsupported. With
non_fatal set, the three places the recompile path gives up - an opcode with no
IR translation, a CFG that will not build, and resource tracking that cannot
resolve a descriptor - record the failure and unwind rather than calling EXIT,
and Recompile returns a result marked unsupported. The caller skips that draw or
dispatch. Nothing changes when non_fatal is clear.
Marvel's Spider-Man: Miles Morales meets an untranslatable compute shader on its
third frame, so a strict build cannot pass the opening logo. Astro's Playroom is
also stopped by a shader today and reaches a later, different failure with this
in place.
A conditional inside a loop where exactly one arm stays in the loop body has its
real merge at the arm that stays, not at the block the generic search finds.
Without this the CFG is rejected as unstructured and the shader falls back to
the dispatcher.
Also splits selection merges shared between a break and its continuation, which
the same shaders rely on.
Two descriptor chains this title uses could not be resolved:
- A descriptor whose address arrives through a phi. Walk the phi to its leaves
and accept the result when they agree, or when exactly one is a real address
and the rest are null/sentinel.
- A descriptor read through ReadFirstLane. This is safe for non-image
descriptors, where every lane holds the same handle, so accept it there. Image
descriptors keep the old restriction, gated by the dword count.
A buffer load wrote its destination unconditionally, clobbering lanes the exec
mask had masked off. Select against the previous value so inactive lanes keep
what they held.
S_CMP_{EQ,LG}_U64 against a mask operand and zero is the idiom for 'are any
lanes live'. Treating it as a scalar compare loses the per-lane information, so
emit an actual ballot for that shape.
OpGroupNonUniformShuffle with Subgroup scope only reaches 32 lanes on this
hardware, but GCN wave64 code expects all 64. A decoupled-lookback prefix scan
broadcasts its ticket across the whole wave, so the subgroup-scoped lowering
silently read the wrong lane. Lower the broadcast across the workgroup instead.
DS_BPERMUTE and DS_SWIZZLE keep the raw subgroup id: they are defined on
independent 32-lane halves and must not be widened.
Tracker::IndirectImagePlan lives in an anonymous namespace, so std::projected
cannot be formed for it and the three std::ranges algorithms over
m_indirect_images fail to compile under clang-cl with the MSVC STL:
error: function 'std::projected<..., std::identity>::operator*' is used but
not defined in this translation unit, and cannot be defined in any other
translation unit because its type does not have linkage
Using the iterator-pair overloads compiles and is otherwise identical.
Seen with clang-cl and MSVC 14.29 (VS2019) STL. CI does not catch this because
its build targets are launcher and the smaller test binaries; kyty_emulator,
which is what pulls in this file, is never built there.
Decode the high-half D16 LDS read and route it through the existing unsigned-short load lowering. Represent the destination as a high-half partial write so the low 16 bits of the VGPR remain intact. Add captured-instruction decode coverage and a Vulkan execution regression that verifies the preserved half.
Co-authored-by: SueryRD <the.ai.tester2@gmail.com>
Allow byte, word, and full-dword SDWA source selection for V_NOT_B32 and V_FFBL_B32. Add captured instruction tests that verify decoding, IR extraction, SPIR-V generation, and runtime results.
Co-authored-by: SueryRD <the.ai.tester2@gmail.com>