The format of SPIR-V bytecode is probably one of the least documented parts of both OpenGL and Vulkan that I am aware of. I have compiled a very basic fragment shaders into both the OpenGL and Vulkan SPIR-V formats. Looking at the files in a hex editor, I see no obvious differences, but when I hash the files, they give a different result. What are the differences between the OpenGL and Vulkan SPIR-V formats?
How different is the SPIR-V accepted by OpenGL (ARB_gl_spirv) from SPIR-V accepted by Vulkan?
Vulkan and OpenGL use different models for their resource bindings. Vulkan uses descriptor sets + binding, while OpenGL uses binding indices. As such, the SPIR-V they consume use different decorations for their resources.
There are also a number of differences in terms of built-ins that the two APIs provide. For example, Vulkan accepts the
InstanceIndex built-in, while OpenGL does not. OpenGL uses
InstanceId, which has a different meaning from
The ARB_gl_spirv extension has a pretty exhaustive list of the differences between it and KHR_vulkan_glsl. Many of those are differences that the output SPIR-V will have to expose.