Skip to content

fix(agc): storage access to a depth surface's stencil plane through its stencil aspect - #2325

Closed
fisherjoey wants to merge 9 commits into
boykopovar:mainfrom
fisherjoey:fix/agc-stencil-plane-storage
Closed

fisherjoey wants to merge 9 commits into
boykopovar:mainfrom
fisherjoey:fix/agc-stencil-plane-storage

Conversation

@fisherjoey

Copy link
Copy Markdown
Contributor

What

Storage-image access to a depth surface's stencil plane. #425 handles the depth plane through Transfer and a writer. This change extends that model to the stencil aspect:

  • Transfer takes an aspect. The stencil plane needs an 8-bit storage format and a single layer; anything else still throws.
  • DepthSurface keeps a stencil writer next to the depth one, and TakeWrites and ApplyFastClear handle both planes.
  • SeedStorageFromStencil seeds it, and cachedStorageTexture calls it instead of throwing.

Depends on #425.

The diff shows #425's commits until it merges, since GitHub can't stack a PR on a branch in another fork. Review 598f788 only. #1684 and #1842 also add stencil storage, against main and in a different way, so only one of the two approaches should land.

Tested

Linux (Nobara 44, kernel 7.2), GCC 16, RTX 5070 Ti with NVIDIA 595.91.07, and RADV.

Checklist

MichonGoddijn231849 and others added 9 commits October 8, 2026 17:20
Titles fast-clear a depth surface by filling its HTILE with ZMASK 0
(DMA_DATA immediate fills or the buffer-fill kernel) instead of drawing.
Depth surfaces were only cleared when they were made, so every later
frame kept the previous frame's depth and stencil and most draws failed
the depth test.

The depth target now records DB_HTILE_DATA_BASE. A uniform fill whose
ZMASK is 0 and which covers a surface's HTILE marks the surface cleared;
its next use as a target or a texture clears it to DB_DEPTH_CLEAR and
DB_STENCIL_CLEAR.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ds; HTILE only with TILE_SURFACE_ENABLE

A fill over a depth surface's whole HTILE fast-clears the depth when ZMask is 0
and, when the HTILE holds the stencil state (TILE_STENCIL_DISABLE clear), the
stencil when SMem is 0; a fill writing an aspect's fields otherwise cancels its
pending clear. DB_HTILE_DATA_BASE is taken only with DB_Z_INFO.TILE_SURFACE_ENABLE.
Tests cover the decode and HtileFillClears/HtileFillCovers.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…erage and clear value as inferred

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
A whole-HTILE fill of ZMask 0 clears the depth to DB_DEPTH_CLEAR at the next draw; a fill shorter
than the HTILE and an expanded fill (ZMask 0xf) clear nothing.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…el DCBs; a CPU-stored fill clears too

