Vulkan to wieloplatformowy interfejs API o niskim narzucie, który umożliwia renderowanie grafiki 3D o wysokiej wydajności. Podobnie jak OpenGL ES (GLES), Vulkan udostępnia narzędzia do tworzenia wysokiej jakości grafiki w czasie rzeczywistym w aplikacjach. Zalety korzystania z Vulkana to m.in. zmniejszenie obciążenia procesora i obsługa języka SPIR-V Binary Intermediate.
Aby interfejs Vulkan działał prawidłowo, urządzenie musi zawierać:
- Loader Vulkan dostarczany przez Androida.
- Sterownik Vulkana dostarczany przez układy SoC, takie jak GPU IHV, który implementuje interfejs Vulkan API. Aby obsługiwać funkcje Vulkan, urządzenie z Androidem musi mieć procesor graficzny obsługujący Vulkan i odpowiedni sterownik. Procesor graficzny musi też obsługiwać GLES 3.1 i nowsze wersje. Skontaktuj się z dostawcą układu SoC, aby poprosić o obsługę sterownika.
Jeśli urządzenie zawiera sterownik Vulkan, musi deklarować funkcje systemowe FEATURE_VULKAN_HARDWARE_LEVEL
i FEATURE_VULKAN_HARDWARE_VERSION
w wersjach, które dokładnie odzwierciedlają możliwości urządzenia. Pomaga to zapewnić, że urządzenie jest zgodne z dokumentem definicji zgodności (CDD).
Program ładujący Vulkan
Program ładujący Vulkanplatform/frameworks/native/vulkan
to główne narzędzie do komunikacji między aplikacjami Vulkan a sterownikiem Vulkan urządzenia. Program ładujący Vulkan jest zainstalowany w lokalizacji /system/lib[64]/libvulkan.so
. Program wczytujący udostępnia główne punkty wejścia interfejsu Vulkan API, punkty wejścia rozszerzeń wymaganych przez dokument CDD Androida oraz wiele dodatkowych rozszerzeń opcjonalnych. Rozszerzenia integracji z systemem Windows (WSI) są eksportowane przez program wczytujący i implementowane głównie w nim, a nie w sterowniku. Program ładujący obsługuje też wyliczanie i wczytywanie warstw, które mogą udostępniać dodatkowe rozszerzenia i przechwytywać wywołania podstawowych interfejsów API w drodze do sterownika.
NDK zawiera bibliotekę libvulkan.so
do linkowania. Biblioteka eksportuje te same symbole co program wczytujący. Aplikacje wywołują funkcje wyeksportowane z prawdziwej biblioteki libvulkan.so
, aby w programie wczytującym wywołać funkcje trampoliny, które na podstawie pierwszego argumentu przekazują sterowanie do odpowiedniej warstwy lub sterownika. Wywołanie vkGet*ProcAddr()
zwraca wskaźniki funkcji, do których przekierowują trampoliny (czyli wywołuje bezpośrednio kod podstawowego interfejsu API). Wywoływanie funkcji za pomocą wskaźników funkcji, a nie wyeksportowanych symboli, jest bardziej wydajne, ponieważ pomija trampolinę i wysyłanie.
Wykrywanie i wczytywanie sterowników
Po utworzeniu obrazu systemu Android oczekuje, że system będzie wiedzieć, które procesory graficzne są dostępne. Ładowarka korzysta z istniejącego mechanizmu HAL w hardware.h
, aby wykryć i załadować sterownik. Preferowane ścieżki dla 32-bitowych i 64-bitowych sterowników Vulkan to:
/vendor/lib/hw/vulkan.<ro.hardware.vulkan>.so /vendor/lib/hw/vulkan.<ro.board.platform>.so /vendor/lib64/hw/vulkan.<ro.hardware.vulkan>.so /vendor/lib64/hw/vulkan.<ro.board.platform>.so
W Androidzie 7.0 i nowszym pochodna Vulkan hw_module_t
otacza pojedynczą strukturę hw_module_t
. Obsługiwany jest tylko jeden sterownik, a stały ciąg znaków HWVULKAN_DEVICE_0
jest przekazywany do open()
.
Pochodna Vulkan hw_device_t
odpowiada pojedynczemu sterownikowi, który może obsługiwać wiele urządzeń fizycznych. Struktura
hw_device_t
może obejmować funkcje eksportu
vkGetGlobalExtensionProperties()
, vkCreateInstance()
i
vkGetInstanceProcAddr()
. Program wczytujący może znaleźć wszystkie inne funkcje VkInstance()
, VkPhysicalDevice()
i vkGetDeviceProcAddr()
, wywołując vkGetInstanceProcAddr()
struktury hw_device_t
.
ro.vulkan.apex
na nazwę pakietu APEX Vulkan, aby załadować interfejs Vulkan z pakietu APEX.
Wykrywanie i wczytywanie warstw
Program ładujący Vulkan obsługuje wyliczanie i wczytywanie warstw, które mogą udostępniać dodatkowe rozszerzenia i przechwytywać wywołania podstawowych interfejsów API w drodze do sterownika. Android nie zawiera warstw w obrazie systemu, ale aplikacje mogą je uwzględniać w swoim pliku APK.
Pamiętaj, że model zabezpieczeń i zasady Androida znacznie różnią się od innych platform. W szczególności Android nie zezwala na wczytywanie kodu zewnętrznego do procesu, którego nie można debugować, na urządzeniach produkcyjnych (bez dostępu do roota) ani nie zezwala na sprawdzanie ani kontrolowanie pamięci, stanu itp. procesu przez kod zewnętrzny. Obejmuje to zakaz zapisywania na dysku zrzutów pamięci, śladów API itp. w celu późniejszego sprawdzenia. Na urządzeniach produkcyjnych włączone są tylko warstwy dostarczane w ramach aplikacji, których nie można debugować, a sterowniki nie mogą udostępniać funkcji, które naruszają te zasady.
Warstwy mogą być używane w tych przypadkach:
- Warstwy czasu programowania – weryfikacja: warstwy i elementy pośredniczące do narzędzi śledzących, profilujących i debugujących nie powinny być instalowane w obrazie systemu na urządzeniach produkcyjnych. Warstwy weryfikacji i wstawki 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 programowania, mogą zmodyfikować pakiet aplikacji, np. dodając plik do katalogu bibliotek natywnych. Inżynierowie IHV i OEM, którzy chcą diagnozować błędy w przypadku aplikacji, których nie można modyfikować, mają dostęp do wersji obrazu systemu innych niż produkcyjne (z dostępem do roota), 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 urządzenia. Deweloperzy wybierają warstwy i ich wersje, które będą używane w ich aplikacji. Różne aplikacje korzystające z tej samej warstwy mogą używać różnych wersji. Deweloperzy wybierają, które z tych warstw mają być zawarte w pakiecie aplikacji.
- Wstrzykiwane (niejawne) warstwy – obejmują warstwy takie jak liczba klatek na sekundę, nakładki sieci społecznościowych i programów uruchamiających gry dostarczane przez użytkownika lub inną aplikację bez wiedzy lub zgody aplikacji. Te naruszają zasady bezpieczeństwa Androida i nie są obsługiwane.
W przypadku aplikacji, których nie można debugować, program wczytujący wyszukuje warstwy tylko w katalogu bibliotek natywnych aplikacji i próbuje wczytać każdą bibliotekę o nazwie pasującej do określonego wzorca (np. libVKLayer_foo.so
).
W przypadku aplikacji, które można debugować, program wczytujący wyszukuje warstwy w /data/local/debug/vulkan
i próbuje wczytać dowolną bibliotekę pasującą do określonego wzorca.
Android umożliwia przenoszenie warstw ze zmianami w środowisku kompilacji między Androidem a innymi platformami. Szczegółowe informacje o interfejsie między warstwami a programem wczytującym znajdziesz w artykule Architecture of the Vulkan Loader Interfaces (w języku angielskim). Warstwy weryfikacji utrzymywane przez Khronos są hostowane w warstwach weryfikacji Vulkan.
Wersje i możliwości interfejsu Vulkan API
W tej tabeli 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 interfejsu Vulkan 1.3
Wulkan 1.3 wprowadza szereg wcześniej opcjonalnych rozszerzeń do podstawowych funkcji Vulkan. Większość tych funkcji została dodana w celu zwiększenia kontroli i szczegółowości interfejsu programowania Vulkan. Instancje przepustek renderowania jednoprzebiegowego nie potrzebują już obiektów przepustek renderowania ani buforów ramki. Można zmniejszyć łączną liczbę obiektów stanu potoku i zmienić sposób synchronizacji w interfejsie API. Vulkan 1.3 ma takie same wymagania sprzętowe jak Vulkan 1.2, 1.1 i 1.0. Większość implementacji znajduje się w sterowniku graficznym specyficznym dla układu SoC, a nie w platformie.
Najważniejsze funkcje interfejsu Vulkan 1.3 na Androidzie to:
- Obsługa instancji pojedynczego przejścia renderowania
- Obsługa natychmiastowego zakończenia wywołania shadera
- Większa szczegółowość tworzenia, udostępniania i kontrolowania potoków
Vulkan 1.3 zawiera też kilka mniejszych funkcji i ulepszeń w zakresie użyteczności interfejsu API. Wszystkie zmiany wprowadzone w podstawowym interfejsie Vulkan API w ramach drobnej wersji 1.3 znajdziesz na stronie Core Revisions (Vulkan 1.3).
Omówienie funkcji interfejsu Vulkan 1.2
Wulkan 1.2 dodaje wiele funkcji i rozszerzeń, które upraszczają interfejs API. Obejmuje to ujednolicony model pamięci i dodatkowe informacje, o które można zapytać sterownik urządzenia. Wulkan 1.2 ma takie same wymagania sprzętowe jak Wulkan 1.0 i 1.1. Cała implementacja znajduje się w sterowniku graficznym specyficznym dla układu SoC, a nie w frameworku.
Najważniejszą funkcją Vulkan 1.2 dla 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 Vulkan API w ramach drobnej wersji 1.2 znajdziesz na stronie Core Revisions (Vulkan 1.2).
Omówienie funkcji interfejsu Vulkan 1.1
Vulkan 1.1 obsługuje interoperacyjność pamięci i synchronizacji, co umożliwia producentom OEM obsługę tej wersji na urządzeniach. Dodatkowo interoperacyjność pamięci/synchronizacji umożliwia programistom określenie, czy Vulkan 1.1 jest obsługiwany na urządzeniu, i skuteczne korzystanie z niego, gdy jest. Vulkan 1.1 ma takie same wymagania sprzętowe jak Vulkan 1.0, ale większość implementacji znajduje się w sterowniku graficznym specyficznym dla SOC, a nie w frameworku.
Najważniejsze funkcje interfejsu Vulkan 1.1 dla Androida to:
- Obsługa importowania i eksportowania buforów pamięci oraz obiektów synchronizacji spoza Vulkan (w celu współdziałania 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 ramach drobnej wersji 1.1 znajdziesz na stronie Core Revisions (Vulkan 1.1).
Wybierz obsługę interfejsu Vulkan
Urządzenia z Androidem powinny obsługiwać najbardziej zaawansowany dostępny zestaw funkcji Vulkan, o ile obsługują 64-bitowy interfejs ABI i nie mają małej ilości pamięci.
Urządzenia z Androidem 13 lub nowszym powinny obsługiwać interfejs Vulkan 1.3.
Urządzenia z Androidem 10 powinny obsługiwać Vulkan 1.1.
Inne urządzenia mogą opcjonalnie obsługiwać platformy Vulkan 1.3, 1.2 i 1.1.
Obsługa wersji interfejsu Vulkan
Urządzenie z Androidem obsługuje wersję Vulkan, jeśli spełnione są te warunki:
- Dodaj sterownik Vulkan, który obsługuje interesującą Cię wersję Vulkana (musi to być jedna z wersji 1.3, 1.1 lub 1.0) wraz z dodatkowymi wymaganiami CDD dotyczącymi wersji Androida. Możesz też zaktualizować istniejący sterownik Vulkan o niższym numerze wersji.
- W przypadku interfejsu Vulkan 1.3 lub 1.1 upewnij się, że funkcja systemowa zwrócona przez menedżera pakietów zwraca
true
dla prawidłowej wersji interfejsu Vulkan.- W przypadku interfejsu Vulkan 1.3 funkcja ta to
PackageManager#hasSystemFeature(PackageManager.FEATURE_VULKAN_HARDWARE_VERSION, 0x403000)
. - W przypadku interfejsu Vulkan 1.1 ta funkcja jest
PackageManager#hasSystemFeature(PackageManager.FEATURE_VULKAN_HARDWARE_VERSION, 0x401000)
.
true
dla Vulkana 1.3 i Vulkana 1.1, dodając do odpowiedniego plikudevice.mk
regułę w postaci:- W przypadku interfejsu 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 ta to
- W przypadku interfejsu Vulkan 1.1 dodaj te informacje:
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 do dostosowania wszystkich urządzeń z Androidem do najnowszego profilu Android Baseline 2022, zgodnie z przewodnikiem po profilu Android Baseline.
Każde urządzenie, które obsługuje Androida 14 lub nowszego i interfejs API Vulkan, musi spełniać wszystkie funkcje zdefiniowane w profilu Android Baseline 2021. Pełna lista wymaganych funkcji znajduje się w pliku profilu Vulkan json
, ale kluczowy podzbiór wymaganych funkcji obejmuje:
- Skompresowane tekstury w formatach ASTC i ETC.
- Zmienne przestrzenie kolorów przez
VK_EXT_swapchain_colorspace
. - Próbkowanie cieniowania i interpolacja wielopróbkowa za pomocą funkcji
sampleRateShading
.
Integracja systemu okiennego (WSI)
W libvulkan.so
sterownik implementuje te rozszerzenia integracji systemu okien (WSI):
VK_KHR_surface
VK_KHR_android_surface
VK_KHR_swapchain
VK_KHR_driver_properties
, zaimplementowane w przypadku Vulkan 1.1 tylko na Androidzie 10VK_GOOGLE_display_timing
, zaimplementowane w dowolnej wersji interfejsu Vulkan 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 udostępniane aplikacjom.
Flagi użycia Gralloc
Implementacje interfejsu Vulkan mogą wymagać przydzielania buforów łańcucha wymiany z prywatnymi flagami użycia Gralloc zdefiniowanymi przez implementację. Podczas tworzenia łańcucha wymiany 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ć pola *grallocConsumerUsage
i *grallocProducerUsage
flagami użycia Gralloc wymaganymi w przypadku danego formatu i użycia. Flagi użycia zwracane przez sterownik są łączone z flagami użycia żądanymi przez odbiorcę łańcucha wymiany podczas przydzielania buforów.
Android 7.x wywołuje starszą wersję VkSwapchainImageUsageFlagsANDROID()
, o nazwie vkGetSwapchainGrallocUsageANDROID()
. Android 8.0 i nowsze wersje wycofują
vkGetSwapchainGrallocUsageANDROID()
, ale nadal wywołują
vkGetSwapchainGrallocUsageANDROID()
, jeśli
vkGetSwapchainGrallocUsage2ANDROID()
nie jest dostarczany przez sterownik:
VkResult VKAPI vkGetSwapchainGrallocUsageANDROID( VkDevice device, VkFormat format, VkImageUsageFlags imageUsage, int* grallocUsage );
vkGetSwapchainGrallocUsageANDROID()
nie obsługuje flag użycia łańcucha wymiany ani rozszerzonych flag użycia Gralloc.
Obrazy obsługiwane przez Gralloc
VkNativeBufferANDROID
to struktura vkCreateImage
rozszerzenia do tworzenia obrazu obsługiwanego przez bufor Gralloc. VkNativeBufferANDROID
jest przekazywany do vkCreateImage()
w łańcuchu struktury VkImageCreateInfo
. Połączenia z numerem vkCreateImage()
z numeru VkNativeBufferANDROID
są wykonywane podczas połączenia z numerem vkCreateSwapchainKHR
. Implementacja WSI przydziela liczbę buforów natywnych wymaganych dla łańcucha 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
ma 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 udostępnia strukturę rozszerzenia VkSwapchainImageCreateInfoKHR
w łańcuchu VkImageCreateInfo
przekazywanym do vkCreateImage
, gdy dla łańcucha wymiany wymagane są flagi użycia obrazu łańcucha wymiany.
Struktura rozszerzenia zawiera flagi użycia obrazu łańcucha wymiany:
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ługujeVK_KHR_swapchain
v70, więc aplikacja Vulkan może tworzyćVkImage
z pamięcią łańcucha wymiany. Aplikacja najpierw wywołuje funkcję vkCreateImage
ze strukturą VkImageSwapchainCreateInfoKHR
połączoną ze strukturą VkImageCreateInfo
. Następnie aplikacja wywołuje funkcję vkBindImageMemory2(KHR)
ze strukturą VkBindImageMemorySwapchainInfoKHR
połączoną ze strukturą VkBindImageMemoryInfo
. Wartość imageIndex
określona w strukturze VkBindImageMemorySwapchainInfoKHR
musi być prawidłowym indeksem obrazu łańcucha wymiany. Platforma udostępnia strukturę rozszerzenia z odpowiednimi informacjami o buforze Gralloc do łańcucha VkBindImageMemoryInfo
, dzięki czemu sterownik wie, z którym buforem Gralloc powiązać VkImage
.VkNativeBufferANDROID
Pobieranie obrazów
vkAcquireImageANDROID
przejmuje własność obrazu łańcucha wymiany i importuje do istniejącego obiektu VkSemaphore
i istniejącego obiektu VkFence
zewnętrznie sygnalizowany natywny płot:
VkResult VKAPI vkAcquireImageANDROID( VkDevice device, VkImage image, int nativeFenceFd, VkSemaphore semaphore, VkFence fence );
vkAcquireImageANDROID()
jest wywoływana podczas vkAcquireNextImageKHR
, aby zaimportować natywny płot do obiektów VkSemaphore
i VkFence
dostarczonych przez aplikację (jednak zarówno obiekty semafora, jak i płotu są w tym wywołaniu opcjonalne). Sterownik może też wykorzystać tę okazję do rozpoznania i obsłużenia wszelkich zewnętrznych zmian stanu bufora Gralloc. Wiele sterowników nie będzie musiało niczego robić. To wywołanie umieszcza VkSemaphore
i VkFence
w tym samym stanie oczekiwania, co w przypadku sygnału wysyłanego przez vkQueueSubmit
, dzięki czemu kolejki mogą czekać na semafor, a aplikacja może czekać na barierę.
Oba obiekty są sygnalizowane, gdy sygnalizuje je bazowy natywny obiekt bariery. Jeśli natywny obiekt bariery został już zasygnalizowany, semafor jest w stanie zasygnalizowanym, gdy ta funkcja zwraca wartość. Sterownik przejmuje własność deskryptora pliku bariery i zamyka go, gdy nie jest już potrzebny. Sterownik musi to zrobić nawet wtedy, gdy nie podano semafora ani obiektu bariery lub nawet wtedy, gdy funkcja vkAcquireImageANDROID
zakończy się niepowodzeniem i zwróci błąd. Jeśli wartość fenceFd
wynosi -1, oznacza to, że natywna bariera została już zasygnalizowana.
Zwalnianie obrazów
vkQueueSignalReleaseImageANDROID
przygotowuje obraz łańcucha wymiany do użytku zewnętrznego, tworzy natywny sygnał i planuje jego wysłanie po wysłaniu sygnałów przez semafory 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 utworzyć natywną barierę, która nie wysyła sygnału, dopóki wszystkie semafory waitSemaphoreCount
w pWaitSemaphores
nie wyślą sygnału i nie zostaną wykonane wszystkie dodatkowe czynności wymagane do przygotowania image
do wyświetlenia.
Jeśli semafory oczekiwania (jeśli takie istnieją) zostały już zasygnalizowane, a queue
jest już w stanie bezczynności, sterownik może ustawić *pNativeFenceFd
na -1
zamiast rzeczywistego deskryptora pliku bariery natywnej, co oznacza, że nie ma na co czekać. Wywołujący jest właścicielem deskryptora pliku
zwróconego w *pNativeFenceFd
i zamyka go.
Wielu sterowników może zignorować parametr obrazu, ale niektóre mogą wymagać przygotowania struktur danych po stronie procesora powiązanych z buforem Gralloc do użycia przez zewnętrznych odbiorców obrazu. Przygotowywanie zawartości bufora do użycia przez odbiorców zewnętrznych powinno odbywać się asynchronicznie w ramach przekształcania obrazu w 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 wywoływania funkcji vkAcquireImageANDROID()
.
Obsługa udostępnianych obrazów
Niektóre urządzenia mogą współdzielić własność pojedynczego obrazu między potokiem wyświetlania a implementacją Vulkan, aby zminimalizować opóźnienie.
W Androidzie 9 i nowszych wersjach program wczytujący warunkowo reklamuje rozszerzenie VK_KHR_shared_presentable_image
na podstawie odpowiedzi sterownika 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ępnionych obrazów prezentowanych. W przeciwnym razie moduł wczytujący 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ć własność obrazu systemowi wyświetlania, ustawia wartość sharedImage
na VK_TRUE
.
Weryfikacja
Producenci OEM mogą testować implementację Vulkan za pomocą CTS, który obejmuje:
- Testy zgodności Khronos Vulkan w module
CtsDeqpTestCases
, które obejmują testy funkcjonalne interfejsu API Vulkan 1.0, 1.1, 1.2 i 1.3. CtsGraphicsTestCases
moduł, który sprawdza, czy urządzenie jest prawidłowo skonfigurowane pod kątem obsługiwanych funkcji Vulkan;
Flaga funkcji Vulkan
Aby udostępnić flagę funkcji, wymagane jest urządzenie z Androidem 11 lub nowszym, które obsługuje interfejs Vulkan API.
android.software.vulkan.deqp.level
Wartość tego flagi funkcji to data zakodowana jako liczba całkowita. Określa datę powiązaną z testami Vulkan dEQP, które urządzenie rzekomo przeszło.
Data w formacie RRRR-MM-DD jest kodowana jako 32-bitowa liczba całkowita w następujący sposób:
- Bity 0–15 przechowują rok.
- Bity 16–23 przechowują miesiąc.
- Bity 24–31 przechowują dzień.
Minimalna dozwolona wartość flagi funkcji to 0x07E30301
, co odpowiada dacie 2019-03-01, która jest datą powiązaną z testami Vulkan dEQP na Androida 10. Jeśli flaga funkcji ma co najmniej tę wartość, urządzenie deklaruje, że przeszło wszystkie testy dEQP Vulkan w Androidzie 10.
Wartość 0x07E40301
odpowiada dacie 2020-03-01, która jest datą powiązaną z testami Vulkan dEQP na Androida 11. Jeśli flaga funkcji ma co najmniej tę wartość, urządzenie deklaruje, że przeszło wszystkie testy dEQP Vulkan w Androidzie 11.
Wartość 0x07E60301
odpowiada dacie 2022-03-01, która jest datą powiązaną z testami Vulkan dEQP na Androidzie 13. Jeśli flaga funkcji ma co najmniej tę wartość, urządzenie deklaruje, że przeszło wszystkie testy dEQP Vulkan w Androidzie 13.
Urządzenie, które udostępnia konkretną flagę funkcji (np.
0x07E30301
, 0x07E40301
, 0x07E60301
), deklaruje, że przechodzi wszystkie testy dEQP Vulkan na Androidzie dotyczące tej flagi funkcji (odpowiednio Android 10, Android 11 i Android 13). To urządzenie może przejść testy dEQP Vulkana z późniejszej wersji Androida.
Vulkan dEQP jest częścią pakietu Android CTS. Od Androida 11 komponent CTS o nazwie dEQP test runner
rozpoznaje android.software.vulkan.deqp.level
flagę funkcji i pomija wszystkie testy Vulkan dEQP, które – zgodnie z tą flagą funkcji – urządzenie nie obsługuje. Takie testy są zgłaszane jako trywialnie zdane.