Implementar o Vulkan

Vulkan é uma API multiplataforma de baixa sobrecarga para gráficos 3D de alto desempenho. Assim como o OpenGL ES (GLES), o Vulkan oferece ferramentas para criar gráficos de alta qualidade em tempo real nos apps. As vantagens de usar o Vulkan incluem reduções na sobrecarga da CPU e compatibilidade com a linguagem binária intermediária SPIR-V.

Para implementar o Vulkan, um dispositivo precisa incluir:

  • O carregador do Vulkan, fornecido pelo Android.
  • Um driver do Vulkan, fornecido por SoCs como IHVs de GPU, que implementa a API do Vulkan. Para oferecer suporte à funcionalidade do Vulkan, o dispositivo Android precisa de hardware de GPU compatível com Vulkan e do driver associado. A GPU também precisa ser compatível com GLES 3.1 e versões mais recentes. Consulte o fornecedor do SoC para solicitar suporte para o driver.

Se um dispositivo incluir um driver do Vulkan, ele precisará declarar os recursos do sistema FEATURE_VULKAN_HARDWARE_LEVEL e FEATURE_VULKAN_HARDWARE_VERSION, com versões que reflitam com precisão as funcionalidades do dispositivo. Isso ajuda a garantir que o dispositivo esteja em conformidade com o Documento de definição de compatibilidade (CDD).

Carregador do Vulkan

O carregador do Vulkan platform/frameworks/native/vulkan é a interface principal entre apps Vulkan e o driver Vulkan de um dispositivo. O carregador do Vulkan está instalado em /system/lib[64]/libvulkan.so. O carregador fornece os pontos de entrada principais da API Vulkan, os pontos de entrada das extensões exigidas pelo CDD do Android e muitas outras extensões opcionais. As extensões de integração do sistema de janelas (WSI, na sigla em inglês) são exportadas pelo carregador e implementadas principalmente nele, em vez de no driver. O carregador também oferece suporte à enumeração e ao carregamento de camadas que podem expor extensões adicionais e interceptar chamadas de API principais a caminho do driver.

O NDK inclui uma biblioteca libvulkan.so stub para vinculação. A biblioteca exporta os mesmos símbolos que o carregador. Os apps chamam as funções exportadas da biblioteca libvulkan.so real para inserir funções de trampolim no carregador, que enviam para a camada ou driver apropriado com base no primeiro argumento. A chamada vkGet*ProcAddr() retorna os ponteiros de função para os quais os trampolins enviam (ou seja, ela chama diretamente o código da API principal). Chamar pelos ponteiros de função, em vez dos símbolos exportados, é mais eficiente, porque pula o trampolim e o envio.

Enumeração e carregamento de drivers

Quando a imagem do sistema é criada, o Android espera que o sistema saiba quais GPUs estão disponíveis. O carregador usa o mecanismo HAL existente em hardware.h para descobrir e carregar o driver. Os caminhos preferenciais para drivers Vulkan de 32 e 64 bits são:

/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

No Android 7.0 e versões mais recentes, o derivado hw_module_t do Vulkan encapsula uma única struct hw_module_t. Apenas um driver é compatível, e a string constante HWVULKAN_DEVICE_0 é transmitida para open().

O derivado do Vulkan hw_device_t corresponde a um único driver que pode oferecer suporte a vários dispositivos físicos. A estrutura hw_device_t pode ser estendida para exportar funções vkGetGlobalExtensionProperties(), vkCreateInstance() e vkGetInstanceProcAddr(). O carregador pode encontrar todas as outras funções VkInstance(), VkPhysicalDevice() e vkGetDeviceProcAddr() chamando o vkGetInstanceProcAddr() da estrutura hw_device_t.

Desde o Android 15, o carregador oferece suporte ao APEX para carregar o driver do Vulkan. Defina ro.vulkan.apex como o nome do APEX do Vulkan para carregar o Vulkan do APEX.

Descoberta e carregamento de camadas

