Implementa Vulkan

Vulkan es una API multiplataforma de baja sobrecarga para gráficos 3D de alto rendimiento. Al igual que OpenGL ES (GLES), Vulkan proporciona herramientas para crear gráficos de alta calidad en tiempo real en las apps. Entre las ventajas de usar Vulkan, se incluyen la reducción de la sobrecarga de la CPU y la compatibilidad con el lenguaje intermedio binario SPIR-V.

Para implementar Vulkan correctamente, un dispositivo debe incluir lo siguiente:

  • Cargador de Vulkan proporcionado por Android.
  • Es un controlador de Vulkan proporcionado por los SoC, como los IHV de GPU, que implementa la API de Vulkan. Para admitir la funcionalidad de Vulkan, el dispositivo Android necesita hardware de GPU compatible con Vulkan y el controlador asociado. La GPU también debe admitir GLES 3.1 y versiones posteriores. Consulta a tu proveedor de SoC para solicitar asistencia con el controlador.

Si un dispositivo incluye un controlador de Vulkan, debe declarar las funciones del sistema FEATURE_VULKAN_HARDWARE_LEVEL y FEATURE_VULKAN_HARDWARE_VERSION, con versiones que reflejen con precisión las capacidades del dispositivo. Esto ayuda a garantizar que el dispositivo cumpla con el Documento de definición de compatibilidad (CDD).

Cargador de Vulkan

El cargador de Vulkan platform/frameworks/native/vulkan es la interfaz principal entre las apps de Vulkan y el controlador de Vulkan de un dispositivo. El cargador de Vulkan se instala en /system/lib[64]/libvulkan.so. El cargador proporciona los puntos de entrada principales de la API de Vulkan, los puntos de entrada de las extensiones requeridas por el CDD de Android y muchas extensiones opcionales adicionales. El cargador exporta las extensiones de integración del sistema de ventanas (WSI) y se implementan principalmente en el cargador en lugar de en el controlador. El cargador también admite la enumeración y la carga de capas que pueden exponer extensiones adicionales y, además, interceptar llamadas a la API principal en su camino hacia el controlador.

El NDK incluye una biblioteca libvulkan.so de código auxiliar para la vinculación. La biblioteca exporta los mismos símbolos que el cargador. Las apps llaman a las funciones exportadas desde la biblioteca libvulkan.so real para ingresar funciones de trampolín en el cargador, que se envían a la capa o al controlador adecuados según su primer argumento. La llamada a vkGet*ProcAddr() devuelve los punteros de función a los que se despachan los trampolines (es decir, llama directamente al código de la API principal). Llamar a través de los punteros de función, en lugar de los símbolos exportados, es más eficiente, ya que omite el trampolín y el envío.

Enumeración y carga de controladores

Cuando se compila la imagen del sistema, Android espera que el sistema sepa qué GPUs están disponibles. El cargador usa el mecanismo HAL existente en hardware.h para descubrir y cargar el controlador. Las rutas preferidas para los controladores de Vulkan de 32 y 64 bits son las siguientes:

/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

En Android 7.0 y versiones posteriores, el derivado hw_module_t de Vulkan encapsula una sola estructura hw_module_t; solo se admite un controlador y la cadena constante HWVULKAN_DEVICE_0 se pasa a open().

El derivado de Vulkan hw_device_t corresponde a un solo controlador que puede admitir varios dispositivos físicos. La estructura hw_device_t se puede extender para exportar las funciones vkGetGlobalExtensionProperties(), vkCreateInstance() y vkGetInstanceProcAddr(). El cargador puede encontrar todas las demás funciones VkInstance(), VkPhysicalDevice() y vkGetDeviceProcAddr() llamando a vkGetInstanceProcAddr() de la estructura hw_device_t.

Desde Android 15, el cargador admite APEX para cargar el controlador de Vulkan. Establece ro.vulkan.apex en el nombre del APEX de Vulkan para cargar Vulkan desde el APEX.

Descubrimiento y carga de capas

