Glslang, as cool as it is, was honestly a bit of a headache through this project. Their ABI is really closed off so you can’t peek at much besides the most basic reflection data, and you’re pretty SOL if you want to modify the AST in any way.
Eventually I just said screw it and forked glslang, and added a few transformation passes which I needed to get things working:
Firstly, glslang was generating combined image sampler objects in the SPIR-V for GLSL’s sampler2D object. I wasn’t sure shader_c had support for those (and if it did, I wasn’t able to find a descriptor range for them), so I added a transform pass to glslang which would take any combined image samplers and decombine them, putting the separated textures in descriptor bindings >= 150 and the separated samplers at >= 70 for fragment shaders (this appears to be the current s&box descriptor layout).
Later on I also added another pass which remaps gl_Position’s z component from [-1,1] (stupid OpenGL coordinates) to [0, 1] (sane Vulkan coordinates) to fix some issues with viewport depth.