O carregador do Vulkan oferece suporte à enumeração e ao carregamento de camadas que podem expor extensões adicionais e interceptar chamadas da API principal no caminho para o driver. O Android não inclui camadas na imagem do sistema, mas os apps podem incluir camadas no APK.

Ao usar camadas, lembre-se de que as políticas e o modelo de segurança do Android são muito diferentes dos que são usados por outras plataformas. Em particular, o Android não permite carregar código externo em um processo não depurável em dispositivos de produção (não rooteados), nem permite que o código externo inspecione ou controle a memória, o estado e assim por diante do processo. Isso inclui a proibição de salvar despejos de memória, rastreamentos de API etc. no disco para inspeção posterior. Apenas as camadas entregues como parte de apps não depuráveis são ativadas em dispositivos de produção, e os drivers não podem fornecer funcionalidades que violem essas políticas.

Os casos de uso de camadas incluem:

  • Camadas de tempo de desenvolvimento: as camadas de validação e os shims para ferramentas de rastreamento/criação de perfil/depuração não devem ser instalados na imagem do sistema de dispositivos de produção. As camadas de validação e os shims para ferramentas de rastreamento/criação de perfil/depuração precisam ser atualizáveis sem uma imagem do sistema. Os desenvolvedores que quiserem usar uma dessas camadas durante o desenvolvimento podem modificar o pacote do app, por exemplo, adicionando um arquivo ao diretório de bibliotecas nativas. Os engenheiros de IHV e OEM que querem diagnosticar falhas no envio de apps imutáveis precisam ter acesso a builds não de produção (com acesso root) da imagem do sistema, a menos que esses apps sejam depuráveis. Para mais informações, consulte Camadas de validação da Vulkan no Android.
  • Camadas de utilidade: expõem extensões, como uma camada que implementa um gerenciador de memória para a memória do dispositivo. Os desenvolvedores escolhem as camadas e as versões delas para usar no app. Apps diferentes que usam a mesma camada ainda podem usar versões diferentes. Os desenvolvedores escolhem qual dessas camadas enviar no pacote do app.
  • Camadas injetadas (implícitas): incluem camadas como taxa de frames, rede social e sobreposições de inicializador de jogos fornecidas pelo usuário ou por algum outro app sem o conhecimento ou consentimento do app. Elas violam as políticas de segurança do Android e não são compatíveis.

Para apps não depuráveis, o carregador procura camadas apenas no diretório de biblioteca nativa do app e tenta carregar qualquer biblioteca com um nome que corresponda a um padrão específico (por exemplo, libVKLayer_foo.so).

Para apps depuráveis, o carregador procura camadas em /data/local/debug/vulkan e tenta carregar qualquer biblioteca que corresponda a um padrão específico.

O Android permite que as camadas sejam portadas com mudanças no ambiente de build entre o Android e outras plataformas. Para detalhes sobre a interface entre camadas e o carregador, consulte Arquitetura das interfaces do carregador do Vulkan. As camadas de validação mantidas pelo Khronos estão hospedadas em Camadas de validação do Vulkan.

Versões e recursos da API do Vulkan

A tabela a seguir lista as versões da API Vulkan para vários lançamentos do Android.
Versão do Android Versão do Vulkan
Android 13 Vulkan 1.3
Android 9 Vulkan 1.1
Android 7 Vulkan 1.0

Visão geral da funcionalidade do Vulkan 1.3

A Vulkan 1.3 canoniza várias extensões antes opcionais na funcionalidade principal do Vulkan. Grande parte dessa funcionalidade está incluída com o objetivo de aumentar o controle e a granularidade da interface de programação Vulkan. As instâncias de transmissão de renderização de passagem única não precisam mais de objetos de transmissão de renderização ou framebuffers. O número total de objetos de estado do pipeline pode ser reduzido, e a sincronização na API é revisada. O Vulkan 1.3 tem os mesmos requisitos de hardware que o Vulkan 1.2, 1.1 e 1.0, com a maior parte da implementação no driver gráfico específico do SoC, não no framework.

