Vulkan را اجرا کنید

ولکان یک API چند پلتفرمی با سربار کم برای گرافیک‌های سه‌بعدی با کارایی بالا است. ولکان مانند OpenGL ES (GLES) ، ابزارهایی برای ایجاد گرافیک‌های با کیفیت بالا و بلادرنگ در برنامه‌ها فراهم می‌کند. مزایای استفاده از ولکان شامل کاهش سربار CPU و پشتیبانی از زبان SPIR-V Binary Intermediate است.

برای پیاده‌سازی موفقیت‌آمیز Vulkan، یک دستگاه باید شامل موارد زیر باشد:

  • لودر Vulkan، ارائه شده توسط اندروید.
  • یک درایور Vulkan، که توسط SoCهایی مانند GPU IHVها ارائه می‌شود و API Vulkan را پیاده‌سازی می‌کند. برای پشتیبانی از قابلیت Vulkan، دستگاه اندروید به سخت‌افزار GPU سازگار با Vulkan و درایور مرتبط با آن نیاز دارد. GPU همچنین باید از GLES 3.1 و بالاتر پشتیبانی کند. برای درخواست پشتیبانی درایور با فروشنده SoC خود مشورت کنید.

اگر دستگاهی شامل درایور Vulkan باشد، دستگاه باید ویژگی‌های سیستمی FEATURE_VULKAN_HARDWARE_LEVEL و FEATURE_VULKAN_HARDWARE_VERSION را به همراه نسخه‌هایی که به طور دقیق قابلیت‌های دستگاه را منعکس می‌کنند، اعلام کند. این امر به اطمینان از مطابقت دستگاه با سند تعریف سازگاری (CDD) کمک می‌کند.

لودر ولکان

لودر Vulkan platform/frameworks/native/vulkan رابط اصلی بین برنامه‌های Vulkan و درایور Vulkan دستگاه است. لودر Vulkan در /system/lib[64]/libvulkan.so نصب شده است. این لودر نقاط ورودی API اصلی Vulkan، نقاط ورودی افزونه‌های مورد نیاز Android CDD و بسیاری از افزونه‌های اختیاری اضافی را فراهم می‌کند. افزونه‌های Window System Integration (WSI) توسط لودر صادر می‌شوند و عمدتاً در لودر پیاده‌سازی می‌شوند نه در درایور. لودر همچنین از شمارش و بارگذاری لایه‌هایی پشتیبانی می‌کند که می‌توانند افزونه‌های اضافی را در معرض نمایش قرار دهند و فراخوانی‌های API اصلی را در مسیر رسیدن به درایور رهگیری کنند.

The NDK includes a stub libvulkan.so library for linking. The library exports the same symbols as the loader. Apps call the functions exported from the real libvulkan.so library to enter trampoline functions in the loader, which dispatch to the appropriate layer or driver based on their first argument. The vkGet*ProcAddr() call returns the function pointers to which the trampolines dispatch (that is, it calls directly into the core API code). Calling through the function pointers, rather than the exported symbols, is more efficient as it skips the trampoline and dispatch.

شمارش و بارگذاری درایورها

وقتی تصویر سیستم ساخته می‌شود، اندروید انتظار دارد که سیستم بداند کدام پردازنده‌های گرافیکی (GPU) در دسترس هستند. لودر از مکانیزم HAL موجود در hardware.h برای کشف و بارگذاری درایور استفاده می‌کند. مسیرهای ترجیحی برای درایورهای 32 بیتی و 64 بیتی Vulkan عبارتند از:

/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

در اندروید ۷.۰ و بالاتر، مشتق hw_module_t در Vulkan یک ساختار hw_module_t را در بر می‌گیرد؛ فقط یک درایور پشتیبانی می‌شود و رشته ثابت HWVULKAN_DEVICE_0 به open() ارسال می‌شود.

مشتق hw_device_t در Vulkan مربوط به یک درایور واحد است که می‌تواند از چندین دستگاه فیزیکی پشتیبانی کند. ساختار hw_device_t می‌تواند به توابع export vkGetGlobalExtensionProperties() ، vkCreateInstance() و vkGetInstanceProcAddr() گسترش یابد. لودر می‌تواند با فراخوانی vkGetInstanceProcAddr() ساختار hw_device_t ، تمام توابع VkInstance() ، VkPhysicalDevice() و vkGetDeviceProcAddr() دیگر را پیدا کند.

