Wdrażaj Vulkana

Vulkan to niedrogi, wieloplatformowy interfejs API zapewniający wysoką wydajność grafiki 3D. Podobnie jak OpenGL ES (GLES) , Vulkan zapewnia narzędzia do tworzenia wysokiej jakości grafiki w czasie rzeczywistym w aplikacjach. Zalety korzystania z Vulkan obejmują zmniejszenie obciążenia procesora i obsługę języka pośredniego binarnego SPIR-V .

Aby pomyślnie wdrożyć Vulkan, urządzenie musi zawierać:

  • Moduł ładujący Vulkan dostarczany przez system Android.
  • Sterownik Vulkan, dostarczany przez SoC, takie jak GPU IHV, który implementuje API Vulkan . Aby obsługiwać funkcjonalność Vulkan, urządzenie z systemem Android wymaga sprzętu GPU obsługującego Vulkan i powiązanego sterownika. Procesor graficzny musi także obsługiwać GLES 3.1 i nowsze wersje. Skonsultuj się ze swoim dostawcą SoC, aby poprosić o pomoc dotyczącą sterowników.

Jeśli urządzenie zawiera sterownik Vulkan, urządzenie musi zadeklarować funkcje systemowe FEATURE_VULKAN_HARDWARE_LEVEL i FEATURE_VULKAN_HARDWARE_VERSION , z wersjami dokładnie odzwierciedlającymi możliwości urządzenia. Pomaga to zapewnić zgodność urządzenia z dokumentem definicji zgodności (CDD).

Ładowarka Vulkan

platform/frameworks/native/vulkan modułu ładującego Vulkan to podstawowy interfejs pomiędzy aplikacjami Vulkan a sterownikiem Vulkan urządzenia. Program ładujący Vulkan jest zainstalowany w /system/lib[64]/libvulkan.so . Moduł ładujący zapewnia podstawowe punkty wejścia API Vulkan, punkty wejścia rozszerzeń wymaganych przez CDD Androida i wiele dodatkowych opcjonalnych rozszerzeń. Rozszerzenia Windows System Integration (WSI) są eksportowane przez moduł ładujący i implementowane głównie w programie ładującym, a nie w sterowniku. Moduł ładujący obsługuje także wyliczanie i ładowanie warstw, które mogą udostępniać dodatkowe rozszerzenia i przechwytywać podstawowe wywołania API w drodze do sterownika.

NDK zawiera bibliotekę pośredniczącą libvulkan.so do łączenia. Biblioteka eksportuje te same symbole, co moduł ładujący. Aplikacje wywołują funkcje wyeksportowane z prawdziwej biblioteki libvulkan.so , aby wprowadzić funkcje trampoliny do modułu ładującego, które wysyłają do odpowiedniej warstwy lub sterownika na podstawie pierwszego argumentu. Wywołanie vkGet*ProcAddr() zwraca wskaźniki funkcji, do których wysyłane są trampoliny (tzn. wywołuje bezpośrednio podstawowy kod API). Wywoływanie wskaźników funkcji zamiast eksportowanych symboli jest bardziej wydajne, ponieważ pomija trampolinę i wysyłanie.

Wyliczanie i ładowanie sterowników

Po utworzeniu obrazu systemu Android oczekuje, że system będzie wiedział, które procesory graficzne są dostępne. Program ładujący wykorzystuje istniejący mechanizm HAL w hardware.h do wykrycia i załadowania sterownika. 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.product.platform>.so
/vendor/lib64/hw/vulkan.<ro.hardware.vulkan>.so
/vendor/lib64/hw/vulkan.<ro.product.platform>.so

W systemie Android 7.0 i nowszych wersjach pochodna Vulkan hw_module_t otacza pojedynczą strukturę hw_module_t ; obsługiwany jest tylko jeden sterownik, a stały ciąg 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. Strukturę hw_device_t można rozszerzyć o funkcje eksportu vkGetGlobalExtensionProperties() , vkCreateInstance() i vkGetInstanceProcAddr() . Program ładujący może znaleźć wszystkie inne funkcje VkInstance() , VkPhysicalDevice() i vkGetDeviceProcAddr() wywołując funkcję vkGetInstanceProcAddr() struktury hw_device_t .

