Skip to content

AGC: agc_driver_sample_order_grid_reference fails on RX 9070 XT: the exact path reads depth 0.0 on every odd row #12732

Closed as not planned

Description

@bunbeans2-arch

What happens

agc_driver_sample_order_grid_reference fails on an RX 9070 XT: AGC graphics: the exact path did not render the checkerboard bit for bit like the reference. Every depth sample the exact path leaves on an odd row reads 0.0, and 402 color samples differ.

Title, test or build step

agc_driver_sample_order_grid_reference

AnyPS5 commit

main 52c09d5 (2026-10-29), nothing merged on top. Same failure and the same counts on main e2d457b (2026-10-27).

System

Windows 11 Pro 10.0.22631, AMD Radeon RX 9070 XT (RDNA 4, 1002:7550), driver 32.0.32015.7029, MSYS2 UCRT64 GCC 16.1.0, Release, BUILD_TESTING=ON.

Steps to reproduce

ANYPS5_REQUIRE_VULKAN=1 ANYPS5_NO_SHADER_CACHE=1 VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation \
  ctest --test-dir build -R '^agc_driver_sample_order_grid_reference$' -V

Fails in 0.6 s.

Log

[gpu] largest sample location grids (vkGetPhysicalDeviceMultisamplePropertiesEXT): 1 samples 2x2, 2 samples 2x2, 4 samples 2x2, 8 samples 2x2; maxSampleLocationGridSize for every count 2x2
the composite of uniform renders: of 3005 sloped depth samples, 3005 hold the slope's depth at the guest's sample locations (1499 of 1499 on even rows, 1506 of 1506 on odd rows) and 0 at the standard 2x locations
the exact path: of 3547 sloped depth samples, 1499 hold the slope's depth at the guest's sample locations (1499 of 1499 on even rows, 0 of 2048 on odd rows) and 0 at the standard 2x locations
pixel (0,0)'s locations alone: of 3005 sloped depth samples, 1499 hold the slope's depth at the guest's sample locations (1499 of 1499 on even rows, 0 of 1506 on odd rows) and 0 at the standard 2x locations
the device's 2x2 grid: of 3005 sloped depth samples, 3005 hold the slope's depth at the guest's sample locations (1499 of 1499 on even rows, 1506 of 1506 on odd rows) and 0 at the standard 2x locations
2x checkerboard at 64x32: the device's 2x2 grid differs from the composite of four uniform renders in 0 samples and from the exact path in 2450 samples
color with the samples put in the guest's order: sample 1 of pixel (33, 1) is 0x3e870000 0x3ef40000 0x3f800000 0x3f800000, the reference's is 0x3bb1c000 0x3f7b8000 0x3f800000 0x3f800000
color with the samples put in the guest's order: sample 0 of pixel (34, 1) is 0x3e890000 0x3ef40000 0x00000000 0x00000000, the reference's is 0x3c6c4000 0x3f7ae000 0x00000000 0x00000000
depth with the samples put in the guest's order: sample 0 of pixel (0, 1) is 0x00000000 0x00000000 0x00000000 0x00000000, the reference's is 0x3f700000 0x00000000 0x00000000 0x00000000
depth with the samples put in the guest's order: sample 1 of pixel (0, 1) is 0x00000000 0x00000000 0x00000000 0x00000000, the reference's is 0x3f700000 0x00000000 0x00000000 0x00000000
2x checkerboard at 64x32: the exact path differs from the reference in 402 color and 2048 depth samples; pixel (0,0)'s locations alone differ in 1552 samples
AGC graphics: the exact path did not render the checkerboard bit for bit like the reference

What was checked

  • The device's own 2x2 grid matches the composite of four uniform renders bit for bit, color and depth, so the reference is sound on this device. Only the exact path (the emulated context, sampleLocationGridSampleCounts = 0) differs.
  • The exact path's odd rows hold 2048 sloped samples where the reference holds 1506: all 64x16x2 odd-row depth samples read 0.0, where the reference holds the slope's depth or the clear value 0.9375 (0x3f700000). Even rows match.
  • Same counts in 4 runs on 52c09d5 and in a full ctest on e2d457b.
  • Validation layer (MSYS2 mingw-w64-ucrt-x86_64-vulkan-validation-layers): VK_LOADER_DEBUG=layer shows VK_LAYER_KHRONOS_validation inserted as instance and device layer, no was not found but was requested by env var VK_INSTANCE_LAYERS, and no VUID- line in the log.
  • The Medal and OBS capture layers installed on this machine were disabled with VK_LOADER_LAYERS_DISABLE; the result is the same with and without them.
  • agc_driver_sample_order, agc_driver_sample_order_recipe_depth_locations and agc_driver_sample_order_planning pass on the same build.
  • Related: on test(agc): read the sample order tests' depth through a sampled copy #9056 a Radeon 680M (RDNA 2, 32.0.21030.2001) still failed this test with that PR merged, but with vkQueueSubmit recorder: Vulkan result -4, not this mismatch.
  • Not narrowed to a pass or a submit.

AI-assisted: yes (Claude Code)