از اندروید ۱۵ به بعد، این لودر از APEX برای بارگذاری درایور Vulkan پشتیبانی می‌کند. برای بارگذاری Vulkan از APEX، ro.vulkan.apex را روی نام Vulkan APEX تنظیم کنید.

کشف و بارگذاری لایه

لودر Vulkan از شمارش و بارگذاری لایه‌ها پشتیبانی می‌کند که می‌توانند افزونه‌های اضافی را در معرض نمایش قرار دهند و فراخوانی‌های API اصلی را در مسیر رسیدن به درایور رهگیری کنند. برنامه‌ها می‌توانند لایه‌هایی را در APK خود داشته باشند. اندروید لایه‌هایی را در تصویر سیستم ندارد.

هنگام استفاده از لایه‌ها، به خاطر داشته باشید که مدل و سیاست‌های امنیتی اندروید با سایر پلتفرم‌ها تفاوت قابل توجهی دارد. به طور خاص، اندروید اجازه بارگذاری کد خارجی را در یک فرآیند غیرقابل اشکال‌زدایی در دستگاه‌های تولیدی (غیر روت) نمی‌دهد و همچنین به کد خارجی اجازه بازرسی یا کنترل حافظه، وضعیت و غیره فرآیند را نمی‌دهد. این شامل ممنوعیت ذخیره نسخه‌های اصلی، ردیابی‌های API و غیره در دیسک برای بررسی‌های بعدی می‌شود. فقط لایه‌هایی که به عنوان بخشی از برنامه‌های غیرقابل اشکال‌زدایی ارائه می‌شوند، در دستگاه‌های تولیدی فعال هستند و درایورها نباید عملکردی را ارائه دهند که این سیاست‌ها را نقض کند.

موارد استفاده از لایه‌ها عبارتند از:

  • لایه‌های زمان توسعه — لایه‌های اعتبارسنجی و ابزارهای ردیابی/پروفایلینگ/اشکال‌زدایی نباید روی تصویر سیستم دستگاه‌های تولیدی نصب شوند. لایه‌های اعتبارسنجی و ابزارهای ردیابی/پروفایلینگ/اشکال‌زدایی باید بدون تصویر سیستم قابل به‌روزرسانی باشند. توسعه‌دهندگانی که می‌خواهند در طول توسعه از یکی از این لایه‌ها استفاده کنند، می‌توانند بسته برنامه را تغییر دهند، به عنوان مثال، با اضافه کردن یک فایل به دایرکتوری کتابخانه‌های بومی خود. فرض می‌شود مهندسان IHV و OEM که می‌خواهند خرابی‌های موجود در ارسال برنامه‌های غیرقابل تغییر را تشخیص دهند، به نسخه‌های غیرتولیدی (روت‌شده) تصویر سیستم دسترسی دارند، مگر اینکه آن برنامه‌ها قابل اشکال‌زدایی باشند. برای اطلاعات بیشتر به لایه‌های اعتبارسنجی Vulkan در اندروید مراجعه کنید.
  • Utility layers — These layers expose extensions, such as a layer that implements a memory manager for device memory. Developers choose layers, and versions of those layers, to use in their app; different apps using the same layer may still use different versions. Developers choose which of these layers to ship in their app package.
  • لایه‌های تزریق‌شده (ضمنی) - شامل لایه‌هایی مانند نرخ فریم، شبکه‌های اجتماعی و پوشش‌های لانچر بازی است که توسط کاربر یا برخی برنامه‌های دیگر بدون اطلاع یا رضایت برنامه ارائه می‌شوند. این موارد سیاست‌های امنیتی اندروید را نقض می‌کنند و پشتیبانی نمی‌شوند.

برای برنامه‌های غیرقابل اشکال‌زدایی، لودر فقط در دایرکتوری کتابخانه بومی برنامه به دنبال لایه‌ها می‌گردد و سعی می‌کند هر کتابخانه‌ای را که نامی مطابق با الگوی خاصی دارد (مثلاً libVKLayer_foo.so ) بارگذاری کند. این لایه‌ها در فضای نام برنامه بارگذاری می‌شوند. به همین دلیل، باید با NDK ساخته شوند.

