Skip to content

fix(agc): zero-fill a vertex fetch past the record count - #2573

Merged
adriadam10 merged 1 commit into
boykopovar:mainfrom
oneandonlydean:fix/carry-2241
Oct 10, 2026
Merged

adriadam10 merged 1 commit into
boykopovar:mainfrom
oneandonlydean:fix/carry-2241

Conversation

@oneandonlydean

Copy link
Copy Markdown
Collaborator

Carrying @danzaio's fix for #2241 while PR intake is paused. The change is theirs (from danzaio/AnyPS5:fix/2241-oob-vertex-fetch, fd3ac4e), with its three commits squashed and rebased onto current main.

What

A strided vertex fetch at or past the descriptor's num_records now reads (0, 0, 0, 0) for OOB_SELECT 0 and 1 instead of throwing. VertexBufferReadSize spans the whole fetch. The staging copy reads the record bytes and zero-fills from num_records * stride onward. Each such fetch gets its own copy, outside the shared copies of its sibling attributes, the host-import in-place path and the draw-snapshot cache. OOB_SELECT 2 and 3 still throw past num_records, since each needs its own rule. Zero-stride descriptors keep their existing checks (#1769 and the later OOB_SELECT rules for them).

Rebase note: since the branch's base, main added in-place vertex reads from host imports and a zero buffer for out-of-range zero-stride fetches. The past-records fetches go alongside these, are excluded from the in-place path, and get the same per-attribute handle and offset mapping. The zero-stride byte check keeps ZeroStrideAvailableBytes.

Why

Fixes #2241. Astro's Playroom (PPSA01325) draws its post-process and composite passes as a 4-vertex triangle strip over a 3-record vertex buffer, and aborts:

[videoout] presentation failed: AGC graphics: vertex fetch exceeds descriptor record count

simonbbby measured the hardware result on RDNA2 (gfx1036) with tools/hw-oracle in the issue. With OOB_SELECT 0 or 1, indices past the records return 0 in all four components, W included, unlike Vulkan's robustBufferAccess (0, 0, 0, 1). OOB_SELECT 2 and 3 follow other rules, measured in the same thread.

Tested

  • The author's runs: the validation tests cover VertexBufferReadSize for OOB_SELECT 0 to 3, vertexZeroFillTests covers the zero-padded copy, and vertexZeroFillMergeTests covers the split from shared copies. simonbbby's agc_driver_vertex_fetch_past_records execution test (on their branch) also passes on the author's branch, on an RTX 4050 on Windows. It covers an in-range draw that follows a past-records draw at the same address.
  • On current main 092e133: the branch merges cleanly and tools/check_conventions.py passes. CI runs the build and tests.

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

A strided vertex fetch whose index is at or past the descriptor's num_records threw and aborted the title. PPSA01325 draws its fullscreen composite as a 4-vertex strip over a 3-record buffer, so the fourth vertex past the records stopped presentation.

Hardware returns (0, 0, 0, 0) for such a fetch with OOB_SELECT 0 and 1, measured on RDNA2 gfx1036 with tools/hw-oracle in boykopovar#2241. VertexBufferReadSize now spans the whole fetch, and the staging copy reads the record bytes then zero-fills from num_records * stride onward. Each such fetch gets its own copy, outside the shared copies of its sibling attributes, the host-import in-place path and the draw-snapshot cache. OOB_SELECT 2 and 3 keep throwing past num_records, since each needs its own rule. Recorded in docs/dev/TechnicalDebt.md.
@github-actions

github-actions Bot commented Oct 10, 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
#1940 docs/dev/TechnicalDebt.md L420

@github-actions github-actions Bot removed the needs rebase Conflicts with main, rebase needed label Oct 10, 2026
@danzaio

danzaio commented Oct 10, 2026

Copy link
Copy Markdown
Contributor

Validated the carried branch on real hardware: RTX 4050 laptop, Windows, MinGW 15.2 build of 5e32689, ANYPS5_GPU=4050. agc_driver_graphics passes in about 14s, including the vertexZeroFillTests and vertexZeroFillMergeTests. AI-assisted: yes.

@adriadam10

Copy link
Copy Markdown
Collaborator

Checked on current main: build + ctest for libSceAgcDriver (agc_driver_graphics, agc_driver_prepared_graphics pass), the new tests fail to build without the change, OOB_SELECT 2/3 and zero-stride paths unchanged, the TechnicalDebt entry records the HW measurement from #2241. Merging.

Note: this conflicts with #1426 (Draw.cpp) and #1940 (TechnicalDebt.md), so whichever lands second needs a rebase.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agc libSceAgc* docs

Projects

None yet

Development

Successfully merging this pull request may close these issues.

PPSA01325: a 4-vertex strip over a 3-record vertex buffer stops on "vertex fetch exceeds descriptor record count"

3 participants