Packet-builder stubs double the DMA tag QWC when the game's own close function runs
Maintainers usually reply within 5 days
Assessment
- Difficulty
- 4/5
- Estimated time
- 1-2 days
- Newbie friendliness
- 48/100
Research direction
Start in ps2xRuntime/src/lib/Kernel/Stubs/GS.cpp and inspect writePacketBuilderCurrent(), refreshPacketBuilderPendingCount(), and the stubbed close/terminate functions; the issue names the test VIF1 packet builders keep chain qwc live before terminate. Reproduce the Tekken 4 sequence described in the issue and check how the CNT tag QWC changes when the game's close function runs. Done means the fix avoids doubling QWC while preserving the tested packet builder behavior.
Written by the indexing model from the issue text.
Description
Summary
The packet-builder stubs in ps2xRuntime/src/lib/Kernel/Stubs/GS.cpp keep the open DMA tag's QWC up to date as they write: every stub that advances pk->cur goes through writePacketBuilderCurrent(), which calls refreshPacketBuilderPendingCount() and rewrites the QWC field of the tag at pk[2].
That's deliberate (the test VIF1 packet builders keep chain qwc live before terminate covers it), but it only works when the tag is also closed by a stub. When a game's own copy of the library's close function is not recognised (so it runs as recompiled game code), that function does what the real library does and adds (cur - tag) / 16 - 1 to the tag's first word. The QWC then comes out doubled.
Where it shows up
Tekken 4 (SCES-50878). Its image-upload helper does:
- its own
sceVif1PkCnt-style open (unrecognised, game code at 0x292970); sceGifPkOpenGifTag-style open (game code);- four
sceGifPkAddGsADcalls (stub); sceGifPkCloseGifTag(stub);- its own close (unrecognised, game code at 0x292900).
By step 5 the stubs have already set the CNT tag's QWC to 5, and the game's close adds another 5. VIF1 then reads 10 qwords for a 5-qword packet, lands mid-stream on garbage that decodes as a REFE tag and ends the transfer early. Logged around each call:
open CNT after: [tag]=10000000
close GIF before: [tag]=10000005 <- set by the AddGsAD stubs
close tag: word0 10000005 -> 1000000a
Possible fixes
- Don't touch the DMA tag from the GIF/VIF data stubs, and compute the QWC only in the stubbed close/terminate functions, as the real library does. This is closest to hardware, but needs checking against every stubbed close.
- Or make the pending-count refresh opt-in, for games whose close functions are all stubbed.
I worked around it in a game override by replacing the game's close function with one that sets the QWC instead of adding it (closeDmaTag in https://github.com/Lautreck/tekken4-recomp/blob/master/runtime/tekken4_overrides.cpp).
Made by Pablo and assisted with Claude Code.
🤖 Generated with Claude Code
- Dominant language
- C++
- Stars
- 3.3k
- Forks
- 149
- Avg merge
- 8h 46m
- Merged PRs (30d)
- 1
Getting set up
This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from ran-j/PS2Recomp
-
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
ran-j/PS2Recomp#393 · 1 comment ·
Maintainers usually reply within 5 days
-
EE sceCdStatus stub always reports READ (6), hanging games that wait for PAUSEPossibly taken @ahmedgamalalzatary claimed this 13 days ago. Open
Difficulty 1/5 Under an hour Newbie friendliness 95/100
Maintainers usually reply within 5 days
-
VU0 macro VSQI / VSQD: address and source registers swapped in generated codePossibly taken @yanm1103 claimed this 21 days ago. Open
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
Maintainers usually reply within 5 days
-
Runtime: SampleTexture casts unbounded or NaN texture coordinates to int, which is undefined behaviourMay be free again A pull request for this issue was closed without being merged. Open
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
ran-j/PS2Recomp#273 · 2 comments ·
Maintainers usually reply within 5 days
-
Build: /Qspectre- is MSVC-only and breaks every Release target under clang-clPossibly taken @ahmedgamalalzatary claimed this 13 days ago. Open
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
Maintainers usually reply within 5 days
Similar issues
-
Difficulty 1/5 Under an hour Newbie friendliness 65/100
-
[XLA] hlo/pass/README.md says passes implement Run; since the NVI change they implement RunImplOpen
Difficulty 1/5 Under an hour Newbie friendliness 91/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
NVIDIA-RTX/NRI#312 ·
Maintainers usually reply within 1 day
-
permute_q_b_proj / permute_wv_proj accept scale factors from another devicePossibly taken @0z5a claimed this today. Open
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
deepseek-ai/FlashMLA#247 ·
Maintainers usually reply within 1 day
-
Linux npm packaging leaves workspace files that block subsequent CI checkoutPossibly taken @Spockkk0225 claimed this today. Openci
Difficulty 2/5 1-3 hours Newbie friendliness 73/100
alibaba/neug#1195 · 1 comment ·
Maintainers usually reply within 1 day