Skip to content

AGC: agc_driver_sample_order_recipe_depth_locations fails on RADV Polaris: the recorded 2x depth draw is mostly at the standard locations, its recipe replay at the custom ones #9759

Open

Description

@ryanc2112

Observed

On main 4777caca3, agc_driver_sample_order_recipe_depth_locations fails 3/3, with and without the Khronos validation layer, at the first case (SampleOrder.cpp:1392, RecipeDepthLocations):

AGC graphics: pixel (0,0)'s locations in every pixel: the recipe's replay did not leave the depth the recorded draw left, as the device reads both back

The test's own location counts show the two draws do not use the same sample positions:

the recorded draw: of 3005 sloped depth samples, 1268 hold the slope's depth at the guest's sample locations (628 of 1499 on even rows, 640 of 1506 on odd rows) and 1737 at the standard 2x locations
the recipe's replay as the first draw of a pass: of 3005 sloped depth samples, 2749 hold the slope's depth at the guest's sample locations (1371 of 1499 on even rows, 1378 of 1506 on odd rows) and 256 at the standard 2x locations
the device reads depth drawn at custom sample locations back at other locations, even after a transition that names them
64x32: the recipe's replay differs from the recorded draw in 1481 of 4096 samples

First mismatch: sample 0 of pixel (51, 0) is 0x3d9ae9c0, the reference's is 0x3da61296.

Each run also logs 3× VUID-VkWriteDescriptorSet-descriptorType-00337, all for one image:

vkUpdateDescriptorSets(): pDescriptorWrites[0].pImageInfo[0].imageView references an image which was not created with VK_IMAGE_USAGE_SAMPLED_BIT, but descriptorType is VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE.
VkImage ... was created with VK_IMAGE_USAGE_2_TRANSFER_SRC_BIT_KHR|VK_IMAGE_USAGE_2_TRANSFER_DST_BIT_KHR|VK_IMAGE_USAGE_2_DEPTH_STENCIL_ATTACHMENT_BIT_KHR.

I have not established whether this read-back binding is related to the location mismatch.

Environment

SteamOS 3.8.28 (Arch distrobox), AMD Radeon RX 570 (RADV POLARIS10, 1002:67df), Mesa 26.2.5, GCC 16.2.1, Release. ANYPS5_REQUIRE_VULKAN=1 ANYPS5_NO_SHADER_CACHE=1, VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation (loader confirms the layer is inserted). The device reports VK_EXT_sample_locations, variableSampleLocations = true, standardSampleLocations = true and 2x2 sample location grids at 2, 4 and 8 samples, so the test's skip conditions do not apply.

Reproduce

ctest --test-dir build -R '^agc_driver_sample_order_recipe_depth_locations$' -V

Not checked on other GPUs. Found during a full agc_* run on this device; it fails the same way on main and with #8898 and #8998 applied.

AI-assisted: yes.

