Building Vulkan shaders with Bazel
Bazel for Vulkan projects
This is the second part of a series of blog posts about building projects that use Vulkan graphics API with Bazel build system. In the first part, we performed an environment setup for a simple Vulkan project that uses GLM and GLFW libraries. In this blog post, we are going to expand our knowledge and see how to build GLSL shaders with Bazel and run a project that draws a triangle.
Be sure to check part 1 before proceeding with this blog post.
You can find a complete source code of a sample project on GitHub.
Building shaders
OpenGL Shading Language (GLSL) — is a high-level shading language with a syntax based on the C programming language. It is also supported by Vulkan.
We are going to start with creating simple vector and fragment shaders for building a triangle. The source code was taken from the official Vulkan tutorial, so feel free to check it out for more details about the shaders code itself.
Create a shader.vert
file and put it in the triangle/shaders
directory in the project we used in part 1 of this series.
Similarly, create a file for a fragment shader called shader.frag
under the triangle/shaders
directory. Add there the code below.
Now, we are ready to create a Bazel target that is going to build our shaders. We are going to use a glsl_shader
rule from rules_vulkan
we previously included in the project. Create a BUILD
file in the same directory and populate it with the following code.
To verify all was done correctly, run the following commands in the terminal and make sure shaders are built successfully.
bazel build //triangle/shaders:vert_shader
bazel build //triangle/shaders:frag_shader
Here is the directory structure we have so far.
vulkan-bazel-samples
├── triangle
│ └── shaders
│ ├── shader.frag
│ ├── shader.frag
│ └── BUILD
│
├── env_setup
├── third_party
└── WORKSPACE
Finally, we are ready to build our application that will use these shaders and draw a triangle.
Drawing a triangle
In order to build the app that draws a triangle, we will use a source code from an official Vulkan tutorial. Create a main.cpp
file and place it in the triangle
directory. Fill it with the source code copied from the Vulkan tutorial.
We won’t be focusing on the code itself as everything would be identical to the Vulkan tutorial. However, we would need to do a slight correction to the code for our project. Open main.cpp
file and find a createGraphicsPipeline
function declaration. Here, we would need to edit its first 2 lines where we change paths to our compiled shaders as shown below.
Now, the only thing left is to define a Bazel target that will build and run our program. To do so, create a BUILD
file inside a triangle
directory. We are going to use a standard cc_binary
rule.
In the deps
parameter we need to include glfw
and glm
libraries we defined in the previous blog post. In addition, we need to add a Vulkan library itself.
In the data
parameter, we are referencing the shader targets we’ve just created.
Eventually, the final folder structure of our sample project looks like below.
vulkan-bazel-samples
├── triangle
│ ├── shaders
│. │
│ ├── main.cpp
│ └── BUILD
│
├── env_setup
├── third_party
└── WORKSPACE
Running the app
This is all we need to run a triangle Vulkan app with Bazel.
Now, use the following command to build and launch our application.
bazel run //triangle
If all is done correctly, it will run an app that draws a triangle on the screen as shown below.
Conclusion
This is it! In this short series of blog posts, we’ve seen how to perform a basic setup to be able to use Bazel in projects with Vulkan graphics API.
In part 1 we performed an environment setup for the project and now we ran a basic triangle app built with Bazel.
All the source code from this blog post could be found on GitHub.
References
- rules_vulkan — a repository that enables Bazel support for Vulkan projects, created by Juan David Adarve.