Vulkan implementieren

Vulkan ist eine plattformübergreifende API mit geringem Overhead für leistungsstarke 3D-Grafiken. Wie OpenGL ES (GLES) bietet Vulkan Tools zum Erstellen hochwertiger Echtzeitgrafiken in Apps. Zu den Vorteilen der Verwendung von Vulkan gehören die Reduzierung des CPU-Overheads und die Unterstützung der Sprache SPIR-V Binary Intermediate .

Um Vulkan erfolgreich zu implementieren, muss ein Gerät Folgendes enthalten:

  • Der Vulkan-Loader, bereitgestellt von Android.
  • Ein Vulkan-Treiber, der von SoCs wie GPU-IHVs bereitgestellt wird und die Vulkan-API implementiert. Um die Vulkan-Funktionalität zu unterstützen, benötigt das Android-Gerät Vulkan-fähige GPU-Hardware und den zugehörigen Treiber. Die GPU muss außerdem GLES 3.1 und höher unterstützen. Wenden Sie sich an Ihren SoC-Anbieter, um Treiberunterstützung anzufordern.

Wenn ein Gerät einen Vulkan-Treiber enthält, muss das Gerät die FEATURE_VULKAN_HARDWARE_LEVEL und FEATURE_VULKAN_HARDWARE_VERSION mit Versionen deklarieren, die die Fähigkeiten des Geräts genau widerspiegeln. Dadurch wird sichergestellt, dass das Gerät dem Compatibility Definition Document (CDD) entspricht.

Vulkan-Loader

Die Vulkan-Loader- platform/frameworks/native/vulkan ist die primäre Schnittstelle zwischen Vulkan-Apps und dem Vulkan-Treiber eines Geräts. Der Vulkan-Loader wird unter /system/lib[64]/libvulkan.so installiert. Der Loader stellt die zentralen Einstiegspunkte der Vulkan-API sowie die Einstiegspunkte von Erweiterungen bereit, die von der Android-CDD benötigt werden. Window System Integration (WSI)-Erweiterungen werden vom Loader exportiert und hauptsächlich im Loader und nicht im Treiber implementiert. Der Loader unterstützt auch das Aufzählen und Laden von Schichten, die zusätzliche Erweiterungen verfügbar machen und Kern-API-Aufrufe auf ihrem Weg zum Treiber abfangen können.

Das NDK enthält eine Stub libvulkan.so Bibliothek zum Verlinken. Die Bibliothek exportiert die gleichen Symbole wie der Loader. Apps rufen die aus der echten libvulkan.so Bibliothek exportierten Funktionen auf, um Trampolinfunktionen in den Loader einzugeben, die basierend auf ihrem ersten Argument an die entsprechende Ebene oder den entsprechenden Treiber gesendet werden. Der vkGet*ProcAddr() Aufruf gibt die Funktionszeiger zurück, an die die Trampoline senden (d. h. er ruft direkt in den Kern-API-Code auf). Der Aufruf über die Funktionszeiger anstelle der exportierten Symbole ist effizienter, da Trampolin und Dispatch übersprungen werden.

Treiberaufzählung und Laden

Wenn das Systemabbild erstellt wird, erwartet Android, dass das System weiß, welche GPUs verfügbar sind. Der Loader verwendet den vorhandenen HAL-Mechanismus in hardware.h , um den Treiber zu erkennen und zu laden. Bevorzugte Pfade für 32-Bit- und 64-Bit-Vulkan-Treiber sind:

/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

In Android 7.0 und höher umschließt das Vulkan hw_module_t Derivat eine einzelne hw_module_t Struktur; Es wird nur ein Treiber unterstützt und die Konstantenzeichenfolge HWVULKAN_DEVICE_0 wird an open() übergeben.

