Kompilatory cieniowania Vulkan na Androidzie

Aplikacja Vulkan musi zarządzać programami do cieniowania inaczej niż aplikacja OpenGL ES: W interfejsie OpenGL ES udostępniamy program do cieniowania, czyli zestaw ciągów tekstowych tworzących tekst źródłowy Program do cieniowania GLSL. Z kolei interfejs Vulkan API wymaga udostępnienia programu do cieniowania ma postać punktu wejścia w module SPIR-V.

Wersja NDK 12 i nowsze zawiera bibliotekę środowiska wykonawczego do kompilacji GLSL na SPIR-V. Biblioteka środowiska wykonawczego jest taka sama jak w projektu open source Shaderc i korzysta Kompilator referencyjny Glslang GLSL w tle. Domyślnie wersja Shaderc biblioteki kompilator zakłada, że kompilujesz dane pod kątem języka Vulkan. Po sprawdzeniu, czy Twój kod jest ważny przez Vulkan, kompilator automatycznie włącza rozszerzenie KHR_vulkan_glsl. Shaderc ale generuje też kod SPIR-V zgodny z Vulkanem.

Moduły SPIR-V możesz kompilować w aplikacji Vulkan w trakcie jej tworzenia, ćwiczenie nazywane kompilacją danych z wyprzedzeniem lub AOT. Ewentualnie aplikacja może skompilować je z wysłanego lub wygenerowanego proceduralnie programu do cieniowania. w razie potrzeby w czasie działania. Jest to tzw. kompilacja środowiska wykonawczego. Android Studio ma zintegrowaną obsługę tworzenia cieniowania Vulkan.

Na pozostałych stronach znajdziesz więcej informacji o każdej z tych praktyk, jak zintegrować kompilację cieniowania z aplikacją Vulkan.

Kompilacja AOT

Kompilację AOT można uzyskać na 2 sposoby opisane w sekcjach poniżej.

Korzystanie z Android Studio

Android Studio rozpoznaje cieniowanie według: app/src/main/shaders/ rozszerzenia plików i wykona te czynności:

  • Wszystkie pliki cieniowania są kompilowane rekurencyjnie w tym katalogu.
  • Dodaj sufiks .spv do skompilowanych plików cieniowania SPIR-V.
  • Zapakuj shadery SPIRV do katalogu assets/shaders/ pliku APK.

W czasie działania aplikacja wczyta skompilowane moduły do cieniowania z odpowiedniej lokalizacji assets/shaders/. Struktura skompilowanego pliku cieniowania spv jest taka sama jak struktura pliku cieniowania GLSL aplikacji w zasadzie 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);

Flagi kompilacji Shaderc można skonfigurować w bloku Gradle DSL shaders, jak pokazano w tym przykładzie:

Odlotowe

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 ma zastosowanie do wszystkich kompilacji działających w trybie cieniowania. scopedArgs ma zastosowanie tylko podczas kompilacji dla tego zakresu. Powyższy przykład tworzy argument zakresu lights, który ma zastosowanie tylko do Moduły cieniowania GLSL w katalogu app/src/main/shaders/lights/. Więcej informacji: glslc, aby wyświetlić pełną listę. dostępnych flag kompilacji. Zauważ, że Shaderc w NDK to zrzut z repozytorium GitHub w folderze czas wydania NDK; możesz za pomocą polecenia uzyskać dokładnie obsługiwane flagi dla danej wersji glslc --help, jak opisano w następnej sekcji.

Kompilacja wiersza poleceń offline

Shadery GLSL można kompilować do postaci SPIR-V niezależnie od głównej aplikacji za pomocą kompilatora wiersza poleceń glslc. NDK w wersji 12 i nowszych zawiera wersję gotowego interfejsu glslc oraz w katalogu <android-ndk-dir>/shader-tools/ znajdziesz podobne narzędzia do obsługi tego modelu użycia.

Kompilator jest też dostępny w programie Shaderc project; postępuj zgodnie z podanymi tam instrukcjami, aby utworzyć wersję binarną.