Os recursos mais importantes do Vulkan 1.3 para Android são:

  • Suporte para instâncias de transmissão de renderização de passagem única
  • Suporte para encerrar imediatamente uma invocação de shader
  • Granularidade mais refinada sobre criação, compartilhamento e controle de pipelines

A Vulkan 1.3 também inclui vários recursos menores e melhorias na usabilidade da API. Todas as mudanças feitas na API Vulkan principal com a revisão secundária 1.3 podem ser encontradas em Revisões principais (Vulkan 1.3).

Visão geral da funcionalidade do Vulkan 1.2

O Vulkan 1.2 adiciona vários recursos e extensões que simplificam a superfície da API. Isso inclui um modelo de memória unificado e outras informações que podem ser consultadas em um driver de dispositivo. O Vulkan 1.2 tem os mesmos requisitos de hardware que o Vulkan 1.0 e 1.1. Toda a implementação está no driver de gráficos específico do SoC, não no framework.

O recurso mais importante do Vulkan 1.2 para Android é o suporte ao armazenamento de 8 bits.

O Vulkan 1.2 também inclui vários recursos menores e melhorias na usabilidade da API. Todas as mudanças feitas na API Vulkan principal com a revisão secundária 1.2 podem ser encontradas em Revisões principais (Vulkan 1.2).

Visão geral da funcionalidade do Vulkan 1.1

O Vulkan 1.1 inclui suporte para interoperabilidade de memória/sincronização, o que permite que os OEMs ofereçam suporte ao Vulkan 1.1 em dispositivos. Além disso, a interoperabilidade de memória/sincronização permite que os desenvolvedores determinem se o Vulkan 1.1 é compatível com um dispositivo e o usem de forma eficaz quando for. O Vulkan 1.1 tem os mesmos requisitos de hardware do Vulkan 1.0, mas a maior parte da implementação está no driver gráfico específico do SOC, não no framework.

Os recursos mais importantes do Vulkan 1.1 para Android são:

  • Suporte para importar e exportar buffers de memória e objetos de sincronização de fora do Vulkan (para interoperabilidade com câmera, codecs e GLES)
  • Suporte para formatos YCbCr

O Vulkan 1.1 também inclui vários recursos menores e melhorias na usabilidade da API. Todas as mudanças feitas na API Vulkan principal com a revisão secundária 1.1 podem ser encontradas em Revisões principais (Vulkan 1.1).

Escolher o suporte ao Vulkan

Os dispositivos Android precisam oferecer suporte ao conjunto de recursos mais avançado do Vulkan disponível, desde que sejam compatíveis com uma ABI de 64 bits e não tenham pouca memória.

Os dispositivos lançados com o Android 13 e versões mais recentes precisam ser compatíveis com o Vulkan 1.3.

Os dispositivos lançados com o Android 10 precisam oferecer suporte ao Vulkan 1.1.

Outros dispositivos podem oferecer suporte opcionalmente às versões 1.3, 1.2 e 1.1 do Vulkan.

Suporte a uma versão do Vulkan

Um dispositivo Android oferece suporte a uma versão do Vulkan se as seguintes condições forem atendidas:

  1. Adicione um driver do Vulkan que seja compatível com a versão do Vulkan de interesse (precisa ser uma das versões 1.3, 1.1 ou 1.0) junto com os requisitos adicionais do CDD da versão do Android. Ou atualize um driver do Vulkan com um número de versão mais baixo.
  2. Para Vulkan 1.3 ou 1.1, verifique se o recurso do sistema retornado pelo gerenciador de pacotes retorna true para a versão correta do Vulkan.
    • Para o Vulkan 1.3, o recurso é PackageManager#hasSystemFeature(PackageManager.FEATURE_VULKAN_HARDWARE_VERSION, 0x403000).
    • Para o Vulkan 1.1, o recurso é PackageManager#hasSystemFeature(PackageManager.FEATURE_VULKAN_HARDWARE_VERSION, 0x401000).
    O gerenciador de pacotes vai retornar true para Vulkan 1.3 e Vulkan 1.1 ao adicionar uma regra, mostrada a seguir, a um arquivo device.mk adequado.
    • Adicione o seguinte para o 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
      
    • Adicione o seguinte para o 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 referência do Android (ABP)

