Pedoman desain Vulkan

Tidak seperti API grafis sebelumnya, dengan Vulkan, driver tidak melakukan pengoptimalan tertentu untuk aplikasi, seperti penggunaan kembali pipeline. Sebagai gantinya, aplikasi yang menggunakan Vulkan harus mengimplementasikan sendiri pengoptimalan tersebut. Jika tidak, aplikasi dapat berperforma lebih buruk dibandingkan aplikasi yang menjalankan OpenGL ES.

Saat mengimplementasikan sendiri pengoptimalan tersebut, aplikasi berpeluang untuk melakukannya dengan lebih sukses daripada yang dapat dilakukan oleh driver, karena aplikasi memiliki akses ke informasi yang lebih spesifik untuk kasus penggunaan tertentu. Hasilnya, pengoptimalan aplikasi yang menggunakan Vulkan secara cerdas dapat menghasilkan performa yang lebih baik dibandingkan saat aplikasi tersebut menggunakan OpenGL ES.

Halaman ini memperkenalkan beberapa pengoptimalan yang dapat diimplementasikan oleh aplikasi Android Anda untuk mendapatkan peningkatan performa dari Vulkan.

Akselerasi hardware

Sebagian besar perangkat mendukung Vulkan 1.1 melalui akselerasi hardware, sementara sebagian kecil perangkat lainnya mendukungnya melalui emulasi software. Aplikasi dapat mendeteksi perangkat Vulkan berbasis software menggunakan vkGetPhysicalDeviceProperties dan memeriksa kolom deviceType dalam struktur yang ditampilkan. SwiftShader dan implementasi berbasis CPU lainnya memiliki nilai VK_PHYSICAL_DEVICE_TYPE_CPU. Aplikasi dapat memeriksa SwiftShader secara khusus dengan mencari nilai khusus SwiftShader di kolom vendorID dan deviceID dalam struktur yang sama.

Aplikasi yang penting bagi performa harus menghindari penggunaan implementasi Vulkan yang diemulasi software dan kembali ke OpenGL ES.

Menerapkan rotasi tampilan selama rendering

Saat arah yang menghadap ke atas di aplikasi tidak sama dengan orientasi layar perangkat, compositor akan memutar gambar swapchain aplikasi agar arahnya sama. Compositor melakukan rotasi ini saat menampilkan gambar, yang mengakibatkan penggunaan daya yang lebih tinggi dan terkadang jauh lebih tinggi dibandingkan jika gambar tidak diputar.

Sebaliknya, memutar gambar swapchain saat membuat gambar tersebut akan mengakibatkan sedikit tambahan konsumsi daya, jika ada. Kolom VkSurfaceCapabilitiesKHR::currentTransform menunjukkan rotasi yang diterapkan oleh compositor ke jendela. Setelah menerapkan rotasi tersebut pada waktu rendering, aplikasi akan menggunakan kolom VkSwapchainCreateInfoKHR::preTransform untuk melaporkan bahwa rotasi selesai.

Meminimalkan render pass per bingkai

Pada sebagian besar arsitektur GPU seluler, memulai dan mengakhiri render pass merupakan operasi yang mahal. Aplikasi Anda dapat meningkatkan performa dengan menyusun operasi rendering menjadi sesedikit mungkin render pass.

Operasi attachment-load dan attachment-store yang berbeda menawarkan tingkat performa yang berbeda pula. Misalnya, jika Anda tidak perlu mempertahankan konten lampiran, Anda dapat menggunakan VK_ATTACHMENT_LOAD_OP_CLEAR atau VK_ATTACHMENT_LOAD_OP_DONT_CARE yang lebih cepat, bukan VK_ATTACHMENT_LOAD_OP_LOAD. Demikian juga, jika Anda tidak perlu menuliskan nilai akhir lampiran ke memori untuk digunakan nanti, Anda dapat menggunakan VK_ATTACHMENT_STORE_OP_DONT_CARE untuk mendapatkan performa yang jauh lebih baik daripada VK_ATTACHMENT_STORE_OP_STORE.

Selain itu, pada hampir semua render pass, aplikasi Anda tidak perlu memuat atau menyimpan lampiran kedalaman/stensil. Dalam situasi seperti ini, Anda dapat menghindari perlunya mengalokasikan memori fisik untuk lampiran menggunakan flag VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT saat membuat gambar lampiran. Bit ini memberikan manfaat yang sama seperti glFramebufferDiscard dalam OpenGL ES.

Memilih jenis memori yang sesuai

Saat mengalokasikan memori perangkat, aplikasi harus memilih jenis memori. Jenis memori menentukan cara aplikasi menggunakan memori, dan juga menjelaskan properti caching dan koherensi memori. Perangkat yang berbeda memiliki jenis memori yang berbeda; jenis memori yang berbeda menunjukkan karakteristik performa yang berbeda.

Aplikasi dapat menggunakan algoritme sederhana untuk memilih jenis memori terbaik untuk penggunaan tertentu. Algoritme ini mengambil jenis memori pertama dalam array VkPhysicalDeviceMemoryProperties::memoryTypes yang memenuhi dua kriteria: Jenis memori harus diizinkan untuk buffer atau gambar, dan harus memiliki properti minimal yang diperlukan aplikasi.

Sistem seluler umumnya tidak memiliki heap memori fisik yang terpisah untuk CPU dan GPU. Pada sistem seperti itu, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT tidak terlalu signifikan seperti pada sistem yang memiliki GPU terpisah dengan memori khususnya sendiri. Aplikasi tidak boleh berasumsi properti ini bersifat wajib.

Mengelompokkan kumpulan deskriptor menurut frekuensi

Jika Anda memiliki binding resource yang berubah pada frekuensi yang berbeda, gunakan beberapa kumpulan deskriptor per pipeline, bukan mem-binding ulang semua resource untuk setiap gambar. Misalnya, Anda dapat memiliki satu set deskriptor untuk binding per-scene, set lainnya untuk binding per-material, dan set ketiga untuk binding instance per-mesh.

Gunakan konstanta langsung untuk perubahan dengan frekuensi tertinggi, seperti perubahan yang dijalankan dengan setiap panggilan gambar.