Odkrywanie i ładowanie warstw

Moduł ładujący Vulkan obsługuje wyliczanie i ładowanie warstw, które mogą udostępniać dodatkowe rozszerzenia i przechwytywać podstawowe wywołania API w drodze do sterownika. Android nie zawiera warstw na obrazie systemu; jednak aplikacje mogą zawierać warstwy w swoim pliku APK.

Korzystając z warstw, należy pamiętać, że model zabezpieczeń i zasady Androida znacznie różnią się od innych platform. W szczególności system Android nie pozwala na ładowanie kodu zewnętrznego do niedebugowalnego procesu na urządzeniach produkcyjnych (nierootowanych) ani nie pozwala kodowi zewnętrznemu na sprawdzanie lub kontrolowanie pamięci procesu, stanu itp. Obejmuje to zakaz zapisywania zrzutów rdzenia, śladów API itp. na dysku w celu późniejszej kontroli. 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 naruszających te zasady.

Przypadki użycia warstw obejmują:

  • Warstwy czasu programowania — Warstwy weryfikacyjne i podkładki dla narzędzi do śledzenia/profilowania/debugowania nie powinny być instalowane w obrazie systemu urządzeń produkcyjnych. Warstwy walidacyjne i podkładki dla narzędzi do śledzenia/profilowania/debugowania powinny umożliwiać aktualizację bez obrazu systemu. Deweloperzy, którzy chcą używać jednej z tych warstw podczas programowania, mogą zmodyfikować pakiet aplikacji, na przykład dodając plik do swojego katalogu bibliotek natywnych. Zakłada się, że inżynierowie IHV i OEM, którzy chcą diagnozować błędy w dostarczaniu niemodyfikowalnych aplikacji, mają dostęp do nieprodukcyjnych (zrootowanych) kompilacji obrazu systemu, chyba że aplikacje te można debugować. Aby uzyskać więcej informacji, zobacz Warstwy walidacyjne 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. Programiści wybierają warstwy i wersje tych warstw, które mają zostać użyte w ich aplikacji; różne aplikacje korzystające z tej samej warstwy mogą nadal korzystać z różnych wersji. Programiści wybierają, która z tych warstw ma zostać dostarczona w pakiecie aplikacji.
  • Warstwy wstrzyknięte (niejawne) — obejmują warstwy, takie jak liczba klatek na sekundę, sieć społecznościowa i nakładki programu uruchamiającego gry dostarczone 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, których nie można debugować, moduł ładujący wyszukuje warstwy tylko w natywnym katalogu bibliotek aplikacji i próbuje załadować dowolną bibliotekę o nazwie pasującej do określonego wzorca (na przykład libVKLayer_foo.so ).

W przypadku aplikacji, które można debugować, moduł ładujący wyszukuje warstwy w /data/local/debug/vulkan i próbuje załadować dowolną bibliotekę pasującą do określonego wzorca.

System Android umożliwia przenoszenie warstw ze zmianami środowiska kompilacji między systemem Android a innymi platformami. Aby uzyskać szczegółowe informacje na temat interfejsu pomiędzy warstwami i modułem ładującym, zobacz Architektura interfejsów modułu ładującego Vulkan . Warstwy walidacyjne utrzymywane przez Khronos są hostowane w warstwach walidacyjnych Vulkan .

Wersje i możliwości API Vulkan

W poniższej tabeli wymieniono wersje interfejsu API Vulkan dla kilku wydań Androida.
Wersja Androida Wersja Vulkana
Androida 13 Vulkan 1.3
Androida 9 Vulkan 1.1
Androida 7 Vulkan 1.0

Przegląd funkcjonalności Vulkan 1.3

Vulkan 1.3 kanonizuje wiele wcześniej opcjonalnych rozszerzeń w podstawowej funkcjonalności Vulkan. Wiele z tych funkcji zostało uwzględnionych w celu zwiększenia kontroli i szczegółowości interfejsu programistycznego Vulkan. Instancje przebiegu renderowania jednoprzebiegowego nie wymagają już obiektów przebiegu renderowania ani buforów ramki. Można zmniejszyć całkowitą liczbę obiektów stanu potoku, a synchronizacja w interfejsie API została zmieniona. Vulkan 1.3 ma takie same wymagania sprzętowe jak Vulkan 1.2, 1.1 i 1.0, przy czym większość implementacji znajduje się w sterowniku graficznym specyficznym dla SoC, a nie w frameworku.

