برامج تظليل Vulkan على Android

يجب أن يدير تطبيق Vulkan أدوات التظليل بشكل مختلف عن الطريقة التي يستخدمها تطبيق OpenGL ES: في OpenGL ES، توفر أداة تظليل كمجموعة من السلاسل التي تشكل النص المصدر برنامج تظليل GLSL. في المقابل، تتطلب منك واجهة برمجة التطبيقات Vulkan توفير أداة تظليل على شكل نقطة دخول في وحدة SPIR-V.

يتضمن الإصدار 12 من NDK والإصدارات الأحدث مكتبة وقت تشغيل لتجميع GLSL في SPIR-V. مكتبة بيئة التشغيل هي نفسها المكتبة الموجودة في برنامج مفتوح المصدر Shaderc ويستخدم نفس برنامج التجميع المرجعي Glslang GLSL الواجهة الخلفية. بشكل افتراضي، لا يتم تحديث إصدار Shaderc يفترض أنك تقوم بالتجميع لـ Vulkan. بعد التحقق مما إذا كانت التعليمة البرمجية صالحة Vulkan، برنامج التجميع يعمل تلقائيًا على تفعيل الإضافة KHR_vulkan_glsl. ذا شاديرك من برنامج التحويل البرمجي أيضًا رمز SPIR-V المتوافق مع Vulkan.

يمكنك اختيار تجميع وحدات SPIR-V في تطبيق Vulkan أثناء التطوير، التدريب الذي يطلق عليه تجميع البيانات المسبقة أو AOT. بدلاً من ذلك، يمكنك أن تطلب من تطبيقك تجميعها من أداة تظليل التي تم شحنها أو إنشاؤها بطريقة إجرائية. المصدر عند الحاجة أثناء وقت التشغيل. وتُسمى هذه الممارسة التجميع في وقت التشغيل. تم دمج "استوديو Android" لإنشاء أدوات تظليل Vulkan.

تقدم بقية هذه الصفحة مزيدًا من التفاصيل حول كل ممارسة، ثم توضح كيفية دمج أداة التظليل في تطبيق Vulkan

تجميع AOT

هناك طريقتان لإجراء تجميع أداة التظليل (AOT)، كما هو موضح في الأقسام التالية.

استخدام "استوديو Android"

من خلال وضع أدوات التظليل في app/src/main/shaders/، يتعرّف "استوديو Android" على أدوات التظليل من خلال امتداداتها، وستكمل الإجراءات التالية:

  • اجمع كل ملفات أداة التظليل بشكل متكرر ضمن هذا الدليل.
  • ألحق لاحقة spv .بملفات تظليل SPIR-V المجمّعة.
  • حزم تظليل SPIRV في دليل assets/shaders/ الخاص بحزمة APK.

سيحمّل التطبيق أدوات التظليل المجمَّعة من موقع assets/shaders/ المقابل في وقت التشغيل. تكون بنية ملف تظليل spv المجمّع هي نفسها بنية ملف تظليل GLSL في التطبيق ضمن 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);

يمكن ضبط علامات التجميع في Shaderc داخل كتلة Gradle DSL shaders، كما هو موضَّح في المثال التالي:

Groovy

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 على كل مجموعات أدوات التظليل. لا تنطبق scopedArgs إلا عند التجميع. لهذا النطاق. ينشئ المثال أعلاه وسيطة نطاق lights، والتي سيتم تطبيقها فقط على أدوات تظليل GLSL ضمن الدليل app/src/main/shaders/lights/ ارجع إلى glslc للقائمة الكاملة علامات التجميع المتوفرة. لاحظ أن Shaderc داخل NDK عبارة عن لقطة من مستودع github هذا في وقت إصدار NDK؛ يمكنك الحصول على العلامات المتوافقة تمامًا لهذا الإصدار باستخدام الأمر glslc --help، كما هو موضّح في القسم التالي.

تجميع سطر الأوامر بلا اتصال بالإنترنت

يمكن تجميع أدوات تظليل GLSL في SPIR-V بشكل مستقل عن التطبيق الرئيسي باستخدام المحول البرمجي لسطر الأوامر glslc. يضم الإصدار 12 من NDK والإصدارات الأحدث نسخة من glslc و ذات صلة في دليل <android-ndk-dir>/shader-tools/ لدعم نموذج الاستخدام هذا.

