Внедрить Вулкан

Vulkan — это кроссплатформенный API с низкими издержками для высокопроизводительной 3D-графики. Как и OpenGL ES (GLES) , Vulkan предоставляет инструменты для создания высококачественной графики в реальном времени в приложениях. Преимущества использования Vulkan включают снижение нагрузки на ЦП и поддержку двоичного промежуточного языка SPIR-V .

Для успешного внедрения Vulkan устройство должно включать:

  • Загрузчик Vulkan, предоставляемый Android.
  • Драйвер Vulkan, предоставляемый SoC, например IHV графического процессора, который реализует API Vulkan . Для поддержки функций Vulkan устройству Android требуется аппаратное обеспечение графического процессора с поддержкой Vulkan и соответствующий драйвер. Графический процессор также должен поддерживать GLES 3.1 и выше. Обратитесь к поставщику SoC, чтобы запросить поддержку драйверов.

Если устройство включает драйвер Vulkan, в нем необходимо объявить системные функции FEATURE_VULKAN_HARDWARE_LEVEL и FEATURE_VULKAN_HARDWARE_VERSION с версиями, которые точно отражают возможности устройства. Это помогает гарантировать, что устройство соответствует Документу определения совместимости (CDD).

Вулкан загрузчик

platform/frameworks/native/vulkan — это основной интерфейс между приложениями Vulkan и драйвером Vulkan устройства. Загрузчик Vulkan установлен в /system/lib[64]/libvulkan.so . Загрузчик предоставляет основные точки входа API Vulkan, точки входа расширений, необходимых для Android CDD, а также множество дополнительных дополнительных расширений. Расширения Windows System Integration (WSI) экспортируются загрузчиком и в основном реализуются в загрузчике, а не в драйвере. Загрузчик также поддерживает уровни перечисления и загрузки, которые могут предоставлять дополнительные расширения и перехватывать вызовы основного API на пути к драйверу.

NDK включает в себя библиотеку-заглушку libvulkan.so для компоновки. Библиотека экспортирует те же символы, что и загрузчик. Приложения вызывают функции, экспортированные из реальной библиотеки libvulkan.so , для ввода батутных функций в загрузчик, которые отправляются на соответствующий уровень или драйвер на основе их первого аргумента. Вызов vkGet*ProcAddr() возвращает указатели на функции, к которым отправляются батуты (то есть он вызывает непосредственно в основной код API). Вызов через указатели функций, а не через экспортированные символы, более эффективен, поскольку позволяет избежать батута и диспетчеризации.

Перечисление и загрузка драйверов

Когда образ системы создан, Android ожидает, что система будет знать, какие графические процессоры доступны. Загрузчик использует существующий механизм HAL в hardware.h для обнаружения и загрузки драйвера. Предпочтительные пути для 32-битных и 64-битных драйверов Vulkan:

/vendor/lib/hw/vulkan.<ro.hardware.vulkan>.so
/vendor/lib/hw/vulkan.<ro.product.platform>.so
/vendor/lib64/hw/vulkan.<ro.hardware.vulkan>.so
/vendor/lib64/hw/vulkan.<ro.product.platform>.so

В Android 7.0 и выше производная от Vulkan hw_module_t оборачивает одну структуру hw_module_t ; поддерживается только один драйвер, а константная строка HWVULKAN_DEVICE_0 передается в open() .

Производная Vulkan hw_device_t соответствует одному драйверу, который может поддерживать несколько физических устройств. Структура hw_device_t может расширяться для экспорта функций vkGetGlobalExtensionProperties() , vkCreateInstance() и vkGetInstanceProcAddr() . Загрузчик может найти все остальные функции VkInstance() , VkPhysicalDevice() и vkGetDeviceProcAddr() , вызвав vkGetInstanceProcAddr() структуры hw_device_t .

Обнаружение и загрузка слоев

Загрузчик Vulkan поддерживает перечисление и загрузку слоев, которые могут предоставлять дополнительные расширения и перехватывать вызовы основного API на пути к драйверу. Android не включает слои в образ системы; однако приложения могут включать слои в свой APK.