Najważniejsze funkcje Vulkan 1.3 dla Androida to:

  • Obsługa instancji jednoprzebiegowego renderowania
  • Obsługa natychmiastowego zakończenia wywołania modułu cieniującego
  • Większa szczegółowość tworzenia, udostępniania i kontroli potoku

Vulkan 1.3 zawiera także kilka mniejszych funkcji i ulepszeń użyteczności API. Wszystkie zmiany wprowadzone do podstawowego API Vulkan z niewielką wersją 1.3 można znaleźć w Core Revisions (Vulkan 1.3) .

Przegląd funkcjonalności Vulkan 1.2

Vulkan 1.2 dodaje szereg funkcji i rozszerzeń, które upraszczają interfejs API. Obejmuje to ujednolicony model pamięci i dodatkowe informacje, które można uzyskać ze sterownika urządzenia. Vulkan 1.2 ma takie same wymagania sprzętowe jak Vulkan 1.0 i 1.1; cała implementacja odbywa się w sterowniku graficznym specyficznym dla SoC, a nie w frameworku.

Najważniejszą funkcją Vulkan 1.2 dla Androida jest obsługa 8-bitowej pamięci.

Vulkan 1.2 zawiera także kilka mniejszych funkcji i ulepszeń użyteczności API. Wszystkie zmiany wprowadzone do podstawowego API Vulkan z niewielką wersją 1.2 można znaleźć w Core Revisions (Vulkan 1.2) .

Przegląd funkcjonalności Vulkan 1.1

Vulkan 1.1 zawiera obsługę współdziałania pamięci/synchronizacji, co umożliwia producentom OEM obsługę Vulkan 1.1 na urządzeniach. Dodatkowo interoperacja pamięci/synchronizacji umożliwia programistom określenie, czy Vulkan 1.1 jest obsługiwany na urządzeniu, i efektywne korzystanie z niego, gdy jest to możliwe. 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 Vulkan 1.1 dla Androida to:

  • Obsługa importowania i eksportowania buforów pamięci oraz obiektów synchronizacji spoza Vulkan (w celu współpracy z kamerą, kodekami i GLES)
  • Obsługa formatów YCbCr

Vulkan 1.1 zawiera także kilka mniejszych funkcji i ulepszeń użyteczności API. Wszystkie zmiany wprowadzone do podstawowego API Vulkan z niewielką wersją 1.1 można znaleźć w Core Revisions (Vulkan 1.1) .

Wybierz obsługę Vulkan

Urządzenia z Androidem powinny obsługiwać najbardziej zaawansowany dostępny zestaw funkcji Vulkan, pod warunkiem, że obsługują 64-bitowy ABI i nie mają mało pamięci.

Urządzenia uruchamiane z Androidem 13 i nowszym powinny obsługiwać Vulkan 1.3.

Urządzenia uruchamiane za pośrednictwem Androida 10 powinny obsługiwać Vulkan 1.1.

Inne urządzenia mogą opcjonalnie obsługiwać Vulkan 1.3, 1.2 i 1.1.

Wspieraj wersję Vulkan

Urządzenie z Androidem obsługuje wersję Vulkan, jeśli spełnione są następujące warunki:

  1. Dodaj sterownik Vulkan obsługujący interesującą Cię wersję Vulkan (musi to być jedna z wersji Vulkan 1.3, 1.1 lub 1.0) wraz z dodatkowymi wymaganiami CDD wersji Androida. Alternatywnie zaktualizuj istniejący sterownik Vulkan o niższy numer wersji Vulkan.
  2. W przypadku wersji Vulkan 1.3 lub 1.1 upewnij się, że funkcja systemowa zwrócona przez menedżera pakietów zwraca true dla poprawnej wersji vulkan.
    • W przypadku Vulkan 1.3 jest to funkcja PackageManager#hasSystemFeature(PackageManager.FEATURE_VULKAN_HARDWARE_VERSION, 0x403000) .
    • W przypadku Vulkan 1.1 ta funkcja to PackageManager#hasSystemFeature(PackageManager.FEATURE_VULKAN_HARDWARE_VERSION, 0x401000) .
    Menedżer pakietów zwróci true dla Vulkan 1.3 i Vulkan 1.1, dodając regułę pokazaną poniżej do odpowiedniego pliku device.mk .
    • Dodaj następujące polecenie dla Vulkan 1.3:
      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
      
    • Dodaj następujące polecenie dla Vulkan 1.1:
      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
      

