DirectXShaderCompiler icon indicating copy to clipboard operation
DirectXShaderCompiler copied to clipboard

[SPIR-V] specialization constants are not allowed in numthreads

Open 44DA133A8B opened this issue 3 years ago • 4 comments

DXC does not allow HLSL shader to use specialization constants in numthreads

HLSL example:

[[vk::constant_id(0)]] const int thread_group_size_x = 16;
[[vk::constant_id(1)]] const int thread_group_size_y = 16;

Texture2D<unorm float4> input;
RWTexture2D<unorm float4> output;

[numthreads(thread_group_size_x, thread_group_size_y, 1)]
void main(uint2 thread_id : SV_DispatchThreadId)
{
    output[thread_id] = input.Load(uint3(thread_id, 0));
}

DXC output:

test.cs.hlsl:8:2: error: 'numthreads' attribute requires an integer constant [numthreads(thread_group_size_x, thread_group_size_y, 1)] test.cs.hlsl:8:2: error: 'numthreads' attribute requires an integer constant [numthreads(thread_group_size_x, thread_group_size_y, 1)]

Command line: dxc -all-resources-bound -T cs_6_6 -spirv -Fo test.cs.spv test.cs.hlsl

DXC version: Version: dxcompiler.dll: 1.6 - 1.6.2106.3 (dad1cfc30); dxil.dll: 1.6(101.6.2106.2) (it's DX Compiler release for June 2021)

44DA133A8B avatar Dec 04 '21 04:12 44DA133A8B

Thank you for reporting this issue. By the way, does it (using special consts for the number of threads) work in GLSL or just pure SPIR-V?

jaebaek avatar Dec 06 '21 09:12 jaebaek

By the way, does it (using special consts for the number of threads) work in GLSL or just pure SPIR-V?

Yes, there's a way to do this in GLSL.

Here's an example:

#version 460
#extension GL_EXT_samplerless_texture_functions : enable

// specialization constants
layout(constant_id = 0) const int thread_group_size_x  = 16;
layout(constant_id = 1) const int thread_group_size_y  = 16;

layout(set = 0, binding = 0) uniform texture2D u_input;
layout(set = 0, binding = 1, rgba8) uniform image2D u_output;

// note that it's local_size_*_id instead of local_size_*
layout(local_size_x_id = 0, local_size_y_id = 1) in;
void main()
{
    const ivec2 thread_id = ivec2(gl_GlobalInvocationID.xy);
    const vec4 value = texelFetch(u_input, thread_id, 0);
    imageStore(u_output, thread_id, value);
}

I used the following command line to compile it: glslangValidator --target-env vulkan1.2 -S comp -e main test.glsl

44DA133A8B avatar Dec 07 '21 05:12 44DA133A8B

I'm a glsl user currently working on porting some glsl to hlsl for vulkan usage, I hit the same issue, and I can't find a way to "specialize" threadgroup size in hlsl shader. Do you guys have a fix for this issue? or do you know how to work this out without fix this missing feature?

farosis avatar Jun 07 '22 06:06 farosis

I would be extremely interested in support for this feature being added. I recently found out about the new features in HLSL 2021 and I'd love to use them with Vulkan. However, this issue is a bit of a deal breaker for compute shaders.

MarcelPiNacy avatar Aug 11 '22 17:08 MarcelPiNacy

I could confirm the issue in DXC 1.7.2308.10075.

Goshido avatar Oct 19 '23 08:10 Goshido

This might be possible with something like the concept of constexpr as in https://github.com/microsoft/hlsl-specs/issues/21, but unfortunately it's not currently feasible to support in HLSL. The error is in Sema, and can't be resolved without making the constants static, but spec constants cannot be static. Closing as this cannot be fixed in DXC, but if this is an important feature to you it could be re-opened as an hlsl-specs proposal.

sudonatalie avatar May 09 '24 21:05 sudonatalie