برای برنامه‌های قابل اشکال‌زدایی، لودر به دنبال لایه‌ها در /data/local/debug/vulkan می‌گردد و سعی می‌کند هر کتابخانه‌ای را که با الگوی خاصی مطابقت دارد، بارگیری کند. از اندروید ۱۰ (سطح API ۲۹)، Vulkan همچنین می‌تواند لایه‌های زمان توسعه را از یک APK دیگر بارگیری کند. در هر دو مورد، لودر با استفاده از تنظیمات سیستم ، لایه‌هایی را که برای هر برنامه فعال می‌شوند، انتخاب می‌کند. این لایه‌ها در vkEnumerateInstanceLayerProperties شمارش می‌شوند (یعنی ممکن است برنامه از آنها اطلاع داشته باشد)، حتی اگر بدون رضایت برنامه بارگیری شوند.

اندروید امکان انتقال لایه‌ها با تغییرات محیط ساخت بین اندروید و سایر پلتفرم‌ها را فراهم می‌کند. برای جزئیات بیشتر در مورد رابط بین لایه‌ها و لودر، به معماری رابط‌های لودر Vulkan مراجعه کنید. لایه‌های اعتبارسنجی نگهداری شده توسط Khronos در Vulkan Validation Layers میزبانی می‌شوند.

نسخه‌ها و قابلیت‌های رابط برنامه‌نویسی کاربردی ولکان

جدول زیر نسخه‌های API ولکان را برای چندین نسخه اندروید فهرست می‌کند.
نسخه اندروید نسخه ولکان
اندروید ۱۶ ولکان ۱.۴
اندروید ۱۳ ولکان ۱.۳
اندروید ۹ ولکان ۱.۱
اندروید ۷ ولکان ۱.۰

Vulkan 1.4 functionality overview

ولکان ۱.۴ تعدادی از افزونه‌های قبلاً اختیاری را به قابلیت‌های اصلی ولکان اضافه کرده است. بخش عمده‌ای از این قابلیت‌ها با هدف افزایش کنترل و جزئیات بیشتر بر رابط برنامه‌نویسی ولکان گنجانده شده‌اند. ولکان ۱.۴ در مقایسه با ولکان ۱.۳، الزامات سخت‌افزاری را افزایش می‌دهد و بیشتر پیاده‌سازی‌ها در درایور گرافیکی مخصوص SoC انجام می‌شود، نه در چارچوب.

Vulkan 1.3 functionality overview

ولکان ۱.۳ تعدادی از افزونه‌های قبلاً اختیاری را به قابلیت‌های اصلی ولکان اضافه کرده است. بخش عمده‌ای از این قابلیت‌ها با هدف افزایش کنترل و جزئیات بیشتر بر رابط برنامه‌نویسی ولکان گنجانده شده است. نمونه‌های رندر تک‌گذر دیگر نیازی به اشیاء رندر یا فریم‌بافر ندارند. تعداد کل اشیاء حالت خط لوله می‌تواند کاهش یابد و همگام‌سازی درون API مورد بازنگری قرار می‌گیرد. ولکان ۱.۳ همان الزامات سخت‌افزاری ولکان ۱.۲، ۱.۱ و ۱.۰ را دارد و بیشتر پیاده‌سازی آن در درایور گرافیکی مخصوص SoC انجام شده است، نه در چارچوب.

مهم‌ترین ویژگی‌های Vulkan 1.3 برای اندروید عبارتند از:

  • پشتیبانی از نمونه‌های رندر تک‌گذر
  • پشتیبانی از خاتمه فوری فراخوانی سایه‌زن
  • جزئیات دقیق‌تر در مورد ایجاد، اشتراک‌گذاری و کنترل پایپ‌لاین

ولکان ۱.۳ همچنین شامل چندین ویژگی کوچک‌تر و بهبودهایی در قابلیت استفاده از API است. تمام تغییرات اعمال شده در هسته API ولکان با نسخه جزئی ۱.۳ را می‌توانید در Core Revisions (ولکان ۱.۳) بیابید.

