[SPIR-V] Incorrect ignoring globallycoherent with ResourceDescriptorHeap approach
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:
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:
- Descriptor indexing
- Descriptor buffer
- Mutable descriptor type
Environment
-
git submodule update --inithas been invoked before build -
hctbuildbuild 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.exev1.8.2505.10062 executable, commit SHA-194abfe972ad839185965f670329bcf33cd7bccbd
I found workaround to mitigate the issue for DXC 94abfe972ad839185965f670329bcf33cd7bccbd.
#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
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...
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.