KhronosGroup / Vulkan-Samples

One stop solution for all Vulkan samples
Apache License 2.0
4.23k stars 634 forks source link

[Shading language support] Add support for loading SPIR-V shaders generated from HLSL for ARM framework samples #1108

Open SaschaWillems opened 2 months ago

SaschaWillems commented 2 months ago

With #990 we added support for offline compilation of HLSL shaders via CMake. So any HLSL shader added to a sample's CMakeLists.txt will be compiled to SPIR-V when running CMake.

With #961 we added support for selecting between GLSL (compiled at runtime) and HLSL (compiled offline, loading SPIR-V) to the api based samples. A new command line argument was introduced to select what shader type to load. Default is GLSL, but with --shading-language HLSL one can load HLSL shaders instead if they're present for a sample.

For this to work in a portable way that requires little modification to a sample both the ApiVulkanSample as well as the HPPApiVulkanSample got a new overload for loading shaders. Instead of providing a direct shader file path, path and shader name are separate arguments, and the function then loads either the glsl file (and compiles it at runtime) or loads the offline compiled SPIR-V file from an HLSL shader.

Before:

shader_stages[0] = load_shader("dynamic_uniform_buffers\glsl\base.vert", VK_SHADER_STAGE_VERTEX_BIT);

After:

shader_stages[0] = load_shader("dynamic_uniform_buffers", "base.vert", VK_SHADER_STAGE_VERTEX_BIT);

The latter will select the folder to load the shader from based on the currently selected shading language (glsl or HLSL). If HLSL is selected, shaders are loaded from offline compiled SPIR-V.

The ARM framework samples should be adjusted accordingly and should check for the value of the --shading-language argument and depending on that should select either GLSL (and compile at runtime) or HLSL (and load SPIR-V instead). Hopefully code can be leveraged from the api sample functions, see ApiVulkanSample::load_shader.

This probably requires a change in the ShaderSource class.