При использовании уровней имейте в виду, что модель и политики безопасности Android существенно отличаются от других платформ. В частности, Android не позволяет загружать внешний код в неотлаживаемый процесс на рабочих (нерутированных) устройствах, а также не позволяет внешнему коду проверять или контролировать память, состояние и т. д. процесса. Сюда входит запрет на сохранение дампов ядра, трассировок API и т. д. на диск для последующей проверки. На рабочих устройствах включены только слои, поставляемые как часть неотлаживаемых приложений, а драйверы не должны предоставлять функциональные возможности, нарушающие эти политики.

Варианты использования слоев включают в себя:

  • Слои времени разработки . Слои проверки и прокладки для инструментов трассировки, профилирования и отладки не следует устанавливать в системный образ производственных устройств. Слои проверки и прокладки для инструментов трассировки/профилирования/отладки должны обновляться без образа системы. Разработчики, которые хотят использовать один из этих уровней во время разработки, могут изменить пакет приложения, например, добавив файл в каталог собственных библиотек. Предполагается, что инженеры IHV и OEM, которые хотят диагностировать сбои при доставке неизменяемых приложений, имеют доступ к непроизводственным (рутованным) сборкам образа системы, если только эти приложения не подлежат отладке. Дополнительную информацию см. в разделе Слои проверки Vulkan на Android .
  • Уровни служебных программ . Эти уровни предоставляют расширения, например уровень, реализующий диспетчер памяти для памяти устройства. Разработчики выбирают слои и версии этих слоев для использования в своем приложении; разные приложения, использующие один и тот же слой, могут по-прежнему использовать разные версии. Разработчики выбирают, какой из этих слоев включить в свой пакет приложения.
  • Внедренные (неявные) слои — включают в себя такие слои, как частота кадров, социальные сети и наложения запуска игр, предоставленные пользователем или каким-либо другим приложением без ведома или согласия приложения. Они нарушают политику безопасности Android и не поддерживаются.

Для неотлаживаемых приложений загрузчик ищет слои только в каталоге собственной библиотеки приложения и пытается загрузить любую библиотеку с именем, соответствующим определенному шаблону (например, libVKLayer_foo.so ).

Для отлаживаемых приложений загрузчик ищет слои в /data/local/debug/vulkan и пытается загрузить любую библиотеку, соответствующую определенному шаблону.

Android позволяет переносить слои с изменениями среды сборки между Android и другими платформами. Подробности об интерфейсе между слоями и загрузчиком см. в разделе Архитектура интерфейсов загрузчика Vulkan . Уровни проверки, поддерживаемые Khronos, размещаются в Vulkan Validation Layers .

Версии и возможности Vulkan API

В следующей таблице перечислены версии API Vulkan для нескольких выпусков Android.
Версия Android Вулканская версия
Андроид 13 Вулкан 1.3
Андроид 9 Вулкан 1.1
Андроид 7 Вулкан 1.0

Обзор функциональности Vulkan 1.3

Vulkan 1.3 канонизирует ряд ранее необязательных расширений основной функциональности Vulkan. Большая часть этой функциональности включена с целью повышения контроля и детализации интерфейса программирования Vulkan. Экземпляры прохода рендеринга с одним проходом больше не нуждаются в объектах прохода рендеринга или буферах кадров. Общее количество объектов состояния конвейера может быть уменьшено, а синхронизация внутри API переработана. Vulkan 1.3 имеет те же требования к оборудованию, что и Vulkan 1.2, 1.1 и 1.0, при этом большая часть реализации реализована в графическом драйвере, специфичном для SoC, а не в платформе.

Наиболее важные функции Vulkan 1.3 для Android:

  • Поддержка экземпляров прохода рендеринга за один проход.
  • Поддержка немедленного завершения вызова шейдера.
  • Более тонкая детализация создания конвейера, совместного использования и контроля.

Vulkan 1.3 также включает несколько небольших функций и улучшений удобства использования API. Все изменения, внесенные в основной API Vulkan с незначительной версией 1.3, можно найти в разделе Core Revisions (Vulkan 1.3) .

Обзор функциональности Vulkan 1.2

В Vulkan 1.2 добавлен ряд функций и расширений, упрощающих интерфейс API. Сюда входит унифицированная модель памяти и дополнительная информация, которую можно запросить у драйвера устройства. Vulkan 1.2 предъявляет те же требования к оборудованию, что и Vulkan 1.0 и 1.1; вся реализация находится в графическом драйвере, специфичном для SoC, а не в платформе.

Самая важная особенность Vulkan 1.2 для Android — поддержка 8-битного хранилища.