Das Vulkan hw_device_t Derivat entspricht einem einzelnen Treiber, der mehrere physische Geräte unterstützen kann. Die Struktur hw_device_t kann erweitert werden, um die vkGetGlobalExtensionProperties() , vkCreateInstance() und vkGetInstanceProcAddr() zu exportieren. Der Lader kann alle anderen VkInstance() -, VkPhysicalDevice() - und vkGetDeviceProcAddr() -Funktionen finden, indem er die vkGetInstanceProcAddr() -Struktur der hw_device_t -Struktur vkGetInstanceProcAddr() .

Layer-Erkennung und -Laden

Der Vulkan-Loader unterstützt das Aufzählen und Laden von Schichten, die zusätzliche Erweiterungen verfügbar machen und Kern-API-Aufrufe auf ihrem Weg zum Treiber abfangen können. Android fügt dem Systemabbild keine Ebenen hinzu; Apps können jedoch Ebenen in ihrem APK enthalten.

Beachten Sie bei der Verwendung von Ebenen, dass sich das Sicherheitsmodell und die Richtlinien von Android erheblich von denen anderer Plattformen unterscheiden. Insbesondere erlaubt Android weder das Laden von externem Code in einen nicht debuggbaren Prozess auf Produktionsgeräten (nicht gerootet) noch erlaubt es externem Code, den Speicher, Zustand usw. des Prozesses zu inspizieren oder zu steuern. Dazu gehört ein Verbot, Core-Dumps, API-Traces usw. zur späteren Überprüfung auf der Festplatte zu speichern. Auf Produktionsgeräten sind nur Ebenen aktiviert, die als Teil von nicht debugfähigen Apps bereitgestellt werden, und Treiber dürfen keine Funktionen bereitstellen, die gegen diese Richtlinien verstoßen.

Zu den Anwendungsfällen für Ebenen gehören:

  • Entwicklungszeitschichten – Validierungsschichten und Shims für Ablaufverfolgungs-/Profilerstellungs-/Debugging-Tools sollten nicht auf dem Systemabbild von Produktionsgeräten installiert werden. Validierungsschichten und Shims für Tracing-/Profilerstellungs-/Debugging-Tools sollten ohne Systemabbild aktualisierbar sein. Entwickler, die eine dieser Schichten während der Entwicklung verwenden möchten, können das App-Paket ändern, indem sie beispielsweise eine Datei zu ihrem nativen Bibliotheksverzeichnis hinzufügen. IHV- und OEM-Ingenieure, die Fehler bei der Auslieferung nicht modifizierbarer Apps diagnostizieren möchten, haben vermutlich Zugriff auf nicht produktive (gerootete) Builds des Systemabbilds, es sei denn, diese Apps sind debugfähig. Weitere Informationen finden Sie unter Vulkan-Validierungsebenen auf Android .
  • Utility-Layer – Diese Layer stellen Erweiterungen bereit, z. B. einen Layer, der einen Speichermanager für den Gerätespeicher implementiert. Entwickler wählen Ebenen und Versionen dieser Ebenen aus, die sie in ihrer App verwenden möchten. Verschiedene Apps, die dieselbe Ebene verwenden, können dennoch unterschiedliche Versionen verwenden. Entwickler wählen aus, welche dieser Ebenen in ihrem App-Paket ausgeliefert werden sollen.
  • Injizierte (implizite) Ebenen – Umfasst Ebenen wie Bildrate, soziale Netzwerke und Game Launcher-Overlays, die vom Benutzer oder einer anderen App ohne Wissen oder Zustimmung der App bereitgestellt werden. Diese verstoßen gegen die Sicherheitsrichtlinien von Android und werden nicht unterstützt.

Bei nicht debugfähigen Apps sucht der Loader nur im nativen Bibliotheksverzeichnis der App nach Ebenen und versucht, jede Bibliothek mit einem Namen zu laden, der einem bestimmten Muster entspricht (z. B. libVKLayer_foo.so ).

Bei debugfähigen Apps sucht der Loader nach Ebenen in /data/local/debug/vulkan und versucht, jede Bibliothek zu laden, die einem bestimmten Muster entspricht.