El cargador de Vulkan admite la enumeración y la carga de capas que pueden exponer extensiones adicionales y interceptar llamadas a la API principal en su camino hacia el controlador. Android no incluye capas en la imagen del sistema; sin embargo, las apps pueden incluir capas en su APK.

Cuando uses capas, ten en cuenta que el modelo de seguridad y las políticas de Android difieren significativamente de los de otras plataformas. En particular, Android no permite cargar código externo en un proceso no depurable en dispositivos de producción (sin acceso de administrador), ni permite que el código externo inspeccione o controle la memoria, el estado, etcétera, del proceso. Esto incluye la prohibición de guardar volcados de memoria del kernel, registros de API, etcétera, en el disco para su inspección posterior. En los dispositivos de producción, solo se habilitan las capas que se entregan como parte de apps que no se pueden depurar, y los controladores no deben proporcionar funciones que incumplan estas políticas.

Estos son algunos casos de uso de las capas:

  • Capas de tiempo de desarrollo: Las capas de validación y los adaptadores para las herramientas de seguimiento, generación de perfiles y depuración no deben instalarse en la imagen del sistema de los dispositivos de producción. Las capas de validación y los adaptadores para las herramientas de seguimiento, generación de perfiles y depuración deben poder actualizarse sin una imagen del sistema. Los desarrolladores que deseen usar una de estas capas durante el desarrollo pueden modificar el paquete de la app, por ejemplo, agregando un archivo a su directorio de bibliotecas nativas. Se supone que los ingenieros de IHV y OEM que desean diagnosticar fallas en apps inmodificables enviadas tienen acceso a compilaciones de la imagen del sistema que no son de producción (con permisos de administrador), a menos que esas apps sean depurables. Para obtener más información, consulta Capas de validación de Vulkan en Android.
  • Capas de utilidad: Estas capas exponen extensiones, como una capa que implementa un administrador de memoria para la memoria del dispositivo. Los desarrolladores eligen las capas y las versiones de esas capas que usarán en su app. Las diferentes apps que usan la misma capa pueden usar versiones diferentes. Los desarrolladores eligen cuáles de estas capas incluir en el paquete de su app.
  • Capas insertadas (implícitas): Incluyen capas como la velocidad de fotogramas, la red social y las superposiciones del selector de juegos proporcionadas por el usuario o alguna otra app sin el conocimiento ni el consentimiento de la app. Estos incumplen las políticas de seguridad de Android y no se admiten.

En el caso de las apps que no se pueden depurar, el cargador busca capas solo en el directorio de la biblioteca nativa de la app y trata de cargar cualquier biblioteca con un nombre que coincida con un patrón en particular (por ejemplo, libVKLayer_foo.so).

En el caso de las apps depurables, el cargador busca capas en /data/local/debug/vulkan y trata de cargar cualquier biblioteca que coincida con un patrón determinado.

Android permite que las capas se porten con cambios en el entorno de compilación entre Android y otras plataformas. Para obtener detalles sobre la interfaz entre las capas y el cargador, consulta Arquitectura de las interfaces del cargador de Vulkan. Las capas de validación que mantiene Khronos se alojan en Vulkan Validation Layers.

Versiones y capacidades de la API de Vulkan

En la siguiente tabla, se enumeran las versiones de la API de Vulkan para varias versiones de Android.
Versión de Android Versión de Vulkan
Android 13 Vulkan 1.3
Android 9 Vulkan 1.1
Android 7 Vulkan 1.0

Descripción general de la funcionalidad de Vulkan 1.3

Vulkan 1.3 canoniza varias extensiones que antes eran opcionales en la funcionalidad principal de Vulkan. Gran parte de esta funcionalidad se incluye con la intención de aumentar el control y la granularidad sobre la interfaz de programación de Vulkan. Las instancias de pases de renderización de un solo paso ya no necesitan objetos de pase de renderización ni búferes de fotogramas. Se puede reducir la cantidad total de objetos de estado de la canalización y se revisa la sincronización dentro de la API. Vulkan 1.3 tiene los mismos requisitos de hardware que Vulkan 1.2, 1.1 y 1.0, y la mayor parte de la implementación se encuentra en el controlador de gráficos específico del SoC, no en el framework.

