Repository navigation
fix(agc): drop stale depth planes a uniform fill overwrites - #10882
Conversation
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A pipelined DMA fill never reaches NoteDepthMetadataFill, so dropping the stale plane there left the old depth in the host image. The drop now records the plane clear itself, shares the plane-fill test with NoteDepthMetadataFill, and skips fills that miss every stale plane. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
@EagleBearerYS: #9533, #9717 and #9742 change the lines next to this PR's in |
|
Some comparisons could not be completed because a pull request conflicts with the base branch. Review these shared files manually before concluding that there is no overlap.
|
|
I checked the 21 pull requests the overlap bot could not compare (they conflict with |
|
Thanks for checking the uncomparable PRs. I verified #1368 is still open; it adds |
|
@TibixDev: #1368 adds |
|
Validated Focused
The skips concern imports that cannot retain guest write watching. Disabling nonempty depth-plane discards makes the new regression fail at the full-plane discard assertion; restoring the implementation passes and reproduces byte-identical candidate binaries. No title/performance run or prerequisite-stack integration tested. AI-assisted validation, measured on this machine. |
A uniform fill that a multisample colour target absorbs never reaches guest memory, so the depth plane it covers keeps its stale results. The test now also drives storeBufferFill itself. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
A Windows run of this head with the Radeon iGPU and two NVIDIA cards: Windows 11 Home 10.0.26200, WinLibs GCC 15.2.0 r7 (MinGW-w64 UCRT), Release.
AI-assisted: yes (Claude Code) |
✅ NVIDIA GPU test: passedPR head
Failing on main too (3, not counted against this PR)Validated but not compared (1, not in the main baseline's validation pass)Validation IDs already present on main (5 IDs in 480 tests)Skipped (44)ReproduceAutomated build and test on a contributor's NVIDIA machine; it does not replace upstream CI. A new comment is posted for each new push. Full logs. |
|
@JAB-dev #13021 and #13023 conflict with this PR in |
|
@orezraey I found a current-main interaction in the new stale-range rebuild. After a uniform fill discards one depth plane, this new rebuild can remove an unrelated pending stencil plane from the index while its Could you preserve pending stencil ranges when rebuilding the index and add a regression with a stale depth plane plus a separate pending stencil plane? Discard the depth plane, then read the stencil allocation and verify its GPU data is published. Please cover a stencil-only stale surface too. This is a source-path finding in the clean merge with main |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
@oneandonlydean You're right: the rebuild in
|
✅ NVIDIA GPU test: passedPR head
Intermittent validation messages (1, seen once in the parallel run, not reproduced when the test was re-run alone 2 times; not counted against this PR)Unstable on main (3, these also failed in recent main runs on this machine; not counted against this PR)Failing on main too (4, not counted against this PR)Validated but not compared (1, not in the main baseline's validation pass)Validation IDs already present on main (5 IDs in 483 tests)Skipped (46)ReproduceAutomated build and test on a contributor's NVIDIA machine; it does not replace upstream CI. A new comment is posted for each new push. Full logs. |
# Conflicts: # core/libs/prx/libSceAgcDriver/Graphics/include/DepthSurface.hpp # core/libs/prx/libSceAgcDriver/Graphics/src/DepthSurface.cpp
✅ NVIDIA GPU test: passedPR head
Unstable on main (3, these also failed in recent main runs on this machine; not counted against this PR)Failing on main too (3, not counted against this PR)Validated but not compared (1, not in the main baseline's validation pass)Validation IDs already present on main (8 IDs in 527 tests)Skipped (50)ReproduceAutomated build and test on a contributor's NVIDIA machine; it does not replace upstream CI. A new comment is posted for each new push. Full logs. |
✅ AMD GPU test: passedPR head
Unstable on main (1, these also failed in recent main runs on this machine; not counted against this PR)Failing on main too (10, not counted against this PR)Validated but not compared (1, not in the main baseline's validation pass)Validation IDs already present on main (4 IDs in 510 tests)Skipped (53)ReproduceAutomated build and test on a contributor's AMD machine; it does not replace upstream CI. A new comment is posted for each new push. Full logs. |
What
A depth target drawn on the host leaves its plane stale: the results live in the host depth image and are stored to guest memory when something reads that memory. A uniform buffer fill over the whole plane (a depth clear done as a memory fill) is such a read:
storeBufferFillcallsStorageTexture::FlushPending, which callsFlushDepthPlanes, so the stale plane was stored in full, and the fill then overwrote every byte of it. DEATHLOOP (PPSA01670) clears two 3840x2160 D32 planes this way every frame, 32 MiB each.DiscardFilledDepthPlanes(new, called bystoreBufferFillfor uniform fills before its flushes): a stale single-sample depth plane that the fill covers entirely, with a valueNoteDepthMetadataFillwould turn into a plane clear (a depth in 0..1, or a D16 pair; no HTILE fill over the target), drops its stale units instead of storing them and notes the plane clear itself (NotePlaneFill), so the host image is cleared to the filled value at its next use. Partial fills, fills of other values, planes that are syncing, and fills that a native multisample colour target absorbs (they never reach guest memory) are stored as before.FlushDepthPlanesdoes, so a later read of a stencil plane still stores it after a fill discards a depth plane.agc_driver_depth_plane_fill_discardcovers a stencil-only surface beside the discarded plane and a surface with both planes stale.enqueueDmaPacket) does not reachpreparePacketMemory, soNoteDepthMetadataFillis not called for those fills.planeFillDepthis the plane test bothNoteDepthMetadataFilland the drop use, so they cannot disagree.overlapsStalePlanecheck, without the surfaces lock.agc_driver_depth_plane_fill_discard: a stale 384x200 Z_X plane is kept by a shorter fill, a fill starting past it, a fill of -1.0 and a NaN fill; a fill of 1.0 around it drops it with no store counted, and a draw at 0.5 then passes LESS (the plane was cleared to 1.0) with noNoteDepthMetadataFillcall; an exact fill drops it once; a fill of 0.0 makes the same draw fail LESS. It then callsDriver::storeBufferFillitself (throughDriverTestAccess) with a fill of 0.75 over a stale plane: no store is counted, the plane holds 0.75, a draw at 0.5 passes LESS and a later read stores nothing. With thestoreBufferFillcall removed, that part fails with "the driver's fill of 0.75 over the whole stale plane stored the plane first".This PR makes no frame-time claim; see the captures below.
Tested
Windows 11 Pro 26200, AMD Ryzen 7 9700X, NVIDIA GeForce RTX 5070 Ti (driver 616.64), WinLibs GCC, Release. Head
591da8f4df, which containsmaine67cc81869.ANYPS5_REQUIRE_VULKAN=1 ANYPS5_NO_SHADER_CACHE=1 VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation ctest --test-dir build -R "depth|fill|storage|stencil" -V, 3 runs at591da8f4dfand 1 ate67cc81869: 99 of 102 pass each time on the head and 98 of 101 onmain, 0VUID-and no missing-layer message in any log. The extra test isagc_driver_depth_plane_fill_discard. The 3 not counted were not built for those runs (agc_driver_stencil_plane_memory,guest_np_cpp_web_api_title_cloud_storage,guest_system_service_usb_storage);agc_driver_stencil_plane_memorywas then built and passes 3 of 3 on the head with the same variables, 0VUID-.DiscardFilledDepthPlanes: the stencil-only case with "a read of a stencil-only surface's plane stored nothing after another surface's depth plane was discarded", and, with that case removed, the same-surface case with "a read of the stencil plane stored nothing after its surface's depth plane was discarded".tools/check_conventions.py --base origin/main: passes.agc_driver_depth_plane_fill_discard_testsbuilds at591da8f4df; the test skips 3 of 3 runs and fails withANYPS5_REQUIRE_VULKAN=1, so its GPU paths did not run on Linux here.Earlier results at
aa144ce8f5onmain6c7a3256f2:ANYPS5_REQUIRE_VULKAN=1 ANYPS5_NO_SHADER_CACHE=1 VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation ctest --test-dir build -R "depth|fill|storage" -V, 3 runs ataa144ce8f5: 80 of 81 pass each time, 0VUID-, no missing-layer message. The failure isagc_driver_depth_plane_partial_store("repeated lookups of the first layer of an unchanged array proved no refresh"), which fails the same way onmain(c8d34aa8f4: 79 of 80, 0VUID-). The extra test isagc_driver_depth_plane_fill_discard.ctestataa144ce8f5: 2305 tests; the failures areagc_driver_depth_plane_partial_store,agc_host_import_cut_lifetime(both fail the same way onmainhere) andselect_tests(a temp-directory symlink error intools/tests/test_select_tests.py).tools/check_conventions.py --base origin/main: passes.DEATHLOOP (PPSA01670), the beach at the start of the game (sprint and dodge tutorial), same machine and scripted input.
maincannot reach this scene yet, so both builds aremain+ #10414 + #10507 + #10743 + a port of #6192, without (based26dce2835) and with (change88b55a05ee) this PR's first three commits. The last commit (aa144ce8f5) only keeps planes under fills that a multisample colour target absorbs, which DEATHLOOP's depth clears are not; it was not re-captured. Captures as the Performance report form says:APS5_TRACE_SECONDS=840:60only, log not redirected, runs alternating base and change. The traces and the summary lines are assets of this release on my fork.The frame time does not change beyond run-to-run noise: this scene is CPU-bound. GPU busy per present is 1.3 to 2.1 ms lower in each change run than in the base runs.
Behaviour count, from separate runs with
APS5_PROFILE_DRAW=1(not the captures above): the[storage]lines reportdepth plane storewrite-backs of about 111 to 128 GiB per 330 s run on the title menus with the base build and none with the change. With temporary caller logging added locally (not in this PR), every one of those stores came fromstoreBufferFill(reasonbuffer fill) over the two 0x1fe0000-byte planes. The menus look the same with both builds.aps5-summary.jsonllines of the six runs, in run order{"commit":"d26dce2835cb","dirty":false,"env":{"APS5_TRACE_DIR":"<path>","APS5_TRACE_SECONDS":"840:60"},"gpu":"NVIDIA GeForce RTX 5070 Ti","driver":"NVIDIA 616.64","os":"Windows 10.0.26200","cpu":"AMD Ryzen 7 9700X 8-Core Processor","cpu_threads":16,"memory_mib":31801,"title_id":"PPSA01670","title":"DEATHLOOP","content_version":"01.405.000","resolution":"3840x2160","window":{"spec":"seconds 840:60","first_present":8614,"ms":60107.959},"presents":337,"frame_ms":{"p50":177.951,"p90":183.858,"p99":190.768,"max":196.822},"gpu_busy_ms_per_present":53.271,"worker_busy_pct":{"queue worker 0x0":99.227,"queue worker 0x20":97.824,"queue worker 0x28":97.385,"queue worker 0x38":99.93,"queue worker 0x30":99.658,"queue worker 0x40":99.965,"queue worker 0x48":99.983},"top_phases_ms_per_frame":{"Driver.Packet":1236.547,"Driver.Packet.memory_wait":1043.837,"Graphics.Draw":149.059,"Driver.Packet.draw":148.059,"Driver.Draw":147.73,"Graphics.Draw.draw_and_resource_release":141.774,"Driver.Draw.draw_enqueued":99.446,"Driver.Draw.shader_compile_and_link":28.86},"trace_dropped":true,"trace_dropped_threads":{"queue worker 0x0":{"events_full_after_s":13.279,"events_lost":934051,"totals_full":false},"draw committer":{"events_full_after_s":39.377,"events_lost":137976,"totals_full":false}},"trace":"aps5-trace-d26dce2835cb-41848.json.gz"} {"commit":"88b55a05ee74","dirty":false,"env":{"APS5_TRACE_DIR":"<path>","APS5_TRACE_SECONDS":"840:60"},"gpu":"NVIDIA GeForce RTX 5070 Ti","driver":"NVIDIA 616.64","os":"Windows 10.0.26200","cpu":"AMD Ryzen 7 9700X 8-Core Processor","cpu_threads":16,"memory_mib":31801,"title_id":"PPSA01670","title":"DEATHLOOP","content_version":"01.405.000","resolution":"3840x2160","window":{"spec":"seconds 840:60","first_present":9199,"ms":60122.777},"presents":347,"frame_ms":{"p50":172.474,"p90":181.063,"p99":190.306,"max":192.882},"gpu_busy_ms_per_present":51.182,"worker_busy_pct":{"queue worker 0x0":99.212,"queue worker 0x20":98.54,"queue worker 0x30":99.712,"queue worker 0x28":98.068,"queue worker 0x38":99.936,"queue worker 0x48":99.984,"queue worker 0x40":99.968},"top_phases_ms_per_frame":{"Driver.Packet":1203.588,"Driver.Packet.memory_wait":1017.453,"Graphics.Draw":145.698,"Driver.Packet.draw":145.165,"Driver.Draw":144.824,"Graphics.Draw.draw_and_resource_release":138.468,"Driver.Draw.draw_enqueued":96.263,"Driver.Draw.shader_compile_and_link":29.646},"trace_dropped":true,"trace_dropped_threads":{"queue worker 0x0":{"events_full_after_s":12.576,"events_lost":993452,"totals_full":false},"draw committer":{"events_full_after_s":38.232,"events_lost":150555,"totals_full":false}},"trace":"aps5-trace-88b55a05ee74-40768.json.gz"} {"commit":"d26dce2835cb","dirty":false,"env":{"APS5_TRACE_DIR":"<path>","APS5_TRACE_SECONDS":"840:60"},"gpu":"NVIDIA GeForce RTX 5070 Ti","driver":"NVIDIA 616.64","os":"Windows 10.0.26200","cpu":"AMD Ryzen 7 9700X 8-Core Processor","cpu_threads":16,"memory_mib":31801,"title_id":"PPSA01670","title":"DEATHLOOP","content_version":"01.405.000","resolution":"3840x2160","window":{"spec":"seconds 840:60","first_present":8973,"ms":60076.746},"presents":344,"frame_ms":{"p50":174.347,"p90":179.013,"p99":187.476,"max":191.038},"gpu_busy_ms_per_present":53.288,"worker_busy_pct":{"queue worker 0x0":99.205,"queue worker 0x28":97.381,"queue worker 0x30":99.651,"queue worker 0x20":97.842,"queue worker 0x40":99.965,"queue worker 0x48":99.982,"queue worker 0x38":99.908},"top_phases_ms_per_frame":{"Driver.Packet":1210.601,"Driver.Packet.memory_wait":1021.711,"Graphics.Draw":144.854,"Driver.Packet.draw":144.266,"Driver.Draw":143.92,"Graphics.Draw.draw_and_resource_release":137.657,"Driver.Draw.draw_enqueued":94.934,"Driver.Draw.shader_compile_and_link":29.998},"trace_dropped":true,"trace_dropped_threads":{"queue worker 0x0":{"events_full_after_s":12.617,"events_lost":985100,"totals_full":false},"draw committer":{"events_full_after_s":38.303,"events_lost":147991,"totals_full":false}},"trace":"aps5-trace-d26dce2835cb-24240.json.gz"} {"commit":"88b55a05ee74","dirty":false,"env":{"APS5_TRACE_DIR":"<path>","APS5_TRACE_SECONDS":"840:60"},"gpu":"NVIDIA GeForce RTX 5070 Ti","driver":"NVIDIA 616.64","os":"Windows 10.0.26200","cpu":"AMD Ryzen 7 9700X 8-Core Processor","cpu_threads":16,"memory_mib":31801,"title_id":"PPSA01670","title":"DEATHLOOP","content_version":"01.405.000","resolution":"3840x2160","window":{"spec":"seconds 840:60","first_present":8658,"ms":60020.4},"presents":337,"frame_ms":{"p50":177.364,"p90":185.819,"p99":195.727,"max":205.069},"gpu_busy_ms_per_present":51.611,"worker_busy_pct":{"queue worker 0x0":99.214,"queue worker 0x20":98.56,"queue worker 0x28":98.183,"queue worker 0x30":99.688,"queue worker 0x40":99.963,"queue worker 0x48":99.995,"queue worker 0x38":99.935},"top_phases_ms_per_frame":{"Driver.Packet":1237.63,"Driver.Packet.memory_wait":1047.644,"Graphics.Draw":150.447,"Driver.Packet.draw":149.521,"Driver.Draw":149.177,"Graphics.Draw.draw_and_resource_release":143.101,"Driver.Draw.draw_enqueued":100.166,"Driver.Draw.shader_compile_and_link":29.485},"trace_dropped":true,"trace_dropped_threads":{"queue worker 0x0":{"events_full_after_s":12.776,"events_lost":962266,"totals_full":false},"draw committer":{"events_full_after_s":39.102,"events_lost":139913,"totals_full":false}},"trace":"aps5-trace-88b55a05ee74-41120.json.gz"} {"commit":"d26dce2835cb","dirty":false,"env":{"APS5_TRACE_DIR":"<path>","APS5_TRACE_SECONDS":"840:60"},"gpu":"NVIDIA GeForce RTX 5070 Ti","driver":"NVIDIA 616.64","os":"Windows 10.0.26200","cpu":"AMD Ryzen 7 9700X 8-Core Processor","cpu_threads":16,"memory_mib":31801,"title_id":"PPSA01670","title":"DEATHLOOP","content_version":"01.405.000","resolution":"3840x2160","window":{"spec":"seconds 840:60","first_present":8701,"ms":60020.229},"presents":337,"frame_ms":{"p50":177.932,"p90":183.159,"p99":190.053,"max":193.682},"gpu_busy_ms_per_present":52.968,"worker_busy_pct":{"queue worker 0x0":99.224,"queue worker 0x28":97.481,"queue worker 0x20":97.968,"queue worker 0x38":99.933,"queue worker 0x30":99.664,"queue worker 0x40":99.964,"queue worker 0x48":99.983},"top_phases_ms_per_frame":{"Driver.Packet":1234.919,"Driver.Packet.memory_wait":1042.455,"Graphics.Draw":148.961,"Driver.Packet.draw":148.098,"Driver.Draw":147.758,"Graphics.Draw.draw_and_resource_release":141.741,"Driver.Draw.draw_enqueued":99.759,"Driver.Draw.shader_compile_and_link":28.798},"trace_dropped":true,"trace_dropped_threads":{"queue worker 0x0":{"events_full_after_s":13.197,"events_lost":939608,"totals_full":false},"draw committer":{"events_full_after_s":39.461,"events_lost":136938,"totals_full":false}},"trace":"aps5-trace-d26dce2835cb-37056.json.gz"} {"commit":"88b55a05ee74","dirty":false,"env":{"APS5_TRACE_DIR":"<path>","APS5_TRACE_SECONDS":"840:60"},"gpu":"NVIDIA GeForce RTX 5070 Ti","driver":"NVIDIA 616.64","os":"Windows 10.0.26200","cpu":"AMD Ryzen 7 9700X 8-Core Processor","cpu_threads":16,"memory_mib":31801,"title_id":"PPSA01670","title":"DEATHLOOP","content_version":"01.405.000","resolution":"3840x2160","window":{"spec":"seconds 840:60","first_present":8698,"ms":60148.507},"presents":324,"frame_ms":{"p50":185.446,"p90":189.83,"p99":196.519,"max":200.793},"gpu_busy_ms_per_present":51.722,"worker_busy_pct":{"queue worker 0x0":99.243,"queue worker 0x20":98.622,"queue worker 0x30":99.682,"queue worker 0x28":98.245,"queue worker 0x38":99.934,"queue worker 0x40":99.966,"queue worker 0x48":99.984},"top_phases_ms_per_frame":{"Driver.Packet":1290.156,"Driver.Packet.memory_wait":1092.058,"Graphics.Draw":157.561,"Driver.Packet.draw":156.59,"Driver.Draw":156.24,"Graphics.Draw.draw_and_resource_release":150.091,"Driver.Draw.draw_enqueued":107.474,"Driver.Draw.shader_compile_and_link":29.295},"trace_dropped":true,"trace_dropped_threads":{"queue worker 0x0":{"events_full_after_s":13.388,"events_lost":901172,"totals_full":false},"draw committer":{"events_full_after_s":40.808,"events_lost":124625,"totals_full":false}},"trace":"aps5-trace-88b55a05ee74-34860.json.gz"}Checklist
main; no other open PR implements the same functionsNotImplemented_nid_no_patch); silent stubs are listed under Silent stubs in their library's technical debt file.mdfiles or images added to the repository (attach them to this PR)DepthSurface.hppandDepthSurface.cpplines where this PR addsDiscardFilledDepthPlanes(merge order only); fix(agc): import native multisample D32S8 targets with a separate stencil plane and a depth-only HTILE #9533 and feat(agc): sample the stencil plane of a native multisampled D32S8 target #9717 have merged