Commit Graph
273 Commits
Author SHA1 Message Date
11d145855e fix(shader): keep the literal word of a GCN s_setreg_imm32_b32
The SOPK branch of the GCN decoder never set the literal for
s_setreg_imm32_b32, so the eight-byte instruction was re-encoded as one
word and its decode threw "literal operand word is out of the code span
bounds". The decoder now copies the literal for that opcode; the new
agc_gcn_decode test decodes the reported stream.

Co-authored-by: javierUDP <[email protected]>
Co-authored-by: Savvanis Spyros <[email protected]>
2026-10-22 12:17:44 +03:00
Get-fix 4b717912d7 feat(shader): decode PS4 (GCN) shaders by re-encoding them to RDNA
Each GCN instruction is re-encoded to its RDNA form and decoded by the
existing RDNA decoder, so the PS4 path shares the recompiler. Covers the
legacy VS stage (program at the VS slot, user SGPRs from s0, vertex and
instance index in v0-v3), fetch shaders linked as user-data calls, MIMG
(image_sample and friends), PS4 buffer descriptors (GCN DATA_FORMAT /
NUM_FORMAT, 44-bit base) and T# image descriptors (GCN tiling in word 7).
The GCN switch is keyed into the shader disk cache. PS5 behaviour is
unchanged: every PS4-only rule is gated on GcnGuestShaders().
2026-10-22 12:17:44 +03:00
Dean 4d50d73417 Merge pull request #8015 from fma-rc/fix/shader-mimg-sample-c-o-a
feat(shader): decode MIMG opcode 0xb8 as image_sample_c_o_a
2026-10-21 13:22:07 +13:00
Dean baae66415c Merge pull request #5799 from SleglJan/fix/cube-output-modifiers
fix(shader): apply cube output modifiers whenever IEEE mode is off
2026-10-21 05:38:37 +13:00
fma-rc f50326165e feat(shader): decode MIMG opcode 0xb8 as image_sample_c_o_a 2026-10-19 19:41:16 +02:00
Jan ŠléglandClaude Opus 5.5 e32f5e161d fix(shader): apply cube output modifiers whenever IEEE mode is off
v_cubeid_f32, v_cubesc_f32, v_cubetc_f32 and v_cubema_f32 refused any
output modifier with "VOP3 source modifiers are not implemented";
PPSA11386 stops there on v_cubeid_f32 v, v, -v, -v div:2.

On RDNA2 (gfx1036), over 2048 inputs in every combination of IEEE mode,
the four f32 denormal values and f16/f64 denormals flushed or kept, with
round to nearest even, the four instructions apply mul:2, mul:4 and
div:2 whenever IEEE mode is off, also with f32 output denormals kept,
where v_mul_f32_e64 in the same kernels ignores them, and ignore them
with IEEE mode on. Where applied, the result is the existing bit-level
f32 output modifier result, and clamp is applied after it.

The decoder accepts the modifier on the four instructions. floatCube
applies the shared f32 scaling, now scaleF32Result, in those modes and
writes with the modifier cleared, so clamp is still applied after it.
With IEEE mode on the signaling NaN quieting applies and the modifier is
ignored; with it off the quieting does nothing and the modifier is
applied. agc_driver_vop3_cube_clamp checks each instruction with each
modifier against tables captured on gfx1036.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Fnrk5Dazjb2tLooVSpdRQq
2026-10-14 19:52:46 +02:00
Romans Pokrovskis c8d44e651e feat(shader): decode mixed SGPR and VCC buffer descriptors 2026-10-14 12:26:01 +03:00
Dean 591d39c393 Merge pull request #5005 from fdfawef324/feat/recompiler-aperture-source-values
feat(recompiler): read the scalar aperture sources as values
2026-10-14 19:16:56 +13:00
Dean 9260767a06 Merge pull request #5471 from milescoviello/fix/shader-interp-p2-f16-high-half
fix(shader): decode the high-half result of v_interp_p2_f16
2026-10-14 18:05:04 +13:00
fdfawef324andClaude Opus 5.5 dc1c12a612 feat(recompiler): read the scalar aperture sources as values
Reading src_shared_base, src_shared_limit, src_private_base or
src_private_limit (scalar source codes 235-238) refused the shader since
#1940, because their values were unknown. They now read as the 64-bit
apertures that the flat routing from #1190 classifies: a base is the
aperture's high dword over a low dword of 0, a limit is the same high
dword over 0xffffffff (shared 0x80000000, private 0x70000000).

