Android पर Vulkan शेडर कंपाइलर

Vulkan ऐप्लिकेशन को शेडर को OpenGL ES ऐप्लिकेशन के तरीके से अलग तरीके से मैनेज करना चाहिए: OpenGL ES में, आप स्ट्रिंग के सेट के रूप में शेडर उपलब्ध कराते हैं, जो जीएलएसएल शेडर प्रोग्राम. इसके उलट, Vulkan API के लिए आपको शेडर उपलब्ध कराना होगा किसी SPIR-V मॉड्यूल में एंट्री पॉइंट की तरह.

NDK रिलीज़ 12 और उसके बाद के वर्शन में, GLSL को SPIR-V में कंपाइल करने के लिए एक रनटाइम लाइब्रेरी शामिल है. रनटाइम लाइब्रेरी वही है जो इसमें मौजूद है Shaderc ओपन सोर्स प्रोजेक्ट है और उसी का इस्तेमाल करता है Glslang GLSL रेफ़रंस कंपाइलर बैक एंड. डिफ़ॉल्ट रूप से, Shaderc वर्शन कंपाइलर मान लेता है कि आपने Vulkan के लिए कंपाइल किया है. यह जांचने के बाद कि आपका कोड इनके लिए मान्य है या नहीं Vulkan, कंपाइलर KHR_vulkan_glsl एक्सटेंशन को अपने-आप चालू कर देता है. द शेडर्क कंपाइलर का एक वर्शन भी जनरेट करता है, जो Vulkan के हिसाब से बनाया गया SPIR-V कोड जनरेट करता है.

डेवलपमेंट के दौरान, अपने Vulkan ऐप्लिकेशन में SPIR-V मॉड्यूल को कंपाइल किया जा सकता है, प्रैक्टिस सेट को अहेड-ऑफ़-टाइम या एओटी कंपाइलेशन कहते हैं. इसके अलावा, आपके पास यह तय करने का विकल्प होता है कि ऐप्लिकेशन को शिप किए गए या प्रोसेस तरीके से जनरेट किए गए शेडर से इकट्ठा किया जाए या नहीं स्रोत की ज़रूरत होती है. इस तरीके को रनटाइम कंपाइल करना कहते हैं. Android Studio में Vulkan शेडर बनाने की सुविधा उपलब्ध है.

इस पेज के बाकी हिस्से में, हर प्रैक्टिस के बारे में ज़्यादा जानकारी दी गई है अपने Vulkan ऐप्लिकेशन में शेडर कंपाइलेशन को कैसे इंटिग्रेट करें.

एओटी कंपाइलेशन

शेडर एओटी को कंपाइल करने के दो तरीके हैं, जिनके बारे में नीचे बताया गया है.

Android Studio का इस्तेमाल करना

Android Studio, शेडर को app/src/main/shaders/ में डालकर, शेडर की पहचान करता है: अपने फ़ाइल एक्सटेंशन को ऐक्सेस कर सकते हैं और ये कार्रवाइयां पूरी करेंगे:

  • उस डायरेक्ट्री में सभी शेडर फ़ाइलों को बार-बार कंपाइल करें.
  • कंपाइल की गई SPIR-V शेडर फ़ाइलों में .spv सफ़िक्स जोड़ें.
  • SPIRV-शेडर को APK की assets/shaders/ डायरेक्ट्री में पैक करें.

यह ऐप्लिकेशन, रन टाइम के दौरान assets/shaders/ की मिलती-जुलती जगह से, कंपाइल किए गए शेडर को लोड करेगा; कंपाइल की गई spv शेडर फ़ाइल की बनावट और 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 ब्लॉक में कॉन्फ़िगर किया जा सकता है, जैसा कि इस उदाहरण में दिखाया गया है:

ग्रूवी

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 बनाता है, जो सिर्फ़ इस पर लागू होगा app/src/main/shaders/lights/ डायरेक्ट्री में मौजूद जीएलएसएल शेडर. इससे संदर्भ लें पूरी सूची के लिए glslc कंपाइलेशन फ़्लैग का इस्तेमाल किया जा सकता है. ध्यान दें कि NDK के अंदर Shaderc, इस लिंक पर दिए गए GitHub रेपो का स्नैपशॉट है एनडीके की रिलीज़ का समय; आपको निर्देश देकर उस वर्शन के लिए इस्तेमाल किए जा सकने वाले सही फ़्लैग मिल सकते हैं glslc --help. इसके बारे में अगले सेक्शन में बताया गया है.

ऑफ़लाइन कमांड लाइन कंपाइलेशन

