Vulkan को लागू करना

Vulkan, बेहतरीन परफ़ॉर्मेंस वाले 3D ग्राफ़िक के लिए एक क्रॉस-प्लैटफ़ॉर्म एपीआई है. यह एक लो-ओवरहेड एपीआई है. OpenGL ES (GLES) की तरह ही, Vulkan भी ऐप्लिकेशन में रीयल-टाइम और बेहतर क्वालिटी के ग्राफ़िक बनाने के लिए टूल उपलब्ध कराता है. Vulkan का इस्तेमाल करने के फ़ायदों में सीपीयू के ओवरहेड में कमी आना और SPIR-V बाइनरी इंटरमीडिएट भाषा के लिए सहायता शामिल है.

Vulkan को सही तरीके से लागू करने के लिए, डिवाइस में ये चीज़ें होनी चाहिए:

  • Android की ओर से उपलब्ध कराया गया Vulkan लोडर.
  • जीपीयू IHV जैसे SoC से मिला Vulkan ड्राइवर, जो Vulkan API को लागू करता है. Vulkan की सुविधाएं इस्तेमाल करने के लिए, Android डिवाइस में Vulkan के साथ काम करने वाला जीपीयू हार्डवेयर और उससे जुड़ा ड्राइवर होना चाहिए. जीपीयू के लिए, GLES 3.1 और इसके बाद के वर्शन का इस्तेमाल करना ज़रूरी है. ड्राइवर से जुड़ी सहायता पाने के लिए, अपने SoC वेंडर से संपर्क करें.

अगर किसी डिवाइस में Vulkan ड्राइवर शामिल है, तो डिवाइस को FEATURE_VULKAN_HARDWARE_LEVEL और FEATURE_VULKAN_HARDWARE_VERSION सिस्टम की सुविधाओं के बारे में बताना होगा. साथ ही, डिवाइस के वर्शन की जानकारी भी देनी होगी, ताकि डिवाइस की क्षमताओं के बारे में सटीक जानकारी मिल सके. इससे यह पक्का करने में मदद मिलती है कि डिवाइस कंपैटबिलिटी डेफ़िनिशन दस्तावेज़ (सीडीडी) का पालन करता है.

Vulkan लोडर

Vulkan लोडर platform/frameworks/native/vulkan, Vulkan ऐप्लिकेशन और डिवाइस के Vulkan ड्राइवर के बीच मुख्य इंटरफ़ेस होता है. Vulkan स्क्रिप्ट लोडर, /system/lib[64]/libvulkan.so पर इंस्टॉल किया गया है. लोडर, Vulkan API के मुख्य एंट्री पॉइंट, Android CDD के लिए ज़रूरी एक्सटेंशन के एंट्री पॉइंट, और कई अन्य वैकल्पिक एक्सटेंशन उपलब्ध कराता है. Window System Integration (WSI) एक्सटेंशन, लोडर से एक्सपोर्ट किए जाते हैं और मुख्य रूप से, ड्राइवर के बजाय लोडर में लागू किए जाते हैं. लोडर, उन लेयर को गिनने और लोड करने की सुविधा भी देता है जो ड्राइवर के रास्ते में अतिरिक्त एक्सटेंशन दिखा सकते हैं और कोर एपीआई कॉल को इंटरसेप्ट कर सकते हैं.

NDK में लिंक करने के लिए, स्टब libvulkan.so लाइब्रेरी शामिल होती है. लाइब्रेरी, लोडर के जैसे ही सिंबल एक्सपोर्ट करती है. ऐप्लिकेशन, लोडर में ट्रैंपोलिन फ़ंक्शन डालने के लिए, असली libvulkan.so लाइब्रेरी से एक्सपोर्ट किए गए फ़ंक्शन को कॉल करते हैं. ये फ़ंक्शन, उपयोगकर्ता के पहले तर्क के आधार पर सही लेयर या ड्राइवर को भेज दिए जाते हैं. vkGet*ProcAddr() कॉल, उन फ़ंक्शन पॉइंटर को दिखाता है जिन्हें ट्रैम्पोलिन डिस्पैच करते हैं. इसका मतलब है कि यह सीधे कोर एपीआई कोड में कॉल करता है. एक्सपोर्ट किए गए सिंबल के बजाय, फ़ंक्शन पॉइंटर के ज़रिए कॉल करना ज़्यादा कारगर होता है, क्योंकि यह ट्रैंपोलिन और डिस्पैच को स्किप करता है.

ड्राइवर की संख्या और लोड करने की सुविधा

सिस्टम इमेज बनने के बाद, Android को यह पता होना चाहिए कि कौनसे जीपीयू उपलब्ध हैं. ड्राइवर को ढूंढने और लोड करने के लिए, लोडर hardware.h में मौजूदा HAL मशीन का इस्तेमाल करता है. 32-बिट और 64-बिट Vulkan ड्राइवर के लिए, ये पाथ इस्तेमाल किए जा सकते हैं:

/vendor/lib/hw/vulkan.<ro.hardware.vulkan>.so
/vendor/lib/hw/vulkan.<ro.product.platform>.so
/vendor/lib64/hw/vulkan.<ro.hardware.vulkan>.so
/vendor/lib64/hw/vulkan.<ro.product.platform>.so

