Android'de Vulkan gölgelendirici derleyicileri

Bir Vulkan uygulaması, gölgelendiricileri OpenGL ES uygulamasınınkinden farklı şekilde yönetmelidir: OpenGL ES'de, bir gölgelendiriciyi, birGLSL gölgelendirici programının kaynak metnini oluşturan bir dize kümesi olarak sağlarsınız. Buna karşın Vulkan API, SPIR-V modülündeki bir giriş noktası biçiminde gölgelendirici sağlamanızı gerektirir.

NDK Sürüm 12 ve üzeri, GLSL'yi SPIR-V olarak derlemek için bir çalışma zamanı kitaplığı içerir. Çalışma zamanı kitaplığı, Shaderc açık kaynak projesindeki ile aynıdır ve arka ucu olarak aynı Glslang GLSL referans derleyicisini kullanır. Derleyicinin Shaderc sürümü, varsayılan olarak Vulkan için derleme yaptığınızı varsayar. Derleyici, kodunuzun Vulkan için geçerli olup olmadığını kontrol ettikten sonra KHR_vulkan_glsl uzantısını otomatik olarak etkinleştirir. Derleyicinin Shaderc sürümü de Vulkan uyumlu SPIR-V kodu oluşturur.

Geliştirme sırasında SPIR-V modüllerini Vulkan uygulamanızda derlemeyi (ahead-of-time veya AOT derleme) seçebilirsiniz. Alternatif olarak, çalışma zamanında gerektiğinde uygulamanızın bunları gönderilmiş veya prosedürel olarak oluşturulmuş gölgelendirici kaynağından derlemesini sağlayabilirsiniz. Bu uygulamaya çalışma zamanı derleme denir. Android Studio, Vulkan gölgelendiricileri oluşturmak için entegre desteğe sahiptir.

Bu sayfanın geri kalanında her uygulamayla ilgili daha ayrıntılı bilgi verilmekte ve ardından gölgelendirici derlemenin Vulkan uygulamanıza nasıl entegre edileceği açıklanmaktadır.

AOT derlemesi

Aşağıdaki bölümlerde açıklanan, gölgelendirici AOT derlemesini elde etmenin iki yolu vardır.

Android Studio'yu kullanma

Android Studio, gölgelendiricileri app/src/main/shaders/ bölümüne yerleştirir ve gölgelendiricileri dosya uzantılarına göre tanır ve aşağıdaki işlemleri tamamlar:

  • Tüm gölgelendirici dosyalarını yinelemeli olarak söz konusu dizin altında derleyin.
  • Derlenen SPIR-V gölgelendirici dosyalarına .spv son ekini ekleyin.
  • SPIRV gölgelendiricilerini APK'nın assets/shaders/ dizinine paketleyin.

Uygulama, çalışma zamanında derlenen gölgelendiricileri karşılık gelen assets/shaders/ konumundan yükler. Derlenen spv gölgelendirici dosya yapısı, uygulamanın app/src/main/shaders/ altındaki GLSL gölgelendirici dosya yapısıyla aynıdır:

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);

Shaderc derleme işaretleri, aşağıdaki örnekte gösterildiği gibi gradle DSL shaders bloğunun içinde yapılandırılabilir:

Modern

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, tüm gölgelendirici derlemelere uygulanır; scopedArgs yalnızca bu kapsam için derleme yaparken geçerlidir. Yukarıdaki örnek, yalnızca app/src/main/shaders/lights/ dizinindeki GLSL gölgelendiricileri için geçerli olacak lights kapsam bağımsız değişkeni oluşturur. Kullanılabilir derleme işaretlerinin tam listesi için glslc kaynağına bakın. NDK içindeki Shaderc'in, NDK yayın zamanında bu github deposundan bir anlık görüntü olduğunu unutmayın. Bir sonraki bölümde açıklandığı gibi glslc --help komutuyla bu sürüm için desteklenen tam işaretleri alabilirsiniz.

Çevrimdışı komut satırı derlemesi

GLSL gölgelendiriciler, glslc komut satırı derleyicisi kullanılarak ana uygulamadan bağımsız olarak SPIR-V'de derlenebilir. NDK sürüm 12 ve sonraki sürümler bu kullanım modelini desteklemek için önceden oluşturulmuş bir glslc sürümünü ve <android-ndk-dir>/shader-tools/ dizininde ilgili araçları içerir.

Derleyiciye Shaderc projesinden de erişilebilir. İkili sürüm oluşturmak için buradaki talimatları uygulayın.

