Vulkan to wieloplatformowy interfejs API o niskim obciążeniu, który umożliwia tworzenie wydajnych grafik 3D. Podobnie jak OpenGL ES (GLES), Vulkan udostępnia narzędzia do tworzenia wysokiej jakości grafik w czasie rzeczywistym w aplikacjach. Zalety używania Vulkana to m.in. zmniejszenie obciążenia procesora i obsługa języka SPIR-V Binary Intermediate.
Aby można było wdrożyć Vulkan, urządzenie musi zawierać:
- Ładowarka Vulkana, udostępniana przez Androida.
- Sterownik Vulkana udostępniany przez SoC, np. przez dostawców interfejsu IHV GPU, który implementuje interfejs Vulkan API. Aby obsługiwać funkcję Vulkan, urządzenie z Androidem musi mieć kartę graficzną z obsługą Vulkan i powiązany z nią sterownik. Karta graficzna musi też obsługiwać GLES 3.1 lub nowszą. Aby uzyskać pomoc dotyczącą sterownika, skontaktuj się z dostawcą SoC.
Jeśli urządzenie zawiera sterownik Vulkan, musi deklarować funkcje systemu FEATURE_VULKAN_HARDWARE_LEVEL
i FEATURE_VULKAN_HARDWARE_VERSION
w wersjach, które dokładnie odzwierciedlają możliwości urządzenia. Dzięki temu możesz mieć pewność, że urządzenie jest zgodne z dokumentem z definicją zgodności (CDD).
Ładowarka Vulkan
Ładowarka Vulkana platform/frameworks/native/vulkan
to główny interfejs między aplikacjami Vulkan a sterownikami Vulkana na urządzeniu. Wczytnik Vulkan jest zainstalowany w /system/lib[64]/libvulkan.so
. Ładowarka udostępnia główne punkty wejścia interfejsu Vulkan API, punkty wejścia rozszerzeń wymagane przez specyfikację Android CDD oraz wiele dodatkowych opcjonalnych rozszerzeń. Rozszerzenia integracji z systemem operacyjnym (WSI) są eksportowane przez ładowarkę i głównie są implementowane w ładowarce, a nie w sterowniku. Obsługuje on też warstwy wczytywania i wyliczania, które mogą udostępniać dodatkowe rozszerzenia oraz przechwytywać wywołania interfejsu API na drodze do sterownika.
Pakiet NDK zawiera bibliotekę z kropką libvulkan.so
do łączenia. Biblioteka eksportuje te same symbole co ładowarka. Aplikacje wywołują funkcje wyeksportowane z rzeczywistej biblioteki libvulkan.so
, by wprowadzić w ładowarce funkcje trampolin, które wysyłają je do odpowiedniej warstwy lub sterownika na podstawie pierwszego argumentu. Wywołanie vkGet*ProcAddr()
zwraca wskaźniki funkcji, do których odsyłają trampoliny (czyli wywołuje bezpośrednio kod interfejsu API). Wywoływanie za pomocą wskaźników funkcji zamiast wyeksportowanych symboli jest bardziej wydajne, ponieważ pomija trampolinę i wysyłanie.
Wyliczanie i wczytywanie sterowników
Podczas tworzenia obrazu systemu Android oczekuje, że system będzie wiedział, które GPU jest dostępne. Moduł ładowania korzysta z istniejącego mechanizmu HAL w hardware.h
do wykrywania i wczytywania sterownika. Preferowane ścieżki dla 32- i 64-bitowych sterowników Vulkan:
/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
W Androidzie 7.0 i nowszych pochodna Vulkana hw_module_t
obejmuje pojedynczą strukturę hw_module_t
; obsługiwany jest tylko 1 sterownik, a ciąg znaków stałych HWVULKAN_DEVICE_0
jest przekazywany do funkcji open()
.
Pochodna interfejsu Vulkan hw_device_t
odpowiada jednemu kierowcy, który może obsługiwać wiele urządzeń fizycznych. Struktura hw_device_t
może obejmować eksport funkcji vkGetGlobalExtensionProperties()
, vkCreateInstance()
i vkGetInstanceProcAddr()
. Ładowarka może znaleźć wszystkie inne funkcje VkInstance()
, VkPhysicalDevice()
i vkGetDeviceProcAddr()
, wywołując funkcję vkGetInstanceProcAddr()
struktury hw_device_t
.
Wykrywanie i wczytywanie warstw
Ładowarka Vulkan obsługuje wyliczanie i wczytywanie warstw, które mogą udostępniać dodatkowe rozszerzenia i przechwytywać wywołania interfejsu API na drodze do sterownika. Android nie zawiera warstw w obrazie systemu, ale aplikacje mogą zawierać warstwy w plikach APK.
Pamiętaj, że model zabezpieczeń i zasady Androida znacznie różnią się od tych na innych platformach. W szczególności Android nie zezwala na wczytywanie kodu zewnętrznego do procesu, który nie obsługuje debugowania, na urządzeniach produkcyjnych (niezrootowanych). Nie zezwala też na to, aby kod zewnętrzny sprawdzał ani kontrolował pamięci, stanu itp. procesu. Obejmuje to zakaz zapisywania zrzutów rdzeni, śladów interfejsu API itp. na dysku w celu późniejszej kontroli. Na urządzeniach produkcyjnych można włączyć tylko warstwy dostarczane w ramach aplikacji, które nie są przeznaczone do debugowania. Sterowniki nie mogą zapewniać funkcji, które naruszają te zasady.
Przykłady zastosowań warstw:
- Warstwy na etapie rozwoju – warstw weryfikujących i uzupełniających dla narzędzi do śledzenia, profilowania i debugowania nie należy instalować w obrazie systemu na urządzeniach produkcyjnych. Warstwy weryfikacji i przekładki dla narzędzi do śledzenia, profilowania i debugowania powinny być aktualizowane bez obrazu systemu. Deweloperzy, którzy chcą używać jednej z tych warstw podczas tworzenia aplikacji, mogą zmodyfikować pakiet aplikacji, na przykład przez dodanie pliku do katalogu natywnych bibliotek. Uważa się, że inżynierowie IHV i OEM, którzy chcą zdiagnozować błędy w dostarczanych niemodyfikowalnych aplikacjach, mają dostęp do wersji nieprodukcyjnych (z rootem) obrazu systemu, chyba że te aplikacje można debugować. Więcej informacji znajdziesz w artykule Warstwy weryfikacji Vulkan na Androidzie.
- Warstwy narzędziowe – te warstwy udostępniają rozszerzenia, takie jak warstwa implementująca menedżera pamięci dla pamięci urządzenia. Deweloperzy wybierają warstwy i ich wersje, które mają być używane w aplikacji. Różne aplikacje korzystające z tej samej warstwy mogą używać różnych wersji. Deweloperzy decydują, które z tych warstw uwzględnić w pakiecie aplikacji.
- Wstrzyknięte (niejawne) warstwy – obejmuje warstwy, takie jak liczba klatek, sieć społecznościowa czy nakładki z programem uruchamiającym gry, udostępnione przez użytkownika lub inną aplikację bez wiedzy i zgody aplikacji. Naruszają one zasady bezpieczeństwa Androida i nie są obsługiwane.
W przypadku aplikacji niemożliwych do debugowania moduł ładowania wyszukuje warstwy tylko w katalogu biblioteki natywnej aplikacji i próbuje wczytać dowolną bibliotekę o nazwie pasującej do określonego wzorca (na przykład libVKLayer_foo.so
).
W przypadku aplikacji z możliwością debugowania ładowarka wyszukuje warstwy w /data/local/debug/vulkan
i próbuje załadować wszystkie biblioteki pasujące do określonego wzorca.
Android umożliwia przenoszenie warstw z modyfikacjami środowiska kompilacji między Androidem a innymi platformami. Szczegółowe informacje o interfejsie między warstwami a ładowarką znajdziesz w artykule Architektura interfejsów ładowarki Vulkan. Utrzymywane przez Khronos warstwy walidacji są hostowane w warstwach walidacji Vulkana.
Wersje i możliwości interfejsu Vulkan API
W tabeli poniżej znajdziesz wersje interfejsu Vulkan API dla kilku wersji Androida.Wersja Androida | Wersja interfejsu Vulkan |
---|---|
Android 13 | Vulkan 1.3 |
Android 9 | Vulkan 1.1 |
Android 7 | Vulkan 1.0 |
Omówienie funkcji Vulkan 1.3
Wersja Vulkan 1.3 wprowadza do głównej funkcjonalności Vulkana wiele wcześniej opcjonalnych rozszerzeń. Wiele z tych funkcji zostało dodanych w celu zwiększenia kontroli i dokładności interfejsu programowania Vulkan. Instancji przejść renderowania w jednym przejeździe nie trzeba już tworzyć obiektów ani ramek renderowania przejść. Łączna liczba obiektów stanu potoku może zostać zmniejszona, a synchronizacja w interfejsie API została zmieniona. Vulkan 1.3 ma te same wymagania sprzętowe co Vulkan 1.2, 1.1 i 1.0, a większość implementacji znajduje się w sterowniku graficznym dla konkretnego SoC, a nie w ramach.
Najważniejsze funkcje Vulkan 1.3 dla Androida to:
- Obsługa instancji przejść renderowania w pojedynczym przejeździe
- Obsługa natychmiastowego kończenia wywoływania mechanizmu cieniowania
- Bardziej szczegółowa kontrola nad tworzeniem, udostępnianiem i zarządzaniem przepływem
Vulkan 1.3 zawiera też kilka mniejszych funkcji i ulepszeń interfejsu API. Wszystkie zmiany wprowadzone w podstawowym interfejsie Vulkan API w wersji 1.3 znajdziesz w wersji podstawowej (Vulkan 1.3).
Omówienie funkcji Vulkan 1.2
Vulkan 1.2 zawiera kilka funkcji i rozszerzeń, które upraszczają interfejs API. Obejmuje to zintegrowany model pamięci i dodatkowe informacje, które można zapytać z sterownika urządzenia. Vulkan 1.2 ma te same wymagania sprzętowe co Vulkan 1.0 i 1.1. Cała implementacja znajduje się w sterowniku graficznym dla konkretnego układu SoC, a nie w ramach.
Najważniejszą funkcją Vulkan 1.2 na Androida jest obsługa 8-bitowej pamięci.
Vulkan 1.2 zawiera też kilka mniejszych funkcji i ulepszeń interfejsu API. Wszystkie zmiany wprowadzone w podstawowym interfejsie Vulkana w ramach poprawki 1.2 znajdziesz w sekcji Podstawowe poprawki (Vulkan 1.2).
Omówienie funkcji interfejsu Vulkan 1.1
Vulkan 1.1 obsługuje interoperacyjność pamięci/synchronizacji, dzięki czemu producenci OEM mogą obsługiwać Vulkan 1.1 na swoich urządzeniach. Dodatkowo interoperacyjność pamięci/synchronizacji umożliwia deweloperom określenie, czy Vulkan 1.1 jest obsługiwany na urządzeniu, i jego efektywne używanie w takim przypadku. Vulkan 1.1 ma te same wymagania sprzętowe co Vulkan 1.0, ale większość implementacji znajduje się w sterowniku graficznym dla konkretnego układu SOC, a nie w ramach.
Najważniejsze funkcje Vulkan 1.1 dla Androida to:
- Obsługa importowania i eksportowania buforów pamięci i obiektów synchronizacji spoza Vulkana (na potrzeby współpracy z aparatem, kodekami i GLES)
- Obsługa formatów YCbCr
Vulkan 1.1 zawiera też kilka mniejszych funkcji i ulepszeń interfejsu API. Wszystkie zmiany wprowadzone w podstawowym interfejsie Vulkan API w wersji 1.1 można znaleźć w sekcji Podstawowe wersje (Vulkan 1.1).
Wybierz obsługę interfejsu Vulkan
Urządzenia z Androidem powinny obsługiwać najbardziej zaawansowany dostępny zestaw funkcji Vulkana, o ile obsługują 64-bitowy interfejs ABI i nie mają mało pamięci.
Urządzenia z Androidem 13 lub nowszym powinny obsługiwać interfejs Vulkan 1.3.
Urządzenia uruchamiane w Androidzie 10 powinny obsługiwać Vulkan 1.1.
Inne urządzenia mogą opcjonalnie obsługiwać Vulkan 1.3, 1.2 i 1.1.
Obsługa wersji interfejsu Vulkan
Urządzenie z Androidem obsługuje wersję Vulkan, jeśli są spełnione te warunki:
- Dodaj sterownik Vulkana, który obsługuje interesującą Cię wersję Vulkana (musi to być wersja Vulkana 1.3, 1.1 lub 1.0) wraz z dodatkowymi wymaganiami CDD dla wersji Androida. Możesz też zaktualizować istniejący sterownik Vulkan do niższej wersji.
- W przypadku Vulkana 1.3 lub 1.1 sprawdź, czy funkcja systemu zwracana przez menedżera pakietów zwraca
true
dla prawidłowej wersji Vulkana.- W przypadku interfejsu Vulkan 1.3 funkcja to
PackageManager#hasSystemFeature(PackageManager.FEATURE_VULKAN_HARDWARE_VERSION, 0x403000)
. - W przypadku Vulkan 1.1 ta funkcja jest dostępna w wersji
PackageManager#hasSystemFeature(PackageManager.FEATURE_VULKAN_HARDWARE_VERSION, 0x401000)
.
true
dla Vulkana 1.3 i Vulkana 1.1, dodając regułę (pokazana poniżej) do odpowiedniego plikudevice.mk
.- W przypadku Vulkan 1.3 dodaj te informacje:
PRODUCT_COPY_FILES += frameworks/native/data/etc/android.hardware.vulkan.version-1_3.xml: $(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.vulkan.version.xml
- W przypadku interfejsu Vulkan 1.3 funkcja to
- W przypadku Vulkan 1.1 dodaj:
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
Profil podstawowy Androida (ABP)
Zachęcamy, aby wszystkie urządzenia z Androidem były zgodne z najnowszym profilem Android Baseline 2022 opisanym w przewodniku po profilu Android Baseline.
Każde urządzenie z Androidem 14 lub nowszym i interfejsem Vulkan API musi spełniać wszystkie funkcje zdefiniowane w profilu Android Baseline 2021. Pełna lista wymaganych funkcji jest wymieniona w pliku profilu Vulkana json
, ale kluczowy podzbiór wymaganych funkcji obejmuje:
- skompresowane tekstury za pomocą ASTC i ETC;
- Zmienne przestrzenie kolorów za pomocą
VK_EXT_swapchain_colorspace
. - Przykładowe cieniowanie i interpolacja wielu próbek do
sampleRateShading
.
Integracja z systemem okien (WSI)
W libvulkan.so
sterownik implementuje te rozszerzenia integracji z systemem okien (WSI):
VK_KHR_surface
VK_KHR_android_surface
VK_KHR_swapchain
VK_KHR_driver_properties
, wdrożone w Vulkan 1.1 tylko na Androidzie 10VK_GOOGLE_display_timing
, zaimplementowane w dowolnej wersji Vulkana w Androidzie 10
Obiekty VkSurfaceKHR
i VkSwapchainKHR
oraz wszystkie interakcje z ANativeWindow
są obsługiwane przez platformę i nie są widoczne dla kierowców. Implementacja WSI opiera się na rozszerzeniu VK_ANDROID_native_buffer
, które musi być obsługiwane przez sterownik. To rozszerzenie jest używane tylko przez implementację WSI i nie jest widoczne dla aplikacji.
Flagi wykorzystania Gralloc
Implementacje Vulkan mogą wymagać przydzielenia buforów swapchain za pomocą flag prywatnego użycia Gralloc zdefiniowanych przez implementację. Podczas tworzenia swapchain Android prosi sterownik o przetłumaczenie żądanego formatu i flag użycia obrazu na flagi użycia Gralloc, wywołując:
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 );
Parametry format
i imageUsage
są pobierane ze struktury VkSwapchainCreateInfoKHR
. Sterownik powinien wypełnić flagi wykorzystania Gralloc i *grallocConsumerUsage
oraz *grallocProducerUsage
wymagane w przypadku formatu i użytkowania. Flagi użycia zwracane przez sterownik są łączone z flagami użycia żądanymi przez konsumenta swapchainu podczas przydzielania buforów.
Android 7.x wywołuje wcześniejszą wersję VkSwapchainImageUsageFlagsANDROID()
o nazwie vkGetSwapchainGrallocUsageANDROID()
. W Androidzie 8.0 i nowszych vkGetSwapchainGrallocUsageANDROID()
jest wycofane, ale nadal wywołuje vkGetSwapchainGrallocUsageANDROID()
, jeśli kierowca nie poda vkGetSwapchainGrallocUsage2ANDROID()
:
VkResult VKAPI vkGetSwapchainGrallocUsageANDROID( VkDevice device, VkFormat format, VkImageUsageFlags imageUsage, int* grallocUsage );
vkGetSwapchainGrallocUsageANDROID()
nie obsługuje flag wykorzystania swapchain ani rozszerzonych flag wykorzystania Gralloc.
Obrazy z obsługą Gralloc
VkNativeBufferANDROID
to struktura rozszerzenia vkCreateImage
służąca do tworzenia obrazu obsługiwanego przez bufor Gralloc. VkNativeBufferANDROID
jest dostarczany do vkCreateImage()
w łańcuchu struktury VkImageCreateInfo
. Połączenia z numerem vkCreateImage()
z użytkownikiem VkNativeBufferANDROID
są wykonywane podczas połączenia z numerem vkCreateSwapchainKHR
. Implementacja WSI przydziela liczbę natywnych buforów żądanych na potrzeby wymiany, a następnie tworzy VkImage
dla każdego z nich:
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;
Podczas tworzenia obrazu obsługiwanego przez Gralloc, VkImageCreateInfo
zawiera te dane:
.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
W Androidzie 8.0 i nowszych platforma zapewnia strukturę rozszerzenia VkSwapchainImageCreateInfoKHR
w łańcuchu VkImageCreateInfo
udostępnianym vkCreateImage
, gdy do swapchain wymagane są jakiekolwiek flagi wykorzystania obrazu wymiany.
Struktura rozszerzenia zawiera flagi użycia obrazu swapchain:
typedef struct { VkStructureType sType; // must be VK_STRUCTURE_TYPE_SWAPCHAIN_IMAGE_CREATE_INFO_ANDROID const void* pNext; VkSwapchainImageUsageFlagsANDROID usage; } VkSwapchainImageCreateInfoANDROID;
W Androidzie 10 i nowszych platforma obsługuje VK_KHR_swapchain
w wersji 70, dzięki czemu aplikacja Vulkan może utworzyć VkImage
z pamięcią swapchain. Aplikacja najpierw wywołuje funkcję vkCreateImage
z strukturą VkImageSwapchainCreateInfoKHR
połączoną z strukturą VkImageCreateInfo
. Następnie aplikacja wywołuje funkcję vkBindImageMemory2(KHR)
z strukturą VkBindImageMemorySwapchainInfoKHR
połączoną z strukturą VkBindImageMemoryInfo
. imageIndex
określony w strukturze VkBindImageMemorySwapchainInfoKHR
musi być prawidłowym indeksem obrazów zamiany. Platforma udostępnia strukturę rozszerzenia VkNativeBufferANDROID
z odpowiednimi informacjami o buforze Gralloc dla łańcucha VkBindImageMemoryInfo
, dzięki czemu sterownik wie, z którym buforem Gralloc ma powiązać VkImage
.
Pobieranie obrazów
vkAcquireImageANDROID
przejmuje własność obrazu swapchain i importuje natywny płot sygnalizowany z zewnątrz do istniejącego obiektu VkSemaphore
i istniejącego obiektu VkFence
:
VkResult VKAPI vkAcquireImageANDROID( VkDevice device, VkImage image, int nativeFenceFd, VkSemaphore semaphore, VkFence fence );
Funkcja vkAcquireImageANDROID()
jest wywoływana podczas vkAcquireNextImageKHR
, aby zaimportować natywne ogrodzenie do obiektów VkSemaphore
i VkFence
dostarczanych przez aplikację (w tym wywołaniu obiekty semfora i ogrodzenia są opcjonalne). Kierowca może również wykorzystać tę możliwość, by rozpoznać i zająć wszelkie zewnętrzne zmiany w stanie bufora Gralloca – wielu kierowców nie będzie musiało nic robić. To wywołanie powoduje, że VkSemaphore
i VkFence
przechodzą w taki sam stan oczekiwania, jak gdyby sygnał został wysłany przez vkQueueSubmit
. Dzięki temu kolejki mogą czekać na semaforze, a aplikacja może czekać na semaforze.
Oba obiekty są sygnalizowane, gdy sygnał wysyła rdzenna bariera. Jeśli rdzenna bariera została już sygnalizowana, semafora jest w stanie sygnalizowanym, gdy funkcja zwraca wartość. Kierowca przejmuje prawo własności do deskryptora pliku ogrodzenia i zamyka go, gdy nie jest już potrzebny. Musi to zrobić nawet wtedy, gdy nie podano obiektu semafora ani ogrodzenia lub gdy vkAcquireImageANDROID
zakończy działanie z błędem. Jeśli fenceFd
to –1, oznacza to, że sygnał został już przekazany.
Opublikuj zdjęcia
vkQueueSignalReleaseImageANDROID
przygotowuje obraz swapchain do użytku zewnętrznego, tworzy natywny płot i planuje wysłanie sygnału do natywnego płotu po tym, jak sygnały zostaną wysłane przez semapfory wejściowe:
VkResult VKAPI vkQueueSignalReleaseImageANDROID( VkQueue queue, uint32_t waitSemaphoreCount, const VkSemaphore* pWaitSemaphores, VkImage image, int* pNativeFenceFd );
vkQueuePresentKHR()
połączeń vkQueueSignalReleaseImageANDROID()
w podanej kolejce. Sterownik musi wygenerować natywną barierę, która nie sygnalizuje, dopóki wszystkie semafory waitSemaphoreCount
w sygnale pWaitSemaphores
i wszystkie dodatkowe czynności wymagane do przygotowania image
do prezentacji nie zostaną ukończone.
Jeśli semafora oczekiwania (jeśli występuje) została już sygnalizowana, a proces queue
jest nieaktywny, sterownik może ustawić *pNativeFenceFd
na -1
zamiast rzeczywistego natywnego deskryptora pliku ogrodzenia, co oznacza, że nie ma na co czekać. Użytkownik wywołujący jest właścicielem i zamyka wskaźnik pliku zwracany w funkcji *pNativeFenceFd
.
Wiele sterowników może zignorować parametr image, ale niektóre mogą wymagać przygotowania struktur danych po stronie procesora powiązanych z buforem Gralloc na potrzeby zewnętrznych konsumentów obrazu. Przygotowanie zawartości bufora do użycia przez zewnętrznych odbiorców powinno odbywać się asynchronicznie w ramach przejścia obrazu do VK_IMAGE_LAYOUT_PRESENT_SRC_KHR
.
Jeśli obraz został utworzony za pomocą funkcji VK_SWAPCHAIN_IMAGE_USAGE_SHARED_BIT_ANDROID
, sterownik musi zezwalać na wielokrotne wywoływanie funkcji vkQueueSignalReleaseImageANDROID()
bez ingerencji w wywołania vkAcquireImageANDROID()
.
Obsługa udostępnianych obrazów
Niektóre urządzenia mogą udostępniać własność jednego obrazu między rurociągiem wyświetlania a implementacją Vulkan, aby zminimalizować opóźnienia.
W Androidzie 9 i nowszych wersjach ładowarka wyświetla reklamę rozszerzenia VK_KHR_shared_presentable_image
w sytuacji, gdy kierowca zareaguje na wywołanie funkcji vkGetPhysicalDeviceProperties2
.
Jeśli sterownik nie obsługuje Vulkan 1.1 ani rozszerzenia VK_KHR_physical_device_properties2
, program ładujący nie reklamuje obsługi udostępnianych obrazów do prezentacji. W przeciwnym razie ładowarka wysyła zapytanie o możliwości sterownika, wywołując funkcję vkGetPhysicalDeviceProperties2()
i uwzględniając w łańcuchu VkPhysicalDeviceProperties2::pNext
tę strukturę:
typedef struct { VkStructureType sType; // must be VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENTATION_PROPERTIES_ANDROID const void* pNext; VkBool32 sharedImage; } VkPhysicalDevicePresentationPropertiesANDROID;
Jeśli sterownik może udostępnić obraz systemowi wyświetlania, ustawia element sharedImage
na VK_TRUE
.
Weryfikacja
Producenci OEM mogą testować implementację Vulkana za pomocą CTS, która obejmuje:
- testy zgodności Khronos Vulkan w module
CtsDeqpTestCases
, które obejmują testy funkcjonalności interfejsu API dla Vulkan 1.0, 1.1, 1.2 i 1.3; - moduł
CtsGraphicsTestCases
, który sprawdza, czy urządzenie jest prawidłowo skonfigurowane pod kątem obsługiwanych przez nie funkcji Vulkan;
Flaga funkcji Vulkan
Aby ujawnić flagę funkcji, wymagane jest urządzenie z Androidem 11 lub nowszym, które obsługuje interfejs Vulkan API.android.software.vulkan.deqp.level
Wartość tej flagi funkcji to data zakodowana jako liczba całkowita. Określa datę związaną z testami Vulkan dEQP, które urządzenie twierdzi, że przeszło.
Data w formacie RRRR-MM-DD jest zakodowana jako 32-bitowa liczba całkowita w następujący sposób:
- Bity 0–15 przechowują rok.
- Bity 16–23 przechowują miesiąc
- Bits 24-31 store the day
Minimalna dozwolona wartość flagi funkcji to 0x07E30301
, która odpowiada dacie 01.03.2019, czyli dacie powiązanej z testami dEQP Vulkana dla Androida 10. Jeśli flaga funkcji ma co najmniej tę wartość, urządzenie twierdzi, że przeszło wszystkie testy dEQP Vulkan w Androidzie 10.
Wartość 0x07E40301
odpowiada dacie 1 marca 2020 r., czyli daty związanej z testami dEQP interfejsu Vulkan w Androidzie 11. Jeśli flaga funkcji ma co najmniej tę wartość, urządzenie informuje, że przeszły wszystkie testy dEQP Androida 11.
Wartość 0x07E60301
odpowiada dacie 1 marca 2022 r., czyli daty związanej z testami dEQP interfejsu Vulkan na Androidzie 13. Jeśli flaga funkcji ma co najmniej tę wartość, urządzenie ma przejść wszystkie testy dEQP Vulkana w Androidzie 13.
Urządzenie, które udostępnia określoną flagę funkcji (np.
0x07E30301
, 0x07E40301
, 0x07E60301
),
zapewnia, że wszystkie testy dEQP Vulkana w Androidzie (Android 10,
Android 11 lub Android 13) z tą flagą zostały zaliczone. To urządzenie może przejść testy Vulkan dEQP z późniejszej wersji Androida.
Vulkan dEQP jest częścią pakietu Android CTS. Od Androida 11 komponent testów dEQP w CTS jest świadomy flagi funkcji android.software.vulkan.deqp.level
i pomija wszystkie testy Vulkan dEQP, które – zgodnie z tą flagą funkcji – nie są obsługiwane przez urządzenie. Takie testy są zgłaszane jako testy, które łatwo przejść.