Skip to content

fix(agc): refuse native MSAA index buffer reads - #6590

Merged
3 commits merged into
boykopovar:mainfrom
MarcZX10:codex/msaa-index-guard-6579
Oct 17, 2026
Merged

3 commits merged into
boykopovar:mainfrom
MarcZX10:codex/msaa-index-guard-6579

Conversation

@MarcZX10

Copy link
Copy Markdown
Contributor

What

Adds the live multisampled-target guard to fixed-function index-buffer reads after validating the guest range. The existing render-target alias check remains in place. Extends the multisample execution fixture to cover 16-bit and 32-bit index reads from a native target, the last in-range index words, and a valid neighboring index range; the target samples must remain unchanged. Updates the driver debt entry to list index reads among guarded accesses.

Fixes #6579. The issue report supplied the detailed Windows reproduction and an initial focused test/fix experiment; this PR adapts the guard and fixture to current main.

Related to #6498: that PR covers shader buffer descriptors; this change covers fixed-function index input. They share the existing multisample fixture and debt entry, but neither depends on the other.

Tested

  • Debian 12, GCC 12.2: built agc_driver_sample_multisample_target_tests successfully. Building required a temporary local template parser fix for the unrelated GCC 12 error in SrtDescriptorEvaluation.cpp; that edit is not in this PR.
  • python3 tools/check_conventions.py --base upstream/main: passed.
  • git diff --check: passed.
  • Local CTest execution did not reach Vulkan: this host exposes an Intel Xeon E5-1620 v2 without AVX2/FMA, which AnyPS5 requires. No local GPU runtime result is claimed. The issue report documents 5/5 regression and fix runs on Windows with an RTX 5080 and AMD Radeon integrated GPU; those runs were performed by the reporter, not on this PR head.

Checklist

  • Based on current main; no open PR implements fixed-function index-buffer guard checks
  • One topic per PR; follow-ups go in a new PR
  • No comments in code except technical debt
  • Unimplemented paths throw
  • No notes, investigation .md files or images added to the repository
  • New third-party code is a submodule built from source
  • Generic behavior, not specific to one title
  • Depends on: none
  • Unblocks: none
  • GPUs tested: none locally; local execution stops at the host CPU feature check
  • AI-assisted: yes

@github-actions

github-actions Bot commented Oct 15, 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
PR 6215 docs/dev/debt/libSceAgcDriver.md L122
PR 6571 docs/dev/debt/libSceAgcDriver.md L122-123
PR 6973 core/libs/prx/libSceAgcDriver/tests/execution/SampleMultisampleTarget.cpp L5-6, L27, L29-31, L388-389
PR 6987 core/libs/prx/libSceAgcDriver/tests/execution/SampleMultisampleTarget.cpp L5-6, L27, L29-31, L388-389
PR 6989 core/libs/prx/libSceAgcDriver/tests/execution/SampleMultisampleTarget.cpp L5-6, L27, L29-31, L388-389
PR 6995 core/libs/prx/libSceAgcDriver/tests/execution/SampleMultisampleTarget.cpp L5-6, L27, L29-31, L388-389
PR 7002 core/libs/prx/libSceAgcDriver/tests/execution/SampleMultisampleTarget.cpp L5-6, L27, L29-31, L388-389

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.

Pull request Shared files not compared
PR 1191 core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
PR 1368 core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
PR 1395 core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
PR 2434 docs/dev/debt/libSceAgcDriver.md
PR 4072 core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
PR 4448 docs/dev/debt/libSceAgcDriver.md
PR 4650 docs/dev/debt/libSceAgcDriver.md
PR 5058 docs/dev/debt/libSceAgcDriver.md
PR 5390 core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
docs/dev/debt/libSceAgcDriver.md
PR 5431 core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
PR 5441 core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
PR 5499 core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
docs/dev/debt/libSceAgcDriver.md
PR 5609 core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
PR 5925 core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6188 core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
PR 6222 core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6279 core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
PR 6297 core/libs/prx/libSceAgcDriver/tests/execution/SampleMultisampleTarget.cpp
PR 6412 docs/dev/debt/libSceAgcDriver.md
PR 6414 core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
PR 6529 core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6539 core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
PR 6548 docs/dev/debt/libSceAgcDriver.md
PR 6563 docs/dev/debt/libSceAgcDriver.md
PR 6718 core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
PR 6808 core/libs/prx/libSceAgcDriver/tests/execution/SampleMultisampleTarget.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6946 core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
docs/dev/debt/libSceAgcDriver.md
PR 6947 core/libs/prx/libSceAgcDriver/Graphics/src/Draw.cpp
docs/dev/debt/libSceAgcDriver.md

