Migrar scripts para Vulkan

Para cargas de trabalho em que o uso da GPU é ideal, a migração de scripts do RenderScript para computação do Vulkan oferece ao app mais controle direto sobre o hardware da GPU, possivelmente desbloqueando mais desempenho em comparação com outras APIs.

Confira abaixo uma visão geral de alto nível para ajudar você a usar sombreadores de computação do Vulkan para substituir scripts do RenderScript.

Inicialização do Vulkan

Em vez de criar um objeto de contexto do RenderScript em Kotlin ou Java, siga as próximas etapas para criar um contexto do Vulkan usando o NDK.

  1. Crie uma instância do Vulkan.

  2. Escolha um dispositivo físico Vulkan compatível com uma fila de computação.

  3. Crie um dispositivo lógico Vulkan e acesse a fila de computação.

Como alternativa, você pode configurar as camadas de validação do Vulkan no Android para acelerar o desenvolvimento de apps Vulkan.

O app de exemplo demonstra como inicializar o contexto do Vulkan em VulkanContext.h (link em inglês). Para saber mais, consulte as seções Inicialização e Dispositivos e filas (links em inglês) da especificação do Vulkan.

Alocações do Vulkan

Uma alocação do RenderScript pode ser migrada para uma imagem de armazenamento do Vulkan ou um buffer de armazenamento do Vulkan (links em inglês). Para um melhor desempenho com imagens somente leitura, use uma imagem de amostra com operações de busca, seja como um amostrador de imagem combinada ou com vinculações distintas de amostrador e imagem de amostra.

Os recursos do Vulkan são alocados nele. Para evitar a sobrecarga de cópia da memória ao interagir com outros componentes do Android, use a extensão VK_ANDROID_external_memory_android_hardware_buffer para importar uma AHardwareBuffer do Android para o Vulkan. Essa extensão está disponível em todos os dispositivos Android compatíveis com o Vulkan 1.1. Para ver mais informações, consulte FEATURE_VULKAN_HARDWARE_VERSION.

O app de exemplo demonstra como criar recursos do Vulkan em VulkanResources.h (link em inglês). Para saber mais, consulte as seções Criação de recursos e descritores de recursos da especificação do Vulkan.

Conversão para sombreadores de computação do Vulkan

Os scripts do RenderScript precisam ser convertidos em sombreadores de computação do Vulkan. Talvez também seja necessário adaptar seu código, dependendo do uso de elementos globais do RenderScript.

Criar um sombreador de computação do Vulkan

Um sombreador de computação do Vulkan é geralmente programado usando a OpenGL Shading Language (GLSL) e, em seguida, compilado para o formato Standard Portable Intermediate Representation-V (SPIR-V) (links em inglês).

Para ver informações e instruções detalhadas sobre como integrar sombreadores no app, consulte Compiladores de sombreador do Vulkan no Android.

Adaptação de scripts globais

Com base nas características dos scripts globais, recomendamos usar constantes de especialização, constantes de push ou objetos de buffer uniformes para globais que não sejam modificados no sombreador:

  • Constantes de especialização (link em inglês): são recomendadas para scripts globais que são mais consistentes entre as invocações do kernel. Alterar o valor das constantes de especialização exigirá a recriação do pipeline de computação.
  • Constantes de push (link em inglês): recomendados para scripts globais com alterações frequentes e menores que maxPushConstantsSize (mínimo garantido: 128 bytes).
  • Buffer uniforme (link em inglês): é recomendado para scripts globais com alterações frequentes e maiores que o limite da constante de push.

Para variáveis globais que são alteradas no sombreador, é possível usar a imagem de armazenamento da Vulkan ou o buffer de armazenamento do Vulkan (links em inglês).

Cálculos

É preciso criar um pipeline de computação do Vulkan para que a GPU execute o sombreador de computação.

Criar um pipeline de computação do Vulkan

O arquivo ComputePipeline.h no app de exemplo demonstra como criar o pipeline de computação do Vulkan.

Para usar um sombreador SPIR-V compilado no Vulkan, crie um pipeline de computação do Vulkan desta forma:

  1. Crie um módulo de sombreador usando o sombreador SPIR-V compilado.
  2. Crie um layout de conjunto de descritor especificando as vinculações de recursos. Consulte Alocações para mais detalhes.
  3. Crie um conjunto de descritor com base no layout dele.
  4. Crie um layout de pipeline com base no layout do conjunto de descritor.
  5. Crie um pipeline de computação usando o módulo do sombreador e o layout do pipeline.

Para saber mais, consulte a seção Pipelines de computação na especificação do Vulkan.

Iniciar um cálculo

Para iniciar o cálculo usando um pipeline de computação:

  1. Atualize o conjunto de descritor usando os recursos do Vulkan.
  2. Crie um buffer de comando do Vulkan e registre os seguintes comandos:
    1. Vincule o pipeline e o conjunto do descritor.
    2. Envie grupos de trabalho de computação.
  3. Envie o buffer de comando para a fila de computação.
  4. Aguarde o resultado da fila ou, como opção, retorne um limite de sincronização.

Para encadear vários kernels (por exemplo, para migrar códigos usando um ScriptGroup), grave-os em um único buffer de comando e sincronize-os com as barreiras de memória.

O app de exemplo (link em inglês) demonstra duas tarefas de computação:

  • Rotação HUE: uma tarefa de computação simples com um único sombreador de computação. Consulte ImageProcessor::rotateHue para ver o exemplo de código.
  • Desfoque: uma tarefa de computação mais complexa que executa dois sombreadores de computação em sequência. Consulte ImageProcessor::blur para conferir o exemplo de código.

Para saber mais sobre buffers de comando ou barreiras de memória, consulte as seções Buffers de comando e Barreiras de memória (links em inglês) na especificação do Vulkan.