A 64-bit read (s_mov_b64, a 64-bit VALU source, a wave64 lane mask)
gets the whole value and a 32-bit read gets the low dword. A flat
pointer built from the high dword therefore reaches LDS or scratch, and
64-bit compares against the limits order as on the hardware. The flat
routing and the reads share one definition of the two high dwords.

Sources: LLVM SIRegisterInfo.td (aperture registers are 64-bit, their
low 32 bits are always 0 for a base and -1 for a limit) and
getSegmentAperture in AMDGPULegalizerInfo.cpp and SIISelLowering.cpp
(a 64-bit read whose high half is the aperture); the RDNA 2 ISA guide,
sections 5.2, 5.8 (SH_MEM_BASES holds 16-bit bases) and 9.3; the KFD's
MAKE_LDS_APP_LIMIT (limit = base | 0xffffffff); the gfx1030 and gfx1035
readouts on #1190 and #3803. The PS5's two high dwords stay inferred,
as the shader technical debt records.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-13 22:39:49 -04:00
Dean 3e485ed53c Merge pull request #4996 from MarcZX100/codex/mimg-sampler-vcc-4991
fix(shader): accept MIMG sampler tuples ending in VCC
2026-10-14 14:34:27 +13:00
Dean b9e0e4ed30 Merge pull request #5149 from xXPBSXx/fix/agc-texture-snorm-sint-2101010
fix(agc): sample 10_10_10_2 SNorm and SInt textures
2026-10-14 14:34:11 +13:00
milescovielloandClaude Opus 5.5 2265e8b1cd fix(shader): decode the high-half result of v_interp_p2_f16
Forspoken (PPSA03984) has a pixel shader with
v_interp_p2_f16 v1, ..., v7 op_sel:[0,0,0,1], and main throws
"VOP3 interpolation modifiers are not implemented" one second after
start.

On GFX10, op_sel[3] of a 16-bit VOP3 result selects the high half of
the destination and keeps the other half. The decoder already maps
that bit to destination.sdwaSel 5 for the other 16-bit VOP3 ops, and
write16Bits/writeRawU32 then insert the result into bits 31:16 and
keep bits 15:0. v_interp_p2_f16 is the only 16-bit-result
interpolation instruction, so only it accepts the bit; other op_sel
bits and the bit on the 32-bit-result p1ll/p1lv forms are still
refused.

agc_vop3_interp_decode checks the decoded selector with and without
the bit, and that v_interp_p1ll_f16 still refuses it. In
agc_driver_interpolation_f16 the second v_interp_p2_f16 now writes the
high half of a register holding 0x00001234, and the GPU result must
keep 0x1234 in the low half.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-13 20:37:44 +00:00
Dean Galvin 7b2104ee0d fix(recompiler): accept SDWA source selects on v_cvt_f32_ubyte1, ubyte2 and ubyte3
v_cvt_f32_ubyte0 accepts every SDWA source selector, but the other three byte
conversions had no VOP1 SDWA rule, so any SDWA source select on them was refused
("VOP1 SDWA source selector 4 of opcode 0x12 at pc 0xfcc is not supported").
The selected and optionally sign-extended source goes through the same operand
path as for ubyte0 before byte N is extracted: SDWA supplies source 0 (RDNA 2 ISA
guide 6.8 and 13.3.7) and the opcode reads S0.u[8N+7:8N] (12.8).