Las funciones más importantes de Vulkan 1.3 para Android son las siguientes:

  • Compatibilidad con instancias de pase de renderización de un solo paso
  • Compatibilidad para finalizar de inmediato una invocación de sombreador
  • Mayor nivel de detalle en la creación, el uso compartido y el control de canalizaciones

Vulkan 1.3 también incluye varias funciones más pequeñas y mejoras en la usabilidad de la API. Todos los cambios realizados en la API de Vulkan principal con la revisión secundaria 1.3 se pueden encontrar en Core Revisions (Vulkan 1.3).

Descripción general de la funcionalidad de Vulkan 1.2

Vulkan 1.2 agrega varias funciones y extensiones que simplifican la superficie de la API. Esto incluye un modelo de memoria unificado y la información adicional que se puede consultar desde un controlador de dispositivo. Vulkan 1.2 tiene los mismos requisitos de hardware que Vulkan 1.0 y 1.1. Toda la implementación se encuentra en el controlador de gráficos específico del SoC, no en el framework.

La función más importante de Vulkan 1.2 para Android es la compatibilidad con el almacenamiento de 8 bits.

Vulkan 1.2 también incluye varias funciones más pequeñas y mejoras en la usabilidad de la API. Todos los cambios realizados en la API principal de Vulkan con la revisión secundaria 1.2 se pueden encontrar en Core Revisions (Vulkan 1.2).

Descripción general de la funcionalidad de Vulkan 1.1

Vulkan 1.1 incluye compatibilidad con la interoperabilidad de memoria y sincronización, lo que permite a los OEM admitir Vulkan 1.1 en los dispositivos. Además, la interoperabilidad de memoria y sincronización permite a los desarrolladores determinar si Vulkan 1.1 es compatible con un dispositivo y usarlo de manera eficaz cuando lo es. Vulkan 1.1 tiene los mismos requisitos de hardware que Vulkan 1.0, pero la mayor parte de la implementación se encuentra en el controlador de gráficos específico del SoC, no en el framework.

Las funciones más importantes de Vulkan 1.1 para Android son las siguientes:

  • Compatibilidad con la importación y exportación de búferes de memoria y objetos de sincronización desde fuera de Vulkan (para la interoperabilidad con la cámara, los códecs y GLES)
  • Compatibilidad con formatos YCbCr

Vulkan 1.1 también incluye varias funciones más pequeñas y mejoras en la usabilidad de la API. Todos los cambios realizados en la API principal de Vulkan con la revisión secundaria 1.1 se pueden encontrar en Core Revisions (Vulkan 1.1).

Cómo elegir la compatibilidad con Vulkan

Los dispositivos Android deben admitir el conjunto de funciones de Vulkan más avanzado disponible, siempre que admitan una ABI de 64 bits y no tengan poca memoria.

Los dispositivos que se lancen con Android 13 y versiones posteriores deben admitir Vulkan 1.3.

Los dispositivos que se lancen con Android 10 deben admitir Vulkan 1.1.

Otros dispositivos pueden admitir de forma opcional Vulkan 1.3, 1.2 y 1.1.

Cómo admitir una versión de Vulkan

Un dispositivo Android admite una versión de Vulkan si se cumplen las siguientes condiciones:

  1. Agrega un controlador de Vulkan que admita la versión de Vulkan de interés (debe ser una de las versiones 1.3, 1.1 o 1.0) junto con los requisitos adicionales del CDD de la versión de Android. Como alternativa, actualiza un controlador de Vulkan existente con un número de versión de Vulkan inferior.
  2. En el caso de Vulkan 1.3 o 1.1, asegúrate de que la función del sistema que devuelve el administrador de paquetes muestre true para la versión correcta de Vulkan.
    • Para Vulkan 1.3, la función es PackageManager#hasSystemFeature(PackageManager.FEATURE_VULKAN_HARDWARE_VERSION, 0x403000).
    • Para Vulkan 1.1, la función es PackageManager#hasSystemFeature(PackageManager.FEATURE_VULKAN_HARDWARE_VERSION, 0x401000).
    El administrador de paquetes devolverá true para Vulkan 1.3 y Vulkan 1.1 agregando una regla, como se muestra a continuación, a un archivo device.mk adecuado.
    • Agrega lo siguiente para 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
      
    • Agrega lo siguiente para 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

