Skip to content

feat(shader): implement the 32-bit DS src2 operations - #938

Merged
adriadam10 merged 2 commits into
boykopovar:mainfrom
CnRJay:feat/ds-src2-b32
Oct 8, 2026
Merged

adriadam10 merged 2 commits into
boykopovar:mainfrom
CnRJay:feat/ds-src2-b32

Conversation

@CnRJay

@CnRJay CnRJay commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

What

The decoder threw on the GFX10.1 DS src2 opcodes 0x80-0x8b, 0x8d, 0x92, 0x93 and 0x95. Each one reads DS[B], where B is the address plus four times the 15-bit signed offset in offset1[6:0]:offset0, and applies the matching operation to DS[A]:

  • add, sub, rsub, inc, dec, signed and unsigned min and max, and, or, xor, and f32 min, max and add, through the 32-bit LDS atomics;
  • a plain write for ds_write_src2_b32.

These forms still throw, and are recorded in TechnicalDebt:

  • the form that takes the offset from the address bits (offset1[7]);
  • the 64-bit forms;
  • GDS.

Tested

Windows 11, MinGW GCC Release build, ctest agc_driver_lds_src2 passes (new, on the GPU). Each lane runs every src2 operation on its own LDS words, and each result is compared with the value computed from the ISA pseudocode. A shader that uses the address-offset form must be rejected at compile time.

Checklist

  • Based on current main; no other open PR implements the same functions
  • One topic per PR; follow-ups go in a new PR
  • No comments in code except technical debt
  • Unimplemented paths throw (NotImplemented_nid_no_patch); silent stubs are listed in TechnicalDebt
  • No notes, investigation .md files or images added to the repository (attach them to this PR)
  • New third-party code is a submodule built from source
  • Generic behaviour, not specific to one title
  • Depends on: none
  • AI-assisted: yes

🤖 Generated with Claude Code

@adriadam10

Copy link
Copy Markdown
Collaborator

Heads-up: this PR is on hold, not rejected. It may depend on how ds_{add,min,max}_src2_f32 behaves under the shader float mode (IEEE_MODE, DX10_CLAMP, the denormal bits of FLOAT_MODE in RSRC1). Real titles set that mode per shader, and the recompiler currently assumes a single one; see #981. Until that is settled, no float-mode dependent shader PR gets reviewed or merged. Nothing to do on your side for now. Once #981 lands, this will probably need tests for each mode value it relies on.

@github-actions github-actions Bot added the needs rebase Conflicts with main, rebase needed label Oct 7, 2026
@github-actions github-actions Bot mentioned this pull request Oct 7, 2026
9 tasks done
@github-actions github-actions Bot removed the needs rebase Conflicts with main, rebase needed label Oct 7, 2026
@github-actions

github-actions Bot commented Oct 7, 2026

Copy link
Copy Markdown

Other open pull requests touch the same code. Merging one will break the other, or both implement the same thing. If this one builds on them, list them in Depends on.

Pull request Conflicting files (lines on main) Same exports Same new files
#1270 docs/dev/TechnicalDebt.md L270

claude and others added 2 commits October 8, 2026 23:06
The decoder threw on the GFX10.1 DS src2 opcodes 0x80-0x8b, 0x8d,
0x92, 0x93 and 0x95. Each reads DS[B], where B is the address plus
four times the 15-bit signed offset in offset1[6:0]:offset0, and
applies the matching operation to DS[A]: add, sub, rsub, inc, dec,
signed and unsigned min and max, and, or, xor, f32 min, max and add
through the 32-bit LDS atomics, and a plain write for
ds_write_src2_b32. The form that takes the offset from the address
bits (offset1[7]), the 64-bit forms and GDS still throw.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…als are modelled

Co-Authored-By: Claude <noreply@anthropic.com>
@adriadam10

Copy link
Copy Markdown
Collaborator

Unblocking this from #981. I rebased it on main and pushed one commit on top (your commit is unchanged):

  • Measured on RDNA2 (gfx1035) with the hardware oracle: ds_min_f32, ds_max_f32 and ds_add_f32 ignore IEEE_MODE, but depend on whether f32 denormals are flushed. 28, 28 and 12 of 196 special rows (±0, ±1, ±inf, denormals, quiet and signaling NaNs) differ between flushed and kept. The src2 variants can't be measured: gfx1035 has no src2 opcodes, which exist only on GFX10.1 like the PS5's gfx1013, and AMD's RDNA1/RDNA2 ISA XML doesn't list them. So ds_{min,max,add}_src2_f32 now throw until LDS float denormals are modelled (the FLOAT_MODE step of Shader float mode (IEEE_MODE, DX10_CLAMP, FLOAT_MODE) is per shader; the recompiler assumes one #981). The 13 integer/bitwise src2 ops don't depend on the mode and stay as you wrote them.
  • The test's buffer descriptor now uses raw bounds (OOB_SELECT 3, 0x31016fac), as perf(agc): baseline shader recompilation on registration #639 did for the existing execution tests. Without it the stores were dropped (0xdeadbeef).
  • The test checks the 13 ops and that each f32 opcode is refused. TechnicalDebt says why they throw.

Tested on the merge with main: agc_driver_lds_src2 on RADV and CI's lavapipe, full ctest 491/491. Negative check: lowering the f32 ops again fails at f32 opcode 0x00000092 was not refused.

@adriadam10
adriadam10 merged commit dc79e9b into boykopovar:main Oct 8, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agc libSceAgc* docs shader core/shader

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants