Vulkan'ı uygulama

Vulkan, yüksek performanslı 3D grafikler için kullanılan, düşük ek yüke sahip ve platformlar arası bir API'dir. Vulkan, OpenGL ES (GLES) gibi uygulamalarda yüksek kaliteli ve gerçek zamanlı grafikler oluşturmak için araçlar sağlar. Vulkan kullanmanın avantajları arasında CPU genel giderlerinde azalma ve SPIR-V Binary Intermediate diline destek yer alır.

Vulkan'ı başarılı bir şekilde uygulamak için cihazda şunlar bulunmalıdır:

  • Android tarafından sağlanan Vulkan yükleyici.
  • GPU IHV'ler gibi SoC'ler tarafından sağlanan ve Vulkan API'yi uygulayan bir Vulkan sürücüsü. Android cihazın Vulkan işlevini desteklemesi için Vulkan özellikli GPU donanımına ve ilişkili sürücüye sahip olması gerekir. GPU'nun GLES 3.1 ve sonraki sürümleri de desteklemesi gerekir. Sürücü desteği istemek için SoC tedarikçinizle iletişime geçin.

Bir cihazda Vulkan sürücüsü varsa cihazın, FEATURE_VULKAN_HARDWARE_LEVEL ve FEATURE_VULKAN_HARDWARE_VERSION sistem özelliklerini, cihazın özelliklerini doğru şekilde yansıtan sürümlerle birlikte bildirmesi gerekir. Bu, cihazın Uyumluluk Tanımlama Belgesi'ne (CDD) uygun olmasını sağlar.

Vulkan yükleyici

Vulkan yükleyici platform/frameworks/native/vulkan, Vulkan uygulamaları ile bir cihazın Vulkan sürücüsü arasındaki birincil arayüzdür. Vulkan yükleyici /system/lib[64]/libvulkan.so konumuna yüklenir. Yükleyici, temel Vulkan API giriş noktalarını, Android CDD'nin gerektirdiği uzantıların giriş noktalarını ve birçok ek isteğe bağlı uzantıyı sağlar. Pencere Sistemi Entegrasyonu (WSI) uzantıları yükleyici tarafından dışa aktarılır ve öncelikle sürücüde değil, yükleyicide uygulanır. Yükleyici, ek uzantıları ortaya çıkarabilen ve sürücüye giderken temel API çağrılarını engelleyebilen katmanların numaralandırılmasını ve yüklenmesini de destekler.

NDK, bağlantı için bir saplama libvulkan.so kitaplığı içerir. Kitaplık, yükleyiciyle aynı sembolleri dışa aktarır. Uygulamalar, yükleyicide trambolin işlevlerine girmek için gerçek libvulkan.so kitaplığından dışa aktarılan işlevleri çağırır. Bu işlevler, ilk bağımsız değişkenlerine göre uygun katmana veya sürücüye gönderilir. vkGet*ProcAddr() çağrısı, trambolinlerin gönderildiği işlev işaretçilerini döndürür (yani doğrudan temel API kodunu çağırır). İşlev işaretçileri aracılığıyla yapılan aramalar, atlama ve gönderme işlemlerini atladığı için dışa aktarılan semboller aracılığıyla yapılan aramalara göre daha verimlidir.

Sürücü numaralandırması ve yükleme

Sistem görüntüsü oluşturulduğunda Android, sistemin hangi GPU'ların kullanılabildiğini bilmesini bekler. Yükleyici, sürücüyü keşfetmek ve yüklemek için hardware.h'daki mevcut HAL mekanizmasını kullanır. 32 bit ve 64 bit Vulkan sürücüleri için tercih edilen yollar şunlardır:

/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

Android 7.0 ve sonraki sürümlerde Vulkan hw_module_t türevi tek bir hw_module_t yapısını sarmalar; yalnızca bir sürücü desteklenir ve sabit dize HWVULKAN_DEVICE_0, open()'ye iletilir.

Vulkan hw_device_t türevi, birden fazla fiziksel cihazı destekleyebilen tek bir sürücüye karşılık gelir. hw_device_t yapısı, dışa aktarma vkGetGlobalExtensionProperties(), vkCreateInstance() ve vkGetInstanceProcAddr() işlevlerini kapsayabilir. Yükleyici, VkInstance(), VkPhysicalDevice() ve vkGetDeviceProcAddr() işlevlerinin tümünü hw_device_t yapısının vkGetInstanceProcAddr() işlevini çağırarak bulabilir.

Android 15'ten itibaren yükleyici, Vulkan sürücüsünü yüklemek için APEX'i destekler. ro.vulkan.apex değerini, Vulkan'ı APEX'ten yüklemek için Vulkan APEX'in adı olarak ayarlayın.

Katman keşfi ve yükleme

Vulkan yükleyici, ek uzantılar sunabilen ve sürücüye giderken temel API çağrılarını engelleyebilen katmanların numaralandırılmasını ve yüklenmesini destekler. Uygulamalar, APK'larına katman ekleyebilir. Android, sistem görüntüsünde katmanlar içermez.

Katmanları kullanırken Android'in güvenlik modeli ve politikalarının diğer platformlardan önemli ölçüde farklı olduğunu unutmayın. Android, özellikle üretim (rootlanmamış) cihazlarda harici kodun hata ayıklanamayan bir işleme yüklenmesine izin vermez. Ayrıca harici kodun, işlemin belleğini, durumunu vb. incelemesine veya kontrol etmesine de izin vermez. Bu, daha sonra incelemek üzere çekirdek dökümlerinin, API izlerinin vb. diske kaydedilmesini yasaklamayı içerir. Üretim cihazlarında yalnızca hata ayıklanamayan uygulamaların parçası olarak sunulan katmanlar etkinleştirilir ve sürücüler bu politikaları ihlal eden işlevler sağlamamalıdır.

Katmanların kullanım alanları:

  • Geliştirme zamanı katmanları: İzleme/profil oluşturma/hata ayıklama araçları için doğrulama katmanları ve ara katmanlar, üretim cihazlarının sistem görüntüsüne yüklenmemelidir. İzleme/profil oluşturma/hata ayıklama araçları için doğrulama katmanları ve ara katmanlar, sistem görüntüsü olmadan güncellenebilmelidir. Geliştirme sırasında bu katmanlardan birini kullanmak isteyen geliştiriciler, uygulama paketini değiştirebilir. Örneğin, yerel kitaplıklar dizinine bir dosya ekleyebilirler. Değiştirilemeyen uygulamaların gönderimindeki hataları teşhis etmek isteyen IHV ve OEM mühendislerinin, bu uygulamalarda hata ayıklama yapılamıyorsa sistem görüntüsünün üretim dışı (rootlu) sürümlerine erişebildiği varsayılır. Daha fazla bilgi için Android'de Vulkan doğrulama katmanları başlıklı makaleyi inceleyin.
  • Yardımcı katmanlar: Bu katmanlar, cihaz belleği için bellek yöneticisi uygulayan bir katman gibi uzantıları kullanıma sunar. Geliştiriciler, uygulamalarında kullanmak üzere katmanları ve bu katmanların sürümlerini seçer. Aynı katmanı kullanan farklı uygulamalar yine de farklı sürümleri kullanabilir. Geliştiriciler, uygulama paketlerinde bu katmanlardan hangilerinin gönderileceğini seçer.
  • Enjekte edilen (örtülü) katmanlar: Kullanıcı tarafından veya uygulamanın bilgisi ya da izni olmadan başka bir uygulama tarafından sağlanan kare hızı, sosyal ağ ve oyun başlatıcı yer paylaşımları gibi katmanları içerir. Bunlar Android'in güvenlik politikalarını ihlal ettiğinden desteklenmez.

Hata ayıklanamayan uygulamalarda yükleyici, katmanları yalnızca uygulamanın yerel kitaplık dizininde arar ve belirli bir kalıpla eşleşen ada sahip tüm kitaplıkları yüklemeye çalışır (örneğin, libVKLayer_foo.so). Bu katmanlar, uygulamanın ad alanına yüklenir. Bu nedenle, NDK ile oluşturulmaları gerekir.

Hata ayıklanabilir uygulamalarda yükleyici, /data/local/debug/vulkan konumundaki katmanları arar ve belirli bir kalıpla eşleşen tüm kitaplıkları yüklemeye çalışır. Android 10'dan (API düzeyi 29) itibaren Vulkan, geliştirme zamanı katmanlarını başka bir APK'dan da yükleyebilir. Her iki durumda da yükleyici, sistem ayarlarını kullanarak hangi katmanların uygulama bazında etkinleştirileceğini seçer. Bu katmanlar, uygulamanın izni olmadan yüklenebilmelerine rağmen vkEnumerateInstanceLayerProperties içinde numaralandırılır (yani uygulama bu katmanlar hakkında bilgi sahibi olabilir).