Vulkan 1.2 также включает несколько небольших функций и улучшений удобства использования API. Все изменения, внесенные в основной API Vulkan с незначительной версией 1.2, можно найти в разделе Core Revisions (Vulkan 1.2) .

Обзор функциональности Vulkan 1.1

Vulkan 1.1 включает поддержку взаимодействия памяти/синхронизации, что позволяет OEM-производителям поддерживать Vulkan 1.1 на устройствах. Кроме того, взаимодействие памяти/синхронизации позволяет разработчикам определить, поддерживается ли Vulkan 1.1 на устройстве, и эффективно использовать его, когда это возможно. Vulkan 1.1 имеет те же требования к оборудованию, что и Vulkan 1.0, но большая часть реализации находится в графическом драйвере, специфичном для SOC, а не в платформе.

Наиболее важные функции Vulkan 1.1 для Android:

  • Поддержка импорта и экспорта буферов памяти и объектов синхронизации из-за пределов Vulkan (для взаимодействия с камерой, кодеками и GLES).
  • Поддержка форматов YCbCr.

Vulkan 1.1 также включает несколько небольших функций и улучшений удобства использования API. Все изменения, внесенные в основной API Vulkan с незначительной версией 1.1, можно найти в разделе Core Revisions (Vulkan 1.1) .

Выберите поддержку Vulkan

Устройства Android должны поддерживать самый расширенный доступный набор функций Vulkan при условии, что они поддерживают 64-битный ABI и не имеют недостатка памяти.

Устройства, работающие под управлением Android 13 и более поздних версий, должны поддерживать Vulkan 1.3.

Устройства, запускаемые под управлением Android 10, должны поддерживать Vulkan 1.1.

Другие устройства могут дополнительно поддерживать Vulkan 1.3, 1.2 и 1.1.

Поддержка версии Vulkan

Устройство Android поддерживает версию Vulkan, если выполняются следующие условия:

  1. Добавьте драйвер Vulkan, который поддерживает интересующую версию Vulkan (это должна быть одна из версий Vulkan 1.3, 1.1 или 1.0), а также дополнительные требования CDD для версии Android. Альтернативно обновите существующий драйвер Vulkan до более низкой версии Vulkan.
  2. Для Vulkan 1.3 или 1.1 убедитесь, что системная функция, возвращаемая менеджером пакетов, возвращает true для правильной версии Vulkan.
    • Для Vulkan 1.3 эта функция — PackageManager#hasSystemFeature(PackageManager.FEATURE_VULKAN_HARDWARE_VERSION, 0x403000) .
    • Для Vulkan 1.1 эта функция — PackageManager#hasSystemFeature(PackageManager.FEATURE_VULKAN_HARDWARE_VERSION, 0x401000) .
    Менеджер пакетов вернет true для Vulkan 1.3 и Vulkan 1.1, добавив правило, показанное ниже, в соответствующий файл device.mk .
    • Добавьте следующее для 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
      
    • Добавьте следующее для 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
      

Базовый профиль Android (ABP)

Мы рекомендуем всем устройствам Android соответствовать последней версии профиля Android Baseline 2022, как указано в руководстве по профилю Android Baseline .

Любое устройство, поддерживающее Android 14 или более поздней версии и API Vulkan, должно выполнять все функции, определенные в профиле Android Baseline 2021 . Полный список необходимых функций указан в json файле профиля Vulkan, но ключевое подмножество необходимых функций включает в себя:

  • Текстуры сжаты посредством 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 только в Android 10.
  • VK_GOOGLE_display_timing , реализовано для любой версии Vulkan в Android 10.

Объекты VkSurfaceKHR и VkSwapchainKHR и все взаимодействия с ANativeWindow обрабатываются платформой и не доступны драйверам. Реализация WSI опирается на расширение VK_ANDROID_native_buffer , которое должно поддерживаться драйвером; это расширение используется только реализацией WSI и не доступно приложениям.

Флаги использования Gralloc

Реализациям Vulkan может потребоваться выделение буферов цепочки обмена с определенными реализацией частными флагами использования Gralloc. При создании цепочки обмена Android просит драйвер преобразовать запрошенные флаги использования формата и изображения в флаги использования 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
);

