Vulkan के डिज़ाइन से जुड़े दिशा-निर्देश

Vulkan, पिछले ग्राफ़िक्स एपीआई से अलग है. इसमें ड्राइवर, ऐप्लिकेशन के लिए कुछ ऑप्टिमाइज़ेशन नहीं करते. जैसे, पाइपलाइन का फिर से इस्तेमाल करना. इसके बजाय, Vulkan का इस्तेमाल करने वाले ऐप्लिकेशन को इस तरह के ऑप्टिमाइज़ेशन खुद लागू करने होंगे. ऐसा न होने पर, उनकी परफ़ॉर्मेंस OpenGL ES पर चलने वाले ऐप्लिकेशन की तुलना में खराब हो सकती है.

जब ऐप्लिकेशन खुद इन ऑप्टिमाइज़ेशन को लागू करते हैं, तो वे ड्राइवर की तुलना में ज़्यादा बेहतर तरीके से ऐसा कर सकते हैं. इसकी वजह यह है कि उनके पास इस्तेमाल के किसी खास उदाहरण के लिए ज़्यादा जानकारी होती है. इसलिए, Vulkan का इस्तेमाल करने वाले ऐप्लिकेशन को बेहतर तरीके से ऑप्टिमाइज़ करने पर, OpenGL ES का इस्तेमाल करने वाले ऐप्लिकेशन की तुलना में बेहतर परफ़ॉर्मेंस मिल सकती है.

इस पेज पर, कई ऑप्टिमाइज़ेशन के बारे में बताया गया है. Android ऐप्लिकेशन में इन्हें लागू करके, Vulkan की परफ़ॉर्मेंस को बेहतर बनाया जा सकता है.

हार्डवेयर की मदद से तेज़ी लाने की सुविधा

ज़्यादातर डिवाइसों पर, Vulkan 1.1 को हार्डवेयर ऐक्सलरेशन की मदद से इस्तेमाल किया जा सकता है. हालांकि, कुछ डिवाइसों पर इसे सॉफ़्टवेयर इम्यूलेशन की मदद से इस्तेमाल किया जा सकता है. ऐप्लिकेशन, सॉफ़्टवेयर पर आधारित Vulkan डिवाइस का पता लगा सकते हैं. इसके लिए, उन्हें vkGetPhysicalDeviceProperties का इस्तेमाल करना होगा. साथ ही, उन्हें लौटाए गए स्ट्रक्चर के deviceType फ़ील्ड की जांच करनी होगी. SwiftShader और सीपीयू पर आधारित अन्य सुविधाओं के लिए, वैल्यू VK_PHYSICAL_DEVICE_TYPE_CPU होती है. ऐप्लिकेशन, SwiftShader के लिए खास तौर पर vendorID और deviceID फ़ील्ड की जांच कर सकते हैं. इसके लिए, उन्हें SwiftShader के लिए खास तौर पर बनाए गए इसी स्ट्रक्चर का इस्तेमाल करना होगा.

परफ़ॉर्मेंस के लिहाज़ से ज़रूरी ऐप्लिकेशन में, सॉफ़्टवेयर से बनाए गए Vulkan वर्शन का इस्तेमाल नहीं किया जाना चाहिए. इसके बजाय, उन्हें OpenGL ES का इस्तेमाल करना चाहिए.

रेंडरिंग के दौरान डिसप्ले रोटेशन लागू करें

जब ऐप्लिकेशन का अपवर्ड-फ़ेसिंग ओरिएंटेशन, डिवाइस के डिसप्ले के ओरिएंटेशन से मेल नहीं खाता है, तो कंपोज़िटर, ऐप्लिकेशन की स्वैपचेन इमेज को घुमाता है, ताकि वह मेल खा सके. यह इमेज दिखाते समय रोटेशन करता है. इससे, रोटेशन न करने की तुलना में ज़्यादा बैटरी खर्च होती है. कभी-कभी, यह काफ़ी ज़्यादा होती है.

इसके उलट, इमेज जनरेट करते समय स्वैपचेन इमेज को रोटेट करने से, बिजली की खपत में बहुत कम या कोई बढ़ोतरी नहीं होती. VkSurfaceCapabilitiesKHR::currentTransform फ़ील्ड से पता चलता है कि कंपोज़िटर, विंडो पर कौनसी रोटेशन सेटिंग लागू करता है. रेंडरिंग के दौरान, ऐप्लिकेशन के रोटेशन लागू करने के बाद, ऐप्लिकेशन VkSwapchainCreateInfoKHR::preTransform फ़ील्ड का इस्तेमाल करके यह रिपोर्ट करता है कि रोटेशन पूरा हो गया है.

