Pierwsze kroki z Vulkanem na Androidzie
Vulkan to główny niskopoziomowy interfejs API grafiki na Androidzie. Vulkan zapewnia optymalną wydajność w grach, które implementują własny silnik gry i moduł renderowania.
Aby pomyślnie wdrożyć interfejs Vulkan w silniku gry, musisz:
- Określanie, które urządzenia z Androidem mają używać Vulkana
- Zrozumienie kompromisów związanych z obsługą starszych urządzeń z Androidem
- Dodawanie Vulkana do docelowej kompilacji na Androida
- Wybieranie kompilatora cieniowania do tworzenia SPIR-V dla Vulkan
- Określanie dostępnej wersji interfejsu Vulkan API w czasie działania
- Dowiedz się, jak optymalizować operacje renderowania Vulkan za pomocą profili Vulkan, tempa klatek i wstępnego obracania
- Wybieranie narzędzi graficznych do debugowania i analizy wydajności
- Uwaga: informacje o używaniu interfejsu Vulkan na Androidzie z silnikami gier Unity lub Unreal znajdziesz w tych artykułach:
- Vulkan w Unity
- Vulkan w Unreal
Wybieranie minimalnych specyfikacji urządzeń dla interfejsu Vulkan
Interfejs Vulkan jest dostępny na Androidzie od wersji 7.0 (poziom interfejsu API 24). Nie wszystkie urządzenia z Androidem 7.0 lub nowszym obsługują interfejs Vulkan. Musisz określić, które urządzenia z Androidem obsługujące interfejs Vulkan są zgodne z Twoją grą.
Rekomendacje
Minimalne wymagania dotyczące obsługi Vulkan:
- urządzenie ma Androida 10.0 (interfejs API na poziomie 29) lub nowszego;
- Urządzenie obsługuje interfejs Vulkan API w wersji 1.1 lub nowszej.
- Urządzenie ma funkcje sprzętowe i funkcje zgodne z profilem podstawowym Androida z 2022 r.
Obsługa starszych urządzeń
Jeśli gra jest przeznaczona do działania na wielu urządzeniach o różnych możliwościach graficznych, może być konieczne obsługiwanie urządzeń starszych niż te zalecane w sekcji Wybieranie minimalnych specyfikacji urządzeń dla interfejsu Vulkan. Zanim zaczniesz tworzyć obsługę starszych urządzeń, oceń, czy Vulkan przyniesie korzyści Twojej grze. Gry, które mają wiele wywołań rysowania i używają OpenGL ES, mogą powodować znaczne obciążenie sterownika ze względu na wysoki koszt wywołań rysowania w OpenGL ES. Te gry mogą być ograniczone przez procesor, ponieważ spędzają dużą część czasu renderowania klatki w sterowniku graficznym. Gry mogą też znacznie zmniejszyć wykorzystanie procesora i energii, przechodząc z OpenGL ES na Vulkan. Jest to szczególnie przydatne, jeśli gra zawiera złożone sceny, w których nie można skutecznie używać instancji do zmniejszania liczby wywołań rysowania. Jeśli kierujesz reklamy na starsze urządzenia, uwzględnij obsługę renderowania OpenGL ES jako rozwiązanie zastępcze, ponieważ niektóre urządzenia na liście urządzeń docelowych mogą mieć implementacje Vulkan, które nie mogą niezawodnie uruchamiać gry.
Możesz nie chcieć obsługiwać starszych urządzeń z Vulkanem, ponieważ nie są one wystarczająco wydajne, nie mają odpowiednich funkcji lub mają problemy ze stabilnością.
Wydajność i funkcje
Starsze urządzenia z Androidem obsługujące Vulkan mogą nie mieć wydajności renderowania lub obsługi sprzętowej funkcji potrzebnych do uruchomienia gry. Jest to szczególnie prawdopodobne, jeśli gra ma wysokiej jakości grafikę, a Vulkan jest jedynym interfejsem API, którego używasz na Androidzie. Wiele starszych urządzeń obsługuje tylko wersję 1.0.3 interfejsu Vulkan API i często brakuje im powszechnie używanych rozszerzeń Vulkan dostępnych na nowocześniejszym sprzęcie.
Stabilność
Starsze urządzenia z Androidem mogą używać nieaktualnych sterowników Vulkan. Te wersje sterowników mogą zawierać błędy, które mogą wpływać na stabilność gry. Obejście błędów sterowników może wymagać znacznych nakładów czasu na testowanie i prace inżynieryjne.
Dodawanie Vulkan do projektu
Aby dodać Vulkan do projektu:
- Dołączanie nagłówków interfejsu Vulkan API
- Skompiluj kod cieniowania do SPIR-V
- Wywoływanie interfejsu Vulkan API w czasie działania
Dołączanie nagłówków interfejsu Vulkan API
Gra musi zawierać pliki nagłówkowe interfejsu Vulkan API, aby można było skompilować kod, który korzysta z Vulkana. Kopię nagłówków Vulkan znajdziesz w Android NDK lub w pakietach SDK Vulkan. Każda wersja NDK zawiera tylko nagłówki Vulkan dostępne w momencie wydania NDK. Jeśli używasz plików nagłówka Vulkan z NDK, użyj NDK w wersji 25 lub nowszej, która zawiera pliki nagłówka obsługujące Vulkan w wersji 1.3. Pakiet Vulkan SDK zawiera najnowszą wersję nagłówków.
Skompiluj kod cieniowania do SPIR-V
Interfejs Vulkan API oczekuje, że programy cieniujące będą dostarczane w pośrednim formacie binarnym SPIR-V. Ta konwencja różni się od OpenGL ES, gdzie można było przesyłać kod źródłowy napisany w języku cieniowania OpenGL (GLSL) jako ciągi tekstowe. Użyj kompilatora cieniowania, aby pobrać kod napisany w języku cieniowania, takim jak GLSL lub High-level Shader Language (HLSL), i skompilować go do modułów SPIR-V do użycia z Vulkanem.
Do kompilowania programów do cieniowania napisanych w GLSL do SPIR-V można użyć kompilatora shaderc. Jeśli gra używa HLSL, dane wyjściowe SPIR-V obsługuje DirectXShaderCompiler. Zwykle programy do cieniowania kompiluje się offline w ramach procesu tworzenia zasobów gry, a moduły SPIR-V dołącza się jako zasoby czasu działania.
Wywoływanie interfejsu Vulkan API w czasie działania
Aby wywołać interfejs Vulkan API, gra musi uzyskać wskaźniki funkcji do wywołań interfejsu Vulkan API. Najprostszym sposobem jest połączenie z biblioteką udostępnioną libvulkan.so, która jest dołączona do Androida NDK. Konsolidacja z biblioteką ma 2 wady: dodatkowe obciążenie związane z wywoływaniem funkcji i ograniczenia dotyczące wskaźników funkcji Vulkan API, które są automatycznie rozpoznawane.
Gdy wywołujesz funkcję interfejsu Vulkan API, kontrola przechodzi przez tabelę wysyłania zarządzaną przez konstrukcję zwaną modułem ładującym Vulkan. Android używa własnej implementacji programu ładującego Vulkan, a nie programu ładującego LunarG. Ten system wczytywania jest częścią architektury warstwowej interfejsu Vulkan API. Połączenie z biblioteką systemową w czasie kompilacji powoduje dodatkowy poziom wysyłania dla danego wywołania interfejsu API. Chociaż narzut jest niewielki, może być zauważalny w przypadku gier, które wykonują dużą liczbę wywołań Vulkan.
Biblioteka systemowa zwykle rozpoznaje tylko wskaźniki do funkcji Vulkan, które są uważane za część podstawowego interfejsu API. Vulkan ma wiele rozszerzeń, które definiują dodatkowe funkcje, z których wiele nie jest automatycznie rozwiązywanych przez bibliotekę systemową. Przed użyciem tych funkcji Vulkan musisz ręcznie rozwiązać wskaźniki do nich.
Aby uniknąć tych problemów, dynamicznie rozwiązuj wskaźniki do wszystkich funkcji Vulkan, których chcesz używać w czasie działania. Jednym ze sposobów jest użycie biblioteki meta-loader typu open source, takiej jak volk. W tym celu w przykładowej grze AGDKTunnel zintegrowano bibliotekę volk. Jeśli używasz biblioteki meta-loader, nie twórz w skryptach kompilacji linków do biblioteki udostępnionej libvulkan.so.
Określanie dostępnej wersji interfejsu Vulkan API
Android obsługuje te wersje interfejsu Vulkan API:
- 1.0.3
- 1.1
- 1.3
Najwyższy numer wersji interfejsu Vulkan API dostępny na danym urządzeniu jest określany przez wersję Androida i obsługę sterownika Vulkan.
Wersja Androida
Obsługa wersji interfejsu Vulkan API na platformie zależy od minimalnej wersji Androida (poziomu interfejsu API):
- 1.3 – Android 13.0 (poziom API 33) i nowsze
- 1.1 – Android 10.0 (poziom API 29) i nowsze wersje
- 1.0.3 – Android 7.0 (poziom interfejsu API 24) lub nowszy
Obsługa sterowników Vulkan
Obsługa wersji interfejsu Vulkan API na platformie Androida nie gwarantuje, że ta wersja interfejsu API jest obsługiwana przez sterownik Vulkan na urządzeniu. Urządzenie z Androidem 13 może obsługiwać tylko interfejs Vulkan API w wersji 1.1.
Podczas inicjowania interfejsu Vulkan nie proś o wersję interfejsu API wyższą niż:
- Maksymalna wersja interfejsu Vulkan API dla wersji Androida na urządzeniu.
- Wersja interfejsu Vulkan API zgłaszana przez vkEnumerateInstanceVersion
- Wersja interfejsu Vulkan API zgłaszana przez właściwość
apiVersionstruktury VkPhysicalDeviceProperties
Poniżej znajdziesz przykład określania najwyższej obsługiwanej wersji interfejsu Vulkan API:
// Minimum Android API levels for Vulkan 1.3/1.1 version support
static constexpr int kMinimum_vk13_api_level = 33;
static constexpr int kMinimum_vk11_api_level = 29;
uint32_t GetHighestSupportedVulkanVersion(VkPhysicalDevice physical_device) {
uint32_t instance_api_version = 0;
vkEnumerateInstanceVersion(&instance_api_version);
VkPhysicalDeviceProperties device_properties;
vkGetPhysicalDeviceProperties(physical_device, &device_properties);
// Instance and device versions don't have to match, use the lowest version
// number for API support if they don't.
const uint32_t driver_api_version =
(instance_api_version < device_properties.apiVersion) ?
instance_api_version : device_properties.apiVersion;
const int device_api_level = android_get_device_api_level();
if (device_api_level >= kMinimum_vk13_api_level &&
driver_api_version >= VK_API_VERSION_1_3) {
return VK_API_VERSION_1_3;
} else if (device_api_level >= kMinimum_vk11_api_level &&
driver_api_version >= VK_API_VERSION_1_1) {
return VK_API_VERSION_1_1;
}
return VK_API_VERSION_1_0;
}
Określanie zgodności profilu Vulkan
Profile Vulkan to pliki JSON, które definiują zestaw wymaganych funkcji, rozszerzeń, możliwości i minimalnych limitów parametrów, które urządzenie Vulkan musi obsługiwać, aby było zgodne z profilem. Aby sprawdzić, czy urządzenie jest zgodne z konkretnym profilem Vulkan, np. profilem Android Baseline z 2022 r., użyj biblioteki open source Vulkan Profiles API. Możesz też samodzielnie przeanalizować plik JSON profilu i sprawdzić możliwości urządzenia za pomocą odpowiednich interfejsów Vulkan API, aby określić zgodność profilu.
Profile Vulkan
Android używa profili Vulkan, które określają, jakie funkcje i rozszerzenia są dostępne na poszczególnych urządzeniach z Androidem.
Profil podstawowy Androida (ABP) to pierwsza próba utworzenia profilu Vulkan. ABP2021 i ABP2022 to profile retrospektywne, które mają obejmować ponad 85% aktywnych urządzeń w danym momencie. W przyszłości nie będzie nowych planów ABP.
Profile Vulkan na Androida (VPA) to nowy profil, który ma odzwierciedlać potrzeby deweloperów oprogramowania i zapewniać spójne funkcje, gdy tylko deweloperzy sprzętu będą mogli je dostarczyć. VPA15_minimums to pierwszy profil dla Androida 15. Co roku będzie pojawiać się nowy profil VPA, który będzie obejmować każdą główną wersję Androida.
Wdrażanie tempa klatek
Prawidłowe tempo klatek jest kluczowym elementem zapewniającym wysoką jakość rozgrywki. Android Game Development Kit zawiera bibliotekę Frame Pacing, która pomaga osiągnąć optymalną częstotliwość klatek w grze. Więcej informacji o implementacji znajdziesz w artykule Integracja Android Frame Pacing z rendererem Vulkan.
Nie polegaj na niejawnej synchronizacji i tempie klatek
vkAcquireNextImageKHR i vkQueuePresentKHR służą do zarządzania łańcuchem wymiany. Unikaj polegania na ich potencjalnym zachowaniu blokującym w przypadku ogólnej synchronizacji aplikacji lub GPU.
Dokładne działanie blokowania tych funkcji może się znacznie różnić w zależności od:
- Urządzenia z Androidem
- Sterowniki GPU
- Stany silnika prezentacji (VkPresentModeKHR)
Jedynym celem funkcji vkAcquireNextImageKHR jest uzyskanie dostępnego obrazu do wyświetlenia. Może ona blokować lub nie. Podobnie vkQueuePresentKHR kolejkuje żądanie wyświetlenia obrazu i może, ale nie musi, blokować.
Żadna z tych funkcji nie zapewnia niezawodnych gwarancji synchronizacji niepowiązanych zadań procesora ani operacji GPU.
Aby zapewnić niezawodną synchronizację, zawsze używaj jawnych elementów podstawowych Vulkan, takich jak semafory dla zależności GPU-GPU (np. renderowanie do prezentacji), bariery dla synchronizacji GPU-CPU (np. informacja o zakończeniu renderowania na CPU) oraz bariery potoku lub zdarzenia dla bardziej szczegółowych zależności wykonywania i pamięci GPU. Użycie jawnej synchronizacji zapewnia przewidywalne działanie i pozwala uniknąć subtelnych błędów spowodowanych przez różnice w czasie związane z implementacją, które są nieodłącznym elementem zróżnicowanego ekosystemu sprzętowego Androida.
Wdrażanie rotacji wstępnej
Urządzenia z Androidem mogą wyświetlać treści w różnych orientacjach. Orientacja urządzenia może się różnić od orientacji powierzchni renderowania. W przeciwieństwie do OpenGL ES na Androidzie Vulkan nie obsługuje rozbieżności między nimi. Aby dowiedzieć się, jak działa proces orientacji i jaka jest optymalna metoda obsługi różnic w orientacji podczas korzystania z Vulkana, przeczytaj artykuł Obsługa obracania urządzenia za pomocą wstępnego obracania w Vulkanie.
Rozwiązywanie problemów z renderowaniem w interfejsie Vulkan i profilowanie go
Dostępnych jest wiele narzędzi, które pomagają diagnozować problemy z renderowaniem i wydajnością kodu renderowania Vulkan.
Więcej informacji o narzędziach do debugowania i profilowania Vulkan znajdziesz w sekcji Narzędzia i funkcje zaawansowane.
Warstwy walidacji interfejsu Vulkan
Warstwy walidacji Vulkan to biblioteki środowiska wykonawczego, które można włączyć, aby sprawdzać wywołania interfejsu Vulkan API i wyświetlać ostrzeżenia lub błędy dotyczące nieprawidłowego lub nieoptymalnego użycia. Te warstwy walidacji nie są domyślnie aktywne, ponieważ proces walidacji zwiększa obciążenie w czasie działania i wpływa na wydajność gry. Informacje o tym, jak używać warstw walidacji w grze, znajdziesz w artykule Debugowanie z użyciem warstwy walidacji.
Narzędzia do przechwytywania klatek
Używaj narzędzi do przechwytywania klatek, aby nagrywać i odtwarzać wywołania interfejsu API Vulkan wykonywane podczas klatki gry. Te narzędzia umożliwiają:
- Wyświetlanie informacji o aktywnych zasobach graficznych i ich wizualizacji
- wyświetlać sekwencję wywołań interfejsu API wykonywanych przez grę oraz parametry interfejsu API;
- Sprawdzanie stanu potoku graficznego w momencie wywołania rysowania
- Wizualizacja wyników renderowania do określonego wywołania rysowania w ramce
Użyj narzędzia open source RenderDoc, aby przechwytywać klatki z gier uruchamianych na Androidzie. RenderDoc obsługuje przechwytywanie klatek zarówno w przypadku Vulkan, jak i OpenGL ES.
Do przechwytywania klatek Vulkan można też używać Android GPU Inspector (AGI).
Narzędzia do analizy skuteczności
Użyj narzędzi do analizy wydajności, aby zbadać problemy z renderowaniem w grze, które powodują nieoptymalną liczbę klatek. Poszczególni dostawcy GPU udostępniają narzędzia do profilowania gry i dostarczania danych o skuteczności związanych z ich architekturą GPU. Charakterystyka wydajności i wąskie gardła gry mogą się znacznie różnić w zależności od tego, czy renderowanie odbywa się na GPU różnych dostawców, czy nawet na GPU różnych generacji tego samego dostawcy.
Możesz też użyć Android GPU Inspector, aby zebrać i przeanalizować dane o wydajności. W przeciwieństwie do narzędzi dostawców Android GPU Inspector jest zgodny z wieloma GPU różnych dostawców. Android GPU Inspector nie obsługuje jednak starszych urządzeń z Androidem i może nie być zgodny ze wszystkimi nowymi urządzeniami.
Ulepszanie testowania interfejsu Vulkan za pomocą CTS-D
Producenci urządzeń z Androidem używają pakietu Compatibility Test Suite (CTS), aby zapewnić zgodność swoich urządzeń. Testy CTS opracowane przez deweloperów (CTS-D) to testy przesyłane przez deweloperów aplikacji na Androida, które mają na celu sprawdzenie, czy przyszłe urządzenia z Androidem będą spełniać ich wymagania i będą mogły płynnie i bez błędów uruchamiać ich aplikacje.
Jeśli uda Ci się wywołać nowy błąd w aplikacji Vulkan, który wpływa na konkretne urządzenie z Androidem, możesz przesłać nową propozycję testu, opisując problem i sposoby jego sprawdzenia. Dzięki temu problem zostanie rozwiązany w przyszłej aktualizacji urządzenia, a ten sam błąd nie wystąpi na innych urządzeniach.
Szczegółowe instrukcje przesyłania propozycji testu znajdziesz w opisie procesu przesyłania CTS.