Perfil de Baseline de Android (ABP)

Recomendamos que todos los dispositivos Android cumplan con el perfil de Android Baseline 2022 más reciente, como se describe en la guía del perfil de Android Baseline.

Cualquier dispositivo que admita Android 14 o una versión posterior y la API de Vulkan debe cumplir con la funcionalidad definida en el perfil de Android Baseline 2021. La lista completa de la funcionalidad requerida se enumera en el archivo json del perfil de Vulkan, pero un subconjunto clave de la funcionalidad requerida incluye lo siguiente:

  • Texturas comprimidas a través de ASTC y ETC.
  • Espacios de color variables a través de VK_EXT_swapchain_colorspace
  • Sombreado de muestra y también interpolación de varios ejemplos mediante sampleRateShading.

Integración del sistema de ventanas (WSI)

En libvulkan.so, el controlador implementa las siguientes extensiones de integración del sistema de ventanas (WSI):

  • VK_KHR_surface
  • VK_KHR_android_surface
  • VK_KHR_swapchain
  • VK_KHR_driver_properties, implementado para Vulkan 1.1 solo en Android 10
  • VK_GOOGLE_display_timing, implementado para cualquier versión de Vulkan en Android 10

La plataforma controla los objetos VkSurfaceKHR y VkSwapchainKHR, y todas las interacciones con ANativeWindow, y no se exponen a los conductores. La implementación de WSI se basa en la extensión VK_ANDROID_native_buffer, que debe ser compatible con el controlador. Esta extensión solo se usa en la implementación de WSI y no se expone a las apps.

Marcas de uso de Gralloc

Es posible que las implementaciones de Vulkan necesiten que los búferes de intercambio se asignen con marcas de uso de Gralloc privadas definidas por la implementación. Cuando se crea una cadena de intercambio, Android le pide al controlador que traduzca los indicadores de uso de imagen y formato solicitados en indicadores de uso de Gralloc llamando a lo siguiente:

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

Los parámetros format y imageUsage se toman de la estructura VkSwapchainCreateInfoKHR. El controlador debe completar *grallocConsumerUsage y *grallocProducerUsage con las marcas de uso de Gralloc requeridas para el formato y el uso. Las marcas de uso que devuelve el controlador se combinan con las marcas de uso que solicita el consumidor de la cadena de intercambio cuando asigna búferes.

Android 7.x llama a una versión anterior de VkSwapchainImageUsageFlagsANDROID(), llamada vkGetSwapchainGrallocUsageANDROID(). Android 8.0 y versiones posteriores dejaron de usar vkGetSwapchainGrallocUsageANDROID(), pero aún llaman a vkGetSwapchainGrallocUsageANDROID() si el controlador no proporciona vkGetSwapchainGrallocUsage2ANDROID():

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

vkGetSwapchainGrallocUsageANDROID() no admite marcas de uso de swapchain ni marcas de uso de Gralloc extendidas.

Imágenes respaldadas por Gralloc

VkNativeBufferANDROID es una estructura de extensión vkCreateImage para crear una imagen respaldada por un búfer de Gralloc. VkNativeBufferANDROID se proporciona a vkCreateImage() en la cadena de estructura VkImageCreateInfo. Las llamadas a vkCreateImage() con VkNativeBufferANDROID se producen durante la llamada a vkCreateSwapchainKHR. La implementación de la WSI asigna la cantidad de búferes nativos solicitados para la cadena de intercambio y, luego, crea un VkImage para cada uno:

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;

Cuando se crea una imagen respaldada por Gralloc, VkImageCreateInfo tiene los siguientes datos:

  .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