glslc, bir uygulamanın çeşitli gereksinimlerini karşılamak için gölgelendirici derlemeye yönelik zengin bir komut satırı seçeneği kümesi sunar.

glslc aracı, tek bir kaynak dosyasını tek bir gölgelendirici giriş noktasına sahip bir SPIR-V modülünde derler. Varsayılan olarak çıkış dosyası, kaynak dosyayla aynı ada sahiptir ancak sonuna .spv uzantısı eklenir.

glslc aracına hangi grafik gölgelendiricisi aşamasının derleneceğini veya bir işlem gölgelendiricisinin derlenip derlenmediğini bildirmek için dosya adı uzantılarını kullanırsınız. Bu dosya adı uzantılarının nasıl kullanılacağı ve araçla kullanabileceğiniz seçenekler hakkında bilgi için glslc kılavuzundaki Gölgelendirici aşama spesifikasyonu bölümüne bakın.

Çalışma zamanı derlemesi

Çalışma zamanı sırasında gölgelendiricilerin JIT derlemesi için NDK, hem C hem de C++ API'lerine sahip olan libshaderc kitaplığını sağlar.

C++ uygulamaları C++ API'sını kullanmalıdır. C ABI daha düşük düzeyde olduğu ve muhtemelen daha iyi kararlılık sağlayabileceği için diğer dillerdeki uygulamaların C API'yi kullanmasını öneririz.

Aşağıdaki örnekte C++ API'sinin nasıl kullanılacağı gösterilmektedir:

#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;
}

Projelerinize entegre edin

Vulkan gölgelendirici derleyicisini, projenin Android.mk dosyasını veya Gradle'ı kullanarak uygulamanıza entegre edebilirsiniz.

Android.mk

Gölgelendirici derleyiciyi entegre etmek amacıyla projenizin Android.mk dosyasını kullanmak için aşağıdaki adımları uygulayın.

  1. Android.mk dosyanıza şu satırları ekleyin:
    include $(CLEAR_VARS)
         ...
    LOCAL_STATIC_LIBRARIES := shaderc
         ...
    include $(BUILD_SHARED_LIBRARY)
    
    $(call import-module, third_party/shaderc)
    
  2. APP_STL'yi uygulamanın Application.mk dosyasında c++_static, c++_shared, gnustl_static veya gnustl_shared olarak ayarlayın

Gradle'ın CMake entegrasyonu

  1. Bir terminal penceresinde ndk_root/sources/third_party/shaderc/ adresine gidin.
  2. NDK Shaderc dosyasını derlemek için aşağıdaki komutu çalıştırın. Bu komutu, kullandığınız her NDK sürümünde yalnızca bir kez çalıştırmanız gerekir:
    $ ../../../ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=Android.mk \
    APP_STL:=<stl_version> APP_ABI=all libshaderc_combined
    

    Bu komut, iki klasörü <ndk_root>/sources/third_party/shaderc/ konumuna yerleştirir. Dizin yapısı aşağıdaki gibidir:

    include/
      shaderc/
        shaderc.h
        shaderc.hpp
    libs/
      <stl_version>/
        {all of the abis}
           libshaderc.a
    
  3. Oluşturulan eklemeleri ve kitaplıkları, benzer harici kitaplıklarda yaptığınız gibi target_include_directories ve target_link_libraries kullanarak ekleyin. Uygulamanızın STL türü, stl_version içinde belirtilen stl türlerinden biriyle eşleşmelidir. NDK, c++_shared veya c++_static kullanılmasını önerir ancak gnustl_static ve gnustl_shared de desteklenir.

En son Shaderc'i edinin

NDK'daki Shaderc, yukarı akış Shaderc deposunun anlık görüntüsü olan Android Kaynak ağacından gelir. Shaderc'in en son sürümüne ihtiyacınız varsa ayrıntılar için oluşturma talimatına bakın. Üst düzey adımlar aşağıdaki gibidir:

  1. En son Shaderc'i indirin:
    git clone https://github.com/google/shaderc.git
  2. Bağımlılıkları güncelleyin:
    ./utils/git-sync-deps
  3. Shaderc oluşturun:
    <ndk_dir>/ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=Android.mk \
        APP_STL:=c++_static APP_ABI=all libshaderc_combined -j16
    
  4. Projenizi, derleme komut dosyası dosyanızda kendi Shaderc derlemenizi kullanacak şekilde yapılandırın.