DirectXShaderCompiler
DirectXShaderCompiler copied to clipboard
[SPIR-V] Specialization constants don't work if the shader uses the implicit Globals UBO
Title
[SPIR-V] Specialization constants don't work if the shader uses the implicit Globals UBO
Functional impact
Specialization constants get placed into the $Globals UBO as regular constants when the $Globals UBO is present. This is incorrect and makes them practically unusable.
Minimal repro steps
- Compile the following shader with
dxc.exe -T ps_6_0 -E main -spirv repro_shader.txt:
[[ vk::constant_id ( 1 )]] const int mySpecializationConstant = 0;
//cbuffer NamedCBuffer {
float myGlobal;
//};
float4 main(float4 col : COLOR) : SV_Target0
{
if(mySpecializationConstant)
return 0.xxxx;
return myGlobal.xxxx;
}
Expected result
The SPIR-V should contain a specialization constant named mySpecializationConstant and the $Globals UBO should contain only one member named myGlobal
Actual result
The SPIR-V doesn't contain any specialization constants and it places mySpecializationConstant into the $Globals UBO (see full output in spec_constant_simple_repro.spv.txt):
OpName %type__Globals "type.$Globals"
OpMemberName %type__Globals 0 "mySpecializationConstant"
OpMemberName %type__Globals 1 "myGlobal"
OpName %_Globals "$Globals"
OpName %out_var_SV_Target0 "out.var.SV_Target0"
OpName %main "main"
OpDecorate %out_var_SV_Target0 Location 0
OpDecorate %_Globals DescriptorSet 0
OpDecorate %_Globals Binding 0
OpMemberDecorate %type__Globals 0 Offset 0
OpMemberDecorate %type__Globals 1 Offset 4
OpDecorate %type__Globals Block
Also, the compiler produces a warning pointing to the wrong name myGlobal:
spec_constant_simple_repro.txt:1:65: warning: variable 'myGlobal' will be placed in $Globals so initializer ignored
[[ vk::constant_id ( 1 )]] const int mySpecializationConstant = 0;
^
Further technical details
- Used DXC from the latest official built release v1.6.2112
- Placing the constant
myGlobalinto a named cbuffer (as is commented out in the repro shader) instead of into the implicit$Globalscbuffer fixes the issue