مروری بر قابلیت‌های ولکان ۱.۲

ولکان ۱.۲ تعدادی ویژگی و افزونه اضافه کرده است که سطح API را ساده می‌کند. این شامل یک مدل حافظه یکپارچه و اطلاعات اضافی است که می‌توان از درایور دستگاه درخواست کرد. ولکان ۱.۲ همان الزامات سخت‌افزاری ولکان ۱.۰ و ۱.۱ را دارد؛ تمام پیاده‌سازی‌ها در درایور گرافیکی مخصوص SoC است، نه در چارچوب.

مهم‌ترین ویژگی Vulkan 1.2 برای اندروید، پشتیبانی از ذخیره‌سازی ۸ بیتی است.

ولکان ۱.۲ همچنین شامل چندین ویژگی کوچک‌تر و بهبودهایی در قابلیت استفاده از API است. تمام تغییرات اعمال شده در هسته API ولکان با نسخه جزئی ۱.۲ را می‌توانید در Core Revisions (ولکان ۱.۲) بیابید.

مروری بر قابلیت‌های ولکان ۱.۱

Vulkan 1.1 includes support for memory/synchronization interop, which enables OEMs to support Vulkan 1.1 on devices. Additionally, memory/synchronization interop enables developers to determine whether Vulkan 1.1 is supported on a device, and use it effectively when it is. Vulkan 1.1 has the same hardware requirements as Vulkan 1.0, but most of the implementation is in the SOC-specific graphics driver, not in the framework.

مهم‌ترین ویژگی‌های Vulkan 1.1 برای اندروید عبارتند از:

  • Support for importing and exporting memory buffers and synchronization objects from outside Vulkan (for interop with camera, codecs, and GLES)
  • پشتیبانی از فرمت‌های YCbCr

ولکان ۱.۱ همچنین شامل چندین ویژگی کوچک‌تر و بهبودهایی در قابلیت استفاده از API است. تمام تغییرات اعمال شده در هسته API ولکان با نسخه جزئی ۱.۱ را می‌توانید در Core Revisions (ولکان ۱.۱) بیابید.

پشتیبانی Vulkan را انتخاب کنید

همه دستگاه‌های اندروید باید از پیشرفته‌ترین مجموعه ویژگی‌های Vulkan موجود پشتیبانی کنند، مشروط بر اینکه از ABI 64 بیتی پشتیبانی کنند و حافظه کمی نداشته باشند.

دستگاه‌هایی که با اندروید ۱۶ و بالاتر عرضه می‌شوند، باید از Vulkan 1.4 پشتیبانی کنند.

دستگاه‌هایی که با اندروید ۱۳ و بالاتر عرضه می‌شوند، باید از Vulkan 1.3 پشتیبانی کنند.

دستگاه‌هایی که با اندروید ۱۰ عرضه می‌شوند باید از Vulkan 1.1 پشتیبانی کنند.

سایر دستگاه‌ها می‌توانند به صورت اختیاری از Vulkan 1.4، 1.3، 1.2 و 1.1 پشتیبانی کنند.

پشتیبانی از نسخه Vulkan

یک دستگاه اندروید در صورت برآورده شدن شرایط زیر از نسخه Vulkan پشتیبانی می‌کند:

  1. یک درایور Vulkan که از نسخه Vulkan مورد نظر شما پشتیبانی می‌کند (این باید یکی از نسخه‌های Vulkan 1.4، 1.3، 1.1 یا 1.0 باشد) را در کنار الزامات CDD اضافی نسخه اندروید اضافه کنید. روش دیگر، به‌روزرسانی درایور Vulkan موجود با شماره نسخه پایین‌تر Vulkan است.
  2. برای Vulkan نسخه‌های ۱.۴، ۱.۳ یا ۱.۱، بررسی کنید که ویژگی سیستمی برگردانده شده توسط مدیر بسته، برای نسخه صحیح Vulkan true برگرداند.
    • برای Vulkan 1.4 این ویژگی به PackageManager#hasSystemFeature(PackageManager.FEATURE_VULKAN_HARDWARE_VERSION, 0x404000) است.
    • برای Vulkan 1.3 این ویژگی به PackageManager#hasSystemFeature(PackageManager.FEATURE_VULKAN_HARDWARE_VERSION, 0x403000) است.
    • برای Vulkan 1.1 این ویژگی به PackageManager#hasSystemFeature(PackageManager.FEATURE_VULKAN_HARDWARE_VERSION, 0x401000) است.
    مدیر بسته با اضافه کردن یک قانون، که به شرح زیر نشان داده شده است، به یک فایل device.mk مناسب، برای Vulkan 1.4، 1.3 و 1.1 true برمی‌گرداند.
    • موارد زیر را برای Vulkan 1.4 اضافه کنید:
      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 اضافه کنید:
      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
    • Add the following for 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