Recomendamos que todos os dispositivos Android estejam em conformidade com o perfil de referência do Android 2022 mais recente, conforme descrito no guia do perfil de referência do Android.

Qualquer dispositivo que ofereça suporte ao Android 14 ou versões mais recentes e à API Vulkan precisa atender a todas as funcionalidades definidas no perfil de referência do Android 2021. A lista completa de funcionalidades necessárias está enumerada no arquivo de perfil do Vulkan json, mas um subconjunto importante das funcionalidades necessárias inclui:

  • texturas compactadas por ASTC e ETC;
  • espaços de cores variáveis até VK_EXT_swapchain_colorspace;
  • Sombra de amostras e interpolação multiamostra usando sampleRateShading.

Integração de sistemas de janelas (WSI)

Em libvulkan.so, o driver implementa as seguintes extensões de integração do sistema de janelas (WSI, na sigla em inglês):

  • VK_KHR_surface
  • VK_KHR_android_surface
  • VK_KHR_swapchain
  • VK_KHR_driver_properties, implementado para Vulkan 1.1 somente no Android 10
  • VK_GOOGLE_display_timing, implementado para qualquer versão do Vulkan no Android 10

Os objetos VkSurfaceKHR e VkSwapchainKHR e todas as interações com ANativeWindow são processados pela plataforma e não são expostos aos motoristas. A implementação do WSI depende da extensão VK_ANDROID_native_buffer, que precisa ser compatível com o driver. Essa extensão é usada apenas pela implementação do WSI e não é exposta aos apps.

Flags de uso do Gralloc

As implementações do Vulkan podem precisar que os buffers de cadeia de troca sejam alocados com flags de uso privadas do Gralloc definidas pela implementação. Ao criar uma cadeia de troca, o Android pede ao driver para traduzir o formato solicitado e as flags de uso de imagem em flags de uso do Gralloc chamando:

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

Os parâmetros format e imageUsage são extraídos da estrutura VkSwapchainCreateInfoKHR. O driver precisa preencher *grallocConsumerUsage e *grallocProducerUsage com as flags de uso do Gralloc necessárias para o formato e o uso. As flags de uso retornadas pelo driver são combinadas com as flags de uso solicitadas pelo consumidor da cadeia de troca ao alocar buffers.

O Android 7.x chama uma versão anterior de VkSwapchainImageUsageFlagsANDROID(), chamada vkGetSwapchainGrallocUsageANDROID(). O Android 8.0 e versões mais recentes descontinuam vkGetSwapchainGrallocUsageANDROID(), mas ainda chamam vkGetSwapchainGrallocUsageANDROID() se vkGetSwapchainGrallocUsage2ANDROID() não for fornecido pelo driver:

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

O vkGetSwapchainGrallocUsageANDROID() não aceita flags de uso de swapchain nem flags de uso estendido do Gralloc.

Imagens com suporte de Gralloc

VkNativeBufferANDROID é uma estrutura de extensão vkCreateImage para criar uma imagem com suporte de um buffer do Gralloc. VkNativeBufferANDROID é fornecido a vkCreateImage() na cadeia de estrutura VkImageCreateInfo. As chamadas para vkCreateImage() com VkNativeBufferANDROID acontecem durante a chamada para vkCreateSwapchainKHR. A implementação do WSI aloca o número de buffers nativos solicitados para a cadeia de troca e cria um VkImage para cada um:

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;

Ao criar uma imagem com suporte do Gralloc, o VkImageCreateInfo tem os seguintes dados:

  .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