Android ermöglicht die Portierung von Layern mit Änderungen der Build-Umgebung zwischen Android und anderen Plattformen. Einzelheiten zur Schnittstelle zwischen Layern und dem Loader finden Sie unter Architecture of the Vulkan Loader Interfaces . Die von Khronos verwalteten Validierungsschichten werden in Vulkan Validation Layers gehostet.

Versionen und Funktionen der Vulkan-API

Android 9 und höher unterstützen die Vulkan-API-Version 1.1. Android 7 bis Android 9 unterstützen die Vulkan-API-Version 1.0. Weitere Informationen zur Vulkan 1.1-API finden Sie in der Vulkan 1.1-API-Spezifikation .

Überblick über die Unterstützung von Vulkan 1.1

Vulkan 1.1 umfasst Unterstützung für Speicher-/Synchronisierungs-Interop, wodurch OEMs Vulkan 1.1 auf Geräten unterstützen können. Darüber hinaus ermöglicht die Speicher-/Synchronisierungs-Interop den Entwicklern, festzustellen, ob Vulkan 1.1 auf einem Gerät unterstützt wird, und es effektiv zu nutzen, wenn dies der Fall ist. Vulkan 1.1 hat die gleichen Hardwareanforderungen wie Vulkan 1.0, aber der größte Teil der Implementierung befindet sich im SOC-spezifischen Grafiktreiber, nicht im Framework.

Die wichtigsten Funktionen von Vulkan 1.1 für Android sind:

  • Unterstützung für den Import und Export von Speicherpuffern und Synchronisierungsobjekten von außerhalb von Vulkan (für Interop mit Kamera, Codecs und GLES)
  • Unterstützung für YCbCr-Formate

Vulkan 1.1 enthält auch mehrere kleinere Funktionen und Verbesserungen der API-Benutzerfreundlichkeit.

Implementierung von Vulkan 1.1

Android-Geräte sollten Vulkan 1.1 unterstützen, wenn sie:

  • Starten Sie mit Android 10.
  • Unterstützt eine 64-Bit-ABI.
  • Sind nicht wenig Speicher.

Andere Geräte können optional Vulkan 1.1 unterstützen.

So implementieren Sie Vulkan 1.1:

  1. Fügen Sie einen Vulkan-Treiber hinzu, der Vulkan 1.1 plus die zusätzlichen CDD-Anforderungen für Android 1.1 unterstützt, oder aktualisieren Sie den vorhandenen Vulkan 1.0-Treiber.
  2. Stellen Sie sicher, dass PackageManager#hasSystemFeature(PackageManager.FEATURE_VULKAN_HARDWARE_VERSION, 0x401000) true zurückgibt, indem Sie einer entsprechenden device.mk -Datei eine Regel wie die folgende hinzufügen:
    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
    

Fenstersystemintegration (WSI)

In libvulkan.so implementiert der Treiber die folgenden Erweiterungen der Window System Integration (WSI):

  • VK_KHR_surface
  • VK_KHR_android_surface
  • VK_KHR_swapchain
  • VK_KHR_driver_properties , nur für Vulkan 1.1 in Android 10 implementiert
  • VK_GOOGLE_display_timing , implementiert für jede Vulkan-Version in Android 10

Die VkSurfaceKHR und VkSwapchainKHR Objekte und alle Interaktionen mit ANativeWindow werden von der Plattform gehandhabt und sind nicht für Treiber verfügbar. Die WSI-Implementierung stützt sich auf die VK_ANDROID_native_buffer Erweiterung, die vom Treiber unterstützt werden muss; Diese Erweiterung wird nur von der WSI-Implementierung verwendet und ist nicht für Apps verfügbar.

Gralloc-Nutzungs-Flags

Vulkan-Implementierungen benötigen möglicherweise Swapchain-Puffer, die mit implementierungsdefinierten privaten Gralloc-Nutzungs-Flags zugewiesen werden müssen. Beim Erstellen einer Swapchain fordert Android den Treiber auf, das angeforderte Format und die Bildnutzungs-Flags in Gralloc-Nutzungs-Flags zu übersetzen, indem es aufruft:

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
);