نمایه پایه اندروید (ABP)

ما همه دستگاه‌های اندروید را تشویق می‌کنیم که خود را با آخرین نسخه اندروید بیس‌لاین ۲۰۲۲، همانطور که در راهنمای اندروید بیس‌لاین پروفایل ذکر شده است، مطابقت دهند.

هر دستگاهی که از اندروید ۱۴ یا بالاتر و رابط برنامه‌نویسی کاربردی ولکان (Vulkan API) پشتیبانی می‌کند، باید تمام عملکردهای تعریف‌شده در پروفایل اندروید بیس‌لاین ۲۰۲۱ را برآورده کند. لیست کامل عملکردهای مورد نیاز در فایل json پروفایل ولکان فهرست شده است، اما زیرمجموعه‌ای کلیدی از عملکردهای مورد نیاز شامل موارد زیر است:

  • بافت‌های فشرده‌شده از طریق ASTC و ETC.
  • فضاهای رنگی متغیر از طریق VK_EXT_swapchain_colorspace .
  • سایه‌زنی نمونه و درون‌یابی چندنمونه‌ای از طریق sampleRateShading .

یکپارچه‌سازی سیستم پنجره (WSI)

در libvulkan.so ، درایور افزونه‌های یکپارچه‌سازی سیستم پنجره (WSI) زیر را پیاده‌سازی می‌کند:

  • VK_KHR_surface
  • VK_KHR_android_surface
  • VK_KHR_swapchain
  • VK_KHR_driver_properties ، فقط برای Vulkan 1.1 در اندروید ۱۰ پیاده‌سازی شده است
  • VK_GOOGLE_display_timing , implemented for any Vulkan version in Android 10

اشیاء VkSurfaceKHR و VkSwapchainKHR و تمام تعاملات با ANativeWindow توسط پلتفرم مدیریت می‌شوند و در معرض درایورها قرار ندارند. پیاده‌سازی WSI به افزونه‌ی VK_ANDROID_native_buffer متکی است که باید توسط درایور پشتیبانی شود؛ این افزونه فقط توسط پیاده‌سازی WSI استفاده می‌شود و در معرض برنامه‌ها قرار ندارد.

پرچم‌های استفاده از گرالک

پیاده‌سازی‌های Vulkan ممکن است نیاز داشته باشند که بافرهای swapchain با پرچم‌های استفاده خصوصی Gralloc که توسط پیاده‌سازی تعریف شده‌اند، تخصیص داده شوند. هنگام ایجاد یک swapchain، اندروید از درایور می‌خواهد که با فراخوانی دستور زیر، پرچم‌های استفاده از فرمت و تصویر درخواستی را به پرچم‌های استفاده از Gralloc ترجمه کند:

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

The format and imageUsage parameters are taken from the VkSwapchainCreateInfoKHR structure. The driver should fill *grallocConsumerUsage and *grallocProducerUsage with the Gralloc usage flags required for the format and usage. The usage flags returned by the driver are combined with the usage flags requested by the swapchain consumer when allocating buffers.

اندروید ۷.x نسخه قدیمی‌تری از VkSwapchainImageUsageFlagsANDROID() را با نام vkGetSwapchainGrallocUsageANDROID() فراخوانی می‌کند. اندروید ۸.۰ و بالاتر vkGetSwapchainGrallocUsageANDROID() را منسوخ می‌کند، اما اگر vkGetSwapchainGrallocUsageANDROID vkGetSwapchainGrallocUsageANDROID() vkGetSwapchainGrallocUsage2ANDROID() را فراخوانی می‌کند:

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