No Android 8.0 e versões mais recentes, a plataforma oferece uma estrutura de extensão VkSwapchainImageCreateInfoKHR na cadeia VkImageCreateInfo fornecida a vkCreateImage quando qualquer flag de uso de imagem de cadeia de troca é necessária para a cadeia de troca. A estrutura de extensão contém as flags de uso da imagem da cadeia de troca:

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

    VkSwapchainImageUsageFlagsANDROID      usage;
} VkSwapchainImageCreateInfoANDROID;

No Android 10 e versões mais recentes, a plataforma é compatível com VK_KHR_swapchain v70 para que o app Vulkan possa criar uma VkImage apoiada pela memória de cadeia de troca. Primeiro, o app chama vkCreateImage com uma estrutura VkImageSwapchainCreateInfoKHR encadeada à estrutura VkImageCreateInfo. Em seguida, o app chama vkBindImageMemory2(KHR) com uma estrutura VkBindImageMemorySwapchainInfoKHR encadeada à estrutura VkBindImageMemoryInfo. O imageIndex especificado na estrutura VkBindImageMemorySwapchainInfoKHR precisa ser um índice de imagem de cadeia de troca válido. Enquanto isso, a plataforma fornece uma estrutura de extensão VkNativeBufferANDROID com as informações de buffer do Gralloc correspondentes para a cadeia VkBindImageMemoryInfo, para que o driver saiba a qual buffer do Gralloc vincular o VkImage.

Adquirir imagens

vkAcquireImageANDROID adquire a propriedade de uma imagem de cadeia de troca e importa uma espera nativa sinalizada externamente para um objeto VkSemaphore e um objeto VkFence atuais:

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

vkAcquireImageANDROID() é chamado durante vkAcquireNextImageKHR para importar uma proteção nativa para os objetos VkSemaphore e VkFence fornecidos pelo app. No entanto, os objetos de semáforo e proteção são opcionais nessa chamada. O driver também pode aproveitar essa oportunidade para reconhecer e processar mudanças externas no estado do buffer do Gralloc. Muitos drivers não precisam fazer nada aqui. Essa chamada coloca VkSemaphore e VkFence no mesmo estado pendente como se sinalizados por vkQueueSubmit, para que as filas possam aguardar o semáforo e o app possa aguardar a barreira.

Os dois objetos são sinalizados quando a cerca nativa subjacente sinaliza. Se a cerca nativa já tiver sinalizado, o semáforo estará no estado sinalizado quando essa função retornar. O driver assume a propriedade do descritor do arquivo de bloqueio e o fecha quando não é mais necessário. O driver precisa fazer isso mesmo que um objeto de semáforo ou de bloqueio não seja fornecido ou mesmo que vkAcquireImageANDROID falhe e retorne um erro. Se fenceFd for -1, é como se a cerca nativa já tivesse sido sinalizada.

Imagens de lançamento

vkQueueSignalReleaseImageANDROID prepara uma imagem de cadeia de troca para uso externo, cria uma barreira nativa e agenda a sinalização dela depois que os semáforos de entrada forem sinalizados:

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

vkQueuePresentKHR() chama vkQueueSignalReleaseImageANDROID() na fila fornecida. O driver precisa gerar uma cerca nativa que não sinalize até que todos os semáforos waitSemaphoreCount em pWaitSemaphores sinalizem e que qualquer trabalho adicional necessário para preparar image para apresentação seja concluído.

Se os semáforos de espera (se houver) já tiverem sinalizado e queue já estiver inativo, o driver poderá definir *pNativeFenceFd como -1 em vez de um descritor de arquivo de cerca nativo real, indicando que não há nada para esperar. O chamador é proprietário e fecha o descritor de arquivo retornado em *pNativeFenceFd.

Muitos drivers podem ignorar o parâmetro de imagem, mas alguns podem precisar preparar estruturas de dados do lado da CPU associadas a um buffer do Gralloc para uso por consumidores de imagens externos. A preparação do conteúdo do buffer para uso por consumidores externos deve ser feita de forma assíncrona como parte da transição da imagem para VK_IMAGE_LAYOUT_PRESENT_SRC_KHR.

