glslshadervulkanshaderc

How to infer shader type with "shaderc_glsl_infer_from_source"?


I am using shaderc for compiling my shaders. In order to do so, I have to specify the type of shader (shaderc_shader_kind). One of the available types is shaderc_glsl_infer_from_source. The in-code comments say that this type "deduce the shader kind from #pragma annotation in the source code, and compiler will emit error if #pragma annotation is not found".

I have tried putting #pragma vertex_shader or #pragma shaderc_vertex_shader like in the code below, but the program stops working anyway.

#version 450
#extension GL_ARB_separate_shader_objects : enable
#pragma shaderc_fragment_shader

// The rest of the shader goes here

I get the following error:

Shader module compilation failed -
Validation layer: Validation Error: [ VUID_Undefined ] Object 0: handle = 0x1fa16e5fd90, type = VK_OBJECT_TYPE_DEVICE; | MessageID = 0x79de34d4 | vkCreateShaderModule: parameter pCreateInfo->codeSize / 4 must be greater than 0.
Validation layer: Validation Error: [ UNASSIGNED-CoreValidation-Shader-InconsistentSpirv ] Object 0: handle = 0x1fa16e5fd90, type = VK_OBJECT_TYPE_DEVICE; | MessageID = 0x6bbb14 | SPIR-V module not valid: Invalid SPIR-V magic number.
Failed to create shader module!

However, everything works fine when, instead of using shaderc_glsl_infer_from_source, I specify the type of shader manually (shaderc_vertex_shader or shaderc_fragment_shader) in my Vulkan code. Unfortunately, this is not convenient in my case.

What am I doing wrong? Is the #pragma directive correct?


Solution

  • Digging around in their source code and stumbling into the related test code, the pragmas seem to be #pragma shader_stage(something):

    // Vertex only shader with #pragma annotation.
    const char kVertexOnlyShaderWithPragma[] =
        "#version 310 es\n"
        "#pragma shader_stage(vertex)\n"
        "void main() {\n"
        "    gl_Position = vec4(1.);\n"
        "}";
    
    // Fragment only shader with #pragma annotation.
    const char kFragmentOnlyShaderWithPragma[] =
        "#version 310 es\n"
        "#pragma shader_stage(fragment)\n"
        "void main() {\n"
        "    gl_FragDepth = 10.;\n"
        "}";
    

    and a lot more, tesscontrol, tesseval, geometry, compute, mesh, task.