Die Parameter format und imageUsage stammen aus der VkSwapchainCreateInfoKHR Struktur. Der Treiber sollte *grallocConsumerUsage und *grallocProducerUsage mit den für das Format und die Verwendung erforderlichen Gralloc-Verwendungsflags füllen. Die vom Treiber zurückgegebenen Verwendungs-Flags werden mit den vom Swapchain-Verbraucher angeforderten Verwendungs-Flags kombiniert, wenn Puffer zugewiesen werden.

Android 7.x ruft eine frühere Version von VkSwapchainImageUsageFlagsANDROID() mit dem Namen vkGetSwapchainGrallocUsageANDROID() . Android 8.0 und höher veraltet vkGetSwapchainGrallocUsageANDROID() , ruft aber immer noch vkGetSwapchainGrallocUsageANDROID() auf, wenn vkGetSwapchainGrallocUsage2ANDROID() nicht vom Treiber bereitgestellt wird:

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

vkGetSwapchainGrallocUsageANDROID() unterstützt keine Swapchain-Verwendungs-Flags oder erweiterte Gralloc-Verwendungs-Flags.

Gralloc-unterstützte Bilder

VkNativeBufferANDROID ist eine vkCreateImage Erweiterungsstruktur zum Erstellen eines Bildes, das von einem Gralloc-Puffer unterstützt wird. VkNativeBufferANDROID wird vkCreateImage() in der VkImageCreateInfo Strukturkette bereitgestellt. Aufrufe von vkCreateImage() mit VkNativeBufferANDROID während des Aufrufs von vkCreateSwapchainKHR . Die WSI-Implementierung weist die Anzahl der für die Swapchain angeforderten nativen Puffer zu und erstellt dann für jeden ein 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;

Beim Erstellen eines Gralloc-gestützten Images hat VkImageCreateInfo die folgenden Daten:

  .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

In Android 8.0 und höher stellt die Plattform eine VkSwapchainImageCreateInfoKHR Erweiterungsstruktur in der VkImageCreateInfo -Kette bereit, die für vkCreateImage bereitgestellt wird, wenn Flags für die Verwendung von Swapchain-Images für die Swapchain erforderlich sind. Die Erweiterungsstruktur enthält die Swapchain-Image-Verwendungs-Flags:

typedef struct {
    VkStructureType                        sType; // must be VK_STRUCTURE_TYPE_SWAPCHAIN_IMAGE_CREATE_INFO_ANDROID
    const void*                            pNext;

    VkSwapchainImageUsageFlagsANDROID      usage;
} VkSwapchainImageCreateInfoANDROID;

In Android 10 und höher unterstützt die Plattform VK_KHR_swapchain v70, sodass die Vulkan-App ein durch VkImage -Speicher gesichertes VkImage erstellen kann. Die App ruft zuerst vkCreateImage mit einer VkImageSwapchainCreateInfoKHR Struktur auf, die mit der VkImageCreateInfo -Struktur verkettet ist. Dann ruft die App vkBindImageMemory2(KHR) mit einer VkBindImageMemorySwapchainInfoKHR Struktur auf, die mit der VkBindImageMemoryInfo -Struktur verkettet ist. Der in der imageIndex -Struktur angegebene VkBindImageMemorySwapchainInfoKHR muss ein gültiger Swapchain-Bildindex sein. In der Zwischenzeit stellt die Plattform eine VkNativeBufferANDROID Erweiterungsstruktur mit den entsprechenden Gralloc-Pufferinformationen für die VkBindImageMemoryInfo -Kette bereit, sodass der Treiber weiß, an welchen Gralloc-Puffer das VkImage werden soll.

Bilder beschaffen

vkAcquireImageANDROID erwirbt das Eigentum an einem Swapchain-Image und importiert einen extern signalisierten nativen Zaun sowohl in ein vorhandenes VkSemaphore Objekt als auch in ein vorhandenes VkFence Objekt:

VkResult VKAPI vkAcquireImageANDROID(
    VkDevice            device,
    VkImage             image,
    int                 nativeFenceFd,
    VkSemaphore         semaphore,
    VkFence             fence
);

vkAcquireImageANDROID() wird während vkAcquireNextImageKHR , um einen nativen Zaun in die von der App bereitgestellten VkSemaphore und VkFence Objekte zu importieren (bei diesem Aufruf sind jedoch sowohl Semaphor- als auch Fence-Objekte optional). Der Treiber kann diese Gelegenheit auch nutzen, um externe Änderungen des Gralloc-Pufferzustands zu erkennen und zu handhaben; Viele Fahrer müssen hier nichts tun. Dieser Aufruf versetzt VkSemaphore und VkFence in denselben ausstehenden Zustand, als ob sie von vkQueueSubmit signalisiert würden, sodass Warteschlangen auf das Semaphor und die App auf den Zaun warten können.

Beide Objekte werden signalisiert, wenn der darunter liegende native Zaun signalisiert; Wenn der native Zaun bereits signalisiert hat, befindet sich die Semaphore im signalisierten Zustand, wenn diese Funktion zurückkehrt. Der Treiber übernimmt den Besitz des Fence-Dateideskriptors und schließt den Fence-Dateideskriptor, wenn er nicht mehr benötigt wird. Der Treiber muss dies auch dann tun, wenn weder ein Semaphor- noch ein Fence-Objekt bereitgestellt wird oder selbst wenn vkAcquireImageANDROID fehlschlägt und einen Fehler zurückgibt. Wenn fenceFd -1 ist, ist es so, als ob der native Zaun bereits signalisiert wurde.

Bilder freigeben

vkQueueSignalReleaseImageANDROID bereitet ein Swapchain-Image für die externe Verwendung vor, erstellt einen nativen Zaun und plant, dass der native Zaun signalisiert wird, nachdem die Eingabe-Semaphoren signalisiert haben:

VkResult VKAPI vkQueueSignalReleaseImageANDROID(
    VkQueue             queue,
    uint32_t            waitSemaphoreCount,
    const VkSemaphore*  pWaitSemaphores,
    VkImage             image,
    int*                pNativeFenceFd
);

vkQueuePresentKHR() ruft vkQueueSignalReleaseImageANDROID() in der bereitgestellten Warteschlange auf. Der Treiber muss einen nativen Zaun erzeugen, der kein Signal gibt, bis alle waitSemaphoreCount Semaphoren in pWaitSemaphores signalisieren, und alle zusätzlichen Arbeiten, die erforderlich sind, um image für die Präsentation vorzubereiten, abgeschlossen sind.

Wenn die Wartesemaphore (falls vorhanden) bereits signalisiert haben und die queue bereits im Leerlauf ist, kann der Treiber *pNativeFenceFd auf -1 anstelle eines tatsächlichen nativen Fence-Dateideskriptors setzen, was anzeigt, dass es nichts zu warten gibt. Der Aufrufer besitzt und schließt den in *pNativeFenceFd zurückgegebenen Dateideskriptor.

Viele Treiber können den Bildparameter ignorieren, aber einige müssen möglicherweise CPU-seitige Datenstrukturen vorbereiten, die einem Gralloc-Puffer für die Verwendung durch externe Bildkonsumenten zugeordnet sind. Das Vorbereiten von Pufferinhalten für die Verwendung durch externe Verbraucher sollte asynchron als Teil des Übergangs des Bildes zu VK_IMAGE_LAYOUT_PRESENT_SRC_KHR .

Wenn das Bild mit VK_SWAPCHAIN_IMAGE_USAGE_SHARED_BIT_ANDROID erstellt wurde, muss der Treiber zulassen, dass vkQueueSignalReleaseImageANDROID() wiederholt aufgerufen wird, ohne Aufrufe von vkAcquireImageANDROID() .