agc_driver_sdwa_cvt_f32_ubyte: WORD_0 and WORD_1 selects on ubyte1, and
sign-extended WORD_1 and BYTE_3 selects on ubyte2 and ubyte3.
2026-10-14 09:36:10 +13:00
xXPBSXxandClaude Sonnet 5.5 c6a4223420 fix(agc): sample 10_10_10_2 SNorm and SInt textures
Guest texture formats 51 (SNorm) and 55 (SInt) of the 10-bit packed group were missing from the texture lookup and the descriptor format table, so a descriptor using them threw 'unsupported guest texture format' while the UNorm (50) and UInt (54) siblings worked. Map them to A2B10G10R10_SNORM_PACK32 / A2B10G10R10_SINT_PACK32, classify them for sampling (float / signed integer), and list SINT among the integer formats.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
2026-10-13 14:56:03 +02:00
MarcZX100 3e238ff11d fix(shader): accept MIMG sampler tuples ending in VCC 2026-10-13 07:40:17 +00:00
krishnarayaandClaude Opus 5.5 e5f943e3b3 fix(shader): keep the output modifier of the f16 min3, max3, med3 and div_fixup ops
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
2026-10-11 19:10:15 -04:00
Adrià 3905e7e2c9 Merge pull request #3827 from CouchRiv/fix-shader-combined-cvt-i16-f16-omod
fix(shader): accept output modifiers on v_cvt_i16_f16 and ignore them as the hardware does
2026-10-12 00:39:20 +02:00
Adrià e53c30bcdf Merge pull request #3828 from CouchRiv/fix-shader-combined-pknorm-f16
fix(shader): accept abs, neg and op_sel source modifiers on v_cvt_pknorm_i16_f16 and v_cvt_pknorm_u16_f16
2026-10-12 00:07:49 +02:00
Adrià 4b355d4e68 Merge pull request #3825 from kr4y4/fix/shader-dpp8-pk-fmac-f16
fix(shader): accept DPP8 on v_pk_fmac_f16
2026-10-12 00:07:47 +02:00
Adrià e05a603771 Merge pull request #3668 from CouchRiv/fix-shader-float-compare-clamp
fix(shader): accept the clamp bit on VOP3 float compares
2026-10-11 23:46:41 +02:00
Adrià 097b8d82a5 Merge pull request #3621 from goncalompontes/feat/shader-vop3-interp-f32-e64
feat(shader): decode GFX10 VOP3-encoded interpolation
2026-10-11 23:44:35 +02:00
krishnarayaandClaude Opus 5.5 8a0395381e fix(shader): accept DPP8 on v_pk_fmac_f16
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
2026-10-11 13:16:11 -04:00
AlexandClaude Haiku 5.5 2f5d166e2b fix(shader): accept output modifiers on v_cvt_i16_f16 and ignore them as the hardware does
v_cvt_i16_f16 with mul:2, mul:4, div:2 or clamp in the VOP3 encoding
stops the recompiler with "VOP3 source modifiers are not implemented".
On gfx1036 (Radeon 610M) the result is identical with and without
mul:2, mul:4, div:2 and clamp combined with mul:2, for all 66 measured
inputs; clamp on its own is not a measured case.

The decoder now accepts omod and clamp on v_cvt_i16_f16 and drops them,
as measured. Clamp without an output multiplier is accepted by the same
rule: clamp with mul:2 gives the same hardware result as mul:2 alone.
Matches 528 of 528 rows in two float modes, 0 differing.
v_cvt_u16_f16 is not measured and stays refused.

Co-Authored-By: Claude Haiku 5.5 <[email protected]>
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
2026-10-11 12:40:48 -04:00
AlexandClaude Haiku 5.5 b00efdb261 fix(shader): accept abs, neg and op_sel source modifiers on v_cvt_pknorm_i16_f16 and v_cvt_pknorm_u16_f16
v_cvt_pknorm_i16_f16 and v_cvt_pknorm_u16_f16 with |x|, -x or op_sel in
the VOP3 encoding stop the recompiler with "VOP3 source modifiers are
not implemented", although the RDNA2 hardware executes them.

These two opcodes now use the two-source f16 modifier path of
v_pack_b32_f16: op_sel picks the high half of either source, then abs
and neg apply. Other op_sel bits, clamp and omod are still refused.
Matches 15632 of 15632 rows measured on gfx1036 (Radeon 610M) in two
float modes, 0 differing.

Co-Authored-By: Claude Haiku 5.5 <[email protected]>
2026-10-11 11:45:26 -04:00
AlexandClaude Haiku 5.5 9ff132d9a5 fix(shader): accept the clamp bit on VOP3 float compares
The decoder throws "VOP3 source modifiers are not implemented" for
VOP3-encoded float compares (v_cmp_*_f16/f32/f64) that set the clamp
bit, so shaders using them fail to compile.

On RDNA2 hardware the clamp bit does not change the result of a float
compare: the measured results with and without it are the same. The
decoder now accepts the bit on float compares; clamp on other carry-out
and scalar-destination opcodes still throws.