Se a imagem foi criada com VK_SWAPCHAIN_IMAGE_USAGE_SHARED_BIT_ANDROID, o driver precisa permitir que vkQueueSignalReleaseImageANDROID() seja chamado repetidamente sem chamadas de intervenção para vkAcquireImageANDROID().

Suporte para imagens apresentáveis compartilhadas

Alguns dispositivos podem compartilhar a propriedade de uma única imagem entre o pipeline de exibição e a implementação do Vulkan para minimizar a latência. No Android 9 e versões mais recentes, o carregador anuncia condicionalmente a extensão VK_KHR_shared_presentable_image com base na resposta do driver a uma chamada para vkGetPhysicalDeviceProperties2.

Se o driver não for compatível com o Vulkan 1.1 ou a extensão VK_KHR_physical_device_properties2, o carregador não anunciará a compatibilidade com imagens apresentáveis compartilhadas. Caso contrário, o carregador consulta os recursos do driver chamando vkGetPhysicalDeviceProperties2() e incluindo a seguinte estrutura na cadeia VkPhysicalDeviceProperties2::pNext:

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

Se o driver puder compartilhar a propriedade de uma imagem com o sistema de exibição, ele definirá o membro sharedImage como VK_TRUE.

Validação

Os OEMs podem testar a implementação do Vulkan usando o CTS, que inclui o seguinte:

  • Testes de conformidade do Khronos Vulkan no módulo CtsDeqpTestCases, que incluem testes funcionais de API para Vulkan 1.0, 1.1, 1.2 e 1.3.
  • O módulo CtsGraphicsTestCases, que testa se o dispositivo está configurado corretamente para os recursos do Vulkan que ele oferece suporte.

Flag de recurso do Vulkan

Um dispositivo compatível com o Android 11 ou versões mais recentes e com a API Vulkan é necessário para expor uma flag de recurso, android.software.vulkan.deqp.level. O valor dessa flag de recurso é uma data, codificada como um valor inteiro. Especifica a data associada aos testes dEQP do Vulkan que o dispositivo afirma ter passado.

Uma data no formato AAAA-MM-DD é codificada como um número inteiro de 32 bits da seguinte maneira:

  • Os bits de 0 a 15 armazenam o ano
  • Os bits 16 a 23 armazenam o mês.
  • Os bits 24 a 31 armazenam o dia

O valor mínimo permitido para a flag de recurso é 0x07E30301, que corresponde à data 2019-03-01, associada aos testes dEQP do Vulkan para o Android 10. Se a flag de recurso tiver pelo menos esse valor, o dispositivo vai afirmar que passou em todos os testes dEQP do Vulkan do Android 10.

O valor 0x07E40301 corresponde à data 2020-03-01, que é a data associada aos testes dEQP do Vulkan para Android 11. Se a flag de recurso tiver pelo menos esse valor, o dispositivo vai passar em todos os testes dEQP do Vulkan do Android 11.

O valor 0x07E60301 corresponde à data 2022-03-01, que é a data associada aos testes dEQP do Vulkan para o Android 13. Se a flag de recurso tiver pelo menos esse valor, o dispositivo vai afirmar que passou em todos os testes dEQP do Vulkan do Android 13.

Um dispositivo que expõe uma flag de recurso específica (ou seja 0x07E30301, 0x07E40301, 0x07E60301) afirma passar em todos os testes dEQP do Android Vulkan dessa flag de recurso (Android 10, Android 11 e Android 13, respectivamente). Este dispositivo pode passar nos testes dEQP do Vulkan de uma versão mais recente do Android.

O dEQP do Vulkan faz parte do CTS do Android. No Android 11, o componente do CTS de execução de testes dEQP reconhece a flag de recurso android.software.vulkan.deqp.level e pula todos os testes dEQP do Vulkan que, de acordo com essa flag de recurso, o dispositivo não afirma oferecer suporte. Esses testes são informados como aprovados de forma trivial.