En Android 8.0 y versiones posteriores, la plataforma proporciona una estructura de extensión VkSwapchainImageCreateInfoKHR en la cadena VkImageCreateInfo proporcionada a vkCreateImage cuando se requieren marcas de uso de imágenes de swapchain para la swapchain. La estructura de la extensión contiene las marcas de uso de la imagen de intercambio:

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

    VkSwapchainImageUsageFlagsANDROID      usage;
} VkSwapchainImageCreateInfoANDROID;

En Android 10 y versiones posteriores, la plataforma admite VK_KHR_swapchain v70, por lo que la app de Vulkan puede crear un VkImage respaldado por memoria de cadena de intercambio. Primero, la app llama a vkCreateImage con una estructura VkImageSwapchainCreateInfoKHR encadenada a la estructura VkImageCreateInfo. Luego, la app llama a vkBindImageMemory2(KHR) con una estructura VkBindImageMemorySwapchainInfoKHR encadenada a la estructura VkBindImageMemoryInfo. El imageIndex especificado en la estructura VkBindImageMemorySwapchainInfoKHR debe ser un índice de imagen de cadena de intercambio válido. Mientras tanto, la plataforma proporciona una estructura de extensión VkNativeBufferANDROID con la información del búfer de Gralloc correspondiente a la cadena VkBindImageMemoryInfo, de modo que el controlador sepa con qué búfer de Gralloc debe vincular el VkImage.

Adquiere imágenes

vkAcquireImageANDROID adquiere la propiedad de una imagen de cadena de intercambio y, luego, importa una barrera nativa señalizada de forma externa en un objeto VkSemaphore existente y en un objeto VkFence existente:

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

Se llama a vkAcquireImageANDROID() durante vkAcquireNextImageKHR para importar una barrera nativa en los objetos VkSemaphore y VkFence que proporciona la app (sin embargo, tanto los objetos de semáforo como de barrera son opcionales en esta llamada). El controlador también puede aprovechar esta oportunidad para reconocer y controlar cualquier cambio externo en el estado del búfer de Gralloc. Muchos controladores no necesitarán hacer nada aquí. Esta llamada coloca los objetos VkSemaphore y VkFence en el mismo estado pendiente que si se hubiera indicado con vkQueueSubmit, de modo que las filas puedan esperar el semáforo y la app pueda esperar la barrera.

Ambos objetos se señalan cuando se señala la barrera nativa subyacente. Si la barrera nativa ya se señaló, el semáforo estará en el estado señalado cuando se devuelva esta función. El controlador toma la propiedad del descriptor de archivo de la barrera y lo cierra cuando ya no es necesario. El controlador debe hacerlo incluso si no se proporciona un objeto de semáforo o de barrera, o incluso si vkAcquireImageANDROID falla y devuelve un error. Si fenceFd es -1, es como si la valla nativa ya se hubiera señalado.

Imágenes de lanzamiento

vkQueueSignalReleaseImageANDROID prepara una imagen de cadena de intercambio para uso externo, crea una barrera nativa y programa la barrera nativa para que se señale después de que se hayan señalado los semáforos de entrada:

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

vkQueuePresentKHR() llama a vkQueueSignalReleaseImageANDROID() en la cola proporcionada. El controlador debe producir una barrera nativa que no señale hasta que todos los semáforos waitSemaphoreCount en pWaitSemaphores señalen y se complete cualquier trabajo adicional necesario para preparar image para la presentación.

Si los semáforos de espera (si los hay) ya señalaron y queue ya está inactivo, el controlador puede establecer *pNativeFenceFd en -1 en lugar de un descriptor de archivo de barrera nativo real, lo que indica que no hay nada que esperar. El llamador posee y cierra el descriptor de archivos que se devuelve en *pNativeFenceFd.

Muchos controladores pueden ignorar el parámetro de imagen, pero algunos pueden necesitar preparar estructuras de datos del lado de la CPU asociadas con un búfer de Gralloc para que los consumidores de imágenes externos las usen. La preparación del contenido del búfer para que lo usen los consumidores externos debe realizarse de forma asíncrona como parte de la transición de la imagen a VK_IMAGE_LAYOUT_PRESENT_SRC_KHR.

