I'm trying to understand what spirv-remap does, so I created a simple fragment shader with a simple layout(location=0) out vec4 fragColor;, compiled with glslang -V shader.frag -o shader.frag.spv and then spirv-remap --do-everything -i shader.frag.spv -o finalSpirV. As expected, changing variable names inside a uniform block does not change the final data in finalSpirV, after all, it's just data and offsets. To my surprise, renaming fragColor changed it. I thought that variable name was completely internal to the shader, and meaningless to the "outside world". What is my misunderstanding about spirv and spirv-remap?
Example:
shader1.frag
#version 460
layout(location=0) out vec4 fragColor;
void main()
{
fragColor = vec4(1,0,0,1);
}
shader2.frag
#version 460
layout(location=0) out vec4 outout;
void main()
{
outout = vec4(1,0,0,1);
}
after running glslang -V shader1.frag -o shader1.frag.spv && spirv-remap --do-everything -i shader1.frag.spv -o finalSpirV1, glslang -V shader2.frag -o shader2.frag.spv && spirv-remap --do-everything -i shader2.frag.spv -o finalSpirV2, spirv-dis finalSpirV1 -o orgFrag1.frag and spirv-dis finalSpirV2 -o orgFrag2.frag gives:
orgFrag1.frag
; SPIR-V
; Version: 1.0
; Generator: Khronos Glslang Reference Front End; 11
; Bound: 9012
; Schema: 0
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %5663 "main" %3647
OpExecutionMode %5663 OriginUpperLeft
OpDecorate %3647 Location 0
%void = OpTypeVoid
%1282 = OpTypeFunction %void
%float = OpTypeFloat 32
%v4float = OpTypeVector %float 4
%_ptr_Output_v4float = OpTypePointer Output %v4float
%3647 = OpVariable %_ptr_Output_v4float Output
%float_1 = OpConstant %float 1
%float_0 = OpConstant %float 0
%1416 = OpConstantComposite %v4float %float_1 %float_0 %float_0 %float_1
%5663 = OpFunction %void None %1282
%9011 = OpLabel
OpStore %3647 %1416
OpReturn
OpFunctionEnd
orgFrag2.frag
; SPIR-V
; Version: 1.0
; Generator: Khronos Glslang Reference Front End; 11
; Bound: 9012
; Schema: 0
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %5663 "main" %3067
OpExecutionMode %5663 OriginUpperLeft
OpDecorate %3067 Location 0
%void = OpTypeVoid
%1282 = OpTypeFunction %void
%float = OpTypeFloat 32
%v4float = OpTypeVector %float 4
%_ptr_Output_v4float = OpTypePointer Output %v4float
%3067 = OpVariable %_ptr_Output_v4float Output
%float_1 = OpConstant %float 1
%float_0 = OpConstant %float 0
%1416 = OpConstantComposite %v4float %float_1 %float_0 %float_0 %float_1
%5663 = OpFunction %void None %1282
%9011 = OpLabel
OpStore %3067 %1416
OpReturn
OpFunctionEnd
Cleary some id differs. Maybe SPIRV specification requires unique identifiers for out variables, and spirv-remap uses some kind of hash on the string name instead of a (more reasonable) sequential assignment of internal ids?
I figured it out. The problem is indeed the ID remapping, which I can't find much documentation about. Running
spirv-remaponly with flags--dce all --opt all --strip allgives consistent outputs.I still don't understand what's possibly the benefit of ID remapping, maybe someone can explain in the comments.