Repository navigation
Upstream sync 6: shared AGC driver fixes onto Metal (slice A, first chunk) - #442
Conversation
Killzone: Liberation (PPSA11142) writes its frame fence with `sceAgcDcbWriteData(dst 6, cache policy 3, write confirm)`, which the SPRX-confirmed encoding turns into WRITE_DATA with DST_SEL 3 and a label address in the title's memory that RELEASE_MEM and WAIT_REG_MEM then use. The validator rejected DST_SEL 3 as the GDS; it now writes guest memory like DST_SEL 5, resolves as a label, and the title runs past its first frame. TechnicalDebt records where the semantics come from. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> (cherry picked from commit 9c53b7f) (cherry picked from commit a553e22)
(cherry picked from commit 5550ca6)
…split SWAP_ALT blends Review follow-up to the 8_8 SWAP_ALT blending. The second channel of such a target holds the guest's alpha. Vulkan applies the green blend constant to it for CONSTANT_COLOR and ONE_MINUS_CONSTANT_COLOR, where the guest's alpha equation uses the alpha constant. Decoding now throws for these factors on a SWAP_ALT 8_8 target, unless the equation is MIN or MAX, which ignore factors. The second pass of a split draw runs every stage again, not only the pixel shader, so a vertex or geometry stage that writes memory would write twice. The memory-write check (now ShadersWriteMemory) covers all the draw's stages. (cherry picked from commit 79c8d36)
…words A merged (NGG geometry path) program's user data starts with eight hidden words, so the vertex buffer and attribute table offsets of its AGC header, which count from the first user SGPR, were read eight words too early and found zeros. Killzone: Liberation (PPSA11142) stopped on `AGC graphics: null vertex buffer table address` at the first frame of its PSP game. The decoder now adds the hidden word count to the table reads; the registers reported to the recompiler are unchanged, as it already maps them from the first user SGPR. `agc_driver_graphics` gains a merged and a plain layout case. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> (cherry picked from commit b63996f)
…f the array A color view of slice N of a 2D array (CB_COLOR_VIEW SLICE_START, with CB_COLOR_ATTRIB3 MIP0_DEPTH as the last slice) was rendered as a 2D surface at the slice's address. The swizzle equations of the XOR tile modes take the slice index (the detiler's slice bits), so the texels of slice N of an array are not where a 2D surface at that address puts them: a title that renders into array slices and then samples the array read them scrambled. The decoded target now keeps the array's address, its last slice and the view's slice. A resident target that is a slice of an array attaches that layer of the array's storage image, so the texels follow the array's layout; storage images of 2D arrays are color attachments for this, and an attachment view selects a layer. A slice whose array has DCC, CMASK or an attachment proxy has no resident array image, and a non-resident slice of an XOR-tiled array now throws instead of being written in the 2D layout. (cherry picked from commit eba67d4)
…oes not export
A pixel input whose SPI_PS_INPUT_CNTL offset names a parameter the
previous stage does not export failed validation ("graphics interfaces
disagree"), so the draw threw. No export writes that parameter slot for
the draw. radeonsi programs a pixel input without a matching vertex
output as OFFSET 0x20 with DEFAULT_VAL 0, so that it reads (0, 0, 0, 0)
(SI_PS_INPUT_CNTL_UNUSED in si_shader.h, applied in si_shader.c), and
rect-list draws already pass zero for such inputs.
Before the pixel stage of a draw is prepared, inputs that read a
parameter the previous stage's program does not export now read zero:
OFFSET bit 5 is set, DEFAULT_VAL and FLAT_SHADE are cleared, and an FP16
input also reads zero in its high half (USE_DEFAULT_ATTR1 set,
DEFAULT_VAL_ATTR1 cleared). Inputs that already read a default value
are unchanged.
Fixes boykopovar#2975.
(cherry picked from commit 2f140cb)
DecodeState bound the depth surface whenever DB_DEPTH_CONTROL enabled a depth, stencil or depth bounds test and either plane was valid. A stencil test beside a depth-only surface (DB_STENCIL_INFO format invalid, depth test off) tests nothing, but the surface was still attached and the render extent was clamped to it. A draw into a 1920x1080 target with a 960x540 depth surface left bound then covered only the top-left quarter. A test whose plane is present but invalid no longer binds the surface. Such a draw renders without a depth attachment, as it already does when both planes are invalid. DrawRejection follows the same rule. (cherry picked from commit c1287d7)
(cherry picked from commit 82ac3bd)
CB_COLOR_INFO format 17 with UNORM and the standard component swap renders into VK_FORMAT_A1R5G5B5_UNORM_PACK16, whose attachment and blend support Vulkan requires. AMD keeps X in the low bits and Vulkan keeps R in the high bits, so the exports are mapped with X and Z exchanged and the stored bits follow the guest layout. PPSA06699 renders into this format. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> (cherry picked from commit 61a9f5d)
Initialize the guest write tracker during Driver construction so its function-local static is destroyed after Driver on process exit. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> (cherry picked from commit 471d9ec)
…r unregistered streams sceAgcDcbSetWorkloadsActive writes an 18-dword IT_NOP packet (stream id, 64-bit workload mask) and sceAgcDcbSetWorkloadComplete a 12-dword one (stream id, workload id, 64-bit clear mask), following KytyPS5. Both return null for a null buffer, an unregistered or out-of-range stream, a workload id above 63, and for active a duplicate id or a count of 0 or above 63. sceAgcDriverRegisterWorkloadStream and sceAgcDriverUnregisterWorkloadStream now record the stream ids the DCB calls check. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> (cherry picked from commit 2a7b38a)
Keep the tracker initialization fix without an explanatory code comment or technical-debt entry, as requested in review. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> (cherry picked from commit fc7a965)
On GFX10.3 the DEPTH field of a 1D or 2D non-array linear T# carries the row pitch minus one (Mesa's ac_descriptors.c sets it for custom pitches, which must be multiples of 256 bytes). A single-level, uncompressed 2D linear texture whose DEPTH equals its default 256-byte-aligned pitch now decodes as that 2D texture; any other pitch still throws. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit 6b24328)
FailureCapture now requires the code address and stage in the diagnosed failure, with and without the request dump. Fails before the wrap, passes after. AI-assisted: yes. (cherry picked from commit 768929b)
PrepareShaderWithDiagnostics dumped the request but rethrew the raw error, so a failure never said which shader it came from. Wrap it with the shader address and stage, keeping the dump. AI-assisted: yes. (cherry picked from commit e71e3a4)
Capture the request once before rethrowing from the shared handler. Standard exceptions keep the shader address, stage, optional dump filename and full message; non-standard exceptions remain unchanged after capture. AI-assisted: yes. (cherry picked from commit 56df893)
Retain weak identities and the full failed span so a replacement of either owner or a shorter remaining run retries the import. Keep unchanged failures cached across unrelated mapping changes without pinning their allocations. Existing upstream import lifetime, span windows and Windows fallback remain in place. AI-assisted implementation. (cherry picked from commit 2441a4b)
A device replaced at AttachWindow keeps its host imports in HostImports::parked until it is destroyed, and each parked import keeps its guest ranges pinned. A guest munmap, mprotect or free of such a range spun in the pin waiter until APS5_PIN_WAIT_MS and then failed, because the waiter only looked at the live imports. The replaced device was already waited idle by PrepareForReplacement, so the waiter now drops the parked imports over the range. agc_parked_import_unmap imports a range on one device, again on a second one, and unmaps it with a 3 s pin wait. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit cd067d1)
(cherry picked from commit 661f8e1)
Draws 32_ABGR exports into a tiled and a linear format 17 target and compares every texel with the layout X in bits 0-4, Y in 5-9, Z in 10-14, W in bit 15, including the X/Z-swapped pairs, rounding edges and texels outside the scissor. Reverting the X/Z exchange fails it. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> (cherry picked from commit deaa2e3)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> (cherry picked from commit c914bcd)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> (cherry picked from commit c58c948)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> (cherry picked from commit 89c1287)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> (cherry picked from commit 485c0f3)
(cherry picked from commit 9394c74)
…back (cherry picked from commit 6c94d31)
(cherry picked from commit 4dfe052)
(cherry picked from commit 512ea3e)
(cherry picked from commit dd4504e)
…o the first zero vertex Goat Simulator 3 draws a triangle list whose indices are all 0xffffffff with primitive restart off. Each fetch past a descriptor's records reads zeros (out-of-bounds select 0 or 1), but the zero-padded vertex copies were sized to the highest index: 160 GiB, which vkAllocateMemory refused. When the highest index is at least 64Ki vertices past the largest per-vertex record count, the draw now uses a copy of its indices with every index past that count moved to it. Each attribute reads zeros there as at the original index; only the vertex index the shader sees changes, so indices closer to the records are left as they are. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit a3cba2d)
Read the device-local heap's VK_EXT_memory_budget figures before a texture or storage image allocation and pick a host memory type when the allocation does not fit, rather than allocating again after the driver refused the first attempt. The allocation itself is made once and still throws when it fails. (cherry picked from commit b35117c)
…each the surface The memo stamp held TrackerGeneration, which every collect and driver store advances, so it almost never matched. Driver stores into uncovered ranges record their generation per 64 KiB block, and NewestStamp of the surface replaces TrackerGeneration in the stamp. (cherry picked from commit ca99658)
…tput format The kernel boykopovar#2081 matches stores each pattern dword with buffer_store_format_x, so what lands in memory depends on the output descriptor's FORMAT (bits 12-18 of user[3]). Only 32_UINT, 32_SINT and 32_FLOAT (20-22) store the dword unchanged. Other formats convert it, and an 8- or 16-bit one writes 1 or 2 bytes of every 4-byte element, so a buffer fill would also overwrite the bytes in between. Such a dispatch now goes to the recompiler. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit 4309bff)
(cherry picked from commit bdb0be0)
Map SW_64KB_D_X color surfaces through the existing source-backed texture equations and mip geometry. Keep display and render-target equation caches separate. Reject unresolved raw column bits for the new mode instead of accepting them. Cover the captured PPSA99902 descriptor, independent source offsets, pipe/bank tags, transfers, array/mip placement and resident/non-resident GPU draws. Record unmeasured console behavior in TechnicalDebt. CPU validation on main e013f8c: captured-descriptor failure 5/5; changed passes 5/5; pinned AMD addrlib reference 536940 addresses per run, five runs. Full build and GPU validation are tracked externally. AI-assisted implementation and validation: Codex. (cherry picked from commit f27bdf4)
Apply the source-configured D_X XOR refusal during color decoding as well as direct layout construction. Regression tests reject each raw column-bit combination before storage or rendering is selected. Existing resident-array and packed-mip refusal paths remain in force. AI-assisted implementation and validation: Codex. (cherry picked from commit 4326c7c)
Run the existing array-layer draw, recompiled shader load, untouched-layer and guest-publication checks with D_X as well as R_X. This exercises the resident array path that carries slice-dependent address XOR; a direct per-slice copy is not an equivalent model. AI-assisted implementation and validation: Codex. (cherry picked from commit b6f1a4a)
…the GPU ClearColorFor refused every integer format, so a fast-cleared R32_UINT/R16_UINT/R8_UINT surface was uploaded through the CPU path: a guest read that waits for the GPU writers, then FillDccClear's zero texels. Code 0000 is zero bits in any format, so it maps to a zero integer clear. PPSA28416: ~1.4 s per 10 s of CPU uploads gone, 4.9 -> 5.3 fps. (cherry picked from commit 92b46a2)
StorageClearAvailable takes code 0000 on R8/R16/R32_UINT and refuses every other code; drop the header comment that said integer formats were refused. (cherry picked from commit 09aa34d)
(cherry picked from commit b3c8be5)
(cherry picked from commit 0b54425)
…or stencil planes (cherry picked from commit d9fbaf7)
… pixel center (cherry picked from commit fdfbeba) Fork adaptation: applied to the fork MSAA model (rasterSamples from PA_SC_AA_CONFIG); a single-sample scan with MSAA_ENABLE that the attachments raise to a multisampled pass stays refused. Upstream sample-location tables are not taken here. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…END_BYPASS DecodeState threw "blend bypass conflicts with enabled blending" when CB_BLENDn_CONTROL enabled blending for a target whose CB_COLORn_INFO has BLEND_BYPASS (bit 16, Mesa src/amd/registers/gfx10.json) set. The bit makes the color block skip the blender for that target: Mesa sets it "according to docs" for UINT/SINT and 8_24/24_8/X24_8_32_FLOAT targets, which the blender cannot process (src/amd/common/ac_descriptors.c, shared by radeonsi and RADV). Marvel's Guardians of the Galaxy (PPSA01748) issues such draws right after its loading screen. Blending is now enabled only when it is requested and not bypassed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit baaad78)
…gment without writing DecodeColorMetadataPass refuses an eliminate-fast-clear or DCC-decompress pass when DB_DEPTH_CONTROL has any of its low four bits set and depth or stencil planes are bound. Marvel's Guardians of the Galaxy (PPSA01748) issues one with the Z test enabled, ZFUNC ALWAYS and no Z write (DB_DEPTH_CONTROL 0x72) while a Z32 and an S8 target are bound. That test passes every fragment and leaves depth unchanged, so the pass does no depth work. Draws already treat this state as a pass-through (depthPassThrough); the metadata pass now uses the same rule. Depth bounds, depth writes, stencil tests and DB_RENDER_CONTROL clears or copies are still refused, and the error names the four registers involved. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit b90ec1e)
…xecution libSceAgc's workload packets (upstream 2a7b38a) ask libSceAgcDriver whether a stream is registered. The Rosetta libs link the two libraries; the Metal utilities build links libSceAgc's host objects against anyps5_metal_native_execution, which now carries Resource/src/Registration.cpp. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
anyps5_metal_render_state now decodes a guest draw with CB_COLOR_INFO BLEND_BYPASS (upstream PR 4862) and with MSAA_ENABLE on a single-sample scan (upstream fdfbeba) and renders both through the Metal backend. MSAA_ENABLE is read only when PA_SC_MODE_CNTL_0 is written, as the fork's decode accepted before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
# Conflicts: # docs/dev/TechnicalDebt.md
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configuration
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Merged |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: cf3e75f357
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if (VertexBufferOutOfBoundsSelect(attribute) > 1u) return std::nullopt; | ||
| zeroFrom = std::max(zeroFrom, attribute.resource.fields[2]); | ||
| } | ||
| return zeroFrom; |
There was a problem hiding this comment.
Skip index clamping when no vertex fetch qualifies
ZeroFetchVertex returns an engaged optional containing zero when the shader has no attributes, or when every attribute is null, zero-stride, instance-indexed, or otherwise skipped. Consequently, prepareDrawInputs rewrites 32-bit indices at least 65,536 past zero to index 0 even though there is no vertex-indexed buffer fetch to protect. Procedural shaders that derive positions from the vertex ID, or shaders with only instance attributes, therefore receive incorrect vertex IDs and render different geometry; return nullopt unless at least one qualifying vertex fetch contributed a record limit.
Useful? React with 👍 / 👎.
| localDevice->ColorMetadataPass(*pass); | ||
| return DrawVerdict::Drawn; | ||
| } | ||
| if (Graphics::DepthResummarizeDrawsNothing(queue)) return DrawVerdict::Nothing; |
There was a problem hiding this comment.
Preserve shader writes from resummarize draws
When this predicate matches a read-only resummarize draw, the precheck returns before decoding or executing any shader. PixelProgramSkipped only proves that the pixel stage is absent; a vertex, tessellation, or geometry stage can still perform supported guest-buffer or image writes (as accounted for by ShadersWriteMemory in Pipeline.cpp). Such a draw now silently loses those side effects instead of being rejected, so this fast path should only classify the draw as empty after ruling out shader writes, or retain the previous rejection for that case.
Useful? React with 👍 / 👎.
Part of #415. Refs #418 (first chunk; not all shared-logic commits are in, see "Remaining").
Ports upstream
libSceAgcDriverfixes onto the fork's Metal path withgit cherry-pick -x(each commit carries its upstream sha). Range: non-merge commits in2ccbd376f..upstream/maintouchingcore/libs/prx/libSceAgcDriver(118), plus the shared-file prerequisites froma11c8f7f7..2ccbd376fthat later commits build on, plus two small open upstream PRs.Note on range.
2ccbd376fis not merged into the fork: the fork's last upstream base is stilla11c8f7f7, and none of the 104 commits ina11c8f7f7..2ccbd376f(the range #418's body describes) had been ported. This PR takes the 8 of those that touch Metal-compiled shared files and apply on the fork. The upstream MSAA rework in that range is not taken (see "Remaining").What the Metal path compiles
The Metal and Rosetta builds compile only part of the driver (
cmake/RosettaGraphics.cmake,core/shader/recompiler/MetalReplay/CMakeLists.txt):Graphics/src/State.cpp,ShaderInputState,ColorTargetLayout,SurfaceMetadata,DccClearEncoding,MeshDraw,Execution/src/Pm4.cpp,EntryPoints.cpp,Submit/*,Eq/*,State/*,Resource/*,Unimplemented.cpp.Graphics/src/Texture.cpp,DepthSurface.cpp,Draw.cpp,GuestMemory.cpp,GuestBufferMemory.cppandShaderRegistry.cppare the Vulkan driver's and are not built on macOS. Commits for those files are taken where they apply cleanly, so later syncs do not conflict, but they are compile-checked only by upstream.Ported
Shared logic the Metal path compiles:
61a9f5dc1render 1_5_5_5 UNORM color targets (State.cpp), withdeaa2e3ef(test)c914bcd72,485c0f334color mip targets with parent layout (ColorTargetLayout), withc58c9488e,6c94d31d7,4dfe0526b; Draw.cpp side89c128782,9394c7430f27bdf4d764 KiB display XOR color targets (ColorTargetLayout),4326c7c21validate display XOR bits before resident lookup (State.cpp),b6f1a4a69(test)d9fbaf767accept a CB metadata pass beside depth state without depth or stencil planes (State.cpp; conflict, hand-resolved to the fork's line)fdfbeba8aaccept MSAA_ENABLE on a single-sample target sampled at the pixel center (State.cpp). Adapted to the fork's MSAA model (rasterSamplesfrom PA_SC_AA_CONFIG,AttachmentSampleCount): the fork'sscanModeMaskis replaced by upstream's check, and a single-sample scan with MSAA_ENABLE that the attachments raise to a multisampled pass stays refused. Upstream's sample-location tables are not taken.2a7b38ab7KytyPS5 workload packets, workload stream registry (libSceAgcWorkload.cpp,Resource/Registration.cpp); forkCommands.cpptests merged with upstream'stestWorkloads661f8e1e7sceAgcAcbWaitUntilSafeForRendering(libSceAgc, Pm4.cpp)bdb0be019exportsceAgcDriverGetHsOffchipParam(Unimplemented.cpp; the validation stubs upstream still had there stay in the fork'sState/src/Status.cpp)a11c8f7f7..2ccbd376f:a553e2263WRITE_DATA DST_SEL 3,5550ca63dwait for shutdown at shader ABI entrypoints (EntryPoints.cpp conflict: the fork's Metal no-op branches kept, upstream'sProcessShutdownhandling wraps the Vulkan branch),79c8d3690split SWAP_ALT blends,b63996f1fmerged program vertex tables,eba67d4132D array color slice,2f140cb8bzero for unexported parameters,c1287d73cdepth surface left out without a tested plane,82ac3bd93read-only depth resummarize drawsVulkan-side Graphics/Execution (applied cleanly; not built on macOS):
92b46a2b7clear integer storage images with DCC code 0000,09aa34d06,b3c8be588(tests; CMake conflict resolved to this commit's test only),0b54425e3ca99658cememoize untracked texture comparisons61180981c,eb03e0e15,85929389b,b35117c28host-memory fallback when device memory runs out512ea3ec0,dd4504ee4recorded fast clears synchronized with attachments2441a4b0d,cd067d156host import retry and parked imports (CMake conflict: test list merged)471d9eced,fc7a9650fwrite tracker lifetime at teardown6b2432875linear 2D texture with default-pitch DEPTH768929bb7,e71e3a4b3,56df89366shader preparation failures name address and stage (ShaderRegistry; applied cleanly onto the fork's shortenedRegisterShader, no deleted path restored)a3cba2d1findex move past vertex fetch records (VertexInput.hpp is also used by MetalDraw.mm)4309bffdbdword pattern-fill kernel only for 32-bit outputa55472cf9test registration overlapOpen upstream PRs (shared State.cpp logic):
baaad78e8): leave blending off for a target with CB_COLOR_INFO.BLEND_BYPASSb90ec1ed4): accept a CB metadata pass whose depth test passes every fragment without writing (conflict: the fork has no CB resolve pass, so upstream'sresolvebranch is dropped)Fork commits:
Resource/src/Registration.cppintoanyps5_metal_native_execution, so the Metal libSceAgc host fixture resolvesAgcDriverWorkloadStreamRegistered(the Rosetta libs already link libSceAgc to libSceAgcDriver)anyps5_metal_render_stategainsSharedStateDecode: decodes a guest draw with BLEND_BYPASS and with MSAA_ENABLE on a single-sample scan and renders both through the Metal backend (blend 128,128,0,191 vs bypass 255,0,0,128; MSAA_ENABLE at the pixel center renders the same pixels as without; a sample off the center is refused). It fails onmain("blend bypass conflicts with enabled blending"). MSAA_ENABLE is read only when PA_SC_MODE_CNTL_0 is written, as before.Docs (
docs/dev/TechnicalDebt.md,docs/dev/debt/*.md) conflicts: the fork's text is kept and only the entry each commit adds is appended.Skipped
8e5a1cae2(validation and shader-debugging queries; the fork answers them inState/src/Status.cpp).99edf9435 de54527a8 fded8a7e7 364d7cf29 48654bdc8 7f5cd4480 ddb668066 765ea6a10 baf343746 67556722e 672e43ca6 56d5a4985 f9b592806 b1ee794a6 bb1325938 d37463e76 436e4191c b3587f952 3ea89674d 0bcff53b2 803a13127 bb028203d 676622fd7 a9c625aca 7b9c7ca58 37003b7a3 7d508cf77 18d9874a0 d0aca69ef c52321fab.18d9874a0addsRasterPrimitiveOfto State.cpp only for recompiler request version 19.4d0b5c789 d7e0f27d6 7f64d1477 e9def903f 9eb42ca2d 361c7e202 d809e6d0d 2919dd38c 9aeeea848 4f5f6d671 28ca53dc8 5668e0d0e 5c7da226d af52bc430 eb8a7255d 016b2dbe8 21b9e2efe abc1cfa57 7d34a6aa8 2115dac9a 522c7424a 9387da4fa.22d662edastencil reference export: needs VK_EXT_shader_stencil_export on Vulkan; its State.cpp/ShaderInputState hunk would turn on[[stencil]]export in Metal pipelines, which needs its own Metal test. Not taken.f2d698674 a70ec3946 bff955a3e 2add25cea.9f0617633 49e929870 d635d1896.428963d3b(worker sampler stacks; the fork's StackWalk/WorkerSampler differ),69728a0cb(the fork'sAttachmentSampleCountalready rasterizes a single-sample scan into a multisampled target, at the standard locations).Remaining (next chunk)
a11c8f7f7..2ccbd376fprerequisites: depth storage reuse4de5726d3 b9b83cef2 ef218ef92; write-tracking host holes1b4baaee2 b45232dda 29a843579 59db660f7; host import holdse785a902b eaf5ca240 ff349a9a5 63ddeb09f; depth plane sampling086f7d509 dc0c2cf8c 90d899d98; HTILE memory-value fast clearsd31b13f49 fd98327ba.a11c8f7f7..2ccbd376fMSAA rework and sample locations (ebf361103 163947ef7 eeefb0654 ae6dfd907 c9e48e5ae, plus605741d39 fb7615e30 e28dcc0c1named in [upstream] Port shared AGC driver fixes since sync #4 onto Metal #418): upstream's model (onesamples, EQAA refused, CB resolve pass) differs from the fork's (coverageSamples/samples, EQAA accepted). These need porting function by function onto the fork's model, not cherry-picks.a11c8f7f7..2ccbd376f(Vulkan side, recompiler, tests).SET_*_REG_INDIRECTat submit time on the Metal path), which [upstream] Port shared AGC driver fixes since sync #4 onto Metal #418's review asks to fold in.Tests
-DANYPS5_METAL_UTILITIES_ONLY=ON -DANYPS5_METAL_SHADER_BRIDGE=ON -DANYPS5_BUILD_METAL_SHADER_BRIDGE_TESTS=ON -DANYPS5_METAL_GUEST_REPLAY=ON): full build,ctest --output-on-failure --timeout 30036/36 passed.anyps5_metal_render_statewithmain's State.cpp: fails with "blend bypass conflicts with enabled blending"; with this branch: passes.-DANYPS5_ROSETTA_LIBS=ON): targetsrosetta_libs rosetta_engine rosetta_launcher_tests direct_memory_darwin_tests metal_utility_tests rosetta_direct_graphics_tests rosetta_cpuid_testsandrosetta_runtime_testsbuilt;ctest -R 'direct_memory_darwin|metal_utility_tests|rosetta_direct_graphics|rosetta_lib_binds|rosetta_runtime|rosetta_launcher|rosetta_cpuid'9/9 passed.Game run (one, reference title)
tools/rosetta/run_title.py --wall 280with this branch's Rosetta build, underwith-lock eboot, on a private APFS clone of the data image mounted read-only (detached and deleted afterwards), private empty shader cache.mainstopped at. No frame captures were taken (ANYPS5_FRAME_CAPTURE_DIRwas not set), so there is no fps number from this run; Metal: cut per-draw shader conversions and copies (gpu-pipeline) #440'smainfigure is 28–31 fps on the early screen.AGC graphics:refusals in the log (none of the decode paths changed here refused). The Metal backend loggedskipped draw ... Subgroup builtins are not available in this type of function(log-scaled counter reached x100000). That comes from the shader bridge's MSL conversion, which this PR does not touch; not compared against amainrun.sceAgcSuspendPointgotDriverStoppedfromMetalDriver::SuspendPointand aborted (exit 134). That code is unchanged here; it is a teardown path on SIGTERM, worth its own issue.🤖 Generated with Claude Code