Android, katmanların Android ile diğer platformlar arasında derleme ortamı değişiklikleriyle taşınmasını sağlar. Katmanlar ve yükleyici arasındaki arayüz hakkında ayrıntılı bilgi için Vulkan Yükleyici Arayüzlerinin Mimarisi başlıklı makaleyi inceleyin. Khronos tarafından sürdürülen doğrulama katmanları, Vulkan Validation Layers'da barındırılır.

Vulkan API sürümleri ve özellikleri

Aşağıdaki tabloda, çeşitli Android sürümleri için Vulkan API sürümleri listelenmiştir.
Android Sürümü Vulkan sürümü
Android 16 Vulkan 1.4
Android 13 Vulkan 1.3
Android 9 Vulkan 1.1
Android 7 Vulkan 1.0

Vulkan 1.4 işlevlerine genel bakış

Vulkan 1.4, daha önce isteğe bağlı olan bir dizi uzantıyı Vulkan'ın temel işlevselliğine dahil eder. Bu işlevlerin çoğu, Vulkan programlama arayüzü üzerinde kontrolü ve ayrıntı düzeyini artırmak amacıyla sunulur. Vulkan 1.4, Vulkan 1.3'e kıyasla donanım gereksinimlerini artırır. Uygulamanın çoğu, çerçevede değil SoC'ye özgü grafik sürücüsünde yer alır.

Vulkan 1.3 işlevlerine genel bakış

Vulkan 1.3, daha önce isteğe bağlı olan bir dizi uzantıyı Vulkan'ın temel işlevine dahil eder. Bu işlevlerin çoğu, Vulkan programlama arayüzü üzerinde kontrolü ve ayrıntı düzeyini artırmak amacıyla sunulur. Tek geçişli oluşturma geçişi örnekleri artık oluşturma geçişi nesneleri veya çerçeve arabellekleri gerektirmiyor. Toplam ardışık düzen durumu nesnesi sayısı azaltılabilir ve API içindeki senkronizasyon yenilenir. Vulkan 1.3, Vulkan 1.2, 1.1 ve 1.0 ile aynı donanım gereksinimlerine sahiptir. Uygulamanın çoğu, çerçevede değil, SoC'ye özgü grafik sürücüsünde yer alır.

Android için en önemli Vulkan 1.3 özellikleri şunlardır:

  • Tek geçişli oluşturma geçişi örnekleri için destek
  • Bir gölgelendirici çağrısını anında sonlandırma desteği
  • İşlem hattı oluşturma, paylaşma ve kontrol etme üzerinde daha ayrıntılı denetim

Vulkan 1.3'te ayrıca çeşitli küçük özellikler ve API kullanılabilirliği geliştirmeleri de yer alıyor. Vulkan API'nin 1.3 küçük sürümünde yapılan tüm değişiklikleri Core Revisions (Vulkan 1.3) sayfasında bulabilirsiniz.

Vulkan 1.2 işlevselliğine genel bakış

Vulkan 1.2, API yüzeyini basitleştiren bir dizi özellik ve uzantı ekler. Buna, birleştirilmiş Bellek Modeli ve cihaz sürücüsünden sorgulanabilen ek bilgiler dahildir. Vulkan 1.2, Vulkan 1.0 ve 1.1 ile aynı donanım gereksinimlerine sahiptir. Uygulamanın tamamı, çerçevede değil, SoC'ye özgü grafik sürücüsündedir.

Android için en önemli Vulkan 1.2 özelliği, 8 bit depolama desteğidir.

Vulkan 1.2'de ayrıca çeşitli küçük özellikler ve API kullanılabilirliği geliştirmeleri de yer alıyor. 1.2 küçük düzeltmesiyle temel Vulkan API'sinde yapılan tüm değişiklikleri Temel Düzeltmeler (Vulkan 1.2) bölümünde bulabilirsiniz.

Vulkan 1.1 işlevlerine genel bakış