Activity

  1. ryanc2112 commented on Oct 22, 2026

    @ryanc2112
    ContributorAuthor

    Passes on a Steam Deck (RADV VANGOGH, RDNA 2, Mesa 26.2.5) at main 4777caca3, so this looks specific to Polaris (GCN 4).

  2. MarcZX10 commented on Oct 22, 2026

    @MarcZX10
    Contributor

    This reproduces the same invalid sampled-depth read (VUID-VkWriteDescriptorSet-descriptorType-00337) that open PR #9056 addresses by copying the depth aspect into an image created with sampled usage before the test reads it. On #9056's head, the recipe-depth-locations test is reported passing on several NVIDIA devices and on AMD Windows (Radeon 680M and RX 6700 XT); Linux RADV Polaris is not in that matrix. PR #9057 separately fixes a depth/stencil copy barrier VUID.

    Could you rerun this test on the RX 570/RADV with #9056 and #9057 applied and report both the location mismatch and validation output? If the mismatch remains after the invalid readback is removed, that would isolate the Polaris-specific sample-location behavior as a separate issue. I did not run this Vulkan test locally.

  3. MarcZX10 commented on Oct 22, 2026

    @MarcZX10
    Contributor

    The current cross-check still isolates Polaris: the reported depth-location test passes on Steam Deck/RADV VANGOGH, while #9759 is an RX 570/POLARIS10 failure. The comparison requested earlier with #9056 and #9057 remains useful because #9057 fixes the separate depth/stencil copy VUID and the issue report does not yet include that corrected-path result. Please post the RX 570 test and validation-layer result with those changes applied before concluding whether this is an additional Polaris sample-location defect.

  4. ryanc2112 commented on Oct 22, 2026

    @ryanc2112
    ContributorAuthor

    Rerun on the RX 570 (RADV POLARIS10, Mesa 26.2.5) with #9056 (d0a747e07; the current head 0fd624d93 is the same change rebased, identical patch-id) and #9057 (78254bef6) merged onto main 4777caca3, VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation:

    • The validation output is gone: 0 validation errors (3× VUID-VkWriteDescriptorSet-descriptorType-00337 per run on main).
    • The location mismatch is unchanged, 3/3 runs and without the layer: the recorded draw has 1268 of 3005 sloped samples at the guest's locations and 1737 at the standard 2x ones, the replay 2749 and 256, and the replay differs in 1481 of 4096 samples. Same failure message.
    • agc_driver_sample_order and agc_driver_sample_order_planning pass; agc_driver_sample_order_grid_reference skips as on main.

    So with the invalid readback removed, the mismatch remains: it is Polaris-specific sample-location behaviour (it passes on the Steam Deck, RDNA 2). I've kept this issue for that part.

  5. MarcZX10 commented on Oct 23, 2026

    @MarcZX10
    Contributor

    Thanks, this isolates the Polaris mismatch from the prior invalid sampled-depth read: with #9056 and #9057 applied, validation is clean but the location mismatch remains 3/3. One integration detail before treating that as the current-main result: the rerun used base 4777caca3, while current main is 7e69be6793; since then DepthSurface and MultisampleTarget have changed, and #9056/#9057 remain open rather than merged. Could you repeat the focused RX 570 test and validation-layer capture against current main with both PR heads applied, then report whether the same 1481/4096 sample mismatch remains? That will distinguish a still-current Polaris-specific issue from changes in the depth-copy/recipe path since the earlier run.

  6. tablefrogpillow commented on Oct 24, 2026

    @tablefrogpillow
    Contributor

    Adding a GCN5 data point on current main, since the open question is the architecture scope.

    agc_driver_sample_order_recipe_depth_locations, ctest -V with ANYPS5_REQUIRE_VULKAN=1 ANYPS5_NO_SHADER_CACHE=1 VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation, Mesa 25.2.8 / Linux, both on main 5d251e6:

    RX Vega 56 (RADV VEGA10, GCN5): pass -- the recorded draw and the recipe replay both land at the standard 2x locations (3004 of 3005), 0 of 4096 differ.

    RX 7900 GRE (RADV NAVI31, RDNA3): pass -- both land at the guest/custom locations (3005 of 3005), 0 of 4096 differ.

    So on current main the recorded and replay paths agree on both of these (VEGA10 both standard, NAVI31 both guest). The original Polaris report (base 4777caca3) had them disagree -- recorded mostly standard (1737), replay mostly custom (2749), 1481/4096. I don't have Polaris hardware to answer whether that still holds on current main (per @MarcZX10's RX 570 request), but GCN5 -- the generation between Polaris and RDNA -- does not reproduce it here, which points to a Polaris/GCN4-specific record-vs-replay divergence rather than a GCN-family one.

    (Both also log the pre-existing VUID-VkWriteDescriptorSet-descriptorType-00337 for the sampled depth view, unrelated to the failure.)

    AI-assisted: yes.

  7. ryanc2112 commented on Oct 26, 2026

    @ryanc2112
    ContributorAuthor

    Rerun on current main 4e43321bd6 (includes #9056 and #9057), RX 570 (RADV POLARIS10), Mesa 26.2.5, VK_INSTANCE_LAYERS=VK_LAYER_KHRONOS_validation (loader confirms the layer is inserted):

    • Still fails 3/3, also without the layer, with the same numbers: the recorded draw has 1268 of 3005 sloped samples at the guest's locations and 1737 at the standard 2x ones, the replay 2749 and 256, and they differ in 1481 of 4096 samples. Validation is now clean (0 errors; the 00337 errors are gone with test(agc): read the sample order tests' depth through a sampled copy #9056).
    • With RADV_DEBUG=nohiz (HTILE off) it passes 3/3: both the recorded draw and the replay hold 3005 of 3005 samples at the guest's locations, 0 of 4096 differ, and the "without a 2x2 grid" case passes too.

    So the standard-location values come from HTILE decompression. A likely path, from reading the source: both devices take the dynamic-rendering path (Pipeline.cpp, dynamicRendering follows graphicsPipelineLibrary), so the depth attachment never gets render-pass initial sample locations. None of the depth barriers in DepthSurface.cpp chain a VkSampleLocationsInfoEXT, and the guest write-back copies read the target in GENERAL (e.g. DepthSurface.cpp:1160, :1420). On GFX8, a 2x depth target's HTILE is presumably not TC-compatible, so a copy makes RADV decompress it in place at the standard positions; the replay is read through transitionLocated before any write-back, which would explain the split. That would also fit Vega 56 agreeing at standard locations (tablefrogpillow) and RDNA keeping the guest's. A located transition around those copies, as SampleOrder.cpp:209-211 does for its own copy, looks like the fix shape. I can run any candidate on the RX 570.

    AI-assisted: yes.

  8. tablefrogpillow commented on Oct 26, 2026

    @tablefrogpillow
    Contributor

    Ran your RADV_DEBUG=nohiz experiment on the Vega 56 (RADV VEGA10, GCN5), current main 4e43321, same test and ANYPS5_NO_SHADER_CACHE=1 + validation layer:

    • HTILE on (default): the recorded draw and the replay both put 3004/3005 sloped samples at the standard 2x locations (1 at the guest's), 0/4096 differ — passes.
    • RADV_DEBUG=nohiz (HTILE off): both put 3005/3005 at the guest's locations, 0 at standard, 0/4096 differ — passes.

    So on GCN5 the standard-location values are HTILE decompression, as you found on Polaris — turning HTILE off flips Vega from the standard locations to the guest's. The difference here is only that on Vega the recorded draw and the replay decompress the same way, so they still agree; the recorded-vs-replay split you see on the RX 570 is what fails. Consistent with HTILE decompression being the source, as you diagnosed.

    (Validation layer active; both runs log only the pre-existing VUID-VkDeviceCreateInfo-pNext-pNext for VkStructureType 1000574000, newer than this layer build — unrelated and identical in both runs.)

    Happy to run further sample-order or depth checks on the Vega 56 (GCN5) or the 7900 GRE (RDNA3) if another data point would help — feel free to mention me.

    AI-assisted: yes (Claude Code); run on this machine.

  9. ryanc2112 commented on Oct 26, 2026

    @ryanc2112
    ContributorAuthor

    Thanks for running it. That also means Vega keeps the standard positions in both paths with HTILE on, so the depth there differs from the guest's locations too; the test passes only because it compares the replay with the recorded draw, and both decompress the same way. So the fix probably matters for GCN 5 as well, not just Polaris, even though only the RX 570 trips this test.

    AI-assisted: yes.

  10. ryanc2112 commented on Oct 26, 2026

    @ryanc2112
    ContributorAuthor

    Correction to the code path I suggested: with APS5_NO_GPL=1 (render-pass path, which names the depth attachment's initial and post-subpass sample locations) the RX 570 result is identical on main 4e43321bd6: 1268 vs 2749 samples at the guest's locations, 1481 of 4096 differ, 3/3. So the missing render-pass sample locations under dynamic rendering are not the cause; the HTILE result (RADV_DEBUG=nohiz passes) stands, but where the decompression at standard positions happens is still open.

    AI-assisted: yes.

  11. ryanc2112 commented on Nov 4, 2026

    @ryanc2112
    ContributorAuthor

    Found the cause: RADV's TC-compatible HTILE in VK_IMAGE_LAYOUT_GENERAL. It's a driver issue, not AnyPS5's.

    On current main b11c7bf84f, RX 570 (RADV POLARIS10), Mesa 26.2.5, agc_driver_sample_order_recipe_depth_locations, 2 runs each:

    Environment Result Recorded draw: sloped samples at the guest's locations Replay differs in
    default fails 1268 of 3005 1481 of 4096
    radv_disable_tc_compat_htile_general=true passes 3005 of 3005 0

    radv_disable_tc_compat_htile_general is a RADV drirc option, set here through the environment.

    Why, from the Mesa 26.2.5 source (unchanged on Mesa main):

    • TC-compatible HTILE is enabled: radv_use_tc_compat_htile_for_image (radv_image.c) enables it for this target, a single-layer 2x VK_FORMAT_D32_SFLOAT image with sampled or transfer-source usage on GFX8. Nothing in RADV checks VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT.
    • No decompression happens: radv_layout_is_htile_compressed keeps a TC-compatible image compressed in GENERAL, and in the read layouts too. AnyPS5 keeps depth targets in GENERAL, and SampleOrder.cpp's transitionLocated goes GENERAL → TRANSFER_SRC_OPTIMAL. So the decompression that would honour the barrier's VkSampleLocationsInfoEXT never runs.
    • What the reads see: they go through the texture path on the still-compressed HTILE. That path appears to evaluate compressed Z planes at the standard 2x positions, while expanded tiles keep the values written at the guest's locations. That would give the 1268 / 1737 split.
    • It fits the earlier results:
      • RADV_DEBUG=nohiz passes on both Polaris and Vega.
      • Vega reads the standard positions in both paths, so it passes only because both sides match.
      • VANGOGH and NAVI31 read the guest's locations.

    So reads of a sample-locations-compatible depth image on RADV before RDNA2 don't see depth at its custom locations, even after a barrier that names them. I'll report it to Mesa. On the AnyPS5 side, I don't see a clean workaround that doesn't give up HTILE for these targets or depend on a driver-specific layout. Do you want one in the meantime, or should the test wait for Mesa?

    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