Android 7.0 और उसके बाद के वर्शन में, Vulkan hw_module_t डेरिवेटिव में एक hw_module_t स्ट्रक्चर को रैप किया जाता है. इसमें सिर्फ़ एक ड्राइवर काम करता है और कॉन्सटेंट स्ट्रिंग HWVULKAN_DEVICE_0, open() को पास की जाती है.

Vulkan hw_device_t डेरिवेटिव, एक ऐसे ड्राइवर से जुड़ा होता है जो एक से ज़्यादा फ़िज़िकल डिवाइसों के साथ काम कर सकता है. hw_device_t स्ट्रक्चर को एक्सपोर्ट करने के लिए, vkGetGlobalExtensionProperties(), vkCreateInstance(), और vkGetInstanceProcAddr() फ़ंक्शन का इस्तेमाल किया जा सकता है. लोडर, hw_device_t स्ट्रक्चर के vkGetInstanceProcAddr() को कॉल करके, अन्य सभी VkInstance(), VkPhysicalDevice(), और vkGetDeviceProcAddr() फ़ंक्शन ढूंढ सकता है.

लेयर खोजने और लोड करने की प्रोसेस

Vulkan लोडर, उन लेयर को एनोमेरेट और लोड करने की सुविधा देता है जो अतिरिक्त एक्सटेंशन दिखा सकते हैं और ड्राइवर के रास्ते पर कोर एपीआई कॉल को इंटरसेप्ट कर सकते हैं. Android, सिस्टम इमेज में लेयर शामिल नहीं करता. हालांकि, ऐप्लिकेशन अपने APK में लेयर शामिल कर सकते हैं.

लेयर का इस्तेमाल करते समय, ध्यान रखें कि Android का सुरक्षा मॉडल और नीतियां, दूसरे प्लैटफ़ॉर्म से काफ़ी अलग हैं. खास तौर पर, Android, प्रोडक्शन (नॉन-रूट किए गए) डिवाइसों पर, ऐसी प्रोसेस में बाहरी कोड लोड करने की अनुमति नहीं देता जिसे डीबग नहीं किया जा सकता. साथ ही, यह बाहरी कोड को प्रोसेस की मेमोरी, स्थिति वगैरह की जांच करने या उसे कंट्रोल करने की अनुमति भी नहीं देता. इसमें कोर डंप, एपीआई ट्रेस वगैरह को डिस्क पर सेव करने पर पाबंदी है, ताकि बाद में उसकी जांच की जा सके. प्रोडक्शन डिवाइसों पर, सिर्फ़ नॉन-डीबग किए जा सकने वाले ऐप्लिकेशन के हिस्से के तौर पर डिलीवर की गई लेयर ही चालू होती हैं. साथ ही, ड्राइवरों को इन नीतियों का उल्लंघन करने वाली सुविधाएं नहीं देनी चाहिए.

लेयर के इस्तेमाल के उदाहरणों में ये शामिल हैं:

  • डेवलपमेंट के समय लेयर — प्रोडक्शन डिवाइसों की सिस्टम इमेज पर, ट्रैकिंग/प्रोफ़ाइलिंग/डीबगिंग टूल के लिए पुष्टि करने वाली लेयर और शिम इंस्टॉल नहीं की जानी चाहिए. ट्रैकिंग/प्रोफ़ाइलिंग/डीबगिंग टूल के लिए, पुष्टि करने वाली लेयर और शिम को सिस्टम इमेज के बिना अपडेट किया जा सकता है. जो डेवलपर डेवलपमेंट के दौरान इनमें से किसी एक लेयर का इस्तेमाल करना चाहते हैं वे ऐप्लिकेशन पैकेज में बदलाव कर सकते हैं. उदाहरण के लिए, अपनी नेटिव लाइब्रेरी डायरेक्ट्री में कोई फ़ाइल जोड़कर. जिन IHV और OEM इंजीनियर को, बदलाव न किए जा सकने वाले ऐप्लिकेशन को शिप करने में होने वाली गड़बड़ियों का पता लगाना है उनके पास, सिस्टम इमेज के नॉन-प्रोडक्शन (रूट किए गए) बिल्ड का ऐक्सेस होना चाहिए. हालांकि, ऐसा तब तक नहीं किया जा सकता, जब तक उन ऐप्लिकेशन को डीबग नहीं किया जा सकता. ज़्यादा जानकारी के लिए, Android पर Vulkan की पुष्टि करने वाली लेयर लेख पढ़ें.
  • यूटिलिटी लेयर — ये लेयर, एक्सटेंशन दिखाती हैं. जैसे, डिवाइस की मेमोरी के लिए मेमोरी मैनेजर लागू करने वाली लेयर. डेवलपर अपने ऐप्लिकेशन में इस्तेमाल करने के लिए, लेयर और उन लेयर के वर्शन चुनते हैं. एक ही लेयर का इस्तेमाल करने वाले अलग-अलग ऐप्लिकेशन, अब भी अलग-अलग वर्शन का इस्तेमाल कर सकते हैं. डेवलपर यह चुनते हैं कि उनके ऐप्लिकेशन पैकेज में इनमें से कौनसी लेयर शिप की जाएंगी.
  • इंजेक्ट की गई (अहम) लेयर — इसमें फ़्रेम रेट, सोशल नेटवर्क, और गेम लॉन्चर ओवरले जैसी लेयर शामिल होती हैं. ये लेयर, उपयोगकर्ता या किसी अन्य ऐप्लिकेशन की ओर से दी जाती हैं. ऐसा, ऐप्लिकेशन की जानकारी या सहमति के बिना किया जाता है. ये Android की सुरक्षा नीतियों का उल्लंघन करते हैं और इनका इस्तेमाल नहीं किया जा सकता.

