Skip to content

feat(agc): depth planes sampled as 2D arrays, cubes and integer views - #425

Merged
oneandonlydean merged 3 commits into
boykopovar:mainfrom
MichonGoddijn231849:feat/depth-surface-reads
Oct 12, 2026
Merged

oneandonlydean merged 3 commits into
boykopovar:mainfrom
MichonGoddijn231849:feat/depth-surface-reads

Conversation

@MichonGoddijn231849

@MichonGoddijn231849 MichonGoddijn231849 commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor

What

Depth surfaces could only be sampled as one 2D slice of their own format. 2D arrays, cubes and the R16_UINT integer view of a D16 plane were refused with sampling the depth plane of depth surface ... is not implemented.

They now work:

  • A one-slice 2D array views the depth image as an array.
  • Several slices, a cube (6 faces) or an integer view of a D16 plane are copied into a per-use image of consecutive slices (DepthPlaneCopy):
    • a slice a depth surface holds comes from that surface's depth plane, after its pending fast clear;
    • any other slice comes from guest memory, detiled (DepthSliceBytes apart).
  • A depth-bits R16_UINT view (an R16_UINT T# with a depth swizzle) keeps the depth copy, because the shader converts the sampled depth to its bits itself. GTA V's compute 0x242d4a200 samples a D16 plane array that way (reported by @tibzejoker).
  • Such a texture is re-copied at every use, so it never serves a draw template or the stage-A fast path.
  • Depth surfaces can now be transfer sources.

Storage-image access to depth surfaces was part of this PR at first. #4500 implements it, with stencil planes and the reused-memory fall-through, so it is no longer in this PR.

Part of #1409 (the sampled views; #4500 covers its storage half).

Tested

Windows 11 Pro, AMD Ryzen 5 7600, NVIDIA GeForce RTX 5080 (driver 32.0.16.1074), MinGW-w64 GCC 15.2.0, on main 82b1b2e7a.

  • New agc_driver_depth_plane_sampling loads row 0 through each view and pins the values:

    • a 3-slice D32 2D array (slice 0 from a drawn surface, slices 1 and 2 from guest memory);
    • a D32 cube, all six faces;
    • a D16 plane as R16_UINT;
    • a D16 depth-bits R16_UINT array, both slices' raw values;
    • a plane array from base slice 1, still refused.

    It fails on main (the array is refused) and without the depth-bits format gate (with GTA V's message).

  • agc_driver_graphics, depth_compare_copy, depth_storage_reuse, depth_fast_clear(_submit), depth_bias_per_face, pending_exact_surface, prepared_graphics and check_conventions.py pass.

  • GTA V (PPSA04264): earlier heads of this PR (with the storage half) took the Prologue past its first depth-plane read. I have not rerun the title on this head.

Checklist

  • Based on current main; no other open PR implements the same functions (feat(libSceAgcDriver): storage image access to depth surfaces #4500 is the storage half)
  • 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
  • New third-party code is a submodule built from source
  • Generic behaviour, not specific to one title
  • Depends on: none
  • AI-assisted: yes. Written with Claude (Anthropic) under my direction; I reviewed and tested it.

🤖 Generated with Claude Code

@ThisIsAkill

Copy link
Copy Markdown
Contributor

A case from PPSA21567 (Astro Bot) for this PR's depth storage-image path, in case it helps. Linux, on #426 with main and other local changes, so not clean main. The facts come from a local-only trace; nothing below is a decision.

What the title does with one allocation (base 0x53a500000, 960x540, 4 bytes per texel). T# and DB fields are decoded with Mesa's gfx10-rsrc.json / gfx10.json; swizzle names are from addrlib addrtypes.h.

Use Format Swizzle Metadata
Depth target (DB_Z_INFO 0x80000183, DB_DEPTH_VIEW 0) Z_32_FLOAT 24 SW_64KB_Z_X TILE_SURFACE_ENABLE 0, DB_HTILE_DATA_BASE 0, so no HTILE
Compute storage and texture views R32_FLOAT (guest format 22) 24 SW_64KB_Z_X none
Compute storage and texture views B10G11R11 (guest format 36) 27 SW_64KB_R_X DCC: COMPRESSION_EN 1, WRITE_COMPRESS_ENABLE 1, metadata at about 0x5708e4000

Every view has the same base, extent, slice 0 and mip 0. The colour view uses the render-target swizzle and DCC; the depth target and the R32F views use the depth swizzle.

Order of uses, every frame once the scene starts:

  1. A compute shader writes the memory as R32F storage, and several compute shaders read it as R32F.
  2. About 50 draws bind it as the D32 depth target.
  3. Two compute shaders then bind the B10G11R11 view as both a sampled image and a storage image. Both read it before writing it (image_sample_lz / image_load, then image_store). In one of them the two T# registers hold the same B10G11R11 descriptor, so it updates the view in place.

In earlier frames (before the depth pass appears) the memory is only ever used through the R32F and B10G11R11 views.

On this branch, step 3 throws storage image access to depth surface 0x53a500000 (960x540, vk format 126) as a 960x540 image of vk format 122, then sampling the depth plane ... as a texture of guest format 36. Both are refused because the views are routed into the depth path by base address.

What I could not observe: whether the B10G11R11 read in step 3 depends on the bytes the depth pass left. That depends on the view's DCC keys. The trace sees them as 0000 at the first bind and uncompressed at every bind and depth bind after that, with no fills over them. But the driver itself marks keys uncompressed after its write-backs (MarkDccUncompressed), so inside the emulator "uncompressed" doesn't show what the hardware keys would be.

A suggestion, for you to judge:

  1. Match a view to a depth surface by layout, not only by base address. Only a depth (Z) swizzle with the depth format's element size and no colour metadata is a view of the depth surface. The R32F views here qualify; the B10G11R11 views would take the ordinary colour and storage path over guest memory instead of throwing.
  2. When a view with a different layout touches the allocation, write the depth image back to guest memory in its own layout and mark the surface stale. Guest memory is then the source of truth, so the colour path reads the same bytes the hardware would, whatever the shader means by them.
  3. On the next depth bind of a stale surface, reseed the depth image from guest memory. Here the R32F compute pass rewrites the surface before the depth draws anyway.

That reproduces the hardware without guessing the title's intent, as long as the colour path itself is exact. The one remaining gap is the DCC keys being rewritten as uncompressed after write-backs. I'm trying this locally and can report how it behaves, if that's useful.

@oneandonlydean

Copy link
Copy Markdown
Collaborator

@boykopovar this one needs your call on where depth bits live when something other than the depth path reads them. This PR copies the slices a host depth surface holds from its depth image and reads every other slice from guest memory. On main, depth surfaces never write back to guest memory (DepthSurface.cpp only creates and clears the image), so a slice that a host depth surface wrote but no longer holds reads stale bytes without an error.

ThisIsAkill described the other model in #425 (comment): write the depth image back to guest memory when a view with another layout touches it, mark the surface stale, and reseed it at the next depth bind. That changes how depth surfaces work for every title, so it's your decision. My read: the write-back model is the exact one, and this PR's reads are exact only while no host depth surface wrote those slices. It also has no unit test yet.

@MichonGoddijn231849

MichonGoddijn231849 commented Oct 4, 2026 •

Copy link
Copy Markdown
Contributor Author

@ThisIsAkill, thanks, that trace is very useful. You're both right about the gap. This PR copies the slices a host depth surface still holds and reads the rest from guest memory. Because depth surfaces never write back on main, a slice the surface wrote but no longer holds reads stale bytes.

My proposal, for @boykopovar to decide:

  1. In this PR: match a view to a depth surface by layout, not only by base address. Only a depth (Z) swizzle with the depth format's element size and no colour metadata counts as a view of the depth plane. Other views (the B10G11R11 render-target swizzle with DCC in Astro Bot) take the ordinary colour and storage path instead of throwing. I'll add the unit test Dean asked for.
  2. Separately, because it changes every title: the write-back model ThisIsAkill describes. The depth image is written back to guest memory when a view with another layout touches it, the surface is marked stale, and it is reseeded from guest memory at the next depth bind. That is the exact model, and multisampled targets (feat(agc): multisampled color and depth targets with CB resolves #419) need the same machinery, so I'd do both in one follow-up.

If you'd rather go straight to write-back, I'll fold it into this PR instead.

@MichonGoddijn231849

Copy link
Copy Markdown
Contributor Author

Restacked on the updated #374 (per-aspect HTILE clears) and #294; both still ship inside this PR until they merge. The fast-clear merge keeps this PR's reset of the storage link (writer, seeded) on a clear, now only when an aspect is actually cleared. Build and ctest are clean apart from the failures main has locally. The layout-matching change I proposed above waits for @boykopovar's call.

@oneandonlydean

Copy link
Copy Markdown
Collaborator

Thanks for the restack. Step 1 sounds right to me as long as one case keeps throwing. In ThisIsAkill's trace the B10G11R11 view comes right after about 50 depth draws into the same memory. Without the write-back, the ordinary colour path would read guest memory the depth image never wrote, so today's refusal would turn into a silent stale read. Could step 1 still refuse a view with another layout while a host depth surface at that address holds depth newer than guest memory, and route only views that alias no live depth surface? The write-back model itself is still @boykopovar's call.

@github-actions github-actions Bot added the needs rebase Conflicts with main, rebase needed label Oct 4, 2026
@github-actions github-actions Bot added needs rebase Conflicts with main, rebase needed and removed needs rebase Conflicts with main, rebase needed labels Oct 4, 2026
@MichonGoddijn231849

Copy link
Copy Markdown
Contributor Author

Agreed, that's the right line: a view with another layout should only take the colour path when no live host depth surface at that address holds depth newer than guest memory, and keep throwing otherwise.

One thing to coordinate: #454 (@SP4C3B4R-8) changes the same routing in DepthSurface::Sampled. A texture whose format doesn't match the depth view returns nullptr there and reads guest memory. That's my step 1, but without the check you describe, so it would read stale bytes after ThisIsAkill's ~50 depth draws. I'd rather not have two PRs change that path. I suggest the routing plus your live-surface refusal goes into #454, and this PR stays with arrays, cubes, the R16_UINT view and storage access. If you or @SP4C3B4R-8 would rather I add it here instead, I will.

Rebased onto current main (and today's rebase of #374). The conflict was in cachedStorageTexture, where main renamed the resource to viewed for views past the last mip (#490). The depth seeding now sits on top of main's lookup, and main's own depth-surface refusal there is replaced by it as before. Build and ctest are clean apart from the failures main has locally.

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

Copy link
Copy Markdown
Collaborator

That split sounds right to me. #454's author already plans the same rule: retire the depth surface when a colour target, a storage write or a CPU write covers its range, and keep the throw while it's still the latest writer. So moving the other-layout routing there, together with that refusal, keeps one PR on that path. They mentioned being away until 7 October and planned to build on this branch.

So this PR would stay with arrays, cubes, the R16_UINT view and storage access, and none of those reroute other-layout views. The write-back model is a separate question, and it's still with the maintainer.

@MichonGoddijn231849

Copy link
Copy Markdown
Contributor Author

Thanks, then that's the split. This PR stays with arrays, cubes, the R16_UINT view and storage access. It never reroutes views with another layout: those still throw here, and the routing with the live-surface refusal goes into #454. I'll keep this branch stable for @SP4C3B4R-8 to build on.

Restacked on today's rebase of #374 so the commits it carries match #374's head (now b0414a9), with no other changes. Builds; the driver tests pass apart from agc_driver_scalar_sop1, which fails without this PR too.

@Celegans12

Copy link
Copy Markdown
Contributor

Ghost of Yōtei (PPSA26344) writes the stencil plane through this storage path, and on this branch that would stop throwing without being handled, so here's the case.

Its deferred-decal compute shader (0x800027c200) does a per-texel read-modify-write of its 3840x2160 D32S8 target's stencil: it loads the value, ORs in 0x04 and stores it back through an 8_UINT T# at the DB stencil base (0x5004850000, same swizzle as the DB). DB_STENCIL_INFO has TILE_STENCIL_DISABLE = 1, so there's no HTILE stencil and the T# is exactly the plane the DB tests. On main the store throws in cachedStorageTexture (5 skipped dispatches per run for us).

On b0414a9, DepthSurfaceAt matches the stencil address, but SeedStorageFromDepth only looks for target.address and Transfer copies only the depth aspect. So the store lands in an R8 image over guest memory with no seed and no take-back, while the shader's stencil loads still read the D32S8 image through DepthSurface::Sampled. Bit 0x04 never reaches the depth surface, and nothing reports it. Vulkan has no storage view of the plane either: neither NVIDIA 610.62 nor lavapipe exposes STORAGE_IMAGE on D32_SFLOAT_S8_UINT or S8_UINT, and RADV refuses stencil formats.

Things I noticed while reading, in case they help under whichever model gets picked:

  • there's one writer/seeded/writerLayer slot per surface, so a dispatch storing to both planes would need state per aspect;
  • SeedStorageFromDepth calls TakeWrites but not ApplyFastClear before seeding, which matters for Z too;
  • a stencil kept in HTILE (htileStencil) would still have to throw; Yōtei doesn't hit that.

A test that fails on both main and this branch: clear a D32S8 surface to stencil 0x11, look up R8_UINT storage at stencilAddress and expect 0x11, write 0x15, bind it as depth again and expect 0x15 in the stencil aspect. I can send the request file and register dump, or run Yōtei on this branch once the stencil plane is in.

Details
  • DB_Z_INFO 0xa0000183 (Z_32_FLOAT, SW 24, HTILE at 0x50050c0000), DB_STENCIL_INFO 0x20000181 (STENCIL_8, SW 24). Stencil base 0x5004850000 = Z base 0x5002870000 + DepthSliceBytes(3840x2160, 4).
  • Stencil T# (SRT+0xc0): 50048500 c0500000 021bc3bf 91800924 0 00700000 0 0.
  • 0x800027c200: image_load glc pc 0xa8 and 0x400c, v_or_b32 at 0x3ce4 (bit 0x04) and 0x4018, image_store glc pc 0x401c, at each invocation's own pixel.
  • b0414a9: DepthSurface.cpp:116-118 (writer slot), :141 (depth aspect in Transfer), :451 (SeedStorageFromDepth), :494 (DepthSurfaceAt); ShaderResources.cpp:562.
  • Mesa: ac_descriptors.c:570-571 (stencil T# at stencil_offset), radv_formats.c:118-119.

@SP4C3B4R-8

Copy link
Copy Markdown
Contributor

@MichonGoddijn231849 agreed on the split, thanks for keeping the branch stable. #454 takes the routing of views with another layout in DepthSurface::Sampled, with the rule from Dean's review: the depth surface is retired when a colour target, a storage write or a CPU write covers its range (the read then goes to guest memory), and the refusal stays while a live depth surface still holds depth newer than guest memory. I'll rebuild #454 on top of this branch (b0414a9f) rather than on main, list #425 under Depends on, and add tests for both orders.

@Pacuka's case on #454 (a 2848x1600 R32 texture over a 1024x1024 D32 surface) should fall under the same rule; I'll ask for a run once the branch is up.

Written with AI assistance (Claude Code).

@xXPBSXx

xXPBSXx commented Oct 12, 2026

Copy link
Copy Markdown
Contributor

Repeat runs for the branch above (https://github.com/xXPBSXx/AnyPS5/tree/test/depth-harmony-425-on-main, 5ef0e5144), as promised on #1409: agc_driver_depth_storage_reuse, agc_driver_depth_compare_copy, agc_driver_depth_fast_clear and agc_driver_depth_fast_clear_submit each ran three times in a row, 12 of 12 passes, no flicker (Windows 10, MinGW-w64 GCC 15.2.0, Release, RTX 4080 SUPER, built -j2). With the earlier single run of depth_bias_per_face, pending_exact_surface and agc_driver_graphics that covers the depth tests of the tree. Not checked: Linux, other GPUs, a rendering check of the cube map.

AI-assisted (Claude Code).

@oneandonlydean

Copy link
Copy Markdown
Collaborator

This needs a rebase on main and two fixes before it can go in:

Merged with main 27873b0 the rest holds: agc|shader is 459 of 459, and the new test fails on main's sources with main's refusal.

A patch that does the two fixes, if it helps:

--- a/core/libs/prx/libSceAgcDriver/Graphics/src/DepthSurface.cpp
+++ b/core/libs/prx/libSceAgcDriver/Graphics/src/DepthSurface.cpp
@@ -441,6 +441,7 @@ std::shared_ptr<Texture> DepthSurfaceTexture(const Context& context, std::span<c
     const bool cube = resource.dimension == TextureDimension::kCube;
     const bool layered = cube || (resource.dimension == TextureDimension::k2DArray && resource.depthOrLastArray != 0);
     if (stencil || (!layered && !integer)) return (*found)->Sampled(words, resource, components);
+    Require((*found)->hostFormat == base.format, "sampling several slices or an integer view of a depth plane that the device stores in another depth format is not implemented");
     const auto copyFormat = integer ? VK_FORMAT_R16_UINT : d16 ? VK_FORMAT_R16_UNORM : VK_FORMAT_R32_SFLOAT;
     const auto layers = cube ? 6u : layered ? resource.depthOrLastArray + 1u : 1u;
     if ((format != copyFormat && !depthBits) || resource.width != base.extent.width || resource.height != base.extent.height || resource.baseLevel != 0 || resource.lastLevel != 0 || resource.baseArray != 0 || (cube && resource.depthOrLastArray != 0 && resource.depthOrLastArray != 5) || (resource.dimension != TextureDimension::k2D && resource.dimension != TextureDimension::k2DArray && !cube)) {
--- a/core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
+++ b/core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp
@@ -671,6 +671,11 @@ Texture::Texture(const Context& context, VkImage depthImage, VkFormat depthForma
     viewInfo.subresourceRange = {aspect, 0, 1, 0, viewType == VK_IMAGE_VIEW_TYPE_2D ? 1u : VK_REMAINING_ARRAY_LAYERS};
     Check(context.Function<PFN_vkCreateImageView>("vkCreateImageView")(context.device, &viewInfo, nullptr, &view), "vkCreateImageView depth plane");
     viewRange = {viewInfo.viewType, viewInfo.subresourceRange.levelCount, viewInfo.subresourceRange.layerCount};
+    if (viewType != VK_IMAGE_VIEW_TYPE_2D_ARRAY) return;
+    viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
+    viewInfo.subresourceRange.layerCount = 1;
+    Check(context.Function<PFN_vkCreateImageView>("vkCreateImageView")(context.device, &viewInfo, nullptr, &firstLayerView), "vkCreateImageView depth plane first layer");
+    firstLayerRange = {viewInfo.viewType, viewInfo.subresourceRange.levelCount, viewInfo.subresourceRange.layerCount};
 }
 
 Texture::~Texture() {

Data point from a title we test with: on main it stops before its title screen at storage image access to depth/stencil surface 0x53a500000 is not implemented (compute shader 0x50073d500); with #4500 it reaches sampling the depth plane of depth surface 0x528c30000 (1536x1536, vk format 126) ... dimension 2 ... is not implemented (compute shader 0x500599900); with #4500 and this head merged onto main 682ef0c it runs 330 s with no stop, error line or device loss. Title and menu then run at 0.78 and 0.63 fps, which is the per-use copy; #2490 and #2491 are for that.

MichonGoddijn231849 and others added 3 commits October 13, 2026 12:11
A texture over a depth surface could only sample one 2D slice of the
plane's own format; 2D arrays, cubes and the R16_UINT view of a D16
plane were refused ("sampling the depth plane of depth surface ... is
not implemented"). A one-slice 2D array now views the depth image as an
array. Several slices, a cube, or an integer view of a D16 plane are
copied into a DepthPlaneCopy image at every use: each slice from the
depth surface bound at its address (base plus one 64 KiB-block depth
slice per layer), otherwise from guest memory, detiled. A depth-bits
R16_UINT view (a depth swizzle) keeps the depth copy, since the shader
converts the sampled depth to its bits itself (GTA V's compute
0x242d4a200 samples a D16 plane array that way, reported by
@tibzejoker). Such a texture is not kept in resource templates.

Storage-image access to depth surfaces is no longer part of this
change; boykopovar#4500 implements it.

TechnicalDebt (Depth plane copies) and ARCHITECTURE describe the copy and
what still throws.
image_load of row 0 through each view, against a live surface drawn at a
known depth and guest-memory slices filled with known values: a 3-slice
D32 2D array, a D32 cube (all six faces), a D16 plane as R16_UINT, and a
D16 depth-bits R16_UINT array (both slices' raw values). A plane array
from base slice 1 is still refused. Fails on main (the array is refused)
and without the depth-bits format gate (GTA V's refusal message).
… of another host format

A 2D-array T# over a depth surface bound to a shader image declared 2D had
no first-layer view, so the descriptor got a null view and the shader read 0.
The depth plane texture now creates the 2D view of its first slice when its
view is a 2D array, for the depth image itself and for the plane copy.

A 16-bit depth surface with stencil may be stored as D24_UNORM_S8_UINT or
D32_SFLOAT_S8_UINT. The plane copy sizes and copies slices by the guest
format, so several slices or an R16_UINT view of such a surface now throw.
@oneandonlydean
oneandonlydean force-pushed the feat/depth-surface-reads branch from e6d75b4 to 90d899d Compare October 12, 2026 23:30
@oneandonlydean
oneandonlydean dismissed stale reviews from adriadam10 and adriadam10 October 12, 2026 23:31

The points of this review are met on the sampled half that remains (one per-use flag, the reuse check, pinned execution test, debt entry, ARCHITECTURE note); the storage half moved to #4500.

@oneandonlydean

Copy link
Copy Markdown
Collaborator

Pushed the rebase and the two fixes from the comment above so this can go in (head 90d899d). Your two commits are unchanged apart from the conflict in Sampled, which takes hostFormat from #3846 and keeps your viewType; the debt entry moved to docs/dev/debt/libSceAgcDriver.md. The third commit adds the first-slice view for 2D array depth views and the refusal when the device stores the plane in another depth format, with a case for each (DepthPlaneSampling.cpp, DepthSurfaceReuse.cpp). agc|shader is 461 of 461 here, and a full build is running: https://github.com/boykopovar/AnyPS5/actions/runs/38322596395. I'll merge when it is green.

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

github-actions Bot commented Oct 12, 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
#2076 core/libs/prx/libSceAgcDriver/Graphics/src/DepthSurface.cpp L47, L143, L152-154
core/libs/prx/libSceAgcDriver/tests/DepthSurfaceReuse.cpp L183
#4500 core/libs/prx/libSceAgcDriver/Graphics/src/DepthSurface.cpp L47, L143, L152-154
core/libs/prx/libSceAgcDriver/tests/DepthSurfaceReuse.cpp L183
#4646 core/libs/prx/libSceAgcDriver/Graphics/src/DepthSurface.cpp L240-241, L291, L294-295
#4683 core/libs/prx/libSceAgcDriver/Graphics/src/DepthSurface.cpp L47, L241-242, L290-291, L296-312
#4747 core/libs/prx/libSceAgcDriver/Graphics/include/Texture.hpp L69-70, L128
core/libs/prx/libSceAgcDriver/Graphics/src/Texture.cpp L478, L537-539
#4820 core/libs/prx/libSceAgcDriver/Graphics/src/ShaderResources.cpp L1719

@oneandonlydean
oneandonlydean merged commit 1c5e628 into boykopovar:main Oct 12, 2026
8 checks passed
danielradosa added a commit to danielradosa/AnyPS5 that referenced this pull request Oct 13, 2026
…ed path

SILENT HILL: The Short Message (PPSA10112) stopped at
"compute shader 0x2007a70000: AGC graphics: storage image access to depth/stencil surface
0x205da70000 is not implemented (storage=1024x1024 guest format=7 mip=0 dimension=2 tile=4)":
a compute shader binds a depth surface as a 2D array storage image of more than one layer.
Main's depth plane storage path (boykopovar#4500/boykopovar#2076), which replaced our boykopovar#425 port in the
e965b46 merge, takes one layer only.

DepthSurface::Storage now leaves a depth (not stencil) 2D array from layer 0 to the ordinary
storage path, and cachedStorageTexture seeds that image from the depth slices again
(SeedStorageFromDepth: every layer that is a depth surface of its own is copied in, the
surface becomes its writer and takes its writes back when it is drawn to; the code the merge
left without a caller). Stencil arrays and arrays from a later layer still refuse.

Tests: agc_driver_depth_storage expects the two-layer depth view to be left to that path;
agc_driver_depth_storage_dispatch now stores through a two-layer 2D array view and requires
the depth test to see layer 0's stored row (was: expected the refusal). test_fast 1126/1127
(windows_import_modules = Defender WinError 225).
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.