KhronosGroup / KhronosGroup/glslang
Nonliteral [[vk::constant_id]] generates standard constant
- Dominant language
- C++
- Stars
- 3.6k
- Forks
- 989
- Avg merge
- 1d 2h
- Merged PRs (30d)
- 31
Description
I am attempting to compile the following code:
```HLSL
static int NEXT_SPEC_CONST_ID = 0;
[[vk::constant_id(NEXT_SPEC_CONST_ID++)]] const float TEST_FLOAT_1 = 0.32f;
[[vk::constant_id(NEXT_SPEC_CONST_ID++)]] const float TEST_FLOAT_2 = 0.33f;
struct VS_INPUT
{
float4 pos : POSITION;
};
struct VS_OUTPUT
{
float4 pos : SV_POSITION;
};
VS_OUTPUT main( const VS_INPUT input )
{
VS_OUTPUT output;
output.pos = input.pos;
output.pos.x *= TEST_FLOAT_1;
output.pos.y *= TEST_FLOAT_2;
return output;
}
```
I'm reasonably certain this isn't allowed. However in that case, I'd expect it to give me a compiler error, rather than silently demoting the specialization constants to regular constants:
```SPIR-V
; SPIR-V
; Version: 1.0
; Generator: Khronos Glslang Reference Front End; 7
; Bound: 84
; Schema: 0
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Vertex %main "main" %input_pos %_entryPointOutput_pos
OpSource HLSL 500
OpName %main "main"
OpName %input_pos "input.pos"
OpName %_entryPointOutput_pos "@entryPointOutput.pos"
OpDecorate %input_pos Location 0
OpDecorate %_entryPointOutput_pos BuiltIn Position
%void = OpTypeVoid
%3 = OpTypeFunction %void
%float = OpTypeFloat 32
%v4float = OpTypeVector %float 4
%float_0_319999993 = OpConstant %float 0.319999993
%float_0_330000013 = OpConstant %float 0.330000013
%_ptr_Input_v4float = OpTypePointer Input %v4float
%input_pos = OpVariable %_ptr_Input_v4float Input
%_ptr_Output_v4float = OpTypePointer Output %v4float
%_entryPointOutput_pos = OpVariable %_ptr_Output_v4float Output
%main = OpFunction %void None %3
%5 = OpLabel
%44 = OpLoad %v4float %input_pos
%56 = OpCompositeExtract %float %44 0
%57 = OpFMul %float %56 %float_0_319999993
%80 = OpCompositeInsert %v4float %57 %44 0
%60 = OpCompositeExtract %float %44 1
%61 = OpFMul %float %60 %float_0_330000013
%83 = OpCompositeInsert %v4float %61 %80 1
OpStore %_entryPointOutput_pos %83
OpReturn
OpFunctionEnd
```
If the IDs for the specialization constants are changed to literals, the codegen is correct:
```HLSL
...
[[vk::constant_id(2)]] const float TEST_FLOAT_1 = 0.32f;
[[vk::constant_id(5)]] const float TEST_FLOAT_2 = 0.33f;
...
```
```SPIR-V
; SPIR-V
; Version: 1.0
; Generator: Khronos Glslang Reference Front End; 7
; Bound: 84
; Schema: 0
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Vertex %main "main" %input_pos %_entryPointOutput_pos
OpSource HLSL 500
OpName %main "main"
OpName %TEST_FLOAT_1 "TEST_FLOAT_1"
OpName %TEST_FLOAT_2 "TEST_FLOAT_2"
OpName %input_pos "input.pos"
OpName %_entryPointOutput_pos "@entryPointOutput.pos"
OpDecorate %TEST_FLOAT_1 SpecId 2
OpDecorate %TEST_FLOAT_2 SpecId 5
OpDecorate %input_pos Location 0
OpDecorate %_entryPointOutput_pos BuiltIn Position
%void = OpTypeVoid
%3 = OpTypeFunction %void
%float = OpTypeFloat 32
%v4float = OpTypeVector %float 4
%TEST_FLOAT_1 = OpSpecConstant %float 0.319999993
%TEST_FLOAT_2 = OpSpecConstant %float 0.330000013
%_ptr_Input_v4float = OpTypePointer Input %v4float
%input_pos = OpVariable %_ptr_Input_v4float Input
%_ptr_Output_v4float = OpTypePointer Output %v4float
%_entryPointOutput_pos = OpVariable %_ptr_Output_v4float Output
%main = OpFunction %void None %3
%5 = OpLabel
%44 = OpLoad %v4float %input_pos
%56 = OpCompositeExtract %float %44 0
%57 = OpFMul %float %56 %TEST_FLOAT_1
%80 = OpCompositeInsert %v4float %57 %44 0
%60 = OpCompositeExtract %float %44 1
%61 = OpFMul %float %60 %TEST_FLOAT_2
%83 = OpCompositeInsert %v4float %61 %80 1
OpStore %_entryPointOutput_pos %83
OpReturn
OpFunctionEnd
```
Contributor guide
Research direction
Reproduce the issue using the HLSL examples and inspect the generated SPIR-V for literal versus nonliteral vk::constant_id values. Start by tracing the compiler path that handles vk::constant_id and compare its behavior with the shown OpConstant and OpSpecConstant output. Done means nonliteral IDs no longer silently become regular constants, with the intended diagnostic or behavior covered by a regression test.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100