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 <iostream> 89#include <string> 90#include <vector> 91#include <shaderc/shaderc.hpp> 92 93std::vector<uint32_t> 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<uint32_t> 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 <ndk_root>/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:=<stl_version> APP_ABI=all libshaderc_combined 167</pre> 168 169<p> 170This command places two folders in <ndk_root>/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 <stl_version>/ 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