vkGetSwapchainGrallocUsageANDROID() از پرچم‌های استفاده از swapchain یا پرچم‌های استفاده از Gralloc توسعه‌یافته پشتیبانی نمی‌کند.

تصاویر با پشتیبانی گرالک

VkNativeBufferANDROID یک ساختار افزونه vkCreateImage برای ایجاد تصویری است که توسط یک بافر Gralloc پشتیبانی می‌شود. VkNativeBufferANDROID در زنجیره ساختار VkImageCreateInfo برای vkCreateImage() ارائه شده است. فراخوانی‌های vkCreateImage() با VkNativeBufferANDROID در طول فراخوانی vkCreateSwapchainKHR اتفاق می‌افتد. پیاده‌سازی WSI تعداد بافرهای بومی درخواست شده برای swapchain را اختصاص می‌دهد، سپس برای هر یک یک VkImage ایجاد می‌کند:

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

    // Buffer handle and stride returned from gralloc alloc()
    buffer_handle_t             handle;
    int                         stride;

    // Gralloc format and usage requested when the buffer was allocated.
    int                         format;
    int                         usage;
    // Beginning in Android 8.0, the usage field above is deprecated and the
    // usage2 struct below was added. The usage field is still filled in for
    // compatibility with Android 7.0 drivers. Drivers for Android 8.0
    // should prefer the usage2 struct, especially if the
    // android.hardware.graphics.allocator HAL uses the extended usage bits.
    struct {
        uint64_t                consumer;
        uint64_t                producer;
    } usage2;
} VkNativeBufferANDROID;

هنگام ایجاد یک تصویر با پشتیبانی Gralloc، VkImageCreateInfo داده‌های زیر را دارد:

  .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

در اندروید ۸.۰ و بالاتر، پلتفرم یک ساختار افزونه VkSwapchainImageCreateInfoKHR را در زنجیره VkImageCreateInfo ارائه می‌دهد که در صورت نیاز به هرگونه پرچم استفاده از تصویر swapchain برای swapchain، در اختیار vkCreateImage قرار می‌گیرد. این ساختار افزونه شامل پرچم‌های استفاده از تصویر swapchain است:

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

    VkSwapchainImageUsageFlagsANDROID      usage;
} VkSwapchainImageCreateInfoANDROID;

در اندروید ۱۰ و بالاتر، این پلتفرم از VK_KHR_swapchain نسخه ۷۰ پشتیبانی می‌کند، بنابراین برنامه Vulkan قادر به ایجاد یک VkImage با پشتیبانی حافظه swapchain است. برنامه ابتدا vkCreateImage با ساختار VkImageSwapchainCreateInfoKHR که به ساختار VkImageCreateInfo زنجیر شده است، فراخوانی می‌کند. سپس برنامه vkBindImageMemory2(KHR) را با ساختار VkBindImageMemorySwapchainInfoKHR که به ساختار VkBindImageMemoryInfo زنجیر شده است، فراخوانی می‌کند. imageIndex مشخص شده در ساختار VkBindImageMemorySwapchainInfoKHR باید یک شاخص تصویر معتبر swapchain باشد. در همین حال، این پلتفرم یک ساختار افزونه VkNativeBufferANDROID با اطلاعات بافر Gralloc مربوطه را به زنجیره VkBindImageMemoryInfo ارائه می‌دهد، بنابراین راننده می‌داند که VkImage با کدام بافر Gralloc متصل کند.

Acquire images

vkAcquireImageANDROID مالکیت یک تصویر swapchain را به دست می‌آورد و یک حصار بومی سیگنال‌دهی شده خارجی را هم به یک شیء VkSemaphore موجود و هم به یک شیء VkFence موجود وارد می‌کند:

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