Vulkan 1.1, bellek/senkronizasyon birlikte çalışabilirliği için destek içerir. Bu sayede OEM'ler cihazlarda Vulkan 1.1'i destekleyebilir. Ayrıca, bellek/senkronizasyon birlikte çalışabilirliği, geliştiricilerin bir cihazda Vulkan 1.1'in desteklenip desteklenmediğini belirlemesini ve desteklendiğinde etkili bir şekilde kullanmasını sağlar. Vulkan 1.1, Vulkan 1.0 ile aynı donanım gereksinimlerine sahiptir ancak uygulamanın çoğu çerçevede değil, SOC'ye özgü grafik sürücüsündedir.

Android için en önemli Vulkan 1.1 özellikleri şunlardır:

  • Bellek arabelleklerini ve senkronizasyon nesnelerini Vulkan'ın dışından (kamera, codec'ler ve GLES ile birlikte çalışabilirlik için) içe ve dışa aktarma desteği
  • YCbCr biçimleri için destek

Vulkan 1.1, daha küçük çeşitli özellikler ve API kullanılabilirliği geliştirmeleri de içerir. Küçük revizyon 1.1 ile temel Vulkan API'sinde yapılan tüm değişiklikleri Temel Revizyonlar (Vulkan 1.1) bölümünde bulabilirsiniz.

Vulkan desteğini seçme

Tüm Android cihazlar, 64 bit ABI'yi desteklemeleri ve düşük belleğe sahip olmamaları koşuluyla, mevcut en gelişmiş Vulkan özellik setini desteklemelidir.

Android 16 ve sonraki sürümlerle kullanıma sunulan cihazlar Vulkan 1.4'ü desteklemelidir.

Android 13 ve sonraki sürümlerle kullanıma sunulan cihazlar Vulkan 1.3'ü desteklemelidir.

Android 10 ile kullanıma sunulan cihazlar Vulkan 1.1'i desteklemelidir.

Diğer cihazlar isteğe bağlı olarak Vulkan 1.4, 1.3, 1.2 ve 1.1'i destekleyebilir.

Vulkan sürümünü destekleme