Podstawowy profil Androida (ABP)

Zachęcamy wszystkie urządzenia z Androidem do dostosowania się do najnowszego profilu Android Baseline 2022, jak opisano w przewodniku po profilach Android Baseline .

Każde urządzenie obsługujące system Android 14 lub nowszy oraz Vulkan API musi spełniać wszystkie funkcjonalności zdefiniowane w profilu Android Baseline 2021 . Pełna lista wymaganych funkcjonalności jest wymieniona w pliku json profilu Vulkan, ale kluczowy podzbiór wymaganych funkcjonalności obejmuje:

  • Skompresowane tekstury poprzez ASTC i ETC.
  • Zmienne przestrzenie kolorów poprzez VK_EXT_swapchain_colorspace .
  • Cieniowanie próbek i interpolacja wielu próbek poprzez sampleRateShading .

Integracja systemu okiennego (WSI)

W libvulkan.so sterownik implementuje następujące rozszerzenia integracji systemu okiennego (WSI):

  • VK_KHR_surface
  • VK_KHR_android_surface
  • VK_KHR_swapchain
  • VK_KHR_driver_properties , zaimplementowany dla Vulkan 1.1 tylko w systemie Android 10
  • VK_GOOGLE_display_timing , zaimplementowany dla dowolnej wersji Vulkan w systemie Android 10

Obiekty VkSurfaceKHR i VkSwapchainKHR oraz wszystkie interakcje z ANativeWindow są obsługiwane przez platformę i nie są widoczne dla sterownikó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 użycia Gralloc

Implementacje Vulkan mogą wymagać przydzielenia buforów swapchain ze zdefiniowanymi przez implementację prywatnymi flagami użycia Gralloc. Podczas tworzenia łańcucha wymiany system 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 pobierane są ze struktury VkSwapchainCreateInfoKHR . Sterownik powinien wypełnić *grallocConsumerUsage i *grallocProducerUsage flagami użycia Gralloc wymaganymi dla formatu i użycia. Flagi użycia zwrócone przez sterownik są łączone z flagami użycia żądanymi przez konsumenta swapchain podczas alokacji buforów.

Android 7.x wywołuje wcześniejszą wersję VkSwapchainImageUsageFlagsANDROID() o nazwie vkGetSwapchainGrallocUsageANDROID() . Android 8.0 i nowsze wersje mają przestarzałą funkcję vkGetSwapchainGrallocUsageANDROID() ale nadal wywołują funkcję vkGetSwapchainGrallocUsageANDROID() , jeśli sterownik nie udostępnia vkGetSwapchainGrallocUsage2ANDROID() :

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

vkGetSwapchainGrallocUsageANDROID() nie obsługuje flag użytkowania swapchain ani rozszerzonych flag użytkowania Gralloc.

Obrazy wspierane przez Gralloc

