Skip to content

fix(agc): prepare a rect-list draw's missing rectangle at draw from its prepared stages - #1928

Merged
adriadam10 merged 2 commits into
boykopovar:mainfrom
fisherjoey:fix/agc-draw-rectangle-fallback
Oct 10, 2026
Merged

adriadam10 merged 2 commits into
boykopovar:mainfrom
fisherjoey:fix/agc-draw-rectangle-fallback

Conversation

@fisherjoey

Copy link
Copy Markdown
Contributor

Closes #1927

What

A rect-list draw needs a prepared rectangle for its (front, vertex variant, fragment variant). Rectangles are built only when the title resolves the graphics ABI through sceAgcCreateInterpolantMapping. A fragment variant prepared at the draw (the null pixel program, or a shader deferred at registration) therefore has none, and the draw throws prepared rectangle artifacts are missing.

There are two commits:

  1. refactor(agc): look up a rect-list draw's rectangle through DrawRectangle moves the lookup into DrawRectangle(front, fragment, vertexId, fragmentId, target). Behaviour is unchanged.
  2. fix(agc): prepare a rect-list draw's missing rectangle at draw from its prepared stages: when the lookup misses, DrawRectangle logs it, calls ResolvePreparedGraphics(front, fragment, 17, target) and looks it up again. Any other failure still throws.

Tested

Linux (Nobara 44, GCC), RTX 5070 Ti, NVIDIA 595.91.07.

The new check in tests/execution/PreparedGraphics.cpp prepares a fragment variant that was never linked to the front through the ABI, then draws a rectangle with it through DrawRectangle.

ctest -R agc_driver_prepared_graphics
main 1be6f9f + commit 1 (lookup moved, no behaviour change) + the test fails: AGC driver: prepared rectangle artifacts are missing
this branch passes, logging Rect-list draw of shader ... has no rectangle for fragment shader ...; preparing it at draw

The test can't run on main without commit 1. The draw path has no function a test can call short of a full GPU draw, and the ctest suite has no harness for that. Commit 1 adds that function without changing behaviour, so the test builds and fails there because of the bug, not because it doesn't compile. I can squash the two commits if you prefer one.

The agc_driver_prepared_shaders* tests and pixel_ancillary also pass on the combined branch.

Stray, with #1902: without this change it aborts on the first rect-list draw that uses the null pixel program. With it, the log shows Rect-list draw of shader 0x200bbe0000 has no rectangle for fragment shader ...; preparing it at draw and the run continues to a later, unrelated error.

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
  • No notes, investigation .md files or images added to the repository
  • Generic behaviour, not specific to one title
  • Depends on: none to build or test. In a title it shows up once fix(agc): prepare the null pixel program at draw when its variant was not prepared #1902 prepares the null pixel program at draw.
  • AI-assisted: yes

@klosixgaming-arch klosixgaming-arch left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Small, correct, and the test strategy is the right one for a code path that otherwise can only be reached by a full GPU draw.

  • Commit 1 (move the lookup into DrawRectangle) is behaviour-preserving and gives a callable seam for the test — good reasoning, and the test genuinely fails on main+commit-1 and passes on this branch.
  • The fallback only fires on a lookup miss, calls ResolvePreparedGraphics, then re-looks-up; any other failure still throws. No silent stub, no guessing.
  • Interacts correctly with #1902 (null pixel program prepared at draw).

One note (non-blocking): the fallback hard-codes 17 as the primitiveType passed to ResolvePreparedGraphics. Everywhere else the primitive type comes from the decoded draw state. If a rect-list draw can legitimately be issued with a different primitive type, preparing with 17 may produce a rectangle that doesn't match. Please confirm rect-list draws are always type 17 (or pull the real value from the packet if not) — that's the only thing I'd want grounded before this is a long-term fix rather than a workaround.

Written with AI assistance.

@fisherjoey

Copy link
Copy Markdown
Contributor Author

#1825 and #1732 change the same lines in Draw.cpp. Both call ResolvePreparedGraphics(..., 17u, ...) before the PreparedRectangle lookup, but only when the vertex program is unregistered (programs[0].snapshot->header.empty()). This PR covers a different trigger: the vertex program is registered and the fragment variant was prepared at the draw (the null pixel program from #1902, or a shader deferred by #1836).

So the changes don't duplicate each other, but they will conflict. Whichever lands first, I'm happy to rebase so both cases go through one helper (DrawRectangle here, which builds the rectangle when the lookup misses), or to drop that part if the other PR's version covers it once merged.

AI-assisted: yes

@MarcZX10

MarcZX10 commented Oct 9, 2026

Copy link
Copy Markdown
Contributor