Si la imagen se creó con VK_SWAPCHAIN_IMAGE_USAGE_SHARED_BIT_ANDROID, el controlador debe permitir que se llame a vkQueueSignalReleaseImageANDROID() de forma repetida sin llamadas intermedias a vkAcquireImageANDROID().

Compatibilidad con imágenes presentables compartidas

Algunos dispositivos pueden compartir la propiedad de una sola imagen entre la canalización de visualización y la implementación de Vulkan para minimizar la latencia. En Android 9 y versiones posteriores, el cargador anuncia de forma condicional la extensión VK_KHR_shared_presentable_image según la respuesta del controlador a una llamada a vkGetPhysicalDeviceProperties2.

Si el controlador no admite Vulkan 1.1 ni la extensión VK_KHR_physical_device_properties2, el cargador no anuncia la compatibilidad con imágenes presentables compartidas. De lo contrario, el cargador consulta las capacidades del controlador llamando a vkGetPhysicalDeviceProperties2() e incluyendo la siguiente estructura en la cadena VkPhysicalDeviceProperties2::pNext:

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

Si el controlador puede compartir la propiedad de una imagen con el sistema de visualización, establece el miembro sharedImage en VK_TRUE.

Validación

Los OEM pueden probar su implementación de Vulkan con el CTS, que incluye lo siguiente:

  • Pruebas de cumplimiento de Khronos Vulkan en el módulo CtsDeqpTestCases, que incluyen pruebas funcionales de la API para Vulkan 1.0, 1.1, 1.2 y 1.3.
  • El módulo CtsGraphicsTestCases, que prueba que el dispositivo esté configurado correctamente para las capacidades de Vulkan que admite.

Marca de función de Vulkan

Se requiere un dispositivo que admita Android 11 o versiones posteriores y la API de Vulkan para exponer un parámetro de configuración, android.software.vulkan.deqp.level. El valor de esta marca de función es una fecha, codificada como un valor entero. Especifica la fecha asociada con las pruebas de dEQP de Vulkan que el dispositivo afirma aprobar.

Una fecha con el formato AAAA-MM-DD se codifica como un número entero de 32 bits de la siguiente manera:

  • Los bits del 0 al 15 almacenan el año.
  • Los bits del 16 al 23 almacenan el mes.
  • Los bits del 24 al 31 almacenan el día.

El valor mínimo permitido para la marca de función es 0x07E30301, que corresponde a la fecha 2019-03-01, que es la fecha asociada con las pruebas de dEQP de Vulkan para Android 10. Si el parámetro de la función es al menos este valor, el dispositivo afirma que supera todas las pruebas de dEQP de Vulkan de Android 10.

El valor 0x07E40301 corresponde a la fecha 2020-03-01, que es la fecha asociada con las pruebas de dEQP de Vulkan para Android 11. Si la marca de función tiene al menos este valor, el dispositivo afirma que supera todas las pruebas de dEQP de Vulkan de Android 11.

El valor 0x07E60301 corresponde a la fecha 2022-03-01, que es la fecha asociada con las pruebas de dEQP de Vulkan para Android 13. Si la marca de función tiene al menos este valor, el dispositivo afirma que supera todas las pruebas de dEQP de Vulkan de Android 13.

Un dispositivo que expone un parámetro de configuración específico (es decir, 0x07E30301, 0x07E40301, 0x07E60301) afirma que pasa todas las pruebas de dEQP de Vulkan de Android de ese parámetro de configuración (Android 10, Android 11 y Android 13, respectivamente). Es posible que este dispositivo apruebe las pruebas de dEQP de Vulkan en una versión posterior de Android.

Vulkan dEQP forma parte del CTS de Android. A partir de Android 11, el componente de CTS del ejecutor de pruebas de dEQP conoce el parámetro de configuración android.software.vulkan.deqp.level y omite cualquier prueba de dEQP de Vulkan que, según este parámetro de configuración, el dispositivo no afirma admitir. Estas pruebas se informan como aprobadas de forma trivial.