Bir Android cihazın Vulkan sürümünü desteklemesi için aşağıdaki koşulların karşılanması gerekir:

  1. İlgili Vulkan sürümünü destekleyen bir Vulkan sürücüsü ekleyin (bu, Vulkan sürümü 1.4, 1.3, 1.1 veya 1.0 olmalıdır). Ayrıca Android sürümünün ek CDD koşullarını da ekleyin. Alternatif olarak, daha düşük bir Vulkan sürüm numarasına sahip mevcut bir Vulkan sürücüsünü güncelleyin.
  2. Vulkan 1.4, 1.3 veya 1.1 için paket yöneticisi tarafından döndürülen sistem özelliğinin doğru Vulkan sürümü için true döndürdüğünü doğrulayın.
    • Vulkan 1.4 için özellik PackageManager#hasSystemFeature(PackageManager.FEATURE_VULKAN_HARDWARE_VERSION, 0x404000).
    • Vulkan 1.3 için özellik PackageManager#hasSystemFeature(PackageManager.FEATURE_VULKAN_HARDWARE_VERSION, 0x403000).
    • Vulkan 1.1 için özellik PackageManager#hasSystemFeature(PackageManager.FEATURE_VULKAN_HARDWARE_VERSION, 0x401000).
    Paket yöneticisi, uygun bir device.mk dosyasına aşağıdaki gibi gösterilen bir kural ekleyerek Vulkan 1.4, 1.3 ve 1.1 için true değerini döndürür.
    • Vulkan 1.4 için aşağıdakileri ekleyin:
      PRODUCT_COPY_FILES += frameworks/native/data/etc/android.hardware.vulkan.version-1_4.xml:
      $(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.vulkan.version.xml
    • Vulkan 1.3 için aşağıdakileri ekleyin:
      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
    • Vulkan 1.1 için aşağıdakileri ekleyin:
      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

Android Baseline profili (ABP)

Android Baseline profili rehberinde belirtildiği gibi tüm Android cihazların en yeni Android Baseline 2022 profiline uygun olmasını öneririz.

Android 14 veya sonraki sürümleri ve Vulkan API'yi destekleyen tüm cihazlar, Android Baseline 2021 profilinde tanımlanan tüm işlevleri karşılamalıdır. Gerekli işlevlerin tam listesi Vulkan profili json dosyasında belirtilmiştir. Ancak gerekli işlevlerin önemli bir alt kümesi şunları içerir:

  • ASTC ve ETC aracılığıyla sıkıştırılmış dokular.
  • VK_EXT_swapchain_colorspace aracılığıyla değişken renk alanları.
  • sampleRateShading aracılığıyla örnek gölgelendirme ve çok örnekli enterpolasyon.

Pencere sistemi entegrasyonu (WSI)

libvulkan.so, sürücüde aşağıdaki pencere sistemi entegrasyonu (WSI) uzantıları uygulanır:

  • VK_KHR_surface
  • VK_KHR_android_surface
  • VK_KHR_swapchain
  • VK_KHR_driver_properties, yalnızca Android 10'da Vulkan 1.1 için uygulanır.
  • VK_GOOGLE_display_timing, Android 10'daki tüm Vulkan sürümlerinde uygulanır.

VkSurfaceKHR ve VkSwapchainKHR nesneleri ile ANativeWindow ile yapılan tüm etkileşimler platform tarafından işlenir ve sürücülere gösterilmez. WSI uygulaması, sürücü tarafından desteklenmesi gereken VK_ANDROID_native_buffer uzantısını kullanır. Bu uzantı yalnızca WSI uygulaması tarafından kullanılır ve uygulamalara sunulmaz.

Gralloc kullanım işaretleri

Vulkan uygulamalarının, uygulama tarafından tanımlanan özel Gralloc kullanım işaretleriyle ayrılmış takas zinciri arabelleklerine ihtiyacı olabilir. Android, bir takas zinciri oluştururken sürücüden istenen biçimi ve resim kullanım işaretlerini Gralloc kullanım işaretlerine çevirmesini ister. Bu işlem için aşağıdaki işlev çağrılır:

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

format ve imageUsage parametreleri, VkSwapchainCreateInfoKHR yapısından alınır. Sürücü, *grallocConsumerUsage ve *grallocProducerUsage alanlarını biçim ve kullanım için gereken Gralloc kullanım işaretleriyle doldurmalıdır. Sürücü tarafından döndürülen kullanım işaretleri, arabellekler ayrılırken takas zinciri tüketicisi tarafından istenen kullanım işaretleriyle birleştirilir.

Android 7.x, VkSwapchainImageUsageFlagsANDROID()'nin vkGetSwapchainGrallocUsageANDROID() adlı eski bir sürümünü çağırır. Android 8.0 ve sonraki sürümlerde vkGetSwapchainGrallocUsageANDROID() kullanımdan kaldırılmıştır ancak vkGetSwapchainGrallocUsage2ANDROID() sürücü tarafından sağlanmıyorsa vkGetSwapchainGrallocUsageANDROID() çağrılmaya devam eder:

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

vkGetSwapchainGrallocUsageANDROID(), swapchain kullanım işaretlerini veya genişletilmiş Gralloc kullanım işaretlerini desteklemez.

Gralloc destekli resimler

VkNativeBufferANDROID, Gralloc arabelleğiyle desteklenen bir görüntü oluşturmak için kullanılan bir vkCreateImage uzantı yapısıdır. VkNativeBufferANDROID, VkImageCreateInfo yapı zincirinde vkCreateImage()'e sağlanır. VkNativeBufferANDROID ile vkCreateImage() numaralı telefona yapılan aramalar, vkCreateSwapchainKHR numaralı telefona yapılan arama sırasında gerçekleşir. WSI uygulaması, takas zinciri için istenen doğal arabelleklerin sayısını ayırır ve ardından her biri için bir VkImage oluşturur:

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;

Gralloc destekli bir resim oluştururken VkImageCreateInfo aşağıdaki verilere sahiptir:

  .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

Android 8.0 ve sonraki sürümlerde platform, vkCreateImage'ye sağlanan VkImageCreateInfo zincirinde VkSwapchainImageCreateInfoKHR uzantı yapısı sağlar. Bu yapı, takas zinciri için herhangi bir takas zinciri resmi kullanım işareti gerektiğinde kullanılır. Uzantı yapısı, takas zinciri görüntü kullanım işaretlerini içerir:

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

    VkSwapchainImageUsageFlagsANDROID      usage;
} VkSwapchainImageCreateInfoANDROID;

