Vulkan को लागू करना

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

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

  • Android से मिलने वाला Vulkan लोडर.
  • GPU IHV जैसे SoCs से मिलने वाला 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 लोडर इंटरफ़ेस का आर्किटेक्चर देखें. Khronos की ओर से मैनेज की जाने वाली पुष्टि करने वाली लेयर, Vulkan Validation Layers में होस्ट की जाती हैं.

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 के बाहर से मेमोरी बफ़र और सिंक्रोनाइज़ेशन ऑब्जेक्ट इंपोर्ट और एक्सपोर्ट करने की सुविधा (कैमरा, कोडेक, और GLES के साथ इंटरऑपरेट करने के लिए)
  • YCbCr फ़ॉर्मैट के साथ काम करना

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

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 के किसी पुराने वर्शन वाले मौजूदा ड्राइवर को अपडेट करें.
  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() का इस्तेमाल नहीं किया जा सकता. हालांकि, अगर ड्राइवर ने vkGetSwapchainGrallocUsage2ANDROID() की वैल्यू नहीं दी है, तो vkGetSwapchainGrallocUsageANDROID() को कॉल किया जाता है:

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

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

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

VkNativeBufferANDROID, Gralloc बफ़र की मदद से इमेज बनाने के लिए, vkCreateImage एक्सटेंशन का स्ट्रक्चर है. VkNativeBufferANDROID, VkImageCreateInfo स्ट्रक्चर चेन में vkCreateImage() को दिया जाता है. VkNativeBufferANDROID से vkCreateImage() को कॉल करने पर, vkCreateSwapchainKHR को कॉल करने के दौरान ऐसा होता है. WSI लागू करने पर, स्वाॅपचैन के लिए अनुरोध किए गए नेटिव बफ़र की संख्या तय की जाती है. इसके बाद, हर बफ़र के लिए एक 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 टेस्ट को स्किप कर देता है जिनके लिए, इस सुविधा फ़्लैग के मुताबिक डिवाइस पर काम करने का दावा नहीं किया गया है. ऐसे टेस्ट को आसानी से पास होने के तौर पर रिपोर्ट किया जाता है.