如何使用glslang

Aed*_*oro 7 c++ shader glsl vulkan spir-v

我正在尝试使用 glslang 将 glsl 着色器代码编译为 SPIR-V 二进制文件。glslang 项目可以在这里找到:

https://github.com/KhronosGroup/glslang

它可以通过在命令行中手动运行 glslangValidator.exe 来很好地工作。但我想使用 C++ 接口。

我已经按照 github 页面上的描述构建了项目,现在我正在努力解决如何实际使用该界面的问题。

我宁愿不在我的解决方案中实际包含任何项目(我正在使用 Visual Studio),而是链接使用它所需的 .lib 和标头。我只是找不到我需要链接哪些。github页面只提到ShaderLang.h和StandAlone.cpp,这是不够的。

有人可以解释如何设置一个可以使用 glslang 的项目吗?我只需要它来将 glsl 着色器代码编译为 SPIR-V 二进制文件(带有有关着色器编译的调试信息)。我认为对于已经做过或有更多经验的人来说,这将是一个非常简单的问题。

小智 5

您需要使用几个库。一个可供查看的消费者示例是 LunarGLASS: https: //github.com/LunarG/LunarGLASS。在那里,您可以看到该文件:

https://github.com/LunarG/LunarGLASS/blob/master/CMakeLists.txt

其中包含库的内容:

set(GLSLANGLIBS
    glslang
    HLSL
    OSDependent
    OGLCompiler
    SPIRV)
Run Code Online (Sandbox Code Playgroud)

glslang 的自述文件包含一些重要信息。此外,在 glslang 中,glslangValidator 工具(基本上是 StandAlone.cpp)展示了如何使用库的 API。您还可以在 LunarGLASS 项目中查看 Frontends/glslang 目录以进行类似用途。


小智 5

https://github.com/google/shaderc上的 Shaderc 项目提供了一个易于使用的 C++ API,该 API 将 Glslang 的编译器包装到 SPIR-V。

有关示例用法,请参阅https://github.com/google/shaderc/blob/master/examples/online-compile/main.cc

  • 这个答案完全依赖于外部链接的内容。如果它们变得无效,您的答案将毫无用处。因此,请[编辑]您的答案并至少添加可以在那里找到的内容的摘要。谢谢你! (5认同)

Ser*_* K. 5

您可以使用glslangC 接口 ( https://github.com/KhronosGroup/glslang/pull/2038 ) 将着色器源代码编译为 SPIR-V,如下所示。

const char* shaderCodeVertex = ...;

const glslang_input_t input =
{
    .language = GLSLANG_SOURCE_GLSL,
    .stage = GLSLANG_STAGE_VERTEX,
    .client = GLSLANG_CLIENT_VULKAN,
    .client_version = GLSLANG_TARGET_VULKAN_1_1,
    .target_language = GLSLANG_TARGET_SPV,
    .target_language_version = GLSLANG_TARGET_SPV_1_3,
    .code = shaderCodeVertex,
    .default_version = 100,
    .default_profile = GLSLANG_NO_PROFILE,
    .force_default_version_and_profile = false,
    .forward_compatible = false,
    .messages = GLSLANG_MSG_DEFAULT_BIT,
};

glslang_initialize_process();

glslang_shader_t* shader = glslang_shader_create( &input );

if ( !glslang_shader_preprocess(shader, &input) )
{
    // use glslang_shader_get_info_log() and glslang_shader_get_info_debug_log()
}

if ( !glslang_shader_parse(shader, &input) )
{
    // use glslang_shader_get_info_log() and glslang_shader_get_info_debug_log()
}

glslang_program_t* program = glslang_program_create();
glslang_program_add_shader( program, shader );

if (!glslang_program_link(program, GLSLANG_MSG_SPV_RULES_BIT | GLSLANG_MSG_VULKAN_RULES_BIT))
{
    // use glslang_program_get_info_log() and glslang_program_get_info_debug_log();
}

glslang_program_SPIRV_generate( program, input.stage );

if ( glslang_program_SPIRV_get_messages(program) )
{
    printf("%s", glslang_program_SPIRV_get_messages(program));
}

glslang_shader_delete( shader );
Run Code Online (Sandbox Code Playgroud)

编译后的 SPIR-V blob 可以通过以下方式与 Vulkan 一起使用。

const VkShaderModuleCreateInfo ci =
{
    .sType    = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
    .codeSize = glslang_program_SPIRV_get_size(program) * sizeof(unsigned int),
    .pCode    = glslang_program_SPIRV_get_ptr(program)
};

VkResult result = vkCreateShaderModule(device, &ci, nullptr, ...);

glslang_program_delete( program );
Run Code Online (Sandbox Code Playgroud)