Android 10 ve sonraki sürümlerde platform, VK_KHR_swapchain v70'i desteklediğinden Vulkan uygulaması, takas zinciri belleğiyle desteklenen bir VK_KHR_swapchain oluşturabilir.VkImage Uygulama önce vkCreateImage ile VkImageSwapchainCreateInfoKHR yapısını VkImageCreateInfo yapısına zincirleyerek çağırır. Ardından uygulama, vkBindImageMemory2(KHR) ile VkBindImageMemoryInfo yapısına zincirlenmiş bir VkBindImageMemorySwapchainInfoKHR yapısını çağırır. VkBindImageMemorySwapchainInfoKHR yapısında belirtilen imageIndex, geçerli bir takas zinciri resim dizini olmalıdır. Bu sırada platform, VkNativeBufferANDROID uzantı yapısını VkBindImageMemoryInfo zincirine karşılık gelen Gralloc arabellek bilgileriyle birlikte sağlar. Böylece sürücü, VkImage ile hangi Gralloc arabelleğinin bağlanacağını bilir.

Görüntü edinme

vkAcquireImageANDROID, bir takas zinciri görüntüsünün sahipliğini alır ve harici olarak sinyal verilen yerel bir çiti hem mevcut bir VkSemaphore nesnesine hem de mevcut bir VkFence nesnesine aktarır:

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

vkAcquireImageANDROID(), uygulama tarafından sağlanan VkSemaphore ve VkFence nesnelerine yerel bir çit aktarmak için vkAcquireNextImageKHR sırasında çağrılır (ancak bu çağrıda hem semafor hem de çit nesneleri isteğe bağlıdır). Sürücü, bu fırsatı Gralloc arabellek durumundaki harici değişiklikleri tanımak ve işlemek için de kullanabilir. Birçok sürücünün burada herhangi bir işlem yapması gerekmez. Bu çağrı, VkSemaphore ve VkFence öğelerini vkQueueSubmit tarafından sinyal verilmiş gibi aynı bekleme durumuna getirir. Böylece kuyruklar semaforu bekleyebilir ve uygulama çiti bekleyebilir.

Temel yerel çit sinyal verdiğinde her iki nesne de sinyal verir. Yerel çit zaten sinyal vermişse bu işlev döndüğünde semafor sinyal verilmiş durumdadır. Sürücü, çit dosyası tanımlayıcısının sahipliğini alır ve artık gerekmediğinde çit dosyası tanımlayıcısını kapatır. Sürücü, semafor veya bariyer nesnesi sağlanmamış olsa ya da vkAcquireImageANDROID başarısız olup hata döndürse bile bunu yapmalıdır. fenceFd -1 ise yerel çit zaten sinyal verilmiş gibi davranılır.

Görüntüleri yayınlama

vkQueueSignalReleaseImageANDROID, harici kullanım için bir takas zinciri görüntüsü hazırlar, yerel bir bariyer oluşturur ve giriş semaforları sinyal verdikten sonra yerel bariyerin sinyal vermesini planlar:

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

vkQueuePresentKHR() aramalar vkQueueSignalReleaseImageANDROID() sağlanan kuyrukta. Sürücü, waitSemaphoreCount semaforları pWaitSemaphores içinde sinyal verene ve image'yi sunuma hazırlamak için gereken ek çalışmalar tamamlanana kadar sinyal vermeyen yerel bir çit oluşturmalıdır.

Bekleme semaforları (varsa) zaten sinyal vermişse ve queue zaten boşta ise sürücü, beklemesi gereken bir şey olmadığını belirtmek için *pNativeFenceFd değerini gerçek bir yerel çit dosya tanımlayıcısı yerine -1 olarak ayarlayabilir. Arayan, *pNativeFenceFd içinde döndürülen dosya tanımlayıcısına sahiptir ve onu kapatır.

Birçok sürücü, resim parametresini yoksayabilir ancak bazıları, harici görüntü tüketicileri tarafından kullanılmak üzere bir Gralloc arabelleğiyle ilişkili CPU tarafı veri yapılarını hazırlaması gerekebilir. Arabellek içeriklerinin harici tüketiciler tarafından kullanılmak üzere hazırlanması, görüntünün VK_IMAGE_LAYOUT_PRESENT_SRC_KHR'ya geçişi kapsamında eşzamansız olarak yapılmalıdır.

Resim VK_SWAPCHAIN_IMAGE_USAGE_SHARED_BIT_ANDROID ile oluşturulduysa sürücü, vkAcquireImageANDROID()'ye yapılan araya giren çağrılar olmadan vkQueueSignalReleaseImageANDROID()'nin tekrar tekrar çağrılmasına izin vermelidir.

Paylaşılan sunulabilir resim desteği

Bazı cihazlar, gecikmeyi en aza indirmek için tek bir görüntünün sahipliğini ekran ardışık düzeni ve Vulkan uygulaması arasında paylaşabilir. Android 9 ve sonraki sürümlerde yükleyici, sürücünün vkGetPhysicalDeviceProperties2 çağrısına verdiği yanıta göre VK_KHR_shared_presentable_image uzantısının reklamını koşullu olarak yapar.

Sürücü Vulkan 1.1'i veya VK_KHR_physical_device_properties2 uzantısını desteklemiyorsa yükleyici, paylaşılan sunulabilir resimler için desteği duyurmaz. Aksi takdirde yükleyici, vkGetPhysicalDeviceProperties2() çağrısı yaparak sürücü özelliklerini sorgular ve VkPhysicalDeviceProperties2::pNext zincirine aşağıdaki yapıyı dahil eder:

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

Sürücü, bir görüntünün sahipliğini görüntüleme sistemiyle paylaşabiliyorsa sharedImage üyesini VK_TRUE olarak ayarlar.

Doğrulama

OEM'ler, Vulkan uygulamalarını CTS ile test edebilir. CTS'de aşağıdakiler yer alır:

  • CtsDeqpTestCases modülündeki Khronos Vulkan Uygunluk testleri Vulkan 1.0, 1.1, 1.2, 1.3 ve 1.4 için işlevsel API testlerini içerir.
  • Cihazın, desteklediği Vulkan özellikleri için doğru şekilde yapılandırıldığını test eden CtsGraphicsTestCases modülü.

Vulkan özellik bayrağı

Bir özellik bayrağını kullanıma sunmak için Android 11 veya sonraki sürümleri destekleyen ve Vulkan API'sini destekleyen bir cihaz gerekir. android.software.vulkan.deqp.level. Bu özellik bayrağının değeri, tam sayı değeri olarak kodlanmış bir tarihtir. Cihazın geçtiğini iddia ettiği Vulkan dEQP testleriyle ilişkili tarihi belirtir.

YYYY-AA-GG biçimindeki bir tarih, 32 bitlik bir tam sayı olarak şu şekilde kodlanır:

  • 0-15 bitleri yılı saklar.
  • 16-23 bitleri ayı saklar.
  • 24-31. bitler günü saklar.

Özellik bayrağı için izin verilen minimum değer 0x07E30301'dır. Bu değer, Android 10 için Vulkan dEQP testleriyle ilişkili tarih olan 2019-03-01 tarihine karşılık gelir. Özellik bayrağı en az bu değere sahipse cihaz, Android 10 Vulkan dEQP testlerinin tümünü geçtiğini iddia eder.

0x07E40301 değeri, Android 11 için Vulkan dEQP testleriyle ilişkili tarih olan 2020-03-01 tarihine karşılık gelir. Özellik işareti en az bu değere sahipse cihaz, Android 11 Vulkan dEQP testlerinin tümünü geçtiğini iddia eder.

Değer 0x07E60301, Android 13 için Vulkan dEQP testleriyle ilişkilendirilmiş tarih olan 2022-03-01 tarihine karşılık gelir. Özellik bayrağı en az bu değere sahipse cihaz, Android 13 Vulkan dEQP testlerinin tümünü geçtiğini iddia eder.

Belirli bir özellik bayrağını (ör. 0x07E30301, 0x07E40301, 0x07E60301) kullanıma sunan bir cihaz, bu özellik bayrağının tüm Android Vulkan dEQP testlerini (sırasıyla Android 10, Android 11, Android 13) geçtiğini iddia eder. Bu cihaz, daha sonraki bir Android sürümündeki Vulkan dEQP testlerini geçebilir.

Vulkan dEQP, Android CTS'nin bir parçasıdır. Android 11'den itibaren CTS'nin dEQP test çalıştırıcı bileşeni android.software.vulkan.deqp.level özellik bayrağının farkındadır ve bu özellik bayrağına göre cihazın desteklediğini iddia etmediği tüm Vulkan dEQP testlerini atlar. Bu tür testler, önemsiz bir şekilde başarılı olarak bildirilir.