Параметры format и imageUsage взяты из структуры VkSwapchainCreateInfoKHR . Драйвер должен заполнить *grallocConsumerUsage и *grallocProducerUsage флагами использования Gralloc, необходимыми для формата и использования. Флаги использования, возвращаемые драйвером, объединяются с флагами использования, запрошенными потребителем цепочки буферов при выделении буферов.

Android 7.x вызывает более раннюю версию VkSwapchainImageUsageFlagsANDROID() с именем vkGetSwapchainGrallocUsageANDROID() . В Android 8.0 и более поздних версиях vkGetSwapchainGrallocUsageANDROID() устарела, но по-прежнему вызывает vkGetSwapchainGrallocUsageANDROID() , если vkGetSwapchainGrallocUsage2ANDROID() не предусмотрен драйвером:

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

vkGetSwapchainGrallocUsageANDROID() не поддерживает флаги использования цепочки обмена или расширенные флаги использования Gralloc.

Изображения на основе Gralloc

VkNativeBufferANDROID — это структура расширения vkCreateImage для создания изображения, поддерживаемого буфером Gralloc. VkNativeBufferANDROID предоставляется функции vkCreateImage() в цепочке структур VkImageCreateInfo . Вызовы vkCreateImage() с VkNativeBufferANDROID происходят во время вызова vkCreateSwapchainKHR . Реализация WSI выделяет количество собственных буферов, запрошенных для цепочки обмена, а затем создает 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

В Android 8.0 и более поздних версиях платформа предоставляет структуру расширения VkSwapchainImageCreateInfoKHR в цепочке VkImageCreateInfo , предоставляемой vkCreateImage , когда для цепочки обмена требуются какие-либо флаги использования изображения цепочки обмена. Структура расширения содержит флаги использования образа swapchain:

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

    VkSwapchainImageUsageFlagsANDROID      usage;
} VkSwapchainImageCreateInfoANDROID;

В Android 10 и более поздних версиях платформа поддерживает VK_KHR_swapchain v70, поэтому приложение Vulkan может создавать VkImage , поддерживаемый памятью цепочки обмена. Приложение сначала вызывает vkCreateImage со структурой VkImageSwapchainCreateInfoKHR , связанной со структурой VkImageCreateInfo . Затем приложение вызывает vkBindImageMemory2(KHR) со структурой VkBindImageMemorySwapchainInfoKHR , связанной со структурой VkBindImageMemoryInfo . imageIndex , указанный в структуре VkBindImageMemorySwapchainInfoKHR , должен быть допустимым индексом изображения цепочки обмена. Между тем, платформа предоставляет структуру расширения VkNativeBufferANDROID с соответствующей информацией о буфере Gralloc в цепочку VkBindImageMemoryInfo , поэтому драйвер знает, с каким буфером Gralloc связать VkImage .

Получить изображения

vkAcquireImageANDROID приобретает право собственности на образ цепочки обмена и импортирует собственное ограждение с внешним сигналом как в существующий объект VkSemaphore , так и в существующий объект VkFence :

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

vkAcquireImageANDROID() вызывается во время vkAcquireNextImageKHR для импорта собственного ограждения в объекты VkSemaphore и VkFence , предоставляемые приложением (однако в этом вызове как семафор, так и объекты ограждения не являются обязательными). Драйвер также может использовать эту возможность для распознавания и обработки любых внешних изменений состояния буфера Gralloc; многим водителям здесь не нужно ничего делать. Этот вызов переводит VkSemaphore и VkFence в то же состояние ожидания, как если бы он был сигнализирован vkQueueSubmit , поэтому очереди могут ожидать семафора, а приложение может ожидать на ограждении.

Оба объекта получают сигнал, когда сигнализирует базовый собственный барьер; если встроенный забор уже подал сигнал, то семафор находится в сигнальном состоянии, когда эта функция возвращает значение. Драйвер становится владельцем дескриптора файла ограждения и закрывает дескриптор файла ограждения, когда он больше не нужен. Драйвер должен сделать это, даже если не предоставлен ни семафор, ни объект ограждения, или даже если vkAcquireImageANDROID завершается неудачно и возвращает ошибку. Если fenceFd равен -1, это как если бы сигнал о собственном заборе уже был получен.

Выпуск изображений

vkQueueSignalReleaseImageANDROID подготавливает образ цепочки обмена для внешнего использования, создает собственное ограждение и планирует сигнализировать собственное ограждение после того, как входные семафоры подадут сигнал:

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