Activity

  1. bunbeans2-arch commented on Oct 29, 2026

    @bunbeans2-arch
    ContributorAuthor

    Root cause of the depth half: the depth sample swap's descriptor set is bound before its pipeline, the same driver behaviour #9503 describes on an RX 6700 XT. On this RX 9070 XT there is no device fault. Instead every depth sample the swap rewrites (the odd rows, where Village's two locations trade places) ends up 0.0.

    What I ran

    Same machine and driver as above (RX 9070 XT, 32.0.32015.7029), MSYS2 GCC 16.1, Release, base 2960e9a6e7, which already has #9056. agc_driver_sample_order_tests was built with a local env switch in SampleOrders::Depth (Graphics/src/SampleOrder.cpp). With the switch set, the code binds the sampled-image set once after vkCmdBeginRenderPass, as on main. Without it, the set is bound right after each vkCmdBindPipeline inside draw, which is #9503's diff. Both variants are in the same binary, with VK_LAYER_KHRONOS_validation and ANYPS5_NO_SHADER_CACHE=1, 3 runs each:

    set bound exact path vs reference odd-row sloped depth at guest locations VUID- lines
    before the pipeline (main) 402 color, 2048 depth 0 of 2048 0
    after each pipeline (#9503) 42 color, 0 depth 1506 of 1506 0

    Same counts in all 3 runs of each. With #9503's order, agc_driver_sample_order and agc_driver_sample_order_recipe_depth_locations still pass.

    Other switches I tried. None changes the 402/2048 counts on main's order:

    • APS5_NO_DIRECT_DEPTH_COPY
    • APS5_DEPTH_PLANE_WHOLE_STORE
    • APS5_NO_PENDING_HTILE_FILLS
    • APS5_NO_DRAW_RECIPE

    With #9503's order, copying without the located layout transitions also gives the same 42/0 result. Skipping the depth swap entirely leaves the odd rows in host order: 0 of 1506 at guest locations, 1526 depth differences, not 0.0.

    What is left: 42 color samples

    With #9503's order the test still fails on this card, on 42 color samples:

    • All 42 differ only in the second component. The test's pixel shader exports v0, v1, sampleId, sampleId, so that component is the J of the per-sample perspective barycentrics (PERSP_SAMPLE ena). I matches in every sample.
    • The differences are small, about 0.0006 or less in absolute value (1 fp16 ulp near 1.0). They are spread over 32 pixels in rows 1 to 28, on even rows as well as odd ones. Examples: (33,2), (21,12), (19,14), (54,26).
    • In the reference, both samples of such a pixel often hold the same J. The exact path gives the two samples J values on either side of it. Example: pixel (31,3) has 0x3f69c000 for both samples in the reference, and 0x3f69e000 / 0x3f698000 on the exact path.
    • In 2 samples the reference holds -0.0 and the exact path holds 0x3a228000.

    I have not found the cause yet. On even rows the exact path draws at the same locations as the reference renders. From reading the code (not checked at runtime), when the device has interpolation functions and fragment shader barycentrics, both paths read these barycentrics through BaryCoordSmoothSample and InterpolateAtOffset: InstructionTranslator.cpp around line 393, and EmitOffsetBarycentricU32 in SpirvModuleEmitter.cpp. The one difference I can see is that only the exact path's offset table varies per quad pixel (SampleLocationsVary). #9503 reports the test passing 10/10 on RDNA 2 with #9056. My guess, unchecked, is that this residual is specific to RDNA 4.

    So #9503 fixes the depth half of this issue on RDNA 4 as well. Its fix is not mine: I did not open a separate PR. I can rerun on this card if a change for the 42 colour samples comes up.

    AI-assisted: yes (Claude Code)

  2. bunbeans2-arch commented on Oct 29, 2026

    @bunbeans2-arch
    ContributorAuthor

    Follow-up on the 42 colour samples: the per-quad offset table (SampleLocationsVary) is not their cause, so please ignore that lead from my comment above.

    I added a local switch that makes EmitSampleOffset index only by sample, as if the locations did not vary. Then I reran the grid reference test on the same card:

    offset table colour diffs on even rows colour diffs on odd rows
    per quad pixel (as on main) 23 19
    per sample only (switch) 23 2048

    The odd rows break, as expected, because they need their own locations. The 23 even-row diffs stay on exactly the same 23 samples. Their values change, though:

    • With the switch, all 23 hold J equal to the reference's, and none holds the reference's I.
    • In the 5 pixels where both samples are among the 23, the two samples hold the same I and J.

    Example: pixel (19,14).

    sample 0 (R, G) sample 1 (R, G)
    reference 0x3c3e8000 0x3f088000 0x3b2cc000 0x3f088000
    exact path 0x3c3e8000 0x3f086000 0x3b2cc000 0x3f08a000
    per sample only (switch) 0x3be9c000 0x3f088000 0x3be9c000 0x3f088000

    So on even rows, where the exact path draws at the same locations as the reference, these 23 samples get barycentrics that do not match the reference however the offset is looked up. I do not know why yet.

    AI-assisted: yes (Claude Code)

  3. bunbeans2-arch commented on Oct 30, 2026

    @bunbeans2-arch
    ContributorAuthor

    Closing as a duplicate of #12277, filed a day earlier for the same test on an RX 9070 GRE (RDNA 4, Windows). It has the same 402/2048 counts, the same result with #9503's bind order (42/0), and the same 42-colour residual. I missed it when I searched before filing. The RX 9070 XT runs above stay here as extra data for that issue and for #9503.

    AI-assisted: yes (Claude Code)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions