page.title=Vulkan Shader Compilers on Android @jd:body

On this page

  1. AOT Compilation
  2. Runtime Compilation
  3. Integrating Into your Project

A Vulkan app must manage shaders differently from the way an OpenGL ES app does so: In OpenGL ES, you provide a shader as a set of strings forming the source text of a GLSL shader program. By contrast, the Vulkan API requires you to provide a shader in the form of an entry point in a SPIR-V module.

The NDK includes a runtime library for compiling GLSL into SPIR-V. The runtime library is the same as the one in the Shaderc open source project, and use the same Glslang GLSL reference compiler as a back end. By default, the Shaderc version of the compiler assumes you are compiling for Vulkan. After checking whether your code is valid for Vulkan, the compiler automatically enables the {@code KHR_vulkan_glsl} extension. The Shaderc version of the compiler also generates Vulkan-compliant SPIR-V code.

You can choose to compile SPIR-V modules into your Vulkan app during development, a practice called ahead-of-time, or AOT, compiling. Alternatively, you can have your app compile them from shipped or procedurally generated shader source when needed during runtime. This practice is called runtime compiling.

The rest of this page provides more detail about each practice, and then explains how to integrate shader compilation into your Vulkan app.

AOT Compilation

For AOT compilation, we recommend the glslc command-line compiler from GLSL to SPIR-V. This compiler is available from the Shaderc project.Many of its command-line options are similar to those of GCC and Clang, allowing you to integrate glslc into build systems easily.

The glslc tool compiles a single-source file to a SPIR-V module with a single shader entry point. By default, the output file has the same name as that of the source file, but with the {@code .spv} extension appended.

You use filename extensions to tell the glslc tool which graphics shader stage to compile, or whether a compute shader is being compiled. For information on how to use these filename extensions, and options you can use with the tool, see Shader stage specification in the glslc manual.

Runtime Compilation

For JIT compilation of shaders during runtime, the NDK provides the libshaderc library, which has both C and C++ APIs.

C++ applications should use the C++ API. We recommend that apps in other languages use the C API, because the C ABI is lower level, and likely to provide better stability.

The following example shows how to use the C++ API:

#include <iostream>
#include <string>
#include <vector>
#include <shaderc/shaderc.hpp>

std::vector<uint32_t> compile_file(const std::string& name,
                                   shaderc_shader_kind kind,
                                   const std::string& data) {
  shaderc::Compiler compiler;
  shaderc::CompileOptions options;

  // Like -DMY_DEFINE=1
  options.AddMacroDefinition("MY_DEFINE", "1");

  shaderc::SpvCompilationResult module = compiler.CompileGlslToSpv(
      data.c_str(), data.size(), kind, name.c_str(), options);

  if (module.GetCompilationStatus() !=
      shaderc_compilation_status_success) {
    std::cerr << module.GetErrorMessage();
  }

  std::vector<uint32_t> result(module.cbegin(), module.cend());
  return result;
}

Integrating into Your Projects

You can integrate the Vulkan shader compiler into your app using either the project's {@code Android.mk} file or Gradle.

Android.mk

Perform the following steps to use your project's {@code Android.mk} file to integrate the shader compiler.

  1. Include the following lines in your Android.mk file:
    include $(CLEAR_VARS)
         ...
    LOCAL_STATIC_LIBRARIES := shaderc
         ...
    include $(BUILD_SHARED_LIBRARY)
    
    $(call import-module, third_party/shaderc)
    
  2. Set APP_STL to one of {@code c++_static}, {@code c++_shared}, {@code gnustl_static}, or {@code gnustl_shared}.

Gradle

  1. In a terminal window, navigate to {@code <ndk_root>/sources/third_party/shaderc/}.
  2. Run the following command:
    $ ../../../ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=Android.mk \
    APP_STL:=<stl_version> APP_ABI=all libshaderc_combined
    

    This command places two folders in <ndk_root>/sources/third_party/shaderc/. The directory structure is as follows:

    include/
      shaderc/
        shaderc.h
        shaderc.hpp
    libs/
      <stl_version>/
        {all of the abis}
           libshaderc.a
    
  3. Add includes and link lines as you normally would for external libraries.
  4. The STL that you use to build your program must match the {@code stl} specified in {@code stl_version}. Only {@code c++_static}, {@code c++_shared}, {@code gnustl_static}, and {@code gnustl_shared} are supported.