I verified the primitive-type question against the current decoder: Graphics::DecodeState sets rectList only for primitive values 7 or 17. ResolvePreparedGraphics uses the value only to set rectangleRequested when it is either 7 or 17; rectangle generation does not distinguish them. So passing 17 from this fallback is equivalent for any draw that reached the rect-list path.

@MarcZX10 MarcZX10 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the full diff and current head. The helper move is behavior-preserving, the fallback only runs on a missing rectangle, and the execution test exercises the prepared-fragment case. I checked that primitive values 7 and 17 both enter the rect-list path and generate the same rectangle request. Linux and Windows checks and Conventions are green. The author has also documented the distinct overlapping triggers in #1732/#1825 and offered to rebase as needed.

@Raghav314

Copy link
Copy Markdown
Contributor

Tested this with Hades II (PPSA36082), together with a fix for the null program miss (the registration fix I described on #1902). The fallback kicks in once while the level loads, for the null fragment program, and the game goes on to gameplay without problems.

@XairRrR

XairRrR commented Oct 9, 2026

Copy link
Copy Markdown
Contributor

Uncharted: Legacy of Thieves Collection (PPSA05684) stops here once its fragment variants are prepared at the draw (locally: the null pixel program and its own shaders, see #1902):

AGC driver: prepared rectangle artifacts are missing

I fixed it locally the same way (build the rectangle pair from the prepared stages at the draw and keep it with the snapshot) to reach the title's main menu. Separately, the fault buffer of the built control/evaluation shaders could collide with another stage's binding group; that fix is #2198. I have not run this branch itself with the title.

@EdouardSence

Copy link
Copy Markdown
Contributor

Two more titles hit the case this PR fixes, on Linux with an RX 9070 XT (RADV).

Tested and written by Claude (AI assistant) on a contributor's machine.

@orbz22

orbz22 commented Oct 9, 2026

Copy link
Copy Markdown
Contributor

Astro's Playroom (PPSA01325) hits this on Windows with NVIDIA, right after #1902.

Setup: main 745b775 + #1836 + #1837 + #1395 (rebased locally) + #1902, plus a local workaround for vertex fetch exceeds descriptor record count (no PR yet).

Windows 11, RTX 3060 Laptop (NVIDIA 616.92), WinLibs GCC 15.2.

🤖 Generated with Claude Code

@NahuelGenchi

Copy link
Copy Markdown
Contributor

Tested with Sonic Origins (PPSA05324) on Linux, R9 380 (RADV). Its depth/stencil clears are rect-list draws without a pixel program, so they stopped at prepared rectangle artifacts are missing once #1902 prepared the null pixel variants. With this PR, the log shows three Rect-list draw of shader ... has no rectangle for fragment shader ...; preparing it at draw lines, the clears run, and the title presents its SEGA logo. Testing branch: main d70b899 + #2022, #2219, #1902, #1837, #425 and #1544.

Bring-up thread: #2021

@tv7

tv7 commented Oct 10, 2026

Copy link
Copy Markdown
Contributor

Tested on Windows with Marvel's Wolverine (PPSA03671), after #1902.

Setup: Windows 11 Pro (10.0.26200), RTX 3070, GCC 15.2.0 UCRT (WinLibs), Release. This PR (def0be1) merged onto main 54f28f2 with #1836, #1893, #1709, #1837, #1940, #2022, #2219, #1902, and a local change that lets sceKernelSignalSema accept a count of 0. It merged without conflicts.

Without this PR: the first presentation fails with AGC driver: prepared rectangle artifacts are missing.

With this PR: the rect-list draws pass. The next stop is a compute shader deferred at registration: GetImageResource dword 0 is not a valid runtime value; chain: ReadConstBuffer@pc=0x00001140(GetBufferResource(ReadConst(GetSrtResource, Immediate), ..., probably #757's case.

Limits: one title, one run each way. No frame is presented yet.

@adriadam10

Copy link
Copy Markdown
Collaborator

Checked the lookup move is behaviour-preserving, the fallback only runs on a missing rectangle (any other failure still throws), and primitive types 7/17 take the same rect-list path. Build + ctest of libSceAgcDriver green (273/273, agc_driver_prepared_graphics passes), CI green on this head, and several title runs in the thread confirm it. Merging.

Note: #2261 touches the same lines in Draw.cpp; whichever lands second needs a rebase.

@adriadam10
adriadam10 merged commit a02e0a1 into boykopovar:main Oct 10, 2026
6 checks passed
SleglJan pushed a commit to SleglJan/AnyPS5 that referenced this pull request Oct 10, 2026
…ngle-fallback

fix(agc): prepare a rect-list draw's missing rectangle at draw from its prepared stages
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agc libSceAgc*

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Rect-list draw aborts with "prepared rectangle artifacts are missing" when its pixel variant was prepared at draw

10 participants