Cómo migrar secuencias de comandos a Vulkan

Para las cargas de trabajo en las que el se recomienda el procesamiento con GPU, la migraciónde las secuencias de comandos de RenderScript al procesamiento de Vulkan le brinda a tu app un control más directo sobre el hardware de GPU, lo que podría desbloquear un rendimiento adicional en comparación con otras APIs.

A continuación, se incluye una descripción general detallada que te ayudará a usar sombreadores de cómputos de Vulkan para reemplazar las secuencias de comandos de RenderScript.

Inicialización de Vulkan

En lugar de crear un objeto de contexto de RenderScript en Kotlin o Java, realiza los siguientes pasos para crear un contexto de Vulkan con el NDK.

  1. Crea una instancia de Vulkan.

  2. Elige un dispositivo físico de Vulkan que admita una cola de procesamiento.

  3. Crea un dispositivo lógico de Vulkan y obtén la cola de procesamiento.

Opcionalmente, puedes configurar las capas de validación de Vulkan en Android para acelerar el desarrollo de tus aplicaciones de Vulkan.

En la app de ejemplo, se muestra cómo inicializar el contexto de Vulkan en VulkanContext.h. Si deseas obtener más información, consulta las secciones Inicialización y Dispositivos y colas de la especificación de Vulkan.

Asignaciones de Vulkan

Se puede migrar una asignación de RenderScript a una imagen de almacenamiento de Vulkan o a un búfer de almacenamiento de Vulkan. Si deseas obtener un mejor rendimiento con imágenes de solo lectura, usa una imagen de ejemplo con operaciones de recuperación, ya sea como un muestreo de imágenes combinadas o con vinculaciones específicas de muestreo e imagen de muestra.

Los recursos de Vulkan se asignan en Vulkan. Para evitar la sobrecarga de copia de memoria cuando interactúas con otros componentes de Android, procura usar la extensión VK_ANDROID_external_memory_android_hardware_buffer para importar un AHardwareBuffer de Android a Vulkan. Esta extensión está disponible en todos los dispositivos Android que admiten Vulkan 1.1. Si deseas obtener información detallada, consulta FEATURE_VULKAN_HARDWARE_VERSION.

En la app de ejemplo, se muestra cómo crear recursos de Vulkan en VulkanResources.h. Para obtener más información, consulta las secciones sobre la creación de recursos y los descriptores de recursos de la especificación de Vulkan.

Conversión a sombreadores de cómputos de Vulkan

Tus secuencias de comandos de RenderScript deben convertirse a sombreadores de cómputos de Vulkan. Es posible que también debas adaptar tu código en función del uso de globales de RenderScript.

Escribe un sombreador de cómputos de Vulkan

Por lo general, un sombreador de cómputos de Vulkan se escribe en OpenGL Shading Language (GLSL) y, luego, se compila en el formato Standard Portable Intermediate Representation-V (SPIR-V).

Si deseas obtener información detallada e instrucciones para integrar sombreadores en tu app, consulta Compiladores de sombreadores de Vulkan en Android.

Adaptación de globales de secuencias de comandos

Según las características de los globales de secuencias de comandos, te recomendamos que uses constantes de especialización, constantes push u objetos de búfer uniformes para globales que no se modifiquen dentro del sombreador:

  • Constantes de especialización: Se recomiendan para los globales de secuencias de comandos que son mayormente coherentes entre las invocaciones de kernel. Si se modifica el valor de las constantes de especialización, se deberá volver a crear la canalización de cómputos.
  • Constantes push: Se recomiendan para globales de secuencias de comandos que cambian con frecuencia y cuyo tamaño es menor a maxPushConstantsSize (mínimo garantizado de 128 bytes).
  • Búfer uniforme: Se recomienda para globales de secuencias de comandos que cambian con frecuencia y cuyo tamaño es mayor al límite de constante push.

Para los globales que se modifican dentro del sombreador, puedes usar la imagen de almacenamiento de Vulkan o el búfer de almacenamiento de Vulkan.

Cómputos

Debes crear una canalización de cómputos de Vulkan de modo que la GPU ejecute tu sombreador de cómputos.

Crea una canalización de cómputos de Vulkan

El archivo ComputePipeline.h de la app de ejemplo muestra cómo crear la canalización de cómputos de Vulkan.

Para usar un sombreador SPIR-V compilado en Vulkan, crea una canalización de cómputos de Vulkan de la siguiente manera:

  1. Crea un módulo de sombreador que tenga el sombreador SPIR-V compilado.
  2. Crea un diseño del conjunto de descriptores que especifique las vinculaciones de recursos (si deseas obtener información detallada, consulta Asignaciones).
  3. Crea un conjunto de descriptores a partir del diseño de ese conjunto.
  4. Crea un diseño de canalización a partir del diseño del conjunto de descriptores.
  5. Crea una canalización de cómputos con el módulo de sombreador y el diseño de la canalización.

Si deseas obtener más información, consulta la sección Canalizaciones de cómputos en la especificación de Vulkan.

Inicia un cómputo

Para iniciar el cómputo mediante una canalización de cómputos, haz lo siguiente:

  1. Actualiza el conjunto de descriptores con los recursos de Vulkan.
  2. Crea un búfer de comandos de Vulkan y registra los siguientes comandos:
    1. Vincula la canalización y el conjunto de descriptores.
    2. Despacha los grupos de trabajo de cómputos.
  3. Envía el búfer de comandos a la cola de procesamiento.
  4. Espera en la cola o, de manera opcional, muestra una valla de sincronización.

Para encadenar varios kernels (por ejemplo, para migrar códigos con ScriptGroup), regístralos en un solo búfer de comando y sincronízalos con las barreras de memoria.

En la app de ejemplo, se muestran dos tareas de cómputos:

  • Rotación de tonalidad: Es una tarea de cómputos simple con un solo sombreador de cómputos. Consulta ImageProcessor::rotateHue para ver la muestra de código.
  • Desenfoque: Es una tarea de cómputos más compleja que ejecuta dos sombreadores de cómputos en forma secuencial. Consulta ImageProcessor::blur para ver la muestra de código.

Si deseas obtener más información sobre los búferes de comandos o las barreras de memoria, consulta las secciones Búferes de comando y Barreras de memoria de la especificación de Vulkan.