يتوفر برنامج التجميع أيضًا من أداة Shaderc. المشروع؛ اتبع التعليمات الواردة هناك لإنشاء إصدار ثنائي.

glslc يوفر مجموعة غنية من خيارات سطر الأوامر لتجميع أدوات التظليل لتلبية المتطلبات المختلفة للتطبيق.

تجمع أداة glslc ملفًا من مصدر واحد إلى وحدة SPIR-V باستخدام أداة تظليل واحدة. نقطة دخول متعددة. يكون لملف الإخراج بشكل افتراضي نفس اسم ملف المصدر، ولكن مع إلحاق الامتداد .spv.

يمكنك استخدام امتدادات أسماء الملفات لإخبار أداة glslc بمرحلة تظليل الرسومات التي يجب تجميعها، أو ما إذا كان يتم تجميع أداة تظليل الحوسبة. للحصول على معلومات حول كيفية استخدام أسماء الملفات هذه والإضافات والخيارات التي يمكنك استخدامها مع الأداة، يمكنك الاطلاع على مواصفات مرحلة التظليل في دليل glslc

تجميع بيئة التشغيل

لتجميع أدوات التظليل في JIT أثناء وقت التشغيل، يوفر NDK مكتبة libshaderc، والتي تحتوي على واجهات برمجة تطبيقات C وC++.

يجب أن تستخدم تطبيقات C++ واجهة برمجة التطبيقات C++ API. نقترح أن تكون التطبيقات بلغات أخرى استخدام واجهة برمجة التطبيقات C 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;
}

الاندماج في مشاريعك

يمكنك دمج المحول البرمجي Vulkan الثابت في تطبيقك باستخدام إما ملف Android.mk أو Gradle.

Android.mk

نفذ الخطوات التالية لاستخدام Android.mk لمشروعك لدمج المحول البرمجي للتظليل.

  1. أدرِج الأسطر التالية في ملف Android.mk:
    include $(CLEAR_VARS)
         ...
    LOCAL_STATIC_LIBRARIES := shaderc
         ...
    include $(BUILD_SHARED_LIBRARY)
    
    $(call import-module, third_party/shaderc)
    
  2. ضبط APP_STL على أحد c++_static أو c++_shared أو gnustl_static أو أو gnustl_shared في التطبيق Application.mk

تكامل CMake في Gradle

  1. في نافذة Terminal، انتقِل إلى ndk_root/sources/third_party/shaderc/
  2. قم بتشغيل الأمر التالي لإنشاء Shaderc لـ NDK. ما عليك سوى تشغيل هذا الأمر مرة واحدة فقط على كل إصدار NDK تستخدمه:
    $ ../../../ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=Android.mk \
    APP_STL:=<stl_version> APP_ABI=all libshaderc_combined
    

    يضع هذا الأمر مجلدين في <ndk_root>/sources/third_party/shaderc/. الدليل هيكله على النحو التالي:

    include/
      shaderc/
        shaderc.h
        shaderc.hpp
    libs/
      <stl_version>/
        {all of the abis}
           libshaderc.a
    
  3. إضافة التضمينات وlibs التي تم إنشاؤها باستخدام target_include_directories و target_link_libraries، كما تفعل عادةً مع خارجي المكتبات يجب أن يتطابق نوع STL الخاص بتطبيقك مع أحد أنواع stl المحدّدة في stl_version تنصح NDK باستخدام السمة c++_shared أو c++_static، على الرغم من أن gnustl_static و يُسمح أيضًا باستخدام gnustl_shared.

الحصول على أحدث إصدار من Shaderc

Shaderc في NDK تأتي من شجرة مصدر Android، وهي لمحة عن مستودع Shaderc الرئيسي. إذا كنت بحاجة إلى أحدث إصدار من Shaderc، يمكنك الاطّلاع على تعليمات الإصدار للحصول على التفاصيل. الخطوات عالية المستوى هي كما يلي:

  1. نزِّل أحدث إصدار من Shaderc:
    git clone https://github.com/google/shaderc.git
  2. تعديل التبعيات:
    ./utils/git-sync-deps
  3. إنشاء Shaderc:
    <ndk_dir>/ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=Android.mk \
        APP_STL:=c++_static APP_ABI=all libshaderc_combined -j16
    
  4. اضبط مشروعك لاستخدام إصدار Shaderc الخاص بك في ملف النص البرمجي للإصدار.