Erste Schritte mit Vulkan unter Android
Vulkan ist die primäre Low-Level-Grafik-API für Android. Vulkan bietet optimale Leistung für Spiele, die eine eigene Spiel-Engine und einen eigenen Renderer implementieren.
Damit Sie Vulkan erfolgreich in Ihrer Game-Engine implementieren können, müssen Sie Folgendes tun:
- Android-Geräte für die Verwendung mit Vulkan identifizieren
- Kompromisse bei der Unterstützung älterer Android-Geräte
- Vulkan zum Android-Build-Ziel hinzufügen
- Shader-Compiler zum Erstellen von SPIR-V für Vulkan auswählen
- Verfügbare Vulkan API-Version zur Laufzeit ermitteln
- Hier erfährst du, wie du deine Vulkan-Rendering-Vorgänge mit Vulkan-Profilen, Frame-Pacing und Vorrotation optimieren kannst.
- Grafiktools für die Fehlerbehebung und Leistungsanalyse auswählen
- Hinweis: Informationen zur Verwendung von Vulkan auf Android-Geräten mit den Game-Engines Unity oder Unreal finden Sie hier:
- Vulkan in Unity
- Vulkan in Unreal
Mindestgerätespezifikationen für Vulkan auswählen
Vulkan ist ab Android 7.0 (API-Level 24) verfügbar. Nicht alle Android-Geräte mit Android 7.0 oder höher unterstützen Vulkan. Du musst festlegen, welche Vulkan-fähigen Android-Geräte dein Spiel unterstützt.
Empfehlungen
Die folgenden Spezifikationen sind die Mindestanforderungen für die Vulkan-Unterstützung:
- Auf dem Gerät ist Android 10.0 (API-Level 29) oder höher installiert.
- Das Gerät unterstützt Vulkan API-Version 1.1 oder höher.
- Das Gerät verfügt über Hardwarefunktionen und ‑merkmale, die mit dem Android-Baseline-Profil von 2022 kompatibel sind.
Unterstützung älterer Geräte
Wenn Ihr Spiel für eine Vielzahl von Geräten mit unterschiedlichen Grafikleistungen entwickelt wurde, müssen Sie möglicherweise Geräte unterstützen, die älter sind als die unter Mindestspezifikationen für Vulkan-Geräte auswählen empfohlenen Geräte. Bevor du die Unterstützung für ältere Geräte einrichtest, solltest du prüfen, ob Vulkan Vorteile für dein Spiel bietet. Bei Spielen mit vielen Zeichenbefehlen, die OpenGL ES verwenden, kann es aufgrund der hohen Kosten für Zeichenbefehle in OpenGL ES zu einem erheblichen Treiber-Overhead kommen. Diese Spiele können CPU-gebunden werden, da sie einen großen Teil ihrer Frame Time im Grafiktreiber verbringen. Durch den Wechsel von OpenGL ES zu Vulkan können auch die CPU- und Stromnutzung erheblich reduziert werden. Das gilt insbesondere, wenn Ihr Spiel komplexe Szenen hat, in denen Instanziierung nicht effektiv eingesetzt werden kann, um Zeichenbefehle zu reduzieren. Wenn du ältere Geräte als Zielgruppe hast, solltest du die OpenGL ES-Rendering-Unterstützung als Fallback einbeziehen, da einige Geräte in deiner Zielgeräteliste möglicherweise Vulkan-Implementierungen haben, auf denen dein Spiel nicht zuverlässig ausgeführt werden kann.
Möglicherweise möchtest du ältere Vulkan-fähige Geräte nicht unterstützen, weil sie nicht leistungsstark genug sind, Funktionen fehlen oder sie Stabilitätsprobleme haben.
Leistung und Funktionen
Ältere Vulkan-fähige Android-Geräte bieten möglicherweise nicht die Rendering-Leistung oder Hardwareunterstützung für Funktionen, die zum Ausführen deines Spiels erforderlich sind. Das ist besonders wahrscheinlich, wenn Ihr Spiel eine hochauflösende Grafik hat und Vulkan die einzige API ist, die Sie für Android verwenden. Viele ältere Geräte sind auf Version 1.0.3 der Vulkan API beschränkt und verfügen oft nicht über gängige Vulkan-Erweiterungen, die auf modernerer Hardware verfügbar sind.
Stabilität
Auf älteren Android-Geräten werden möglicherweise veraltete Vulkan-Treiber verwendet. Diese Treiberversionen können Fehler enthalten, die die Stabilität des Spiels beeinträchtigen. Die Behebung von Treiberfehlern kann erhebliche Test- und Entwicklungszeit in Anspruch nehmen.
Vulkan zu Ihrem Projekt hinzufügen
So fügen Sie Vulkan Ihrem Projekt hinzu:
- Vulkan API-Header einbinden
- Shader-Code in SPIR-V kompilieren
- Vulkan API zur Laufzeit aufrufen
Vulkan API-Header einbinden
Ihr Spiel muss die Vulkan API-Headerdateien enthalten, um Code zu kompilieren, der Vulkan verwendet. Eine Kopie der Vulkan-Header finden Sie im Android NDK oder in den Vulkan SDK-Releases. Eine bestimmte NDK-Version enthält nur Vulkan-Header, die zum Zeitpunkt des NDK-Release verfügbar waren. Wenn Sie Vulkan-Header aus dem NDK verwenden, verwenden Sie die NDK-Version 25 oder höher, die Header-Dateien enthält, die Vulkan-Version 1.3 unterstützen. Das Vulkan SDK enthält die aktuellste Version der Header.
Shader-Code in SPIR-V kompilieren
Die Vulkan API erwartet, dass Shader-Programme im binären SPIR-V-Zwischenformat bereitgestellt werden. Diese Konvention unterscheidet sich von OpenGL ES, wo Sie in der OpenGL Shading Language (GLSL) geschriebenen Quellcode als Textstrings einreichen konnten. Verwenden Sie einen Shader-Compiler, um Code, der in einer Shader-Sprache wie GLSL oder High-Level Shader Language (HLSL) geschrieben wurde, in SPIR-V-Module für die Verwendung mit Vulkan zu kompilieren.
Mit dem shaderc-Compiler können in GLSL geschriebene Shader-Programme in SPIR-V kompiliert werden. Wenn dein Spiel HLSL verwendet, unterstützt der DirectXShaderCompiler die SPIR-V-Ausgabe. In der Regel kompilieren Sie Shader-Programme offline im Rahmen des Asset-Build-Prozesses für Ihr Spiel und fügen die SPIR-V-Module als Teil Ihrer Laufzeit-Assets hinzu.
Vulkan API zur Laufzeit aufrufen
Damit Ihr Spiel die Vulkan API aufrufen kann, muss es Funktionszeiger für Vulkan API-Aufrufe abrufen. Am einfachsten ist es, eine Verknüpfung mit der gemeinsam genutzten Bibliothek libvulkan.so herzustellen, die im Android NDK enthalten ist. Das Verknüpfen mit der Bibliothek hat zwei Nachteile: zusätzlicher Overhead für die Funktionsverteilung und Einschränkungen bei der automatischen Auflösung von Vulkan API-Funktionszeigern.
Wenn Sie eine Vulkan API-Funktion aufrufen, wird die Steuerung über eine Dispatch-Tabelle übergeben, die von einem Konstrukt namens Vulkan-Loader verwaltet wird. Android verwendet eine eigene Vulkan-Ladeprogramm-Implementierung und nicht das LunarG-Ladeprogramm. Dieses Ladesystem ist Teil der Layer-Architektur der Vulkan API. Die Verknüpfung mit der Systembibliothek während des Build-Vorgangs führt zu einer zusätzlichen Dispatch-Ebene für einen bestimmten API-Aufruf. Der Overhead ist zwar gering, kann aber bei Spielen mit einer großen Anzahl von Vulkan-Aufrufen spürbar sein.
Die Systembibliothek löst in der Regel nur Verweise auf Vulkan-Funktionen auf, die als Teil der Kern-API gelten. Vulkan hat eine große Anzahl von Erweiterungen, die zusätzliche Vulkan-Funktionen definieren. Viele davon werden nicht automatisch von der Systembibliothek aufgelöst. Sie müssen Verweise auf diese Vulkan-Funktionen manuell auflösen, bevor Sie sie verwenden können.
Um diese Probleme zu beheben, lösen Sie Zeiger auf alle Vulkan-Funktionen, die Sie verwenden möchten, dynamisch zur Laufzeit auf. Eine Möglichkeit, dies zu erreichen, ist die Verwendung einer Open-Source-Meta-Loader-Bibliothek wie volk. Im Beispielspiel AGDKTunnel wird volk zu diesem Zweck eingebunden. Wenn Sie eine Meta-Loader-Bibliothek verwenden, verknüpfen Sie in Ihren Build-Skripts nicht die gemeinsam genutzte Bibliothek libvulkan.so.
Verfügbare Vulkan API-Version ermitteln
Android unterstützt die folgenden Vulkan API-Versionen:
- 1.0.3
- 1.1
- 1.3
Die höchste auf einem bestimmten Gerät verfügbare Vulkan API-Versionsnummer wird durch die Android-Version und die Unterstützung des Vulkan-Treibers bestimmt.
Android-Version
Die Plattformunterstützung für eine Vulkan API-Version hängt von einer Mindestversion von Android (API-Level) ab:
- 1.3 – Android 13.0 (API-Level 33) und höher
- 1.1 – Android 10.0 (API-Level 29) und höher
- 1.0.3 – Android 7.0 (API-Level 24) und höher
Vulkan-Treiberunterstützung
Die Unterstützung einer Vulkan API-Version durch die Android-Plattform garantiert nicht, dass die API-Version vom Vulkan-Treiber des Geräts unterstützt wird. Ein Gerät mit Android 13 unterstützt möglicherweise nur Version 1.1 der Vulkan API.
Fordere beim Initialisieren von Vulkan keine API-Version an, die höher ist als:
- Die maximale Vulkan API-Version für die Android-Version, die auf dem Gerät ausgeführt wird
- Die von vkEnumerateInstanceVersion gemeldete Vulkan API-Version
- Die Vulkan API-Version, die vom Attribut
apiVersionder Struktur VkPhysicalDeviceProperties gemeldet wird
Hier ist ein Beispiel für die Ermittlung der höchsten unterstützten Vulkan API-Version:
// 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;
}
Kompatibilität mit Vulkan-Profilen ermitteln
Vulkan-Profile sind JSON-Dateien, die eine Reihe von erforderlichen Funktionen, Erweiterungen, Fähigkeiten und Mindestparametergrenzen definieren, die ein Vulkan-Gerät unterstützen muss, um mit dem Profil kompatibel zu sein. Wenn Sie feststellen möchten, ob ein Gerät mit einem bestimmten Vulkan-Profil kompatibel ist, z. B. mit dem Android-Baseline-Profil von 2022, verwenden Sie die Open-Source-Vulkan Profiles API-Bibliothek. Du kannst die JSON-Datei des Profils auch selbst parsen und die Gerätefunktionen mit den entsprechenden Vulkan APIs abfragen, um die Profilkompatibilität zu ermitteln.
Vulkan-Profile
Android verwendet Vulkan-Profile, die festlegen, welche Funktionen und Erweiterungen für die einzelnen Android-Geräte verfügbar sind.
Das Android Baseline Profile (ABP) ist der erste Versuch, ein Vulkan-Profil zu erstellen. ABP2021 und ABP2022 sind rückwärtsgerichtete Profile, die mehr als 85% der damals aktiven Geräte abdecken sollen. Es wird keine neuen ABPs mehr geben.
Vulkan Profiles for Android (VPA) ist das neue zukunftsorientierte Profil, das die Anforderungen von Softwareentwicklern widerspiegeln und einheitliche Funktionen bieten soll, sobald Hardwareentwickler diese bereitstellen können. VPA15_minimums ist das erste Profil für Android 15. Jedes Jahr wird ein neues VPA veröffentlicht, um die jeweils neue Android-Hauptversion abzudecken.
Frame-Pacing implementieren
Ein korrektes Frame-Pacing ist ein wesentlicher Bestandteil eines hochwertigen Spielerlebnisses. Das Android Game Development Kit enthält die Frame Pacing-Bibliothek, mit der Sie ein optimales Frame Pacing für Ihr Spiel erzielen können. Weitere Informationen zur Implementierung findest du unter Android Frame Pacing in deinen Vulkan-Renderer einbinden.
Verlassen Sie sich nicht auf implizite Synchronisierung und Frame-Pacing
vkAcquireNextImageKHR und vkQueuePresentKHR werden zur Verwaltung der Swapchain verwendet. Verlassen Sie sich nicht auf ihr potenzielles Blockierverhalten für die allgemeine Anwendung oder GPU-Synchronisierung.
Das genaue Blockierverhalten dieser Funktionen kann sich erheblich unterscheiden:
- Android-Geräte
- GPU-Treiber
- Präsentations-Engine-Zustände (VkPresentModeKHR)
Der einzige Zweck von vkAcquireNextImageKHR besteht darin, ein verfügbares darstellbares Bild zu erhalten. Es kann blockiert werden oder nicht. In ähnlicher Weise stellt vkQueuePresentKHR eine Anfrage zum Anzeigen eines Bildes in die Warteschlange und kann blockieren oder auch nicht.
Keine der beiden Funktionen bietet zuverlässige Garantien für die Synchronisierung von nicht zusammenhängenden CPU-Aufgaben oder GPU-Vorgängen.
Für eine robuste Synchronisierung sollten Sie immer explizite Vulkan-Primitive verwenden, z. B. Semaphoren für GPU-GPU-Abhängigkeiten (z. B. Render-to-Present), Fences für die GPU-CPU-Synchronisierung (z. B. um zu wissen, wann das Rendering auf der CPU abgeschlossen ist) und Pipeline-Barrieren oder Ereignisse für feiner abgestufte GPU-Ausführungs- und Speicherabhängigkeiten. Die explizite Synchronisierung sorgt für ein vorhersehbares Verhalten und vermeidet subtile Fehler, die durch implementierungsspezifische Timing-Variationen im vielfältigen Hardware-Ökosystem von Android verursacht werden.
Vorabrotation implementieren
Android-Geräte können in mehreren Ausrichtungen angezeigt werden. Die Geräteausrichtung kann sich von der Ausrichtung der Rendering-Oberfläche unterscheiden. Im Gegensatz zu OpenGL ES unter Android werden Abweichungen zwischen den beiden von Vulkan nicht verarbeitet. Informationen zur Funktionsweise des Ausrichtungsprozesses und zur optimalen Methode für den Umgang mit Ausrichtungsunterschieden bei der Verwendung von Vulkan finden Sie unter Gerätedrehung mit Vulkan-Vordrehung verarbeiten.
Fehlerbehebung und Profilerstellung für Vulkan-Rendering
Es stehen mehrere Tools zur Verfügung, mit denen Sie Rendering- und Leistungsprobleme mit Vulkan-Rendering-Code diagnostizieren können.
Weitere Informationen zu den Debugging- und Profiling-Tools von Vulkan findest du im Abschnitt Tools und erweiterte Funktionen.
Vulkan-Validierungslayer
Vulkan-Validierungslayer sind Laufzeitbibliotheken, die aktiviert werden können, um Ihre Aufrufe der Vulkan API zu prüfen und Warnungen oder Fehler bei falscher oder nicht optimaler Verwendung auszugeben. Diese Validierungslayer sind standardmäßig nicht aktiv, da der Validierungsprozess die Laufzeit erhöht und die Leistung des Spiels beeinträchtigt. Informationen zur Verwendung von Validierungslayern in deinem Spiel findest du unter Debugging mit Validierungslayer.
Tools für die Frame-Aufnahme
Verwende Frame-Capture-Tools, um die Vulkan API-Aufrufe aufzuzeichnen und wiederzugeben, die während eines Spielframes erfolgen. Mit diesen Tools können Sie Folgendes tun:
- Informationen zu und Visualisierungen von aktiven Grafikressourcen ansehen
- Abfolge der API-Aufrufe Ihres Spiels und die API-Parameter ansehen
- Status der Grafikpipeline zum Zeitpunkt eines Zeichenbefehls untersuchen
- Ergebnisse des Renderings bis zu einem bestimmten Zeichenbefehl im Frame visualisieren
Mit dem Open-Source-Tool RenderDoc kannst du Frames aus Spielen erfassen, die auf Android ausgeführt werden. RenderDoc unterstützt die Frame-Erfassung sowohl von Vulkan als auch von OpenGL ES.
Der Android GPU Inspector (AGI) kann auch zum Erfassen von Vulkan-Frames verwendet werden.
Tools zur Leistungsanalyse
Verwenden Sie Tools zur Leistungsanalyse, um Rendering-Probleme in Ihrem Spiel zu untersuchen, die zu suboptimalen Frameraten führen. Die einzelnen GPU-Anbieter stellen Tools bereit, mit denen du dein Spiel profilieren und Leistungsdaten speziell für ihre GPU-Architekturen abrufen kannst. Die Leistungsmerkmale und Engpässe Ihres Spiels können sich erheblich unterscheiden, wenn es auf GPUs von verschiedenen Anbietern oder sogar auf verschiedenen GPU-Generationen desselben Anbieters gerendert wird.
Sie können auch den Android GPU Inspector verwenden, um Leistungsdaten zu erfassen und zu analysieren. Im Gegensatz zu den Tools der Anbieter ist Android GPU Inspector mit mehreren GPUs von verschiedenen Anbietern kompatibel. Der Android GPU Inspector unterstützt jedoch keine älteren Android-Geräte und ist möglicherweise nicht mit allen neuen Geräten kompatibel.
Vulkan-Tests mit CTS-D verbessern
Hersteller von Android-Geräten verwenden die Compatibility Test Suite (CTS), um die Kompatibilität ihrer Geräte zu gewährleisten. Developer-Powered CTS (CTS-D) sind Tests, die von Android-App-Entwicklern eingereicht werden, um sicherzustellen, dass zukünftige Android-Geräte ihre Anwendungsfälle erfüllen und ihre Apps reibungslos und ohne Fehler ausführen können.
Wenn du mit deiner Vulkan-Anwendung einen neuen Fehler auslöst, der ein bestimmtes Android-Gerät betrifft, kannst du einen neuen Testvorschlag einreichen, in dem du das Problem und die Möglichkeiten zur Überprüfung beschreibst. So wird sichergestellt, dass das Problem in einem zukünftigen Update für das Gerät behoben wird und dass derselbe Fehler nicht auf anderen Geräten auftritt.
Eine detaillierte Anleitung zum Einreichen des Testvorschlags finden Sie im CTS-Einreichungsprozess.