Building Vulkan shaders with Bazel

Bazel for Vulkan projects

Pavlo Stavytskyi
CodeX
4 min readNov 14, 2022

--

Image by Javier Miranda on Unsplash

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.

triangle/shaders/shader.vert file contents

Similarly, create a file for a fragment shader called shader.frag under the triangle/shaders directory. Add there the code below.

triangle/shaders/shader.frag file contents

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.

triangle/shaders/BUILD file contents

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.

triangle/main.cpp file contents modification

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.

triangle/BUILD file contents

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.

--

--

Pavlo Stavytskyi
CodeX
Writer for

Staff Software Engineer at Meta • Google Developer Expert for Android, Kotlin