VkNativeBufferANDROID to struktura rozszerzenia vkCreateImage służąca do tworzenia obrazu wspieranego przez bufor Gralloc. VkNativeBufferANDROID jest udostępniany funkcji vkCreateImage() w łańcuchu struktury VkImageCreateInfo . Wywołania funkcji vkCreateImage() za pomocą VkNativeBufferANDROID mają miejsce podczas wywołania funkcji vkCreateSwapchainKHR . Implementacja WSI przydziela liczbę natywnych buforów żądanych 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 opartego na Gralloc VkImageCreateInfo zawiera następujące 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 systemie Android 8.0 i nowszych platforma zapewnia strukturę rozszerzenia VkSwapchainImageCreateInfoKHR w łańcuchu VkImageCreateInfo dostarczanym do vkCreateImage , gdy dla łańcucha wymiany wymagane są jakiekolwiek flagi użycia obrazu swapchain. 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 v70, więc aplikacja Vulkan jest w stanie utworzyć VkImage wspierany przez pamięć swapchain. Aplikacja najpierw wywołuje vkCreateImage ze strukturą VkImageSwapchainCreateInfoKHR połączoną ze strukturą VkImageCreateInfo . Następnie aplikacja wywołuje vkBindImageMemory2(KHR) ze strukturą VkBindImageMemorySwapchainInfoKHR połączoną ze strukturą VkBindImageMemoryInfo . imageIndex określony w strukturze VkBindImageMemorySwapchainInfoKHR musi być prawidłowym indeksem obrazu swapchain. Tymczasem 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 powiązać VkImage .

Zdobądź obrazy

vkAcquireImageANDROID nabywa własność obrazu swapchain i importuje sygnalizowane zewnętrznie natywne ogrodzenie zarówno do istniejącego obiektu VkSemaphore , jak i istniejącego obiektu VkFence :

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

vkAcquireImageANDROID() jest wywoływana podczas vkAcquireNextImageKHR w celu zaimportowania natywnego ogrodzenia do obiektów VkSemaphore i VkFence dostarczonych przez aplikację (jednak w tym wywołaniu zarówno obiekty semafora, jak i ogrodzenia są opcjonalne). Sterownik może również skorzystać z tej możliwości, aby rozpoznać i obsłużyć wszelkie zewnętrzne zmiany stanu bufora Gralloc; wielu kierowców nie będzie musiało tutaj nic robić. To wywołanie umieszcza VkSemaphore i VkFence w tym samym stanie oczekiwania, jak w przypadku sygnalizowania przez vkQueueSubmit , więc kolejki mogą czekać na semaforze, a aplikacja może czekać na ogrodzeniu.

Obydwa obiekty zostają zasygnalizowane, gdy sygnalizuje je natywny płot znajdujący się pod nimi; jeśli ogrodzenie natywne już zasygnalizowało, to semafor znajduje się w stanie sygnalizowanym, gdy funkcja powraca. Sterownik przejmuje deskryptor pliku ogrodzenia i zamyka deskryptor pliku ogrodzenia, gdy nie jest już potrzebny. Sterownik musi to zrobić, nawet jeśli nie zostanie dostarczony żaden obiekt semafora ani ogrodzenia, lub nawet jeśli vkAcquireImageANDROID zakończy się niepowodzeniem i zwróci błąd. Jeśli fenceFd wynosi -1, to tak, jakby natywne ogrodzenie zostało już zasygnalizowane.

Opublikuj obrazy

vkQueueSignalReleaseImageANDROID przygotowuje obraz łańcucha wymiany do użytku zewnętrznego, tworzy natywne ogrodzenie i planuje sygnalizowanie natywnego ogrodzenia po zasygnalizowaniu semaforów wejściowych:

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

vkQueuePresentKHR() wywołuje funkcję vkQueueSignalReleaseImageANDROID() w podanej kolejce. Sterownik musi utworzyć natywne ogrodzenie, które nie będzie sygnalizować, dopóki wszystkie semafory waitSemaphoreCount w pWaitSemaphores nie zasygnalizują sygnału i nie zostaną zakończone wszelkie dodatkowe prace wymagane do przygotowania image do prezentacji.

Jeśli semafory oczekiwania (jeśli istnieją) zostały już zasygnalizowane, a queue jest już bezczynna, sterownik może ustawić *pNativeFenceFd na -1 zamiast rzeczywistego deskryptora natywnego pliku ogrodzenia, wskazując, że nie ma na co czekać. Obiekt wywołujący jest właścicielem deskryptora pliku zwróconego w *pNativeFenceFd i zamyka go.

Wiele sterowników może zignorować parametr obrazu, ale niektóre mogą wymagać przygotowania struktur danych po stronie procesora, powiązanych z buforem Gralloc, do wykorzystania przez zewnętrznych odbiorców obrazu. Przygotowanie zawartości bufora do wykorzystania przez odbiorców zewnętrznych powinno odbywać się asynchronicznie w ramach przenoszenia obrazu do VK_IMAGE_LAYOUT_PRESENT_SRC_KHR .

