Skip to content

fix(recompiler): accept SDWA source selects on v_cvt_f32_ubyte1, ubyte2 and ubyte3 - #5478

Merged
oneandonlydean merged 1 commit into
boykopovar:mainfrom
oneandonlydean:up4/sdwa-ubyte-1014
Oct 13, 2026
Merged

oneandonlydean merged 1 commit into
boykopovar:mainfrom
oneandonlydean:up4/sdwa-ubyte-1014

Conversation

@oneandonlydean

Copy link
Copy Markdown
Collaborator

What

v_cvt_f32_ubyte0 accepts every SDWA source selector, but v_cvt_f32_ubyte1, ubyte2 and ubyte3 have no row in vop1SdwaRules, so any SDWA source select on them is refused. PPSA34299 stops on main 075169f, before its first frame:

terminate called after throwing an instance of 'std::invalid_argument'
  what():  VOP1 SDWA source selector 4 of opcode 0x12 at pc 0xfcc is not supported

Opcode 0x12 is v_cvt_f32_ubyte1, selector 4 is WORD_0.

This adds the three rows, the same as ubyte0's. The selected source goes through the existing SDWA operand path (OperandAccess.cpp: bit-field extract of the selected byte or word, zero- or sign-extended by SRC0_SEXT), and vCvtF32Ubyte then takes byte N of that value. Source of the semantics: the RDNA 2 ISA guide (30 November 2020). 6.8 and 13.3.7 (Table 88): SDWA supplies source 0, with SRC0_SEL selecting a byte, a word or the dword and SRC0_SEXT sign-extending it. 12.8, VOP1 opcodes 18-20: D.f = (float)(S0.u[15:8]), S0.u[23:16] and S0.u[31:24]. So v_cvt_f32_ubyte1 src0_sel:WORD_1 converts bits 31:24 of the register. A byte select on ubyte1-3, and a word select on ubyte2 and ubyte3, convert 0, or 255 when sign-extended from a negative value. Negate and absolute stay refused, as for ubyte0. Not measured on hardware (no AMD GPU here), so it is recorded in docs/dev/debt/shader.md.

Tested

Linux (CachyOS, kernel 7.2.3), GCC, Release with BUILD_TESTING=ON, on main 0aa4cb1.

  • New execution test agc_driver_sdwa_cvt_f32_ubyte (64 lanes, varied bytes): ubyte1 with WORD_0 and WORD_1, ubyte2 with sign-extended WORD_1, ubyte3 with sign-extended BYTE_3. On main it fails with VOP1 SDWA source selector 4 of opcode 0x12 at pc 0x34 is not supported; with the change it passes in 0.15 s (useCache = false). Not run on lavapipe here.
  • ctest -R "sdwa|rdna|vop1|decoder_length": 15 of 15 pass, including the other SDWA execution and decode tests.
  • PPSA34299: the SDWA stop is gone. It now runs 25 s and stops at the next unsupported case, still before its first frame:
    what():  AGC graphics: unsupported SPI_PS_INPUT_ENA/ADDR bit combination (ena 0x6302 addr 0x6302)
    
    (SAMPLE_COVERAGE, bit 14, not handled yet; separate topic.)
  • PPSA02929 runs from the title screen into gameplay unchanged.
  • tools/check_conventions.py and git diff --check pass.
  • Not built or run on Windows or macOS, or on AMD or Intel GPUs.

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 under Silent stubs in their library's technical debt file
  • 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
  • Unblocks: PPSA34299 (no Game bring-up discussion): VOP1 SDWA source selector 4 of opcode 0x12 at pc 0xfcc is not supported
  • GPUs tested: NVIDIA RTX 4090, 610.57.04, Linux (CachyOS)
  • AI-assisted: yes; I reviewed and tested every line

…e2 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.
@github-actions

github-actions Bot commented Oct 13, 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
#4048 docs/dev/debt/shader.md L115
#4926 docs/dev/debt/shader.md L115
#4964 docs/dev/debt/shader.md L115
#5028 docs/dev/debt/shader.md L115
#5049 docs/dev/debt/shader.md L115
#5426 docs/dev/debt/shader.md L115
#5461 docs/dev/debt/shader.md L115
#5472 docs/dev/debt/shader.md L115

@github-actions github-actions Bot added shader core/shader docs agc libSceAgc* labels Oct 13, 2026
@oneandonlydean
oneandonlydean merged commit 65beff9 into boykopovar:main Oct 13, 2026
9 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.

1 participant