fix(vif1): parse VIFcodes between a DIRECT image tag and its pixel data - #269
Open
drakolordx7 wants to merge 1 commit into
Open
drakolordx7 wants to merge 1 commit into
drakolordx7 wants to merge 1 commit into
Conversation
A VIF1 DIRECT can end with a PATH2 GIF IMAGE tag whose pixel data comes
in a later DIRECT, typically "MARK; DIRECT n" in the TTE words of the next
DMAtag. processVIF1Data() remembered the pending image (qwc) and then
treated the bytes right after the first DIRECT as that pixel data. Those
bytes are the next VIFcodes, so every such upload (fonts, CLUT and UI
atlas uploads) was shifted by the two VIFcode words: 2 CT32 pixels or 16
T4 pixels. The last 8 bytes of the data were then parsed as VIFcodes,
which showed up as garbled text and dithered sprite edges.
VIFcodes are now always parsed. When an image is pending, only the payload
of a DIRECT/DIRECTHL is re-wrapped in a synthesized IMAGE tag and
forwarded to PATH2 (forwardVif1DirectData). Raw continuation without
VIFcodes is kept only where hardware has it: a DIRECT cut off at the end
of a processVIF1Data() buffer (m_vif1PendingDirectQwc / m_vif1PendingDirectHl,
reset together with the pending image state).
Two existing tests ("VIF1 DIRECT image tag can continue with raw image
qwords" and "VIF1 DIRECT finds an image continuation after packed setup")
placed the pixel qwords directly after a complete DIRECT with no VIFcode in
front of them, which hardware would decode as a VIFcode. They now put the
pixels behind a DIRECT (and the first one checks the buffer cut-off case,
which is the one that really continues without VIFcodes). A new test covers
"DIRECT; MARK; DIRECT" and fails without the fix.
Found while bringing up a game's UI and font rendering, and verified byte
for byte against the EE RAM of a real PCSX2 through a savestate.
Made by drakolord and assisted with Claude Code.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A VIF1
DIRECTcan end with a PATH2 IMAGE GIFtag whose pixels arrive in a laterDIRECT, typicallyMARK; DIRECT nin the next DMAtag's TTE words.processVIF1Datatook the bytes right after the firstDIRECTas pixel data, but those are the next VIFcodes. Every such upload (fonts, CLUTs, UI atlases) was shifted by 8 bytes and its last 8 bytes were parsed as VIFcodes: garbled text and dithered sprite edges (seen in Killzone, SCUS-97402).VIFcodes are now always parsed, and only the payload of a
DIRECT/DIRECTHLis re-wrapped in a synthesized IMAGE tag while an image is pending. Raw continuation is kept only for aDIRECTcut off at the end of a buffer (m_vif1PendingDirectQwc). Checked byte for byte against real PCSX2's EE RAM (through a PINE savestate) in Killzone.Please look at two existing tests: they placed pixel qwords directly after a complete
DIRECTwith no VIFcode, which hardware decodes as a VIFcode. The first is now the buffer-cut-off case; the second ("finds an image continuation after packed setup") gets aDIRECT 1in front of its pixels. A newDIRECT; MARK; DIRECTtest fails without the fix.ps2x_tests437/437.Made by drakolord and assisted with Claude Code.