6

Instead of manually compiling my GLSL shaders to SPIR-V, I want Visual Studio to automatically detect changes to shader files and run glslangValidator as a build step. I am using Premake to generate the Visual Studio solution/project.

One solution that partly worked was declaring in premake5.lua:

    --prebuildcommands [[for %%i in (..\data\shaders\*) do (..\libs\vulkan\glslangValidator.exe -V -o "%%~dpibin\%%~nxi.spv" %%i)]]

and then right-click shader in solution explorer -> properties -> General -> Item Type -> Custom Build Tool.

There are some downsides to this approach:

  • All shaders recompile when only one changes
  • I had to manually change the VS project settings

The closest thing I could find in the premake documentation was: Custom Build Commands. I think the idea is to use a filter on shader files and generate build commands, but I just couldn't get anything to work. Maybe someone else has an idea?

Petwoip
  • 1,365
  • 2
  • 17
  • 25
  • "*I just couldn't get anything to work.*" In what way? Please post the code you thought should work but didn't, then explain how it didn't work. – Nicol Bolas Aug 22 '16 at 13:09
  • I tried: `filter "files:../data/shaders/*" prebuildcommands [[..\libs\vulkan\glslangValidator.exe -V -o %{file.directory}\bin\%{file.name}.spv %{file.relpath}]]`, but I'm not sure if prebuildcommands is supported for individual files in premake. The github wiki page I linked uses `buildcommands`, but it seems like that is designed for converting a resource to obj files and linking with the rest. Either way my vcxproj, filters, user, sln, etc have no reference to the glslang command so it seems like premake ignored it. – Petwoip Aug 22 '16 at 16:55
  • "*it seems like that is designed for converting a resource to obj files and linking with the rest*" The example on the Wiki compiled Lua scripts. Lua doesn't compile to assembly; it's an *interpreted* language. Compiling the Lua scripts just turns it into Lua assembly, which can only be read by the Lua interpreter. – Nicol Bolas Aug 22 '16 at 19:06

2 Answers2

5

Looks like I misunderstood a few things from the premake documentation (thanks Nicol). I got it working by doing:

filter "files:../data/shaders/*"
    buildcommands '"../libs/vulkan/glslangValidator.exe" -V -o "%{file.directory}/bin/%{file.name}.spv" "%{file.relpath}"'
    buildoutputs "%{file.directory}/bin/%{file.name}.spv"

Now my Visual Studio project settings match krOoze's answer. The only downside is having to manually set this up for each new shader (or regenerate the entire project). Custom Rules look interesting but are only supported for Visual Studio at the moment (also they don't support multiple extension types in the same rule (.frag, .vert, .comp, etc)).

Petwoip
  • 1,365
  • 2
  • 17
  • 25
4

I know nothing of Premake, but this works for Visual Studio:

  1. Add the shaders to your project
  2. In the property page of each shader file set Item Type to Custom Build Tool
  3. In the newly appeared Custom Build Tool tree set for each shader file:
    1. Set Command Line to $(VULKAN_SDK)\Bin32\glslangValidator -V -o $(OutDir)\%(Identity).spv %(Identity) (for x32, otherwise Bin for x64 host)
    2. Set Description to something nice, e.g. Compiling vertex shader
    3. Set Outputs to e.g. $(OutDir)\%(Identity).spv
    4. Set Link Objects to No

Should now work per file and properly compile only the modified one and also delete them on clean.

Although I do prefer the method (as you did) of just adding one command to post-build step:

for %%f in (*.vert *.tesc *.tese *.geom *.frag *.comp) \
   do %VK_SDK_PATH%\Bin\glslangValidator.exe -V -o $(OutDir)\%%f.spv %%f

It has the benefit that it can be easily added to a new project with a Property Sheet.

krOoze
  • 12,301
  • 1
  • 20
  • 34
  • Just letting you know that I read your answer, but won't be able to try out until later today. From the sounds of it this is exactly what I need, just hoping premake can handle the setup for me. – Petwoip Aug 22 '16 at 17:02