हर फ़्रेम के लिए रेंडर पास कम से कम करें

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

अटैचमेंट लोड और अटैचमेंट स्टोर करने के अलग-अलग ऑपरेशंस से, अलग-अलग लेवल की परफ़ॉर्मेंस मिलती है. उदाहरण के लिए, अगर आपको अटैचमेंट के कॉन्टेंट को सेव नहीं करना है, तो VK_ATTACHMENT_LOAD_OP_LOAD के बजाय VK_ATTACHMENT_LOAD_OP_CLEAR या VK_ATTACHMENT_LOAD_OP_DONT_CARE का इस्तेमाल करें. ये दोनों विकल्प, VK_ATTACHMENT_LOAD_OP_LOAD की तुलना में ज़्यादा तेज़ी से काम करते हैं. इसी तरह, अगर आपको अटैचमेंट की फ़ाइनल वैल्यू को बाद में इस्तेमाल करने के लिए मेमोरी में सेव नहीं करना है, तो VK_ATTACHMENT_STORE_OP_STORE के बजाय VK_ATTACHMENT_STORE_OP_DONT_CARE का इस्तेमाल करें. इससे आपको बेहतर परफ़ॉर्मेंस मिलेगी.

इसके अलावा, ज़्यादातर रेंडर पास में, आपके ऐप्लिकेशन को डेप्थ/स्टेंसिल अटैचमेंट को लोड या सेव करने की ज़रूरत नहीं होती. ऐसे मामलों में, अटैचमेंट इमेज बनाते समय VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT फ़्लैग का इस्तेमाल करके, अटैचमेंट के लिए फ़िज़िकल मेमोरी को असाइन करने से बचा जा सकता है. यह बिट, OpenGL ES में glFramebufferDiscard की तरह ही फ़ायदे देती है.

सही तरह की यादें चुनें

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

कोई ऐप्लिकेशन, किसी इस्तेमाल के लिए सबसे अच्छी मेमोरी टाइप चुनने के लिए, सामान्य एल्गोरिदम का इस्तेमाल कर सकता है. यह एल्गोरिदम, VkPhysicalDeviceMemoryProperties::memoryTypes ऐरे में मौजूद पहली मेमोरी टाइप को चुनता है. इसके लिए, दो शर्तें पूरी होनी चाहिए: मेमोरी टाइप को बफ़र या इमेज के लिए अनुमति दी गई हो. साथ ही, इसमें वे कम से कम प्रॉपर्टी मौजूद हों जिनकी ऐप्लिकेशन को ज़रूरत है.

मोबाइल सिस्टम में आम तौर पर, सीपीयू और जीपीयू के लिए अलग-अलग फ़िज़िकल मेमोरी हीप नहीं होते हैं. ऐसे सिस्टम पर, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT उतना अहम नहीं होता जितना उन सिस्टम पर होता है जिनमें अलग-अलग जीपीयू होते हैं और उनकी अपनी मेमोरी होती है. किसी ऐप्लिकेशन को यह नहीं मानना चाहिए कि यह प्रॉपर्टी ज़रूरी है.

फ़्रीक्वेंसी के हिसाब से ग्रुप डिस्क्रिप्टर सेट करना

अगर आपके पास ऐसे संसाधन बाइंडिंग हैं जो अलग-अलग फ़्रीक्वेंसी पर बदलते हैं, तो हर ड्रॉ के लिए सभी संसाधनों को फिर से बाइंड करने के बजाय, हर पाइपलाइन के लिए एक से ज़्यादा डिस्क्रिप्टर सेट का इस्तेमाल करें. उदाहरण के लिए, आपके पास हर सीन के हिसाब से बाइंडिंग के लिए डिस्क्रिप्टर का एक सेट, हर मटीरियल के हिसाब से बाइंडिंग के लिए दूसरा सेट, और हर मेश-इंस्टेंस के हिसाब से बाइंडिंग के लिए तीसरा सेट हो सकता है.

सबसे ज़्यादा बार होने वाले बदलावों के लिए, इमीडिएट कॉन्स्टेंट का इस्तेमाल करें. जैसे, हर ड्रॉ कॉल के साथ किए जाने वाले बदलाव.