जीएलएसएल शेडर को मुख्य ऐप्लिकेशन से अलग SPIR-V में कंपाइल किया जा सकता है. इसके लिए, glslc कमांड-लाइन कंपाइलर का इस्तेमाल किया जाता है. NDK की रिलीज़ 12 और उसके बाद के वर्शन में, पहले से बने glslc का वर्शन और <android-ndk-dir>/shader-tools/ डायरेक्ट्री में मिलते-जुलते टूल मौजूद हैं.

कंपाइलर Shaderc से भी उपलब्ध है प्रोजेक्ट बाइनरी वर्शन बनाने के लिए, दिए गए निर्देशों का पालन करें.

glslc का रिच सेट देता है ऐप्लिकेशन की अलग-अलग ज़रूरी शर्तों को पूरा करने के लिए, शेडर कंपाइलेशन के लिए कमांड-लाइन विकल्प.

glsLC टूल एक सिंगल-सोर्स फ़ाइल को एक शेडर के साथ SPIR-V मॉड्यूल में कंपाइल करता है एंट्री पॉइंट. डिफ़ॉल्ट रूप से, आउटपुट फ़ाइल का नाम वही होता है जो सोर्स फ़ाइल का होता है, लेकिन .spv एक्सटेंशन के साथ.

आप glslc टूल को यह बताने के लिए फ़ाइल नाम एक्सटेंशन का इस्तेमाल करते हैं कि किस ग्राफ़िक शेडर स्टेज को कंपाइल करना है, या कंप्यूट शेडर को कंपाइल किया जा रहा है या नहीं. इन फ़ाइल नामों का इस्तेमाल करने के बारे में जानकारी पाने के लिए एक्सटेंशन और उन विकल्पों का इस्तेमाल करें जिनका इस टूल के साथ इस्तेमाल किया जा सकता है. शेडर स्टेज की खास बातें glslc मैन्युअल.

रनटाइम कंपाइलेशन

रनटाइम के दौरान शेडर को जेआईटी कंपाइल करने के लिए, एनडीके, लिब्शाडर लाइब्रेरी उपलब्ध कराता है. जिसमें C और C++, दोनों एपीआई मौजूद हैं.

C++ ऐप्लिकेशन में C++ API का इस्तेमाल किया जाना चाहिए. हमारा सुझाव है कि दूसरी भाषाओं के ऐप्लिकेशन सी एपीआई का इस्तेमाल करें, क्योंकि सी एबीआई का लेवल कम होता है और यह बेहतर स्थिरता देता है.

नीचे दिए गए उदाहरण में, 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;
}

अपने प्रोजेक्ट में इंटिग्रेट करें

आप प्रोजेक्ट के 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 में से किसी एक पर सेट करें, या ऐप्लिकेशन के App.mk में gnustl_shared

Gradle का CMake इंटिग्रेशन

  1. टर्मिनल विंडो में, यहां जाएं ndk_root/sources/third_party/shaderc/.
  2. NDK का Shaderc बनाने के लिए, नीचे दिया गया कमांड चलाएं. आपको हर उस 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. का इस्तेमाल करके जनरेट किए गए शामिल और लाइब्रेरी जोड़ें target_include_directories और target_link_libraries, जैसा कि आम तौर पर इस तरह के विज्ञापनों के लिए किया जाता है बाहरी सोर्स लाइब्रेरी. आपके ऐप्लिकेशन का एसटीएल टाइप, यहां दिए गए stl टाइप में से किसी एक से मेल खाना चाहिए stl_version. NDK, c++_shared या c++_static, हालांकि gnustl_static और gnustl_shared भी काम करते हैं.

नया Shaderc पाएं

एनडीके में Shaderc Android Source ट्री से मिलता है, जो अपस्ट्रीम शेडर्क रेपो का स्नैपशॉट. अगर आपको Shaderc का नया वर्शन चाहिए, तो ज़्यादा जानकारी के लिए निर्देश बनाएं पर जाएं. इसके लिए, इनमें से कोई एक तरीका अपनाएं:

  1. नया Shaderc डाउनलोड करें:
    git clone https://github.com/google/shaderc.git
  2. डिपेंडेंसी अपडेट करें:
    ./utils/git-sync-deps
  3. शेडर्क बनाएं:
    <ndk_dir>/ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=Android.mk \
        APP_STL:=c++_static APP_ABI=all libshaderc_combined -j16
    
  4. बिल्ड स्क्रिप्ट फ़ाइल में अपने Shaderc बिल्ड का इस्तेमाल करने के लिए, अपना प्रोजेक्ट कॉन्फ़िगर करें.