@jotitadev jotitadev left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A run on hardware, since the description says no local GPU run was possible.

Machine: NVIDIA GeForce RTX 3070, driver 595.99.02, Vulkan 1.4.329, Ubuntu 26.04 (kernel 7.0.0-38), i7-8700. GCC 15.2, Release, BUILD_TESTING=ON, ANYPS5_GPU="NVIDIA GeForce RTX 3070". Head 881facc4f merged onto main 5d9dcc42d, no conflicts.

GPUs tested: NVIDIA GeForce RTX 3070 (595.99.02), Linux

  • agc_driver_sample_multisample_target passes 3/3. The fixture takes the host-import path on this driver (shared-import=1), and all four native-index cases (16/32-bit, base and edge) are refused with an index buffer read of ... overlaps multisampled color target ... whose samples are only on the host. The neighbouring index range draws the triangle.
  • Test only (the PR's fixture with main's Draw.cpp): fails 3/3 with AGC graphics: native indices missed 4 resident-image refusals (refused=0 for all four cases). So the new test catches the missing guard on NVIDIA/Linux too, not only on the Windows RTX 5080 and AMD iGPU from #6579.
  • ctest -R "^agc" -E "agc_display_buffer_dcc|agc_driver_flip|agc_driver_lds_atomics64" -j1 --timeout 60: 591/593 pass, the same result as unchanged main on this machine (agc_driver_stencil_ref_export skipped, agc_driver_store_over_untracked fails as on main, #6385).

Written with AI assistance (Claude Code). I ran the tests above on my machine.

@Amoenus Amoenus left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Windows source review and Vulkan validation of PR head 881facc4fa50a49d4148b4f385b280b62886d144 merged onto main 5d9dcc42d2ec5401aebd089028b8d4d7410a77b4, plus only #6452's independent Windows test-alignment correction: composition b3e7aa184. The submitted Draw.cpp and multisample fixture are unchanged in that composition. This is not a bare submitted-head run.

  • Full Windows application/libs build, conventions and registration pass; all execution fixtures are built.
  • Five fresh focused processes per physical GPU pass all four index refusals, the shared-import neighbor triangle and all 1024 native sample checks.
  • 19 related groups x 5 repetitions per GPU selector pass, with physical selection verified in 17 groups per vendor; no failures/skips/timeouts. Slowest matrix test 5.66s.
  • Removing only the new guard produces all four missing refusals in every one of five fresh processes per GPU. Other controls remain correct.

Hardware: Windows 11 Enterprise 26200, WinLibs GCC 15.2r7 Release; NVIDIA RTX 5080 (10de:2c02, 32.0.16.1062) and AMD Radeon integrated graphics (1002:13c0, 32.0.21036.18). Shader cache disabled; actual vendor/device recorded in every focused process.

The production guard behaves as intended. I confirmed one fixture-oracle gap, detailed inline: omitting the 32-bit neighbor draw still passes 5/5 per GPU because the destination retains the 16-bit triangle. Six-line proposed fixture correction clears/materializes and verifies the destination before each width. It passes 5/5 per GPU, including a restored full build/check run; the same omitted-draw control with that correction now fails 5/5 per GPU at the expected zero-sample coverage assertion. Cppcheck 2.20.0 and clang-tidy 23.1.3 on Draw.cpp/the proposed fixture report no new selected diagnostic compared with the PR composition: three Cppcheck findings and one clang-tidy warning match in message/source context and remain unresolved. No parser/configuration errors or suppression. This is advisory comparison of the fixture proposal, not a clean-analyzer claim for main.

No fresh title replay, Linux runtime or PS5 console-equivalence claim. The issue's earlier Windows tests were mine; these are new tests of this PR composition. AI-assisted review/validation and proposed test correction: Codex.

@MarcZX10

Copy link
Copy Markdown
Contributor Author

Manual overlap check for the bot warning: #6571 changes the CB resolve sample count debt bullet, while this PR changes the adjacent Multisampled target guest access bullet. They document independent fixes; there is no code dependency. git merge-tree confirms a textual conflict in docs/dev/debt/libSceAgcDriver.md because both edits are adjacent long lines. Whichever merges second should preserve both updated bullets when resolving/rebasing.

@nicolasfalesy

Copy link
Copy Markdown
Contributor

Tested on Linux (Arch), c++ (GCC) 16.2.1 20260810, Release, BUILD_TESTING=ON, main at 5d9dcc42d2ec5401aebd089028b8d4d7410a77b4. GPU tests ran on lavapipe (Mesa 26.2.2, llvmpipe with LLVM 22.1.8).

This PR and #5881 break agc_driver_sample_multisample_target together. main passes (2 of 2), each PR alone passes, and the pair fails (2 of 2). All four native-index cases are refused as expected, then the check after them fails:

AGC graphics: sample 1 of pixel (0, 0) loaded (0.75, 0.25, 0.5, 1) after native draw-input alias attempts

That is CheckUniform(LoadSamples(device, source), Ones, "after native draw-input alias attempts") at SampleMultisampleTarget.cpp:358 of this PR: the source target no longer holds the uniform value after the alias draws. #5881 rewrites the multisampled target write path (MultisampleTarget.cpp) and changes the fixture in the same test file, and this PR's fixture assumes the old behaviour. I did not find the exact cause.

AI-assisted: yes

@MarcZX10

Copy link
Copy Markdown
Contributor Author

Thanks for testing both changes together and reporting the standalone controls. I checked the current #5881 and #6590 heads: they merge without a textual conflict, so this is a runtime interaction, not a rebase issue. The failure is after the refused index attempts, when the test reloads the original target's samples; I won't treat the independent green runs as covering this composition.

Could you share the exact main and #5881 SHAs plus the command/checkout composition used? #5881 has had current head 9666c3e for a while, but the report does not include the base pin. I can't run the Vulkan test on this host, so those pins would let us make sure we're investigating the same tree.

@nicolasfalesy

Copy link
Copy Markdown
Contributor

Sure. All runs used these pins (fetched before the runs, unchanged since):

Composition: main, then #5881 merged, then this PR merged (two plain ort merges, both clean). The resulting tree is b8e65cb4e40e254c62f16ceb48608236b4672797. Each control was main plus one PR with the same commands.

git checkout -B test 5d9dcc42d2ec5401aebd089028b8d4d7410a77b4
git fetch upstream pull/5881/head:pr-5881 pull/6590/head:pr-6590
git merge --no-edit pr-5881
git merge --no-edit pr-6590
git submodule update --init
# existing Release build dir, BUILD_TESTING=ON
cmake . && ninja tests/agc_driver_sample_multisample_target_tests
VK_DRIVER_FILES=<lavapipe>/lvp.json ctest -R '^agc_driver_sample_multisample_target$' --output-on-failure

Lavapipe is Mesa 26.2.2 (llvmpipe, LLVM 22.1.8), with an Xwayland display for the device. The pair failed in all 4 runs on these pins, each time with the line from my report. One correction to my earlier comment: each PR alone passed in one run, not two; main alone passed twice.

AI-assisted: yes

@MarcZX10

Copy link
Copy Markdown
Contributor Author

I reconstructed your exact composition locally; the merged tree matches b8e65cb4e40e254c62f16ceb48608236b4672797. The failure appears to be a fixture-order interaction in SampleMultisampleTarget.cpp, rather than evidence that the production write path corrupts the source: #5881 adds StoreSamples(... TargetDescriptor(block, ...), SampleWrites(oneSample)), and oneSample writes Written to sample 1 of every pixel in block. Later, #6590’s CheckNativeIndices uses that same block as source but still asserts every sample is Ones. The reported (0.75, 0.25, 0.5, 1) is exactly Written at the first stored sample. Moving CheckNativeIndices before the new sample-store cases, or restoring the source to the expected uniform state before it, should remove this false failure while preserving the alias checks. I could not run the focused test here: this Linux host is an older Xeon lacking the required AVX2/BMI CPU features, and the test aborts at the project CPU guard. I have not claimed a local runtime reproduction.

@Dextroid17

Copy link
Copy Markdown
Contributor

Tested the fixture-order explanation on Linux with current heads, since no one had run it yet. Pins: main 896e1b2, then #5881 at 6c67548 (its head has moved from 9666c3e), then this PR at 881facc. Both merges are clean, giving tree fa5fec761. Release, BUILD_TESTING=ON, GCC 16.2.1, lavapipe (Mesa 26.2.4, llvmpipe LLVM 23.1.1), clean environment, no CPU-gate bypass. ctest -R '^agc_driver_sample_multisample_target$' --no-tests=error:

  • As merged: fails 3 of 3 with the same line nicolasfalesy reported: sample 1 of pixel (0, 0) loaded (0.75, 0.25, 0.5, 1) after native draw-input alias attempts.
  • Restoring the source first passes 3 of 3. The change is one line just before CheckNativeIndices(*device, block, destination);:
    AgcDriver::Graphics::NoteColorMetadataFill(block.Address(), static_cast<std::size_t>(colorBytes), FillOnes);
  • Moving the destination / ReleaseIndexDevice / CheckNativeIndices block to just before const auto oneSample = ... also passes 3 of 3, and feat(agc): write a multisampled color target through a storage image #5881's store checks after it still pass.
  • Back to the merged file as is: fails again, same line.

With ctest -V, both fixed versions print all four native index ... refused=1 lines, so the alias checks still run and are not skipped. This supports your reading. The failing value is the one #5881's store test writes to block, and resetting the source or reordering the checks makes the test pass. So the failure is in the combined fixture, not the alias guard. It does not test the write path beyond what this test already covers. The assertion that fails is in this PR's CheckNativeIndices, and the one-line refill uses only helpers this PR already uses, so it could go here whether #5881 merges first or not. The move only makes sense once #5881's store section is in the file. I tested both only on the combined tree.

AI-assisted: yes

@MarcZX10

Copy link
Copy Markdown
Contributor Author

Thanks for running the combined-tree check. The 3/3 failure on the merged tree and 3/3 passes after either restoring block or moving CheckNativeIndices before the sample-store cases confirm the fixture-order interaction I suspected; the alias-refusal checks still execute in both passing variants. This is not evidence of a production write-path defect. Please apply the source reset or reorder the index check in this PR so the test remains stable when #5881 is present, then rerun the combined test.

@MarcZX10

Copy link
Copy Markdown
Contributor Author

I also checked Amoenus's inline fixture finding against the current review thread. It is independent of the block source-state issue: the 32-bit positive-control draw can be omitted and still pass because the destination retains the 16-bit triangle from the previous case. Please clear/materialize the destination and assert it is empty before each index-width case (the six-line proposal linked in the inline review does this), then keep the source reset/reordering needed for #5881's sample-store fixture. The reported combined-tree runs support both changes as test-only corrections; they do not call the production guard into question.

@MarcZX10

Copy link
Copy Markdown
Contributor Author

Updated in 45fcdbaa3 to address the two fixture findings:

  • The destination is cleared and verified before each 16-bit/32-bit neighboring draw, so the previous width's triangle cannot make the next positive control pass if its draw is omitted.
  • The source's metadata is restored to the expected all-ones state before the final sample check, avoiding the feat(agc): write a multisampled color target through a storage image #5881 sample-store fixture's write to the shared block.

Validation: git diff --check passes and agc_driver_sample_multisample_target_tests builds on Linux/GCC 12 after a temporary, reverted template keyword correction in unchanged SrtDescriptorEvaluation.cpp. CTest cannot run on this host: its Xeon E5-1620 v2 lacks AVX2/BMI1/BMI2 required by the project CPU gate. Current GitHub conventions, eligibility, intake and report checks pass; platform build jobs are skipped. No runtime result is claimed for this machine.

@Dextroid17

Copy link
Copy Markdown
Contributor

Reran the combined test on 45fcdba as asked. Same setup as my last run, with main now at 4524944: then #5881 at 6c67548, then this PR (clean merges, tree bd2539941), Release, GCC 16.2.1, lavapipe (Mesa 26.2.4), clean environment, ctest -R '^agc_driver_sample_multisample_target$' --no-tests=error -V.

  • Combined, as is: passes 3 of 3, with all four native index ... refused=1 lines. This PR alone on the same main also passes 3 of 3.
  • Destination clear: with the 32-bit neighbor draw skipped, it now fails 3 of 3 (sample 2 of pixel (0, 2) loaded (0, 0, 0, 0), which the triangle covers). With the clear also removed, the same skip passes 3 of 3. So the clear closes the gap Amoenus found.
  • Source refill: removing it brings back the 3 of 3 failure (sample 1 of pixel (0, 0) loaded (0.75, 0.25, 0.5, 1) after native draw-input alias attempts).

One problem with where the refill sits. It runs after the alias attempts and right before the check that the source was not written by them, so that check can no longer see a write. To test this I added one line that zeroes the source's metadata just after the alias loop:

  • With the refill where it is now: still passes 3 of 3. The refill replaces the pending zero fill before the check loads the samples, so the check cannot see it. By reading, a real write to the source's host image would be hidden the same way, because the refill is applied as a clear of the whole image when the check loads it.
  • With the refill moved to before the loop (just above std::uint32_t missed = 0;): fails 3 of 3 (sample 0 of pixel (0, 0) loaded (0, 0, 0, 0) after native draw-input alias attempts).
  • With the refill moved there and no added write: passes 3 of 3 with all four refusals.

Suggested change: move the NoteColorMetadataFill(source.Address(), ..., FillOnes) line from just before the final CheckUniform to just before std::uint32_t missed = 0;. The source then starts clean even after #5881's store cases, and the check after the alias attempts still means something.

AI-assisted: yes

@MarcZX10

Copy link
Copy Markdown
Contributor Author

Fixed in 1271998d4: the source FillOnes metadata refill now runs immediately before the alias attempts, so CheckUniform observes any writes made during them instead of masking those writes. Thanks for the mutation checks; your compatible Linux/lavapipe run confirms the moved refill passes 3/3, and the added metadata invalidation fails 3/3. I built agc_driver_sample_multisample_target_tests locally (GCC 12.2, with a temporary and reverted unrelated GCC 12 template workaround); local CTest could not run the binary because this Xeon E5-1620 v2 lacks BMI1/BMI2/AVX2/FMA required by the project CPU gate.

@MarcZX10

Copy link
Copy Markdown
Contributor Author

Thanks for running the mutation check. You are right: the FillOnes metadata refill is immediately before CheckUniform, after the alias attempts, so it can mask writes made by those attempts. I am moving it before the alias-attempt loop and will rerun the focused fixture where the host permits; the refill must initialize the source before the test, while the post-attempt check must observe untouched metadata.

@MarcZX10

Copy link
Copy Markdown
Contributor Author

Correction after checking the published head: 1271998d4 already moved the refill to immediately before the outer index-width loop, and the per-width neighbor draw precedes the alias attempts. The latest comment describes the earlier 45fcdbaa3 placement, which the follow-up commit fixed. I will verify the new invalidation mutation against the current published head before changing code; I do not want to move the refill without reproducing the claimed masking on this exact tree.

@Dextroid17

Copy link
Copy Markdown
Contributor

You're right: 1271998 already has the refill above std::uint32_t missed = 0;. My 15:39 comment was about 45fcdba and went up before that commit. I re-ran the same mutation on 1271998, and the refill does not need to move again for this check.

Setup: main 4524944, then #5881 at 6c67548, then this PR at 1271998 (clean merges, tree fe901076d), Release, GCC 16.2.1, lavapipe (Mesa 26.2.4), clean environment, ctest -R '^agc_driver_sample_multisample_target$' --no-tests=error -V.

  • Published file, unchanged: passes 3 of 3, with all four native index ... refused=1 lines.
  • One added line just before the final CheckUniform, after the alias loop: NoteColorMetadataFill(source.Address(), ..., 0u), which notes a pending zero fill on the source. Fails 3 of 3 (sample 0 of pixel (0, 0) loaded (0, 0, 0, 0) after native draw-input alias attempts). So the final check now catches a change to the source's metadata made after the alias attempts. This is the same simulated change as last time, not a real write through an alias.
  • Refill above std::uint32_t missed = 0; removed: fails 3 of 3 (sample 1 of pixel (0, 0) loaded (0.75, 0.25, 0.5, 1) after native draw-input alias attempts).
  • File restored: passes 1 of 1. This PR alone on the same main also passes 3 of 3.

AI-assisted: yes

@MarcZX10

Copy link
Copy Markdown
Contributor Author

Thanks for rerunning the mutation on the published 1271998d4 head and for clarifying that your earlier note predated that commit. The reported 3/3 baseline and negative-control results confirm the current refill placement catches the simulated post-attempt metadata change, while removing the initialization restores the original failure. No further source change is needed for this finding.

@MarcZX10

Copy link
Copy Markdown
Contributor Author

Thanks for the fixture-oracle correction. The current head 1271998d4 clears the destination and checks it is uniform before each index-width neighbor draw, so residual samples from the first width cannot mask a missing draw in the second. The equivalent reset/check is present in 45fcdbaa3; I did not cherry-pick the duplicate proposed patch. Your omitted-draw control and per-GPU results are useful confirmation of the fixture behavior.

@Amoenus

Amoenus commented Oct 17, 2026

Copy link
Copy Markdown
Contributor

@MarcZX100 Extending the same component coverage exposed a separate fixed-function vertex-input gap, reported in #7015. I've opened #7016 as a dependent follow-up to your exact #6590 head 1271998d4, preserving your commits and fixture corrections; yours is the prerequisite.

The own production change is one guard call for planned vertex ranges. The index-guard parent still reproduces the vertex gap; the focused fix passes on NVIDIA, AMD and llvmpipe. Exact source pins, 25 current-head passes, 13 baseline controls and the four-file own diff are maintained in #7016. AI-assisted: Codex; author responsible.

@akkadbakkad89

Copy link
Copy Markdown
Contributor

First GPU runtime for this PR (the authoring host could not reach Vulkan).

RTX 3070, Ampere, driver 617.42, Windows 11 26200, WinLibs GCC 15.2.0, Release, ANYPS5_NO_SHADER_CACHE=1. Head 1271998, ctest serial fresh processes:

Test Result
agc_driver_sample_multisample_target pass (incl. the new 16/32-bit index refusal cases)
agc_driver_sample_mask_multisample pass
agc_driver_native_multisample_depth pass
agc_driver_native_depth_retirement pass
agc_driver_native_depth_clears pass
agc_driver_native_depth_clear_refusals pass
agc_multisample_guest_access pass

7/7 pass on the PR head. The one-line Draw.cpp guard plus fixture holds on real NVIDIA hardware.

@github-actions github-actions Bot added the fix error Closes an issue (Fixes #N) label Oct 17, 2026
@oneandonlydean oneandonlydean self-assigned this Oct 17, 2026
@oneandonlydean oneandonlydean closed this pull request by merging all changes into boykopovar:main in c9e6c45 Oct 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agc libSceAgc* docs fix error Closes an issue (Fixes #N)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

AGC: host-imported index buffers bypass the native MSAA guest-access guard

7 participants