Unterstützung für gemeinsam präsentierbare Bilder

Einige Geräte können den Besitz eines einzelnen Bildes zwischen der Display-Pipeline und der Vulkan-Implementierung teilen, um die Latenz zu minimieren. In Android 9 und höher kündigt der Loader die Erweiterung VK_KHR_shared_presentable_image bedingt an, basierend auf der Antwort des Treibers auf einen Aufruf von vkGetPhysicalDeviceProperties2 .

Wenn der Treiber weder Vulkan 1.1 noch die Erweiterung VK_KHR_physical_device_properties2 unterstützt, kündigt der Loader keine Unterstützung für gemeinsam präsentierbare Bilder an. Andernfalls fragt der Loader die Treiberfunktionen ab, indem er vkGetPhysicalDeviceProperties2() und die folgende Struktur in die VkPhysicalDeviceProperties2::pNext -Kette einfügt:

typedef struct {
    VkStructureType sType; // must be VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENTATION_PROPERTIES_ANDROID
    const void*     pNext;
    VkBool32        sharedImage;
} VkPhysicalDevicePresentationPropertiesANDROID;

Wenn der Treiber den Besitz eines Bildes mit dem Anzeigesystem teilen kann, setzt er das sharedImage auf VK_TRUE .

Validierung

OEMs können ihre Vulkan-Implementierung mit CTS testen, was Folgendes beinhaltet:

  • Khronos Vulkan-Konformitätstests im CtsDeqpTestCases -Modul, die funktionale API-Tests für Vulkan 1.0 und 1.1 umfassen.
  • Das CtsGraphicsTestCases -Modul, das testet, ob das Gerät korrekt für die von ihm unterstützten Vulkan-Funktionen konfiguriert ist.

Vulkan-Feature-Flag

Ein Gerät, das Android 11 oder höher und die Vulkan-API unterstützt, muss ein Feature-Flag, android.software.vulkan.deqp.level , verfügbar machen. Der Wert dieses Feature-Flags ist ein Datum, das als ganzzahliger Wert codiert ist. Es gibt das Datum an, das mit den Vulkan dEQP-Tests verbunden ist, die das Gerät angeblich bestanden hat.

Ein Datum im Format JJJJ-MM-TT wird wie folgt als 32-Bit-Ganzzahl codiert:

  • Die Bits 0-15 speichern das Jahr
  • Die Bits 16-23 speichern den Monat
  • Die Bits 24-31 speichern den Tag

Der zulässige Mindestwert für das Feature-Flag ist 0x07E30301 , was dem Datum 2019-03-01 entspricht, dem Datum, das mit den Vulkan-dEQP-Tests für Android 10 verknüpft ist. Wenn das Feature-Flag mindestens diesen Wert hat, behauptet das Gerät alle dEQP-Tests von Android 10 Vulkan bestehen.

Der Wert 0x07E40301 entspricht dem Datum 2020-03-01, dem Datum, das mit den Vulkan-dEQP-Tests für Android 11 verknüpft ist. Wenn das Feature-Flag mindestens diesen Wert hat, behauptet das Gerät, alle Android-11-Vulkan-dEQP-Tests zu bestehen.

Wenn der Wert des Feature-Flags mindestens 0x07E30301 , aber weniger als 0x07E40301 , bedeutet dies, dass das Gerät behauptet, alle Vulkan dEQP-Tests von Android 10 zu bestehen, aber nicht garantiert, dass es die für Android 11 hinzugefügten Vulkan dEQP-Tests besteht.

Vulkan dEQP ist Teil von Android CTS. Ab Android 11 kennt die android.software.vulkan.deqp.level -Test-Runner-Komponente von CTS das Feature-Flag android.software.vulkan.deqp.level und überspringt alle Vulkan-dEQP-Tests, die – gemäß diesem Feature-Flag – das Gerät angeblich nicht unterstützt. Solche Tests werden als trivial bestanden gemeldet.