डीबग नहीं किए जा सकने वाले ऐप्लिकेशन के लिए, लोडर सिर्फ़ ऐप्लिकेशन की नेटिव लाइब्रेरी डायरेक्ट्री में लेयर खोजता है. साथ ही, किसी खास पैटर्न (उदाहरण के लिए, libVKLayer_foo.so) से मेल खाने वाली किसी लाइब्रेरी को लोड करने की कोशिश करता है.

डीबग किए जा सकने वाले ऐप्लिकेशन के लिए, लोडर /data/local/debug/vulkan में लेयर खोजता है और किसी खास पैटर्न से मैच होने वाली लाइब्रेरी को लोड करने की कोशिश करता है.

Android, Android और दूसरे प्लैटफ़ॉर्म के बीच बिल्ड-एनवायरमेंट में बदलाव करके लेयर को पोर्ट करने की सुविधा देता है. लेयर और लोडर के बीच इंटरफ़ेस के बारे में जानकारी पाने के लिए, Vulkan लोडर इंटरफ़ेस का आर्किटेक्चर देखें. क्रोनोस के रखरखाव में इस्तेमाल की जाने वाली पुष्टि करने वाली लेयर, Vulkan की पुष्टि करने वाली लेयर में होस्ट की जाती हैं.

Vulkan API के वर्शन और सुविधाएं

यहां दी गई टेबल में, Android के कई रिलीज़ के लिए, Vulkan API के वर्शन की सूची दी गई है.
Android वर्शन Vulkan वर्शन
Android 13 Vulkan 1.3
Android 9 Vulkan 1.1
Android 7 Vulkan 1.0

Vulkan 1.3 की सुविधाओं के बारे में खास जानकारी

Vulkan 1.3 में, Vulkan के मुख्य फ़ंक्शन में ऐसे कई एक्सटेंशन शामिल किए गए हैं जो पहले ज़रूरी नहीं थे. इस सुविधा का ज़्यादातर हिस्सा, Vulkan प्रोग्रामिंग इंटरफ़ेस पर कंट्रोल और ज़्यादा जानकारी देने के मकसद से शामिल किया गया है. सिंगल-पास रेंडर पास इंस्टेंस के लिए, अब रेंडर पास ऑब्जेक्ट या फ़्रेमबफ़र की ज़रूरत नहीं है. पाइपलाइन स्टेटस ऑब्जेक्ट की कुल संख्या कम की जा सकती है और एपीआई में सिंक करने की सुविधा को बेहतर बनाया जा सकता है. Vulkan 1.3 के लिए हार्डवेयर की ज़रूरी शर्तें, Vulkan 1.2, 1.1, और 1.0 जैसी ही हैं. हालांकि, ज़्यादातर सुविधाओं को SoC के लिए खास ग्राफ़िक्स ड्राइवर में लागू किया गया है, फ़्रेमवर्क में नहीं.

Android के लिए, Vulkan 1.3 की सबसे अहम सुविधाएं ये हैं:

  • सिंगल-पास रेंडर पास इंस्टेंस के लिए सहायता
  • शेडर को तुरंत बंद करने की सुविधा
  • पाइपलाइन बनाने, शेयर करने, और कंट्रोल करने के बारे में ज़्यादा जानकारी

Vulkan 1.3 में कई छोटी सुविधाएं और एपीआई के इस्तेमाल से जुड़े सुधार भी शामिल हैं. मुख्य बदलाव (Vulkan 1.3) में, Vulkan API के कोर वर्शन में किए गए सभी बदलाव देखे जा सकते हैं.

Vulkan 1.2 के काम करने के तरीके के बारे में खास जानकारी

Vulkan 1.2 में कई सुविधाएं और एक्सटेंशन जोड़े गए हैं, जिनसे एपीआई को इस्तेमाल करना आसान हो जाता है. इसमें एक यूनिफ़ाइड मेमोरी मॉडल और अतिरिक्त जानकारी शामिल होती है. इस जानकारी के लिए, डिवाइस ड्राइवर से क्वेरी की जा सकती है. Vulkan 1.2 के लिए, हार्डवेयर की वही ज़रूरी शर्तें हैं जो Vulkan 1.0 और 1.1 के लिए हैं. सभी लागू करने की प्रोसेस, SoC के हिसाब से ग्राफ़िक ड्राइवर में होती है, न कि फ़्रेमवर्क में.

Android के लिए, Vulkan 1.2 की सबसे अहम सुविधा 8-बिट स्टोरेज के साथ काम करना है.

Vulkan 1.2 में कई छोटी-छोटी सुविधाएं और एपीआई की उपयोगिता को बेहतर बनाया गया है. मुख्य बदलाव (Vulkan 1.2) में, Vulkan के मुख्य एपीआई में किए गए सभी बदलाव देखे जा सकते हैं.