agc_driver_depth_fast_clear_submit submits the fills the title uses (a DMA_DATA immediate
fill and the fill kernel's dispatch) over the HTILE and checks the next depth-tested draw;
a depth-only fill over an HTILE with stencil keeps the stencil (a stencil-tested draw).
The depth metadata note now also follows the CPU fallback of a fill the device could not
store.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Sampling a depth surface as a 2D array, a cube or its R16_UINT integer bits copies its
depth planes into a per-use image: each slice a depth surface holds comes from that
surface's plane, any other slice from guest memory. A storage image over a depth
surface's memory takes the depth plane's bits when it is looked up, and the depth
surface takes the image's bits back at its next use. Depth surfaces can be transfer
sources; textures copied per use never serve a draw template or the stage-A fast path.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…owing; seeding applies a pending fast clear

A storage T# at a depth surface's stencil address matched DepthSurfaceAt,
but nothing seeds a storage image from the stencil aspect or takes its
writes back, so a store there landed in an image the depth surface never
read (PPSA26344's deferred-decal pass ORs 0x04 into the stencil this
way). It throws as on main until the stencil plane is handled.
SeedStorageFromDepth now applies a pending HTILE fast clear before
taking writes and copying, as the sampled paths do.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 9, 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
#2156 core/libs/prx/libSceAgcDriver/Execution/include/Pm4.hpp L142
#2169 core/libs/prx/libSceAgcDriver/Execution/src/Driver/Memory/BufferFill.cpp L4, L203
core/libs/prx/libSceAgcDriver/Execution/src/Driver/Packets/PacketMemory.cpp L7, L58
core/libs/prx/libSceAgcDriver/Graphics/include/DepthSurface.hpp L17-18
core/libs/prx/libSceAgcDriver/Graphics/include/State.hpp L65, L154-155
core/libs/prx/libSceAgcDriver/Graphics/src/DepthSurface.cpp L38, L107, L151-152, L155, L172
core/libs/prx/libSceAgcDriver/tests/Graphics.cpp L6, L710, L724
core/libs/prx/libSceAgcDriver/tests/execution/DepthFastClear.cpp
core/libs/prx/libSceAgcDriver/tests/execution/DepthFastClearHarness.hpp
core/libs/prx/libSceAgcDriver/tests/execution/DepthFastClearSubmit.cpp
#2229 core/libs/prx/libSceAgcDriver/Graphics/include/DepthSurface.hpp L17-18
core/libs/prx/libSceAgcDriver/Graphics/include/State.hpp L65, L154-155
core/libs/prx/libSceAgcDriver/Graphics/src/DepthSurface.cpp L12-13, L152-153, L155
#2261 docs/dev/TechnicalDebt.md L235

@Kikoarl

Kikoarl commented Oct 9, 2026

Copy link
Copy Markdown
Contributor

Tested on Linux (CachyOS x86_64, Intel RPL-S iGPU / Mesa 26.3.0-devel / Vulkan 1.4.363, GCC 16.2.1) at 598f7883:

  • Build: Built cleanly in RAM (/tmp/anyps5_build) with zero warnings/errors.
  • Conventions: python3 tools/check_conventions.py --base origin/main --head HEAD -> PASS (0 errors).
  • Verification: Verified depth/stencil plane separation and storage access via stencil aspect in PacketMemory.cpp. Tested cleanly across Vulkan pipeline.

LGTM!

@fisherjoey

Copy link
Copy Markdown
Contributor Author

I missed #2076 when I opened this. @jdmagic opened it nine hours before this one, and it does the same thing: both stack on #425 and route a storage T# at a depth surface's stencil plane through Transfer with the stencil aspect (SeedStorageFromStencil, DepthStencilPlaneAt, a stencil writer next to the depth one). Most of the stencil code is identical.

#2076 came first, so that's the one to review. This PR adds two things on top of it:

  • HTILE stencil fast clears: decodeDepth reads the HTILE address and whether HTILE holds stencil state (TILE_STENCIL_DISABLE), and a whole-HTILE fill with SMem 0 clears the stencil plane (HtileFillClears, HtileFillCovers).
  • agc_driver_stencil_plane_storage: a draw writes stencil 0x5a, a compute image_load must read 0x5a, and an image_store of 42 must make stencil EQUAL 42 pass. It fails on feat(agc): depth planes sampled as 2D arrays, cubes and integer views #425's head and passes here.

I can't open a follow-up PR on top of #2076 (new PRs from me are closed by intake for now), so I'm closing this one. Both parts are in commit 598f788 on fisherjoey/AnyPS5 fix/agc-stencil-plane-storage, on #425's head 62b1e55. @jdmagic, feel free to cherry-pick either part into #2076.

AI-assisted: yes

jdmagic pushed a commit to jdmagic/AnyPS5 that referenced this pull request Oct 11, 2026
A stencil draw fills a D32S8 surface's stencil plane; image_load through an
8-bit T# at the stencil address reads it back, and image_store over the whole
plane replaces it, which a later stencil test sees.

Cherry-picked from 598f788 (closed boykopovar#2325).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.

3 participants