Un'app Vulkan deve gestire gli mesh in modo diverso rispetto a un'app OpenGL ES: in OpenGL ES, fornisci uno Shader come un insieme di stringhe che formano il testo di origine di un programma mesh GLSL. Al contrario, l'API Vulkan richiede di fornire uno meshr sotto forma di punto di ingresso in un modulo SPIR-V.
NDK Release 12 e successive include una libreria di runtime per la compilazione di GLSL in SPIR-V. La libreria di runtime è la stessa del progetto open source Shaderc e utilizza lo stesso compilatore di riferimenti Glslang GLSL come backend. Per impostazione predefinita, la versione Shaderc del compilatore presuppone che tu stia eseguendo la compilazione per Vulkan. Dopo aver verificato se il tuo codice è valido per Vulkan, il compilatore attiva automaticamente l'estensione KHR_vulkan_glsl
. La versione Shaderc
del compilatore genera anche codice SPIR-V conforme a Vulkan.
Puoi scegliere di compilare i moduli SPIR-V nella tua app Vulkan durante lo sviluppo, una pratica chiamata prima del tempo, o AOT, compilazione. In alternativa, puoi fare in modo che la tua app le compili dall'origine Shader spedita o generata proceduralmente quando necessario durante il runtime. Questa pratica è chiamata compilazione runtime. Android Studio ha il supporto integrato per la creazione di mesh Vulkan.
Il resto di questa pagina fornisce ulteriori dettagli su ogni esercitazione e spiega come integrare la compilation Shader nell'app Vulkan.
Compilation di AOT
Esistono due modi per ottenere la compilazione AOT dello Shader, descritti nelle sezioni seguenti.
Utilizzare Android Studio
Quando li inserisce in app/src/main/shaders/
, Android Studio riconosce gli mesh in base alle
loro estensioni file e completa le seguenti azioni:
- Compila tutti i file dello mesh in modo ricorsivo sotto quella directory.
- Aggiungi il suffisso .spv ai file puller SPIR-V compilati.
- Crea gli shard SPIRV nella directory
assets/shaders/
dell'APK.
In fase di esecuzione, l'applicazione caricherebbe gli mesh compilati dalla posizione assets/shaders/
corrispondente. La struttura del file dello Shader GLSL compilato è la stessa in app/src/main/shaders/
:
AAsset* file = AAssetManager_open(assetManager, "shaders/tri.vert.spv", AASSET_MODE_BUFFER); size_t fileLength = AAsset_getLength(file); char* fileContent = new char[fileLength]; AAsset_read(file, fileContent, fileLength);
I flag di compilazione Shaderc possono essere configurati all'interno del blocco shaders
gradle DSL, come mostrato nell'esempio seguente:
Trendy
android { defaultConfig { shaders { glslcArgs.addAll(['-c', '-g']) scopedArgs.create('lights') { glslcArgs.addAll(['-DLIGHT1=1', '-DLIGHT2=0']) } } } }
Kotlin
android { defaultConfig { shaders { glslcArgs += listOf("-c", "-g") glslcScopedArgs("lights", "-DLIGHT1=1", "-DLIGHT2=0") } } }
glslcArgs
si applica a tutte le compilazioni dello mesh; scopedArgs
si applica solo in fase di compilazione
per quell'ambito. L'esempio sopra crea un argomento di ambito lights
, che verrà applicato solo agli mesh GLSL nella directory app/src/main/shaders/lights/
. Consulta glslc per l'elenco completo dei flag di compilazione disponibili. Tieni presente che Shaderc in NDK è uno snapshot di quel repository Github al momento del rilascio NDK; puoi ottenere gli esatti flag supportati per quella versione con il comando
glslc --help
, come descritto nella sezione successiva.
Compilazione a riga di comando offline
Gli Shader GLSL possono essere compilati in SPIR-V indipendentemente dall'applicazione principale utilizzando il compilatore a riga di comando glslc. NDK 12 e versioni successive pacchettizza una versione del codice glslc predefinito e degli strumenti correlati nella directory <android-ndk-dir>/shader-tools/
per supportare questo modello di utilizzo.
Il compilatore è disponibile anche nel progetto Shaderc; segui le istruzioni fornite per creare una versione binaria.
glslc offre un ricco set di opzioni della riga di comando per la compilazione dello shabbyr, in modo da soddisfare i vari requisiti di un'applicazione.
Lo strumento glslc compila un singolo file di origine in un modulo SPIR-V con un singolo punto di ingresso dello shardr. Per impostazione predefinita, il nome del file di output ha lo stesso nome del file di origine, ma viene aggiunta l'estensione .spv
.
Puoi usare le estensioni dei nomi file per indicare allo strumento glslc quale fase di mesh di grafica compilare o se è in corso la compilazione di uno mesh di computing. Per informazioni su come utilizzare queste estensioni per i nomi file e sulle opzioni che puoi utilizzare con lo strumento, consulta la specifica della fase Shader nel manuale glslc.
Compilazione runtime
Per la compilazione JIT degli Shader durante il runtime, l'NDK fornisce la libreria libshaderc, che include le API C e C++.
Le applicazioni C++ devono utilizzare l'API C++. Consigliamo alle app in altri linguaggi di usare l'API C, perché l'ABI C è di livello inferiore ed è probabile che offra una maggiore stabilità.
L'esempio seguente mostra come utilizzare l'API C++:
#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; }
Integrazione nei tuoi progetti
Puoi integrare il compilatore Shader Vulkan nella tua app utilizzando il file Android.mk
del progetto o Gradle.
Android.mk
Esegui i passaggi seguenti per utilizzare il file Android.mk
del progetto per integrare il compilatore Shader.
-
Includi le seguenti righe nel file Android.mk:
include $(CLEAR_VARS) ... LOCAL_STATIC_LIBRARIES := shaderc ... include $(BUILD_SHARED_LIBRARY) $(call import-module, third_party/shaderc)
-
Imposta APP_STL su
c++_static
,c++_shared
,gnustl_static
ognustl_shared
in Application.mk
Integrazione di CMake di Gradle
-
In una finestra del terminale, vai a
ndk_root/sources/third_party/shaderc/
. -
Esegui questo comando per creare Shaderc di NDK. Devi eseguire questo comando una sola volta su ogni versione NDK che utilizzi:
$ ../../../ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=Android.mk \ APP_STL:=<stl_version> APP_ABI=all libshaderc_combined
Questo comando inserisce due cartelle in <ndk_root>/sources/third_party/shaderc/. La struttura delle directory è la seguente:
include/ shaderc/ shaderc.h shaderc.hpp libs/ <stl_version>/ {all of the abis} libshaderc.a
-
Aggiungi le inclusioni e le librerie generate utilizzando
target_include_directories
etarget_link_libraries
, come fai normalmente per librerie esterne simili. Il tipo STL dell'app deve corrispondere a uno dei tipi distl
specificati instl_version
. L'NDK consiglia di utilizzarec++_shared
oc++_static
, nonostante siano supportati anchegnustl_static
egnustl_shared
.
Scarica l'ultima versione di Shaderc
Shaderc in NDK proviene dalla struttura ad albero di origine Android, che è un'istantanea del repository Shaderc a monte. Se ti serve l'ultima versione di Shaderc, consulta l'articolo sulle istruzioni di creazione dei dettagli. I passaggi generali sono i seguenti:
- Scarica l'ultima versione di Shaderc:
git clone https://github.com/google/shaderc.git
- Aggiorna dipendenze:
./utils/git-sync-deps
- Shaderc di build:
<ndk_dir>/ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=Android.mk \ APP_STL:=c++_static APP_ABI=all libshaderc_combined -j16
- Configura il tuo progetto per utilizzare la tua build Shaderc nel file di script di build.