Co-Authored-By: Claude Haiku 5.5 <[email protected]>
2026-10-11 11:04:38 -04:00
goncalompontes 61d4494863 fix(shader): accept the inline constant third source of VOP3 interpolation
The assembler encodes the unused third source of the VOP3-encoded
interpolation forms as the inline constant 0 (src2 = 0x80, bit 25 of the
second word), which the decoder refused. Accept that encoding and refuse
any other third source. The decode test now uses the assembler words for
every accepted form and keeps the refusals one field away from a valid
word.
2026-10-11 16:03:46 +01:00
Adrià 383851643f Merge pull request #2940 from CnRJay/fix/recompiler-sdwa-cvt-f16-16-byte-source
fix(recompiler): accept SDWA byte sources on v_cvt_f16_u16 and v_cvt_f16_i16
2026-10-11 01:33:36 +02:00
Adrià c7375433e9 Merge pull request #2838 from MarcZX100/fix/sdwa-cvt-f16-u16-byte-sources-2747
fix(recompiler): accept byte source selectors on v_cvt_f16_u16 SDWA
2026-10-11 01:07:03 +02:00
goncalompontes 54c839959f feat(shader): decode GFX10 VOP3-encoded interpolation
v_interp_p1_f32_e64, v_interp_p2_f32_e64 and v_interp_mov_f32_e64
(VOP3Interp opcodes 0x200, 0x201 and 0x202) reach the decoder as VOP3
and were refused as unimplemented VOP3 opcodes. Decode them into the
existing VInterpP1F32, VInterpP2F32 and VInterpMovF32 opcodes with the
VOP3Interp operand layout, so the interpolation translation already
used by the VINTRP encodings handles them.

Encodings and operand layout follow LLVM's gfx10 MC tests for
VOP3Interp_Real_gfx10 (D69348). The interpolation parameter is the low
six bits of src0, the channel bits 6:7, the coordinate (or the
interpolation parameter of the mov form) is src1, and clamp and omod
reach the destination. op_sel, the packed-half selector, a third source
and abs/neg on operands that do not exist throw.
2026-10-10 21:07:55 +01:00
Chad 9cf85e94cb fix(recompiler): accept SDWA byte sources on v_cvt_f16_u16 and v_cvt_f16_i16
PPSA28416 stopped at v_cvt_f16_u16_sdwa dst_sel:WORD_0 dst_unused:UNUSED_PRESERVE src0_sel:BYTE_3. The integer source extraction already implements byte selects with src0_sext.
2026-10-10 13:11:10 -05:00
Lexroid ef5221a1e6 fix(recompiler): accept byte source selects on v_cvt_f16_u16 SDWA
v_cvt_f16_u16 SDWA only accepted word and dword source selects. Silent
Hill Townfall (PPSA33286) converts the top byte into the low half of a register
and keeps the high half (src0_sel:BYTE_3 dst_sel:WORD_0
dst_unused:UNUSED_PRESERVE), so its shaders failed to recompile. The
generic SDWA source path already zero-extends byte selects, which is the
u16 value the conversion expects, so the rule now accepts every source
select, with whole and partial destinations.

agc_driver_sdwa_cvt_f16_u16 runs four byte selects with dword, WORD_0
and WORD_1 destinations on the GPU and checks the converted halves and
the preserved bits.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
(cherry picked from commit d55dfe8b33)
2026-10-10 16:17:56 +00:00
Dextroid17 b7e32b3648 fix(shader): decode the scalar aperture sources 235-238 instead of failing the shader 2026-10-10 06:57:12 -04:00
Dextroid17 e5b32bb429 fix(agc): defer a shader the decoder does not implement instead of aborting
The registered-shader decode ran before the deferral decision, so a single
instruction the decoder does not implement ended the title at registration
instead of deferring the shader to its first use.

Give the decoder's unsupported-instruction failures their own type
(UnsupportedInstructionError): the five family-scoped SOP opcode defaults and
the MIMG opcode lookup (which now names the opcode) raise it, and the decode in
PrepareRegistered defers the shader with that reason when it hits one. Any
other exception still throws, so the corrupt-code contract is unchanged.

PPSA26344 hits this: unsupported MIMG opcode 229 (0xE5), issue #1941. The
failing word is reproducible offline from the title's own shader store
(cache_ps5/all_shaders.xpps, code word 260), which is how the fixture was
checked before it was written.

Scope: this defers the scalar-family and MIMG opcode gaps. The vector (VOP*)
and memory (SMEM/MUBUF/MTBUF/FLAT/DS) opcode lookups, the modifier-level
"not supported" throws and the malformed/truncated throws still abort.
Widening the deferral to those is a policy call for the maintainers.

Stacked on #1836 (the deferral machinery); re-stacked on its current head so
this diff no longer carries #1836's earlier broad catch. Once #1836 lands only
the decode change remains.