Vulkan 1.1 की सुविधाओं के बारे में खास जानकारी

Vulkan 1.1 में, मेमोरी/सिंक्रोनाइज़ेशन इंटरऑप की सुविधा उपलब्ध है. इससे OEM, डिवाइसों पर Vulkan 1.1 के साथ काम करता है. इसके अलावा, मेमोरी/सिंक्रोनाइज़ेशन इंटरऑप की मदद से डेवलपर यह तय कर सकते हैं कि किसी डिवाइस पर Vulkan 1.1 काम करेगा या नहीं. अगर वह ऐसा है, तो इसका इस्तेमाल बेहतर तरीके से किया जा सकता है. Vulkan 1.1 के लिए, हार्डवेयर की ज़रूरी शर्तें Vulkan 1.0 जैसी ही हैं. हालांकि, इसे लागू करने का ज़्यादातर तरीका एसओसी के लिए बनाए गए ग्राफ़िक ड्राइवर में है, फ़्रेमवर्क में नहीं.

Android के लिए, Vulkan 1.1 की सबसे अहम सुविधाएं ये हैं:

  • Vulkan के बाहर से मेमोरी बफ़र और सिंक्रोनाइज़ेशन ऑब्जेक्ट को इंपोर्ट और एक्सपोर्ट करने की सुविधा (कैमरा, कोडेक, और जीएलईएस के साथ इंटरऑप के लिए)
  • YCbCr फ़ॉर्मैट के साथ काम करना

Vulkan 1.1 में कई छोटी सुविधाएं और एपीआई के इस्तेमाल से जुड़े सुधार भी शामिल हैं. मामूली बदलाव 1.1 के साथ मुख्य Vulkan API में किए गए सभी बदलाव देखने के लिए, मूल संशोधन (Vulkan 1.1) पर जाएं.

Vulkan सहायता टीम चुनें

Android डिवाइसों में, Vulkan की सबसे बेहतर सुविधाओं का सेट काम करना चाहिए. हालांकि, इसके लिए ज़रूरी है कि डिवाइस में 64-बिट एबीआई की सुविधा हो और उनकी मेमोरी कम न हो.

Android 13 और इसके बाद के वर्शन वाले डिवाइसों में, Vulkan 1.3 काम करना चाहिए.

Android 10 के साथ लॉन्च होने वाले डिवाइसों पर, Vulkan 1.1 काम करना चाहिए.

अन्य डिवाइसों पर, Vulkan 1.3, 1.2, और 1.1 वर्शन काम कर सकते हैं.

Vulkan के किसी वर्शन के साथ काम करना

