Home | History | Annotate | Download | only in graphics
      1 page.title=Vulkan Shader Compilers on Android
      2 @jd:body
      3 
      4 <div id="qv-wrapper">
      5     <div id="qv">
      6       <h2>On this page</h2>
      7 
      8       <ol>
      9         <li><a href="#aot">AOT Compilation</a></li>
     10         <li><a href="#runtime">Runtime Compilation</a></li>
     11         <li><a href="#integrating">Integrating Into your Project</a></li>
     12       </ol>
     13     </div>
     14   </div>
     15 
     16 <p>
     17 A Vulkan app must manage shaders differently from the way an OpenGL ES app does so:
     18 In OpenGL ES, you provide a shader as a set of strings forming the source text of a
     19 GLSL shader program. By contrast, the Vulkan API requires you to provide a shader in
     20 the form of an entry point in a <a href=https://www.khronos.org/spir>SPIR-V</a> module.
     21 </p>
     22 
     23 <p>
     24 The NDK includes a runtime library for compiling GLSL into SPIR-V.
     25 The runtime library is the same as the one in the
     26 <a href="https://github.com/google/shaderc">Shaderc</a> open source project, and use the same
     27 <a href="https://github.com/KhronosGroup/glslang">Glslang GLSL</a> reference compiler as a
     28 back end. By default, the Shaderc version of the
     29 compiler assumes you are compiling for Vulkan.  After checking whether your code is valid for
     30 Vulkan, the compiler automatically enables the {@code KHR_vulkan_glsl} extension. The Shaderc
     31 version of the compiler also generates Vulkan-compliant SPIR-V code.
     32 </p>
     33 
     34 <p>
     35 You can choose to compile SPIR-V modules into your Vulkan app during development, a
     36 practice called <em>ahead-of-time</em>, or <em>AOT</em>, compiling. Alternatively,
     37 you can have your app compile them from shipped or procedurally generated shader
     38 source when needed during runtime. This practice is called <em>runtime compiling</em>.
     39 </p>
     40 
     41 <p>
     42 The rest of this page provides more detail about each practice, and then explains
     43 how to integrate shader compilation into your Vulkan app.
     44 </p>
     45 
     46 <h2 id=aot>AOT Compilation</h2>
     47 
     48 <p>
     49 For AOT compilation, we recommend the <em>glslc</em> command-line compiler from GLSL to SPIR-V.
     50 This compiler is available from the <a href="https://github.com/google/shaderc">Shaderc</a>
     51 project.</a>Many of its command-line options are similar to those of GCC and Clang, allowing
     52 you to integrate glslc into build systems easily.
     53 </p>
     54 
     55 <p>
     56 The glslc tool compiles a single-source file to a SPIR-V module with a single shader
     57 entry point.  By default, the output file has the same name as that of the source file,
     58 but with the {@code .spv} extension appended.
     59 </p>
     60 
     61 <p>
     62 You use filename extensions to tell the glslc tool which graphics shader stage to compile,
     63 or whether a compute shader is being compiled. For information on how to use these filename
     64 extensions, and options you can use with the tool, see
     65 <a href="https://github.com/google/shaderc/tree/master/glslc#user-content-shader-stage-specification">
     66 Shader stage specification</a> in the
     67 <a href="https://github.com/google/shaderc/tree/master/glslc">
     68 glslc</a> manual.
     69 </p>
     70 
     71 <h2 id="runtime">Runtime Compilation</h2>
     72 
     73 <p>
     74 For JIT compilation of shaders during runtime, the NDK provides the libshaderc library,
     75 which has both C and C++ APIs.
     76 </p>
     77 
     78 <p>
     79 C++ applications should use the C++ API. We recommend that apps in other languages
     80 use the C API, because the C ABI is lower level, and likely to provide better stability.
     81 </p>
     82 
     83 <p>
     84 The following example shows how to use the C++ API:
     85 </p>
     86 
     87 <pre>
     88 #include &lt;iostream&gt;
     89 #include &lt;string&gt;
     90 #include &lt;vector&gt;
     91 #include &lt;shaderc/shaderc.hpp&gt;
     92 
     93 std::vector&lt;uint32_t&gt; compile_file(const std::string& name,
     94                                    shaderc_shader_kind kind,
     95                                    const std::string& data) {
     96   shaderc::Compiler compiler;
     97   shaderc::CompileOptions options;
     98 
     99   // Like -DMY_DEFINE=1
    100   options.AddMacroDefinition("MY_DEFINE", "1");
    101 
    102   shaderc::SpvCompilationResult module = compiler.CompileGlslToSpv(
    103       data.c_str(), data.size(), kind, name.c_str(), options);
    104 
    105   if (module.GetCompilationStatus() !=
    106       shaderc_compilation_status_success) {
    107     std::cerr << module.GetErrorMessage();
    108   }
    109 
    110   std::vector&lt;uint32_t&gt; result(module.cbegin(), module.cend());
    111   return result;
    112 }
    113 </pre>
    114 
    115 
    116 
    117 <h2 id=integrating>Integrating into Your Projects</h2>
    118 
    119 <p>
    120 You can integrate the Vulkan shader compiler into your app using either the project's
    121 {@code Android.mk} file or Gradle.
    122 </p>
    123 
    124 <h3 id=androidmk>Android.mk</h3>
    125 
    126 <p>
    127 Perform the following steps to use your project's {@code Android.mk}
    128 file to integrate the shader compiler.
    129 </p>
    130 
    131 <ol>
    132 <li>
    133 Include the following lines in your Android.mk file:
    134 <pre class="no-pretty-print">
    135 include $(CLEAR_VARS)
    136      ...
    137 LOCAL_STATIC_LIBRARIES := shaderc
    138      ...
    139 include $(BUILD_SHARED_LIBRARY)
    140 
    141 $(call import-module, third_party/shaderc)
    142 </pre>
    143 </li>
    144 
    145 <li>
    146 Set APP_STL to one of {@code c++_static}, {@code c++_shared}, {@code gnustl_static},
    147 or {@code gnustl_shared}.
    148 </li>
    149 </ol>
    150 
    151 
    152 
    153 <h3 id=gradle>Gradle</h3>
    154 
    155 <ol>
    156 <li>
    157 In a terminal window, navigate to
    158 {@code &lt;ndk_root&gt;/sources/third_party/shaderc/}.
    159 </li>
    160 
    161 <li>
    162 Run the following command:
    163 
    164 <pre class="no-pretty-print">
    165 $ ../../../ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=Android.mk \
    166 APP_STL:=&lt;stl_version&gt; APP_ABI=all libshaderc_combined
    167 </pre>
    168 
    169 <p>
    170 This command places two folders in &lt;ndk_root&gt;/sources/third_party/shaderc/. The directory
    171 structure is as follows:
    172 </p>
    173 
    174 <pre class="no-pretty-print">
    175 include/
    176   shaderc/
    177     shaderc.h
    178     shaderc.hpp
    179 libs/
    180   &lt;stl_version&gt;/
    181     {all of the abis}
    182        libshaderc.a
    183 </pre>
    184 </li>
    185 
    186 <li>
    187 Add includes and link lines as you normally would for external libraries.
    188 </li>
    189 <p>
    190 The STL that you use to build your program must match the {@code stl} specified in
    191 {@code stl_version}.
    192 Only {@code c++_static}, {@code c++_shared}, {@code gnustl_static}, and
    193 {@code gnustl_shared} are supported.
    194 </p>
    195