1page.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>
17A Vulkan app must manage shaders differently from the way an OpenGL ES app does so:
18In OpenGL ES, you provide a shader as a set of strings forming the source text of a
19GLSL shader program. By contrast, the Vulkan API requires you to provide a shader in
20the form of an entry point in a <a href=”https://www.khronos.org/spir”>SPIR-V</a> module.
21</p>
22
23<p>
24The NDK includes a runtime library for compiling GLSL into SPIR-V.
25The 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
28back end. By default, the Shaderc version of the
29compiler assumes you are compiling for Vulkan.  After checking whether your code is valid for
30Vulkan, the compiler automatically enables the {@code KHR_vulkan_glsl} extension. The Shaderc
31version of the compiler also generates Vulkan-compliant SPIR-V code.
32</p>
33
34<p>
35You can choose to compile SPIR-V modules into your Vulkan app during development, a
36practice called <em>ahead-of-time</em>, or <em>AOT</em>, compiling. Alternatively,
37you can have your app compile them from shipped or procedurally generated shader
38source when needed during runtime. This practice is called <em>runtime compiling</em>.
39</p>
40
41<p>
42The rest of this page provides more detail about each practice, and then explains
43how to integrate shader compilation into your Vulkan app.
44</p>
45
46<h2 id=”aot”>AOT Compilation</h2>
47
48<p>
49For AOT compilation, we recommend the <em>glslc</em> command-line compiler from GLSL to SPIR-V.
50This compiler is available from the <a href="https://github.com/google/shaderc">Shaderc</a>
51project.</a>Many of its command-line options are similar to those of GCC and Clang, allowing
52you to integrate glslc into build systems easily.
53</p>
54
55<p>
56The glslc tool compiles a single-source file to a SPIR-V module with a single shader
57entry point.  By default, the output file has the same name as that of the source file,
58but with the {@code .spv} extension appended.
59</p>
60
61<p>
62You use filename extensions to tell the glslc tool which graphics shader stage to compile,
63or whether a compute shader is being compiled. For information on how to use these filename
64extensions, 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">
66Shader stage specification</a> in the
67<a href="https://github.com/google/shaderc/tree/master/glslc">
68glslc</a> manual.
69</p>
70
71<h2 id="runtime">Runtime Compilation</h2>
72
73<p>
74For JIT compilation of shaders during runtime, the NDK provides the libshaderc library,
75which has both C and C++ APIs.
76</p>
77
78<p>
79C++ applications should use the C++ API. We recommend that apps in other languages
80use the C API, because the C ABI is lower level, and likely to provide better stability.
81</p>
82
83<p>
84The 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
93std::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>
120You 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>
127Perform the following steps to use your project's {@code Android.mk}
128file to integrate the shader compiler.
129</p>
130
131<ol>
132<li>
133Include the following lines in your Android.mk file:
134<pre class="no-pretty-print">
135include $(CLEAR_VARS)
136     ...
137LOCAL_STATIC_LIBRARIES := shaderc
138     ...
139include $(BUILD_SHARED_LIBRARY)
140
141$(call import-module, third_party/shaderc)
142</pre>
143</li>
144
145<li>
146Set APP_STL to one of {@code c++_static}, {@code c++_shared}, {@code gnustl_static},
147or {@code gnustl_shared}.
148</li>
149</ol>
150
151
152
153<h3 id=”gradle”>Gradle</h3>
154
155<ol>
156<li>
157In a terminal window, navigate to
158{@code &lt;ndk_root&gt;/sources/third_party/shaderc/}.
159</li>
160
161<li>
162Run the following command:
163
164<pre class="no-pretty-print">
165$ ../../../ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=Android.mk \
166APP_STL:=&lt;stl_version&gt; APP_ABI=all libshaderc_combined
167</pre>
168
169<p>
170This command places two folders in &lt;ndk_root&gt;/sources/third_party/shaderc/. The directory
171structure is as follows:
172</p>
173
174<pre class="no-pretty-print">
175include/
176  shaderc/
177    shaderc.h
178    shaderc.hpp
179libs/
180  &lt;stl_version&gt;/
181    {all of the abis}
182       libshaderc.a
183</pre>
184</li>
185
186<li>
187Add includes and link lines as you normally would for external libraries.
188</li>
189<p>
190The STL that you use to build your program must match the {@code stl} specified in
191{@code stl_version}.
192Only {@code c++_static}, {@code c++_shared}, {@code gnustl_static}, and
193{@code gnustl_shared} are supported.
194</p>
195