DirectXShaderCompiler icon indicating copy to clipboard operation
DirectXShaderCompiler copied to clipboard

[SPIR-V] Incorrect ignoring globallycoherent with ResourceDescriptorHeap approach

Open Goshido opened this issue 4 months ago • 2 comments

Description I think the latest DXC incorrectly handles globallycoherent with combination ResourceDescriptorHeap. Resulting SPIR-V does not contain Coherent keyword.

Steps to Reproduce The most trivial examples

  • ✅ Using OG descriptor set approach
[[vk::binding ( 7, 0 )]]
globallycoherent RWStructuredBuffer<uint32_t>       g_global:       register ( u0 );


[numthreads ( 8, 8, 1 )]
void CS ( in uint32_t threadID: SV_GroupIndex, in uint32_t3 workGroupID: SV_GroupID )
{
    if ( threadID.x + workGroupID.y + workGroupID.z + threadID == 0U )
    {
        g_global[ 0U ] = 42U;
    }
}
  • ❌ Using ResourceDescriptorHeap
[numthreads ( 8, 8, 1 )]
void CS ( in uint32_t threadID: SV_GroupIndex, in uint32_t3 workGroupID: SV_GroupID )
{
    globallycoherent RWStructuredBuffer<uint32_t> g_global = ResourceDescriptorHeap[ 7U ];

    if ( threadID.x + workGroupID.y + workGroupID.z + threadID == 0U )
    {
        g_global[ 0U ] = 42U;
    }
}

DXC parameters in both cases:

-HV 2021
-spirv
-fvk-use-dx-layout
-fspv-reduce-load-size
-fspv-target-env=vulkan1.1
-ffinite-math-only
-enable-16bit-types
-WX
-O3
-E CS
-T cs_6_9

Actual Behavior

❌ No compilation warnings or errors. The SPIR-V neck by neck:

Image

Expected

Coherent should present somewhere in SPIR-V output when using descriptor indexing + ResourceDescriptorHeap strategy. Without it it's impossible to use modern approach with the following features:

Environment

  • git submodule update --init has been invoked before build
  • hctbuild build parameters: -official -rel -x64 -vs2022 -speak-up -no-dxilconv -spirv
  • Visual Studio 2022 Community components were up to date.
  • Windows 11 Pro (24H2, Build 26100.4351)
  • dxc.exe v1.8.2505.10062 executable, commit SHA-1 94abfe972ad839185965f670329bcf33cd7bccbd

Goshido avatar Sep 06 '25 07:09 Goshido

I found workaround to mitigate the issue for DXC 94abfe972ad839185965f670329bcf33cd7bccbd.

Image
#define RESOURCE_DESCRIPTOR_HEAP_SET                0
#define RESOURCE_DESCRIPTOR_HEAP_BIND               0


[[vk::binding ( RESOURCE_DESCRIPTOR_HEAP_BIND, RESOURCE_DESCRIPTOR_HEAP_SET )]]
globallycoherent RWStructuredBuffer<uint32_t>       g_coherentGlobal[]:     register ( u0 );

[numthreads ( 8, 8, 1 )]
void CS ( in uint32_t threadID: SV_GroupIndex, in uint32_t3 workGroupID: SV_GroupID )
{
    globallycoherent RWStructuredBuffer<uint32_t> g_global = g_coherentGlobal[ 7U ];

    if ( threadID.x + workGroupID.y + workGroupID.z + threadID == 0U )
    {
        g_global[ 0U ] = 42U;
    }
}

As you can see it's inspired glslangValidator approach. My suggestion is to add globallycoherent variants into existing codegen of DXC. This will allow to use ResourceDescriptorHeap naturally.

More complex example also works

Image

Goshido avatar Sep 11 '25 04:09 Goshido

I encountered this today too. I think another limitation with the current design is the inability to use image format attributes like [[vk::image_format("rgba8")]] in conjunction with ResourceDescriptorHeap directly...

vntec avatar Dec 01 '25 00:12 vntec

The globallycoherent bit seems possible, but I'll need to figure out how to correctly pass the attribute to the implicit cast, which for now only takes the type of the variable. But since we create a single resource per heap load, it should be OK. For the other attribute, I'll need to look into them. Might be the same story.

Keenuts avatar Dec 15 '25 17:12 Keenuts