vkQueuePresentKHR() вызывает vkQueueSignalReleaseImageANDROID() в предоставленной очереди. Драйвер должен создать собственное ограждение, которое не подает сигнал до тех пор, пока все семафоры waitSemaphoreCount в pWaitSemaphores не подадут сигнал, а также не завершится любая дополнительная работа, необходимая для подготовки image к представлению.

Если семафоры ожидания (если таковые имеются) уже сигнализировали и queue уже простаивает, драйвер может установить для *pNativeFenceFd значение -1 вместо фактического файлового дескриптора собственного ограждения, указывая, что ждать нечего. Вызывающая сторона владеет и закрывает дескриптор файла, возвращенный в *pNativeFenceFd .

Многие драйверы могут игнорировать параметр изображения, но некоторым может потребоваться подготовить структуры данных на стороне ЦП, связанные с буфером Gralloc, для использования внешними потребителями изображений. Подготовку содержимого буфера для использования внешними потребителями следует выполнять асинхронно в рамках перехода образа в VK_IMAGE_LAYOUT_PRESENT_SRC_KHR .

Если образ был создан с помощью VK_SWAPCHAIN_IMAGE_USAGE_SHARED_BIT_ANDROID , то драйвер должен разрешить повторный вызов vkQueueSignalReleaseImageANDROID() без промежуточных вызовов vkAcquireImageANDROID() .

Поддержка общих презентабельных изображений

Некоторые устройства могут совместно использовать одно изображение между конвейером отображения и реализацией Vulkan, чтобы минимизировать задержку. В Android 9 и выше загрузчик условно объявляет расширение VK_KHR_shared_presentable_image на основе ответа драйвера на вызов vkGetPhysicalDeviceProperties2 .

Если драйвер не поддерживает ни Vulkan 1.1, ни расширение VK_KHR_physical_device_properties2 , загрузчик не объявляет о поддержке общих презентабельных изображений. В противном случае загрузчик запрашивает возможности драйвера, вызывая vkGetPhysicalDeviceProperties2() и включая следующую структуру в цепочку VkPhysicalDeviceProperties2::pNext :

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 1.0, 1.1, 1.2 и 1.3.
  • Модуль CtsGraphicsTestCases , который проверяет правильность настройки устройства для поддерживаемых им возможностей Vulkan.

Флаг функции Vulkan

Устройство, поддерживающее Android 11 или более поздней версии и поддерживающее API Vulkan, должно предоставить флаг функции android.software.vulkan.deqp.level . Значением этого флага функции является дата, закодированная как целое число. Он указывает дату, связанную с тестами Vulkan dEQP, которые, как утверждает устройство, прошли.

Дата в формате ГГГГ-ММ-ДД кодируется как 32-битное целое число следующим образом:

  • Биты 0–15 хранят год.
  • Биты 16-23 хранят месяц.
  • Биты 24-31 хранят день.

Минимально допустимое значение для флага функции — 0x07E30301 , что соответствует дате 2019-03-01, которая является датой, связанной с тестами Vulkan dEQP для Android 10. Если флаг функции равен хотя бы этому значению, устройство утверждает, что пройти все тесты Android 10 Vulkan dEQP.

Значение 0x07E40301 соответствует дате 2020-03-01, которая является датой, связанной с тестами Vulkan dEQP для Android 11. Если флаг функции равен хотя бы этому значению, устройство утверждает, что прошло все тесты Android 11 Vulkan dEQP.

Значение 0x07E60301 соответствует дате 01.03.2022, которая является датой, связанной с тестами Vulkan dEQP для Android 13. Если флаг функции равен хотя бы этому значению, устройство утверждает, что прошло все тесты Android 13 Vulkan dEQP.

Устройство, которое предоставляет определенный флаг функции ( например 0x07E30301 , 0x07E40301 , 0x07E60301 ), утверждает, что прошло все тесты Android Vulkan dEQP этого флага функции (Android 10, Android 11, Android 13 соответственно). Это устройство может пройти тесты Vulkan dEQP из более поздней версии Android.

Vulkan dEQP является частью Android CTS. Начиная с Android 11, компонент запуска тестов dEQP CTS знает о флаге функции android.software.vulkan.deqp.level и пропускает любые тесты Vulkan dEQP, которые, согласно этому флагу функции, устройство не поддерживает. Такие тесты считаются тривиально пройденными.