किसी Android डिवाइस पर Vulkan वर्शन काम करता है, अगर ये शर्तें पूरी होती हैं:

  1. Android वर्शन की सीडीडी की ज़रूरी शर्तों के साथ-साथ, अपनी पसंद के Vulkan वर्शन (यह Vulkan वर्शन 1.3, 1.1 या 1.0 में से कोई एक होना चाहिए) के साथ काम करने वाला Vulkan ड्राइवर जोड़ें. इसके अलावा, Vulkan वर्शन के पुराने वर्शन वाले मौजूदा Vulkan ड्राइवर को भी अपडेट किया जा सकता है.
  2. Vulkan 1.3 या 1.1 के लिए, पक्का करें कि पैकेज मैनेजर से मिली सिस्टम सुविधा, सही Vulkan वर्शन के लिए true दिखाए.
    • Vulkan 1.3 के लिए, यह सुविधा PackageManager#hasSystemFeature(PackageManager.FEATURE_VULKAN_HARDWARE_VERSION, 0x403000) है.
    • Vulkan 1.1 के लिए, यह सुविधा PackageManager#hasSystemFeature(PackageManager.FEATURE_VULKAN_HARDWARE_VERSION, 0x401000) है.
    पैकेज मैनेजर, Vulkan 1.3 और Vulkan 1.1 के लिए true दिखाएगा. इसके लिए, वह device.mk फ़ाइल में एक नियम जोड़ेगा. यह नियम यहां दिखाया गया है.
    • Vulkan 1.3 के लिए, यह जानकारी जोड़ें:
      PRODUCT_COPY_FILES += frameworks/native/data/etc/android.hardware.vulkan.version-1_3.xml:
      $(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.vulkan.version.xml
      
    • Vulkan 1.1 के लिए, यह जानकारी जोड़ें:
      PRODUCT_COPY_FILES += frameworks/native/data/etc/android.hardware.vulkan.version-1_1.xml:
      $(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.vulkan.version.xml
      

Android बेसलाइन प्रोफ़ाइल (एबीपी)

हमारा सुझाव है कि सभी Android डिवाइस, Android बेसलाइन प्रोफ़ाइल गाइड में बताए गए तरीके के मुताबिक, Android बेसलाइन 2022 प्रोफ़ाइल का पालन करें.

Android 14 या इसके बाद के वर्शन और Vulkan API के साथ काम करने वाले किसी भी डिवाइस पर, Android Baseline 2021 प्रोफ़ाइल में बताई गई सभी सुविधाएं काम करनी चाहिए. ज़रूरी फ़ंक्शन की पूरी सूची, Vulkan प्रोफ़ाइल json फ़ाइल में दी गई है. हालांकि, ज़रूरी फ़ंक्शन के मुख्य सबसेट में ये शामिल हैं:

  • ASTC और ETC की मदद से कंप्रेस किए गए टेक्सचर.
  • VK_EXT_swapchain_colorspace की मदद से, वैरिएबल कलरस्पेस.
  • sampleRateShading की मदद से, सैंपल शेडिंग और मल्टीसैंपल इंटरपोलेशन का इस्तेमाल करें.

विंडो सिस्टम इंटिग्रेशन (डब्ल्यूएसआई)

libvulkan.so में, ड्राइवर ये विंडो सिस्टम इंटिग्रेशन (डब्ल्यूएसआई) एक्सटेंशन लागू करता है:

  • VK_KHR_surface
  • VK_KHR_android_surface
  • VK_KHR_swapchain
  • VK_KHR_driver_properties को सिर्फ़ Android 10 में Vulkan 1.1 के लिए लागू किया गया
  • VK_GOOGLE_display_timing, Android 10 में Vulkan के किसी भी वर्शन के लिए लागू किया गया

VkSurfaceKHR और VkSwapchainKHR ऑब्जेक्ट और ANativeWindow के साथ सभी इंटरैक्शन, प्लैटफ़ॉर्म मैनेज करता है. ये ड्राइवर के लिए उपलब्ध नहीं होते. WSI को लागू करने के लिए, VK_ANDROID_native_buffer एक्सटेंशन का इस्तेमाल किया जाता है. यह ज़रूरी है कि ड्राइवर इस एक्सटेंशन के साथ काम करता हो. इस एक्सटेंशन का इस्तेमाल सिर्फ़ WSI को लागू करने के लिए किया जाता है. इसे ऐप्लिकेशन के लिए उपलब्ध नहीं कराया जाता.

Gralloc के इस्तेमाल से जुड़े फ़्लैग

Vulkan को लागू करने के लिए, हो सकता है कि आपको स्वैपचैन बफ़र को लागू करने के लिए तय किए गए निजी Gralloc इस्तेमाल फ़्लैग के साथ, बफ़र को ऐलोकेट करना पड़े. स्वैपचैन बनाते समय, Android ड्राइवर से अनुरोध किए गए फ़ॉर्मैट और इमेज के इस्तेमाल के फ़्लैग को Gralloc के इस्तेमाल के फ़्लैग में बदलने के लिए कहता है. इसके लिए, यह इन फ़ंक्शन को कॉल करता है:

typedef enum VkSwapchainImageUsageFlagBitsANDROID {
    VK_SWAPCHAIN_IMAGE_USAGE_SHARED_BIT_ANDROID = 0x00000001,
    VK_SWAPCHAIN_IMAGE_USAGE_FLAG_BITS_MAX_ENUM = 0x7FFFFFFF
} VkSwapchainImageUsageFlagBitsANDROID;
typedef VkFlags VkSwapchainImageUsageFlagsANDROID;

VkResult VKAPI vkGetSwapchainGrallocUsage2ANDROID(
    VkDevice                          device,
    VkFormat                          format,
    VkImageUsageFlags                 imageUsage,
    VkSwapchainImageUsageFlagsANDROID swapchainUsage,
    uint64_t*                         grallocConsumerUsage,
    uint64_t*                         grallocProducerUsage
);

format और imageUsage पैरामीटर, VkSwapchainCreateInfoKHR स्ट्रक्चर से लिए गए हैं. ड्राइवर को *grallocConsumerUsage और *grallocProducerUsage को भरना चाहिए. इनमें, फ़ॉर्मैट और इस्तेमाल के लिए ज़रूरी Gralloc इस्तेमाल फ़्लैग होने चाहिए. ड्राइवर से मिले इस्तेमाल के फ़्लैग को, बफ़र को असाइन करते समय, स्वैपचैन उपभोक्ता के अनुरोध किए गए इस्तेमाल के फ़्लैग के साथ जोड़ दिया जाता है.

Android 7.x, VkSwapchainImageUsageFlagsANDROID() के पुराने वर्शन को vkGetSwapchainGrallocUsageANDROID() कहता है. Android 8.0 और उसके बाद के वर्शन बंद हो जाते हैं vkGetSwapchainGrallocUsageANDROID(), लेकिन फिर भी vkGetSwapchainGrallocUsageANDROID() को कॉल करता है. ऐसा तब होता है, जब ड्राइवर ने vkGetSwapchainGrallocUsage2ANDROID() नहीं दिया हो:

VkResult VKAPI vkGetSwapchainGrallocUsageANDROID(
    VkDevice            device,
    VkFormat            format,
    VkImageUsageFlags   imageUsage,
    int*                grallocUsage
);

vkGetSwapchainGrallocUsageANDROID(), स्वैपचैन के इस्तेमाल के फ़्लैग या Gralloc के इस्तेमाल के एक्सटेंडेड फ़्लैग के साथ काम नहीं करता.

Gralloc की मदद से बैक अप ली गई इमेज

VkNativeBufferANDROID, Gralloc बफ़र की मदद से इमेज बनाने के लिए, vkCreateImage एक्सटेंशन का स्ट्रक्चर है. VkNativeBufferANDROID, VkImageCreateInfo स्ट्रक्चर चेन में vkCreateImage() को दिया जाता है. vkCreateSwapchainKHR पर कॉल के दौरान, VkNativeBufferANDROID से vkCreateImage() पर कॉल किए जाते हैं. डब्ल्यूएसआई लागू करने की प्रक्रिया में, स्वैपचेन के लिए अनुरोध किए गए नेटिव बफ़र की संख्या तय की जाती है. इसके बाद, हर एक के लिए VkImage बनाया जाता है:

typedef struct {
    VkStructureType             sType; // must be VK_STRUCTURE_TYPE_NATIVE_BUFFER_ANDROID
    const void*                 pNext;

    // Buffer handle and stride returned from gralloc alloc()
    buffer_handle_t             handle;
    int                         stride;

    // Gralloc format and usage requested when the buffer was allocated.
    int                         format;
    int                         usage;
    // Beginning in Android 8.0, the usage field above is deprecated and the
    // usage2 struct below was added. The usage field is still filled in for
    // compatibility with Android 7.0 drivers. Drivers for Android 8.0
    // should prefer the usage2 struct, especially if the
    // android.hardware.graphics.allocator HAL uses the extended usage bits.
    struct {
        uint64_t                consumer;
        uint64_t                producer;
    } usage2;
} VkNativeBufferANDROID;

Gralloc की मदद से इमेज बनाने पर, VkImageCreateInfo में यह डेटा होता है:

  .sType               = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO
  .pNext               = the above VkNativeBufferANDROID structure
  .imageType           = VK_IMAGE_TYPE_2D
  .format              = a VkFormat matching the format requested for the gralloc buffer
  .extent              = the 2D dimensions requested for the gralloc buffer
  .mipLevels           = 1
  .arraySize           = 1
  .samples             = 1
  .tiling              = VK_IMAGE_TILING_OPTIMAL
  .usage               = VkSwapchainCreateInfoKHR::imageUsage
  .flags               = 0
  .sharingMode         = VkSwapchainCreateInfoKHR::imageSharingMode
  .queueFamilyCount    = VkSwapchainCreateInfoKHR::queueFamilyIndexCount
  .pQueueFamilyIndices = VkSwapchainCreateInfoKHR::pQueueFamilyIndices

Android 8.0 और इसके बाद के वर्शन में, प्लैटफ़ॉर्म vkCreateImage को दी गई VkImageCreateInfo चेन में VkSwapchainImageCreateInfoKHR एक्सटेंशन स्ट्रक्चर उपलब्ध कराता है. ऐसा तब होता है, जब स्वैपचैन के लिए इमेज के इस्तेमाल से जुड़े किसी फ़्लैग की ज़रूरत होती है. एक्सटेंशन स्ट्रक्चर में, स्वैपचैन इमेज के इस्तेमाल से जुड़े फ़्लैग होते हैं:

typedef struct {
    VkStructureType                        sType; // must be VK_STRUCTURE_TYPE_SWAPCHAIN_IMAGE_CREATE_INFO_ANDROID
    const void*                            pNext;

    VkSwapchainImageUsageFlagsANDROID      usage;
} VkSwapchainImageCreateInfoANDROID;

Android 10 और उसके बाद के वर्शन में, प्लैटफ़ॉर्म VK_KHR_swapchain v70 के साथ काम करता है. इसलिए, Vulkan ऐप्लिकेशन, स्वैपचैन मेमोरी की मदद से VkImage बना सकता है. ऐप्लिकेशन सबसे पहले VkImageCreateInfo स्ट्रक्चर से जुड़े VkImageSwapchainCreateInfoKHR स्ट्रक्चर के साथ vkCreateImage को कॉल करता है. इसके बाद, ऐप्लिकेशन VkBindImageMemoryInfo स्ट्रक्चर से जुड़े VkBindImageMemorySwapchainInfoKHR स्ट्रक्चर के साथ vkBindImageMemory2(KHR) को कॉल करता है. VkBindImageMemorySwapchainInfoKHR स्ट्रक्चर में बताए गए imageIndex का एक मान्य स्वैपचैन इमेज इंडेक्स होना चाहिए. इस दौरान, प्लैटफ़ॉर्म VkBindImageMemoryInfo चेन के लिए, VkNativeBufferANDROID एक्सटेंशन स्ट्रक्चर के साथ उससे जुड़े Gralloc बफ़र की जानकारी देता है, ताकि ड्राइवर को पता चले कि VkImage को किस Gralloc बफ़र से बांधना है.

इमेज पाएं

vkAcquireImageANDROID, स्वैपचैन इमेज का मालिकाना हक हासिल करता है और किसी मौजूदा VkSemaphore ऑब्जेक्ट और मौजूदा VkFence ऑब्जेक्ट, दोनों में बाहर से सिग्नल भेजने वाले नेटिव फ़ेंस को इंपोर्ट करता है:

VkResult VKAPI vkAcquireImageANDROID(
    VkDevice            device,
    VkImage             image,
    int                 nativeFenceFd,
    VkSemaphore         semaphore,
    VkFence             fence
);

vkAcquireImageANDROID() को vkAcquireNextImageKHR के दौरान कॉल किया जाता है, ताकि ऐप्लिकेशन के दिए गए VkSemaphore और VkFence ऑब्जेक्ट में नेटिव फ़ेंस को इंपोर्ट किया जा सके. हालांकि, इस कॉल में सेमाफ़ोर और फ़ेंस, दोनों ऑब्जेक्ट ज़रूरी नहीं हैं. ड्राइवर इस अवसर का इस्तेमाल, Gralloc बफ़र की स्थिति में होने वाले किसी भी बाहरी बदलाव को पहचानने और मैनेज करने के लिए भी कर सकता है. हालांकि, कई ड्राइवर को यहां कुछ भी करने की ज़रूरत नहीं होगी. इस कॉल से VkSemaphore और VkFence की स्थिति ठीक वैसी ही हो जाती है, जैसी vkQueueSubmit से सिग्नल मिलने पर होती है. इसलिए, लाइन सेमाफ़ोर पर इंतज़ार किया जा सकता है और ऐप्लिकेशन इंतज़ार कर सकता है.

नेटिव फ़ेंस के सिग्नल मिलने पर, दोनों ऑब्जेक्ट को सिग्नल मिल जाता है. अगर नेटिव फ़ेंस ने पहले ही सिग्नल दे दिया है, तो यह फ़ंक्शन वापस आने पर सिग्नल वाली स्थिति में सेमाफ़ोर होता है. ड्राइवर, फ़ेंस फ़ाइल डिस्क्रिप्टर का मालिकाना हक लेता है और ज़रूरत न होने पर फ़ेंस फ़ाइल डिस्क्रिप्टर को बंद कर देता है. ड्राइवर को ऐसा करना चाहिए. भले ही, सेमाफ़ोर या फ़ेंस ऑब्जेक्ट, दोनों में से किसी को भी न दिया गया हो. अगर vkAcquireImageANDROID काम नहीं करता है और गड़बड़ी दिखाता है, तब भी ऐसा किया जा सकता है. अगर fenceFd की वैल्यू -1 है, तो इसका मतलब है कि नेटिव फ़ेंस के लिए पहले ही सिग्नल भेजा जा चुका है.

इमेज रिलीज़ करना

vkQueueSignalReleaseImageANDROID बाहरी इस्तेमाल के लिए एक स्वैपचेन इमेज तैयार करता है, नेटिव फ़ेंस बनाता है, और इनपुट सेमाफ़ोर के सिग्नल मिलने के बाद नेटिव बाड़ को सिग्नल देने के लिए शेड्यूल करता है:

VkResult VKAPI vkQueueSignalReleaseImageANDROID(
    VkQueue             queue,
    uint32_t            waitSemaphoreCount,
    const VkSemaphore*  pWaitSemaphores,
    VkImage             image,
    int*                pNativeFenceFd
);

vkQueuePresentKHR() दी गई सूची में मौजूद vkQueueSignalReleaseImageANDROID() को कॉल करता है. ड्राइवर को ऐसा स्थानीय बाड़ बनाना होगा जो pWaitSemaphores सिग्नल में मौजूद सभी waitSemaphoreCount सेमाफ़ोर से सिग्नल न देता हो. साथ ही, image को प्रज़ेंटेशन के लिए तैयार करने के लिए, कुछ और काम करना ज़रूरी है.

अगर वेट सिग्नल (अगर कोई है) पहले से ही सिग्नल दे चुके हैं और queue पहले से ही आइडल है, तो ड्राइवर किसी नेटिव फ़ेंस फ़ाइल डिस्क्रिप्टर के बजाय, *pNativeFenceFd को -1 पर सेट कर सकता है. इससे पता चलता है कि इंतज़ार करने की ज़रूरत नहीं है. कॉल करने वाले के पास, *pNativeFenceFd में दिखाए गए फ़ाइल डिस्क्रिप्टर का मालिकाना हक होता है और उसे बंद करने का अधिकार भी होता है.

कई ड्राइवर इमेज पैरामीटर को अनदेखा कर सकते हैं, लेकिन कुछ को बाहरी इमेज के उपभोक्ताओं को इस्तेमाल करने के लिए, Gralloc बफ़र से जुड़े सीपीयू-साइड डेटा स्ट्रक्चर तैयार करने पड़ सकते हैं. बाहरी उपभोक्ताओं के इस्तेमाल के लिए बफ़र कॉन्टेंट तैयार करना, इमेज को VK_IMAGE_LAYOUT_PRESENT_SRC_KHR में बदलने के हिस्से के तौर पर, अलग-अलग समय पर किया जाना चाहिए.

अगर इमेज को VK_SWAPCHAIN_IMAGE_USAGE_SHARED_BIT_ANDROID की मदद से बनाया गया है, तो ड्राइवर को vkQueueSignalReleaseImageANDROID() को बार-बार कॉल करने की अनुमति देनी होगी. ऐसा करने के लिए, vkAcquireImageANDROID() को कॉल करने की अनुमति नहीं देनी होगी.

शेयर की जा सकने वाली इमेज से जुड़ी सहायता

कुछ डिवाइस, डिसप्ले पाइपलाइन और Vulkan के बीच किसी एक इमेज का मालिकाना हक शेयर कर सकते हैं, ताकि इंतज़ार का समय कम हो. Android 9 और उसके बाद के वर्शन में, लोडर VK_KHR_shared_presentable_image एक्सटेंशन का विज्ञापन दिखाता है. यह विज्ञापन, vkGetPhysicalDeviceProperties2 के कॉल के लिए ड्राइवर के जवाब के आधार पर दिखाया जाता है.

अगर ड्राइवर, Vulkan 1.1 या VK_KHR_physical_device_properties2 एक्सटेंशन के साथ काम नहीं करता है, तो लोडर, शेयर की गई इमेज के साथ काम करने की सुविधा का विज्ञापन नहीं दिखाता. अगर ऐसा नहीं है, तो लोडर vkGetPhysicalDeviceProperties2() को कॉल करके, ड्राइवर की क्षमताओं के बारे में क्वेरी करता है और VkPhysicalDeviceProperties2::pNext चेन में यह स्ट्रक्चर शामिल करता है:

typedef struct {
    VkStructureType sType; // must be VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENTATION_PROPERTIES_ANDROID
    const void*     pNext;
    VkBool32        sharedImage;
} VkPhysicalDevicePresentationPropertiesANDROID;

अगर ड्राइवर, डिसप्ले सिस्टम के साथ किसी इमेज का मालिकाना हक शेयर कर सकता है, तो वह sharedImage सदस्य को VK_TRUE पर सेट करता है.

पुष्टि करें

OEM, सीटीएस का इस्तेमाल करके, Vulkan को लागू करने की जांच कर सकते हैं. इसमें ये चीज़ें शामिल हैं:

  • CtsDeqpTestCases मॉड्यूल में Khronos Vulkan के मुताबिक टेस्ट, जिनमें Vulkan 1.0, 1.1, 1.2, और 1.3 के लिए फ़ंक्शनल एपीआई टेस्ट शामिल हैं.
  • CtsGraphicsTestCases मॉड्यूल, जो यह जांच करता है कि डिवाइस को Vulkan की उन सुविधाओं के लिए सही तरीके से कॉन्फ़िगर किया गया है जिन पर यह काम करता है.

Vulkan फ़ीचर फ़्लैग

Android 11 या उसके बाद के वर्शन पर काम करने वाले और Vulkan API के साथ काम करने वाले डिवाइस को फ़ीचर फ़्लैग, android.software.vulkan.deqp.level दिखाना ज़रूरी है. इस फ़ीचर फ़्लैग की वैल्यू एक तारीख है, जिसे पूर्णांक के तौर पर एन्कोड किया गया है. इसमें Vulkan dEQP की उन जांचों से जुड़ी तारीख के बारे में पता चलता है जिनके बारे में डिवाइस पुष्टि करता है.

YYYY-MM-DD फ़ॉर्म की तारीख को 32-बिट पूर्णांक के तौर पर इस तरह एन्कोड किया गया है:

  • बिट 0 से 15 में साल का डेटा सेव होता है
  • बिट 16 से 23 में महीना सेव होता है
  • दिन में 24 से 31 बिट का स्टोर

फ़ीचर फ़्लैग के लिए इस्तेमाल की जा सकने वाली कम से कम वैल्यू 0x07E30301 है. यह 01-03-2019 की तारीख है, जो Android 10 के लिए Vulkan dEQP टेस्ट से जुड़ी है. अगर सुविधा फ़्लैग की वैल्यू कम से कम इतनी है, तो डिवाइस के पास Android 10 Vulkan dEQP के सभी टेस्ट पास करने का दावा है.

वैल्यू 0x07E40301, 01-03-2020 की तारीख से जुड़ी है. यह तारीख, Android 11 के लिए Vulkan dEQP टेस्ट से जुड़ी है. अगर सुविधा के लिए फ़्लैग की वैल्यू कम से कम इतनी है, तो इसका मतलब है कि डिवाइस ने Android 11 Vulkan dEQP के सभी टेस्ट पास कर लिए हैं.

वैल्यू 0x07E60301, 01-03-2022 की तारीख है. यह तारीख Android 13 के लिए, Vulkan dEQP टेस्ट से जुड़ी है. अगर सुविधा फ़्लैग की वैल्यू कम से कम इतनी है, तो इसका मतलब है कि डिवाइस ने Android 13 Vulkan dEQP के सभी टेस्ट पास कर लिए हैं.

किसी खास फ़ीचर फ़्लैग (जैसे कि 0x07E30301, 0x07E40301, 0x07E60301) को दिखाने वाला डिवाइस, उस सुविधा फ़्लैग के सभी Android Vulkan dEQP टेस्ट को पास करने का दावा करता है.जैसे, Android 10, Android 11, Android 13. यह डिवाइस, Android के नए वर्शन में Vulkan dEQP टेस्ट पास कर सकता है.

Vulkan dEQP, Android CTS का हिस्सा है. Android 11 से, CTS के dEQP टेस्ट रनर कॉम्पोनेंट को android.software.vulkan.deqp.level सुविधा फ़्लैग के बारे में पता है. साथ ही, यह उन सभी Vulkan dEQP टेस्ट को स्किप कर देता है जिनके लिए, इस सुविधा फ़्लैग के मुताबिक डिवाइस पर काम करने का दावा नहीं किया गया है. इस तरह की जांचों को बहुत आसानी से पास होने के तौर पर माना जाता है.