vkAcquireImageANDROID() در طول vkAcquireNextImageKHR فراخوانی می‌شود تا یک حصار بومی را به اشیاء VkSemaphore و VkFence ارائه شده توسط برنامه وارد کند (با این حال، اشیاء semaphore و fence در این فراخوانی اختیاری هستند). درایور همچنین می‌تواند از این فرصت برای تشخیص و مدیریت هرگونه تغییر خارجی در وضعیت بافر Gralloc استفاده کند. بسیاری از درایورها نیازی به انجام کاری در اینجا ندارند. این فراخوانی VkSemaphore و VkFence را در همان حالت معلق قرار می‌دهد که گویی توسط vkQueueSubmit سیگنال داده شده است، بنابراین صف‌ها می‌توانند در semaphore منتظر بمانند و برنامه می‌تواند در fence منتظر بماند.

هر دو شیء زمانی که حصار بومی زیرین سیگنال می‌دهد، سیگنال دریافت می‌کنند. اگر حصار بومی قبلاً سیگنال داده باشد، آنگاه سمافور هنگام بازگشت این تابع در حالت سیگنال قرار دارد. درایور مالکیت توصیف‌گر فایل حصار را به دست می‌گیرد و وقتی دیگر نیازی به آن نباشد، توصیف‌گر فایل حصار را می‌بندد. درایور باید این کار را انجام دهد، حتی اگر هیچ سمافوری یا شیء حصار ارائه نشده باشد، یا حتی اگر vkAcquireImageANDROID ناموفق باشد و خطایی را برگرداند. اگر fenceFd برابر با -1 باشد، گویی حصار بومی قبلاً سیگنال دریافت کرده است.

انتشار تصاویر

vkQueueSignalReleaseImageANDROID یک تصویر swapchain را برای استفاده خارجی آماده می‌کند، یک حصار بومی ایجاد می‌کند و حصار بومی را طوری زمان‌بندی می‌کند که پس از سیگنال شدن سمافورهای ورودی، سیگنال‌دهی شود:

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

vkQueuePresentKHR() تابع vkQueueSignalReleaseImageANDROID() را در صف ارائه شده فراخوانی می‌کند. درایور باید یک حصار بومی ایجاد کند که تا زمانی که همه سمافورهای waitSemaphoreCount در سیگنال pWaitSemaphores و هرگونه کار اضافی مورد نیاز برای آماده‌سازی image برای ارائه تکمیل نشوند، سیگنال ارسال نکند.

اگر سمافورهای انتظار (در صورت وجود) از قبل سیگنال داده باشند و queue در حال حاضر بیکار باشد، درایور می‌تواند *pNativeFenceFd به جای یک توصیف‌گر فایل حصار بومی واقعی، روی -1 تنظیم کند، که نشان می‌دهد چیزی برای انتظار وجود ندارد. فراخوانی‌کننده توصیف‌گر فایل برگردانده شده در *pNativeFenceFd را در اختیار می‌گیرد و می‌بندد.

بسیاری از درایورها می‌توانند پارامتر تصویر را نادیده بگیرند، اما برخی ممکن است نیاز داشته باشند ساختارهای داده سمت CPU مرتبط با یک بافر Gralloc را برای استفاده توسط مصرف‌کنندگان تصویر خارجی آماده کنند. آماده‌سازی محتوای بافر برای استفاده توسط مصرف‌کنندگان خارجی باید به صورت غیرهمزمان و به عنوان بخشی از انتقال تصویر به VK_IMAGE_LAYOUT_PRESENT_SRC_KHR انجام شود.

If the image was created with VK_SWAPCHAIN_IMAGE_USAGE_SHARED_BIT_ANDROID , then the driver must allow vkQueueSignalReleaseImageANDROID() to be called repeatedly without intervening calls to vkAcquireImageANDROID() .

پشتیبانی از تصویر قابل ارائه مشترک

برخی از دستگاه‌ها می‌توانند مالکیت یک تصویر واحد را بین خط لوله نمایش و پیاده‌سازی Vulkan به اشتراک بگذارند تا تأخیر را به حداقل برسانند. در اندروید ۹ و بالاتر، لودر به طور مشروط افزونه VK_KHR_shared_presentable_image را بر اساس پاسخ درایور به فراخوانی vkGetPhysicalDeviceProperties2 تبلیغ می‌کند.