glslc zapewnia kompletny zestaw opcji wiersza poleceń do kompilacji cieniowania, aby spełnić różne wymagania aplikacji.

Narzędzie glslc kompiluje plik źródłowy w module SPIR-V z pojedynczym cieniowaniem. i punktu wejścia. Domyślnie plik wyjściowy ma taką samą nazwę jak plik źródłowy, ale z dołączonym rozszerzeniem .spv.

Dzięki rozszerzeniom nazw plików narzędzie glslc informuje, który etap cieniowania grafiki ma skompilować czy kompilowany jest program do cieniowania obliczeń. Informacje o korzystaniu z tych nazw plików rozszerzeń oraz opcji, których można używać z narzędziem, Specyfikacja etapu Shader glslc.

Kompilacja środowiska wykonawczego

Do kompilowania cieniowania przy użyciu metody JIT w czasie działania pakiet NDK udostępnia bibliotekę libshaderc, który zawiera interfejsy API C i C++.

Aplikacje w języku C++ powinny używać interfejsu API C++. Zalecamy, aby aplikacje w innych językach używać interfejsu C API, ponieważ jest to niższy poziom interfejsu C ABI, który prawdopodobnie zapewni większą stabilność.

Poniższy przykład pokazuje, jak używać interfejsu 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;
}

Integracja z projektami

Możesz zintegrować ze swoją aplikacją kompilator do cieniowania Vulkan za pomocą Android.mk lub Gradle.

Android.mk

Wykonaj te czynności, aby użyć w projekcie Android.mk aby zintegrować kompilator do cieniowania.

  1. W pliku Android.mk umieść te wiersze:
    include $(CLEAR_VARS)
         ...
    LOCAL_STATIC_LIBRARIES := shaderc
         ...
    include $(BUILD_SHARED_LIBRARY)
    
    $(call import-module, third_party/shaderc)
    
  2. Ustaw APP_STL na jedną z tych wartości: c++_static, c++_shared, gnustl_static, lub gnustl_shared w pliku Application.mk aplikacji

Integracja z interfejsem CMake w Gradle

  1. W oknie terminala przejdź do: ndk_root/sources/third_party/shaderc/
  2. Uruchom to polecenie, aby utworzyć narzędzie Shaderc NDK. Wystarczy uruchomić to polecenie tylko raz dla każdej używanej wersji NDK:
    $ ../../../ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=Android.mk \
    APP_STL:=<stl_version> APP_ABI=all libshaderc_combined
    

    To polecenie umieszcza 2 foldery w folderze <ndk_root>/sources/third_party/shaderc/. Katalog wygląda tak:

    include/
      shaderc/
        shaderc.h
        shaderc.hpp
    libs/
      <stl_version>/
        {all of the abis}
           libshaderc.a
    
  3. Dodaj wygenerowane pliki zawiera i lib za pomocą target_include_directories i . target_link_libraries, jak zwykle zewnętrzne . Typ STL Twojej aplikacji musi być zgodny z jednym z typów STL wymienionych w polu stl stl_version NDK zaleca użycie właściwości c++_shared lub c++_static, ale gnustl_static i Obsługiwane są również wartości gnustl_shared.

Pobierz najnowszą wersję Shaderca

Shaderc w NDK pochodzi z Androida Source Tree, które jest podsumowanie nadrzędnego repozytorium Shaderc. Jeśli potrzebujesz najnowszej wersji Shaderc, szczegółowe informacje znajdziesz w instrukcjach tworzenia kreacji. Ogólne kroki:

  1. Pobierz najnowszą wersję Shaderc:
    git clone https://github.com/google/shaderc.git
  2. Zaktualizuj zależności:
    ./utils/git-sync-deps
  3. Kompilacja Shaderc:
    <ndk_dir>/ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=Android.mk \
        APP_STL:=c++_static APP_ABI=all libshaderc_combined -j16
    
  4. Skonfiguruj projekt tak, aby używał własnej kompilacji Shaderc w pliku skryptu kompilacji.