Jeśli obraz został utworzony za pomocą VK_SWAPCHAIN_IMAGE_USAGE_SHARED_BIT_ANDROID , sterownik musi umożliwiać wielokrotne wywoływanie funkcji vkQueueSignalReleaseImageANDROID() bez pośrednictwa wywołań vkAcquireImageANDROID() .

Udostępniona obsługa reprezentacyjnego obrazu

Niektóre urządzenia mogą dzielić własność pojedynczego obrazu pomiędzy potokiem wyświetlania a implementacją Vulkan, aby zminimalizować opóźnienia. W systemie Android 9 i nowszych moduł ładujący warunkowo reklamuje rozszerzenie VK_KHR_shared_presentable_image na podstawie odpowiedzi sterownika na wywołanie vkGetPhysicalDeviceProperties2 .

Jeśli sterownik nie obsługuje rozszerzenia Vulkan 1.1 ani VK_KHR_physical_device_properties2 , moduł ładujący nie reklamuje obsługi udostępnianych reprezentacyjnych obrazów. W przeciwnym razie moduł ładujący wysyła zapytanie do możliwości sterownika, wywołując funkcję vkGetPhysicalDeviceProperties2() i włączając następującą strukturę do łańcucha VkPhysicalDeviceProperties2::pNext :

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 dzielić własność obrazu z systemem wyświetlania, ustawia element sharedImage na VK_TRUE .

Walidacja

Producenci OEM mogą przetestować implementację Vulkan za pomocą CTS, który obejmuje:

  • Khronos Vulkan Testy zgodności w module CtsDeqpTestCases , które obejmują testy funkcjonalne API dla Vulkan 1.0, 1.1, 1.2 i 1.3.
  • Moduł CtsGraphicsTestCases , który testuje, czy urządzenie jest poprawnie skonfigurowane pod kątem obsługiwanych możliwości Vulkan.

Flaga charakterystyczna Vulkan

Aby wyświetlić flagę funkcji, android.software.vulkan.deqp.level , wymagane jest urządzenie obsługujące system Android 11 lub nowszy oraz interfejs API Vulkan. Wartość tej flagi funkcji to data zakodowana jako wartość całkowita. Określa datę związaną z testami Vulkan dEQP, które urządzenie twierdzi, że przeszło.

Data w postaci 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, czyli dacie powiązanej z testami Vulkan dEQP dla Androida 10. Jeśli flaga funkcji ma co najmniej tę wartość, urządzenie twierdzi, że przejść wszystkie testy Androida 10 Vulkan dEQP.

Wartość 0x07E40301 odpowiada dacie 2020-03-01, czyli dacie powiązanej z testami Vulkan dEQP dla Androida 11. Jeśli flaga funkcji ma co najmniej tę wartość, urządzenie twierdzi, że przeszło wszystkie testy Androida 11 Vulkan dEQP.

Wartość 0x07E60301 odpowiada dacie 2022-03-01, czyli dacie powiązanej z testami Vulkan dEQP dla Androida 13. Jeśli flaga funkcji ma co najmniej tę wartość, urządzenie twierdzi, że przeszło wszystkie testy Androida 13 Vulkan dEQP.

Urządzenie, które ujawnia określoną flagę funkcji ( tj. 0x07E30301 , 0x07E40301 , 0x07E60301 ) twierdzi, że przeszło wszystkie testy Androida Vulkan dEQP dotyczące tej flagi funkcji (odpowiednio Android 10, Android 11, Android 13). To urządzenie może przejść testy Vulkan dEQP z nowszej wersji Androida.

Vulkan dEQP stanowi część systemu Android CTS. Od systemu Android 11 komponent uruchamiający testy dEQP w CTS rozpoznaje flagę funkcji android.software.vulkan.deqp.level i pomija wszelkie testy Vulkan dEQP, których – zgodnie z tą flagą funkcji – urządzenie nie obsługuje. Takie testy są uznawane za banalnie pomyślne.