If the driver doesn't support either Vulkan 1.1 or the VK_KHR_physical_device_properties2 extension, the loader doesn't advertise support for shared presentable images. Otherwise, the loader queries the driver capabilities by calling vkGetPhysicalDeviceProperties2() and including the following structure in the VkPhysicalDeviceProperties2::pNext chain:

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

اگر درایور بتواند مالکیت یک تصویر را با سیستم نمایش به اشتراک بگذارد، عضو sharedImage را روی VK_TRUE تنظیم می‌کند.

اعتبارسنجی

تولیدکنندگان تجهیزات اصلی (OEM) می‌توانند پیاده‌سازی Vulkan خود را با استفاده از CTS آزمایش کنند که شامل موارد زیر است:

  • تست‌های انطباق Khronos Vulkan در ماژول CtsDeqpTestCases که شامل تست‌های عملکردی API برای Vulkan نسخه‌های ۱.۰، ۱.۱، ۱.۲، ۱.۳ و ۱.۴ می‌شود.
  • ماژول CtsGraphicsTestCases که پیکربندی صحیح دستگاه را برای قابلیت‌های Vulkan که از آنها پشتیبانی می‌کند، آزمایش می‌کند.

پرچم ویژه ولکان

دستگاهی که از اندروید ۱۱ یا بالاتر و رابط برنامه‌نویسی کاربردی Vulkan پشتیبانی می‌کند، ملزم به نمایش یک feature flag به نام android.software.vulkan.deqp.level است. مقدار این feature flag یک تاریخ است که به صورت یک عدد صحیح کدگذاری شده است. این تاریخ، تاریخ مرتبط با تست‌های Vulkan dEQP را که دستگاه ادعا می‌کند در آنها قبول شده است، مشخص می‌کند.

یک تاریخ به شکل YYYY-MM-DD به صورت یک عدد صحیح ۳۲ بیتی به صورت زیر کدگذاری می‌شود:

  • بیت‌های ۰ تا ۱۵ سال را ذخیره می‌کنند
  • بیت‌های ۱۶ تا ۲۳ ماه را ذخیره می‌کنند
  • بیت‌های ۲۴ تا ۳۱، روز را ذخیره می‌کنند

حداقل مقدار مجاز برای feature flag برابر با 0x07E30301 است که مربوط به تاریخ 2019-03-01 است، که تاریخ مرتبط با تست‌های Vulkan dEQP برای اندروید 10 است. اگر feature flag حداقل این مقدار را داشته باشد، دستگاه ادعا می‌کند که تمام تست‌های Vulkan dEQP اندروید 10 را با موفقیت پشت سر گذاشته است.

Value 0x07E40301 corresponds to the date 2020-03-01, which is the date associated with the Vulkan dEQP tests for Android 11. If the feature flag is at least this value, the device claims to pass all of the Android 11 Vulkan dEQP tests.

مقدار 0x07E60301 مربوط به تاریخ 2022-03-01 است، که تاریخ مرتبط با آزمایش‌های Vulkan dEQP برای اندروید ۱۳ است. اگر feature flag حداقل این مقدار باشد، دستگاه ادعا می‌کند که تمام آزمایش‌های Vulkan dEQP اندروید ۱۳ را با موفقیت پشت سر گذاشته است.

دستگاهی که یک feature flag خاص ( مثلاً 0x07E30301 ، 0x07E40301 ، 0x07E60301 ) را نمایش می‌دهد، ادعا می‌کند که تمام تست‌های dEQP اندروید Vulkan مربوط به آن feature flag (به ترتیب اندروید 10، اندروید 11، اندروید 13) را با موفقیت پشت سر گذاشته است. این دستگاه ممکن است تست‌های dEQP ولکان مربوط به نسخه‌های بعدی اندروید را با موفقیت پشت سر بگذارد.

Vulkan dEQP بخشی از Android CTS را تشکیل می‌دهد. از اندروید ۱۱، کامپوننت اجراکننده تست dEQP در CTS از پرچم ویژگی android.software.vulkan.deqp.level آگاه است و از هر تست Vulkan dEQP که - طبق این پرچم ویژگی - دستگاه ادعای پشتیبانی از آن را ندارد، صرف نظر می‌کند. چنین تست‌هایی به عنوان تست‌های بی‌اهمیت و موفق گزارش می‌شوند.