Written with AI assistance.
2026-10-10 08:49:08 +02:00
Adrià ecd3dbadb3 Merge pull request #2376 from krishnaraya4/fix/rdna-drop-gcn-vop2-opcodes
fix(shader): stop decoding gfx6/7-only VOP2 opcodes on RDNA
2026-10-10 08:17:22 +02:00
Adrià e53e26a209 Merge pull request #2378 from krishnaraya4/fix/agc-vertex-10-10-10-2-int-class
fix(shader): give 10_10_10_2 integer vertex inputs an integer type
2026-10-10 08:16:57 +02:00
Adrià 21b7876487 Merge pull request #2200 from XairRrR/fix/recompiler-sdwa-v-not-b32
fix(recompiler): accept SDWA destination selects on v_not_b32
2026-10-10 08:14:14 +02:00
Adrià 831e071786 Merge pull request #2199 from XairRrR/fix/recompiler-r8-snorm
feat(agc-driver): sample 8_SNORM images
2026-10-10 08:14:05 +02:00
Adrià 56bfc4d1c9 Merge pull request #2034 from TheAggie/fix/shader-truncated-decode-out-of-range
fix(shader): report a truncated memory, image or export instruction as out of range
2026-10-10 08:08:33 +02:00
Adrià 832e7b4b6b Merge pull request #1948 from arcwiser/fix/mimg-unsupported-opcode-diagnostic
fix(shader): name unsupported MIMG opcodes
2026-10-10 08:05:48 +02:00
Adrià 4adefa0708 Merge pull request #1898 from fisherjoey/fix/vop3-add-sub-clamp
fix(shader): saturate VOP3 v_add/sub_nc_u32 and 16-bit add/sub on clamp
2026-10-10 08:04:49 +02:00
krishnarayaandClaude Opus 5.5 dffd449489 fix(shader): give 10_10_10_2 integer vertex inputs an integer type
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
2026-10-09 12:49:25 -04:00
krishnarayaandClaude Opus 5.5 2ea1f6fb71 fix(shader): stop decoding gfx6/7-only VOP2 opcodes on RDNA
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
2026-10-09 12:30:40 -04:00
XairRrR 09582357f2 fix(recompiler): accept SDWA destination selects on v_not_b32
v_not_b32_sdwa takes the same dst_sel and dst_unused operands as the
other 32-bit VOP1 SDWA forms (RDNA2 ISA 6.3.1 "SDWA"; LLVM
VOP1Instructions.td gives V_NOT_B32 a VOP1_SDWA encoding with dst_sel
and dst_unused). The rule now allows byte and word destinations with
every unused mode, which the existing SDWA writeback implements; the
execution test checks WORD_0 with UNUSED_PRESERVE.

Uncharted: Legacy of Thieves Collection (PPSA05684) stopped at a v_not_b32_sdwa with dst_sel:WORD_0 dst_unused:UNUSED_PRESERVE.
2026-10-09 13:28:48 +02:00
XairRrR 46a0c1a2c3 feat(agc-driver): sample 8_SNORM images
GFX10 image format 2 (8_SNORM, Mesa gfx10_format_table) resolves to
VK_FORMAT_R8_SNORM and is marked sampleable in the recompiler's format
table.

Uncharted: Legacy of Thieves Collection (PPSA05684) stopped at a compute shader sampling an 8_SNORM image.
2026-10-09 13:28:48 +02:00
Scott SchusterandClaude Opus 5.5 1e5b8d9e7c fix(shader): report a truncated memory, image or export instruction as out of range
ReadRawComputeShader decodes a growing prefix of guest memory and reads
more when the decoder throws std::out_of_range, which the vector, scalar
and instruction-length checks throw for an instruction cut off by the end
of the span. The memory (SMEM, DS, MUBUF, MTBUF, FLAT), image and export
decoders threw std::runtime_error instead, so a two-word instruction
across a window boundary failed the read: vkQuake terminated on "truncated
FLAT instruction". These now throw std::out_of_range too.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-08 23:02:17 -05:00
arcwiser 3058b5193b fix(shader): name unsupported MIMG opcodes 2026-10-09 12:43:37 +11:00
Joey Fisher 1f0060d72d fix(shader): saturate VOP3 v_add/sub_nc_u32 and 16-bit add/sub on clamp 2026-10-08 16:55:06 -06:00
krishnarayaandClaude Opus 5.5 96569aac30 fix(shader): refuse the MUBUF lds modifier instead of decoding a VGPR load
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
2026-10-08 18:28:16 -04:00
Adrià ae91d9780b Merge pull request #697 from queeeef/feat/interp-f16
feat(shader): implement v_interp_p1ll_f16, v_interp_p1lv_f16 and v_interp_p2_f16
2026-10-08 23:56:17 +02:00