Search code examples
glslvulkanspir-v

Query existence of GLSL extension in SPIR-V shader


In regular GLSL I can do something like this to conditionally enable a GLSL extension:

#if defined(GL_ARB_shader_viewport_layer_array)
    #extension GL_ARB_shader_viewport_layer_array : enable
    // Some other stuff here
#endif

My question is, how can I achieve the same in SPIR-V using the glslang library? I'm assuming I'll need to compile multiple versions of the same shader to achieve this? Or is there a way to conditionalize SPIR-V on the existence of an extension without generating two binaries for two versions?


Solution

  • In regular GLSL I can do something like this to conditionally enable a GLSL extension:

    First of all, no you can't. Not every OpenGL extension ot GLSL exposes such a #define. For example, nowhere in the GL_ARB_shader_viewport_layer_array extension will you find that define to be specified to be there. By contrast, the GL_ARB_shader_group_vote extension does specify a #define.

    Second, even if the extension provides a #define, that still won't work. Because the #define is only exposed if you activate the extension with a #extension directive. So your example will never get shader_viewport_layer_array working.

    If you want an extension to be conditionally present, you use #extension NAME : enable. If the implementation doesn't support the extension, you won't get it (you'll get a warning in the shader log file). You detect whether or not the extension is active with the #define discussed earlier.

    As for how to do that with SPIR-V... you don't. SPIR-V is an intermediate language, not a high-level one. The expectation is that the SPIR-V is written against a particular version of the host environment, including extensions. If you want to conditionally support some extensions and not others, you have to generate multiple SPIR-V shaders for those combinations of extensions that you intend to support.

    SPIR-V has no equivalent to #ifdef, again because it is an intermediate language.