Начало работы с Vulkan на Android
Vulkan – это основной низкоуровневый графический API для Android. Vulkan обеспечивает оптимальную производительность для игр, в которых используется собственный игровой движок и средство визуализации.
Чтобы успешно реализовать Vulkan в игровом движке, необходимо:
- Как определить, какие устройства Android поддерживают Vulkan
- Учитывайте компромиссы при поддержке старых устройств Android
- Добавьте Vulkan в целевую сборку Android
- Выберите компилятор шейдеров для создания SPIR-V для Vulkan
- Как определить доступную версию Vulkan API во время выполнения
- Узнайте, как оптимизировать рендеринг Vulkan с помощью профилей Vulkan, регулирования частоты кадров и предварительного поворота.
- Выберите графические инструменты для отладки и анализа производительности
- Примечание. Информацию об использовании Vulkan на Android с игровыми движками Unity или Unreal можно найти в следующих статьях:
- Vulkan в Unity
- Vulkan в Unreal
Выберите минимальные характеристики устройств для Vulkan
Vulkan доступен на устройствах с Android 7.0 (уровень API 24) и более поздних версий. Не все устройства Android с Android 7.0 или более поздней версии поддерживают Vulkan. Вам нужно определить, какие устройства Android с поддержкой Vulkan совместимы с вашей игрой.
Рекомендации
Ниже приведены минимальные требования для поддержки Vulkan.
- На устройстве установлена ОС Android 10.0 (уровень API 29) или более поздней версии.
- Устройство поддерживает Vulkan API версии 1.1 или более поздней.
- Аппаратные возможности и функции устройства совместимы с базовым профилем Android 2022 года.
Поддержка устаревших устройств
Если ваша игра предназначена для широкого спектра устройств с разными графическими возможностями, вам может потребоваться поддержка устройств более старых, чем рекомендовано в разделе Выбор минимальных характеристик устройств для Vulkan. Прежде чем добавлять поддержку старых устройств, оцените, дает ли Vulkan преимущества вашей игре. Игры с большим количеством вызовов отрисовки, использующие OpenGL ES, могут значительно нагружать драйвер из-за высокой стоимости вызовов отрисовки в OpenGL ES. Такие игры могут быть ограничены ЦП, поскольку значительная часть времени формирования кадра уходит на работу графического драйвера. Кроме того, переход с OpenGL ES на Vulkan позволяет значительно снизить нагрузку на ЦП и энергопотребление. Это особенно актуально, если в игре есть сложные сцены, в которых нельзя эффективно использовать инстансинг для уменьшения количества вызовов отрисовки. При таргетинге на старые устройства включите поддержку рендеринга OpenGL ES в качестве резервного варианта, поскольку на некоторых устройствах из списка целевых могут быть реализации Vulkan, которые не могут надежно запускать вашу игру.
Вы можете отказаться от поддержки старых устройств с Vulkan, если они не обладают достаточной производительностью, не поддерживают нужные функции или работают нестабильно.
Эффективность и функции
Старые устройства Android с поддержкой Vulkan могут не обладать достаточной производительностью рендеринга или аппаратной поддержкой функций, необходимых для запуска игры. Это особенно вероятно, если в вашей игре высококачественная графика и Vulkan – единственный API, на который вы ориентируетесь в Android. Многие старые устройства поддерживают только Vulkan API версии 1.0.3 и часто не имеют широко используемых расширений Vulkan, доступных на более современном оборудовании.
Стабильность
На старых устройствах Android могут использоваться устаревшие драйверы Vulkan. В этих версиях могут быть ошибки, влияющие на стабильность игры. Устранение ошибок драйвера может потребовать значительного времени на тестирование и разработку.
Как добавить Vulkan в проект
Чтобы добавить Vulkan в проект, выполните следующие действия:
- Включите заголовки Vulkan API
- Компиляция кода шейдера в SPIR-V
- Вызов Vulkan API во время выполнения
Включите заголовки Vulkan API
Чтобы скомпилировать код, использующий Vulkan, в игру нужно включить заголовочные файлы Vulkan API. Копию заголовков Vulkan можно найти в Android NDK или в пакете выпусков Vulkan SDK. В каждую версию NDK входят только те заголовки Vulkan, которые были доступны на момент выпуска этой версии. Если вы используете заголовочные файлы Vulkan из NDK, используйте NDK версии 25 или выше, которая включает заголовочные файлы, поддерживающие Vulkan версии 1.3. В Vulkan SDK есть самая актуальная версия заголовков.
Компиляция кода шейдера в SPIR-V
Vulkan API ожидает, что программы шейдеров будут предоставлены в двоичном промежуточном формате SPIR-V. Это отличается от OpenGL ES, где можно было отправлять исходный код, написанный на OpenGL Shading Language (GLSL), в виде текстовых строк. Используйте компилятор шейдеров, чтобы преобразовать код, написанный на языке шейдеров, например GLSL или HLSL, в модули SPIR-V для использования с Vulkan.
Компилятор shaderc позволяет компилировать шейдерные программы, написанные на GLSL, в SPIR-V. Если в вашей игре используется HLSL, то DirectXShaderCompiler поддерживает вывод SPIR-V. Обычно шейдеры компилируются офлайн в рамках процесса сборки объектов для игры, а модули SPIR-V включаются в состав объектов среды выполнения.
Вызов Vulkan API во время выполнения
Чтобы вызвать Vulkan API, игре нужно получить указатели функций для вызовов Vulkan API. Самый простой способ сделать это – связать приложение с общей библиотекой libvulkan.so, которая входит в Android NDK. У связывания с библиотекой есть два недостатка: дополнительные затраты на диспетчеризацию функций и ограничения на то, какие указатели функций Vulkan API разрешаются автоматически.
При вызове функции Vulkan API управление передается через таблицу диспетчеризации, которой управляет загрузчик Vulkan. В Android используется собственная реализация загрузчика Vulkan, а не загрузчик LunarG. Эта система загрузчиков является частью многоуровневой архитектуры Vulkan API. Привязка к системной библиотеке во время сборки приводит к дополнительному уровню диспетчеризации для данного вызова API. Хотя накладные расходы невелики, они могут быть заметны в играх, которые выполняют большое количество вызовов Vulkan.
Системная библиотека обычно разрешает только указатели на функции Vulkan, которые считаются частью основного API. У Vulkan есть большое количество расширений, которые определяют дополнительные функции Vulkan. Многие из них не разрешаются автоматически системной библиотекой. Прежде чем использовать указатели на эти функции Vulkan, их нужно разрешить вручную.
Чтобы избежать этих проблем, динамически разрешайте указатели на все функции Vulkan, которые вы планируете использовать во время выполнения. Один из способов сделать это – использовать библиотеку метазагрузчика с открытым исходным кодом, например volk. В примере игры AGDKTunnel для этого используется volk. Если вы используете библиотеку метазагрузчика, не связывайте ее с общей библиотекой libvulkan.so в скриптах сборки.
Как определить доступную версию Vulkan API
Android поддерживает следующие версии Vulkan API:
- 1.0.3
- 1.1
- 1.3
Максимальная версия Vulkan API, доступная на устройстве, определяется версией Android и поддержкой драйвера Vulkan.
Версию Android.
Поддержка версий Vulkan API зависит от минимальной версии Android (уровня API):
- 1.3 – Android 13.0 (уровень API 33) и более поздние версии.
- 1.1 – Android 10.0 (уровень API 29) и более поздние версии
- 1.0.3 – Android 7.0 (уровень API 24) и более поздние версии
Поддержка драйвера Vulkan
Поддержка версии Vulkan API на платформе Android не гарантирует, что эта версия поддерживается драйвером Vulkan на устройстве. Устройство с Android 13 может поддерживать только версию 1.1 Vulkan API.
При инициализации Vulkan не запрашивайте версию API выше:
- Максимальная версия Vulkan API для версии Android, установленной на устройстве.
- Версия Vulkan API, возвращаемая функцией vkEnumerateInstanceVersion.
- Версия Vulkan API, указанная в свойстве
apiVersionструктуры VkPhysicalDeviceProperties.
Ниже приведен пример определения самой высокой поддерживаемой версии Vulkan API.
// Minimum Android API levels for Vulkan 1.3/1.1 version support
static constexpr int kMinimum_vk13_api_level = 33;
static constexpr int kMinimum_vk11_api_level = 29;
uint32_t GetHighestSupportedVulkanVersion(VkPhysicalDevice physical_device) {
uint32_t instance_api_version = 0;
vkEnumerateInstanceVersion(&instance_api_version);
VkPhysicalDeviceProperties device_properties;
vkGetPhysicalDeviceProperties(physical_device, &device_properties);
// Instance and device versions don't have to match, use the lowest version
// number for API support if they don't.
const uint32_t driver_api_version =
(instance_api_version < device_properties.apiVersion) ?
instance_api_version : device_properties.apiVersion;
const int device_api_level = android_get_device_api_level();
if (device_api_level >= kMinimum_vk13_api_level &&
driver_api_version >= VK_API_VERSION_1_3) {
return VK_API_VERSION_1_3;
} else if (device_api_level >= kMinimum_vk11_api_level &&
driver_api_version >= VK_API_VERSION_1_1) {
return VK_API_VERSION_1_1;
}
return VK_API_VERSION_1_0;
}
Как определить совместимость профиля Vulkan
Профили Vulkan – это JSON-файлы, в которых определен набор обязательных функций, расширений, возможностей и минимальных ограничений параметров, которые должно поддерживать устройство Vulkan для совместимости с профилем. Чтобы определить, совместимо ли устройство с определенным профилем Vulkan, например Android Baseline Profile 2022 года, используйте библиотеку Vulkan Profiles API с открытым исходным кодом. Вы также можете самостоятельно проанализировать JSON-файл профиля и запросить возможности устройства с помощью соответствующих API Vulkan, чтобы определить совместимость профиля.
Профили Vulkan
В Android используются профили Vulkan, которые определяют, какие функции и расширения доступны для каждого устройства Android.
Базовый профиль Android (ABP) – это первая попытка создать профиль Vulkan. ABP2021 и ABP2022 – это ретроспективные профили, которые охватывают более 85% активных устройств на момент их создания. Новые ABP создаваться не будут.
Профили Vulkan для Android (VPA) – это новый перспективный профиль, призванный отражать потребности разработчиков программного обеспечения и обеспечивать согласованность функций по мере того, как разработчики аппаратного обеспечения смогут их предоставлять. VPA15_minimums – это первый профиль для Android 15. Каждый год мы будем выпускать новый профиль VPA для каждой основной версии Android.
Реализуйте синхронизацию кадров
Правильная синхронизация кадров – важная составляющая качественного игрового процесса. В Android Game Development Kit входит библиотека Frame Pacing, которая помогает оптимизировать смену кадров в игре. Подробную информацию о реализации вы найдете в статье Как интегрировать Android Frame Pacing в средство визуализации Vulkan.
Не полагайтесь на неявную синхронизацию и темп кадров
Для управления цепочкой буферов используются функции vkAcquireNextImageKHR и vkQueuePresentKHR. Не полагайтесь на их потенциальное блокирующее поведение для общей синхронизации приложений или графических процессоров.
Точное поведение блокировки этих функций может существенно различаться в зависимости от:
- Устройства Android
- Драйверы графического процессора
- Состояния механизма презентации (VkPresentModeKHR)
Единственная цель vkAcquireNextImageKHR – получить доступное изображение, которое можно показать. При этом блокировка может как произойти, так и не произойти. Аналогично vkQueuePresentKHR ставит в очередь запрос на показ изображения и также может блокировать или не блокировать.
Ни одна из функций не гарантирует надежную синхронизацию несвязанных задач ЦП или операций графического процессора.
Для надежной синхронизации всегда используйте явные примитивы Vulkan, такие как семафоры для зависимостей между графическими процессорами (например, рендеринг для представления), барьеры для синхронизации между графическим и центральным процессорами (например, чтобы знать, когда рендеринг завершен на центральном процессоре), а также барьеры конвейера или события для более точного выполнения графического процессора и зависимостей памяти. Использование явной синхронизации обеспечивает предсказуемое поведение и позволяет избежать незаметных ошибок, вызванных различиями в синхронизации, зависящими от реализации, которые присущи разнообразной экосистеме оборудования Android.
Как реализовать предварительную ротацию
Устройства Android могут отображать контент в нескольких ориентациях. Ориентация устройства может отличаться от ориентации поверхности рендеринга. В отличие от OpenGL ES на Android, Vulkan не обрабатывает расхождения между ними. Чтобы узнать, как работает процесс ориентации и как лучше всего обрабатывать различия в ориентации при использовании Vulkan, прочитайте статью Как обрабатывать поворот устройства с помощью предварительного поворота Vulkan.
Устранение неполадок и профилирование рендеринга Vulkan
Для диагностики проблем с рендерингом и производительностью кода рендеринга Vulkan доступно несколько инструментов.
Дополнительную информацию об инструментах отладки и профилирования Vulkan можно найти в разделе Инструменты и продвинутые функции.
Уровни проверки Vulkan
Уровни проверки Vulkan – это библиотеки времени выполнения, которые можно включить для проверки вызовов API Vulkan и получения предупреждений или ошибок о неправильном или неоптимальном использовании. По умолчанию эти уровни проверки неактивны, поскольку процесс проверки увеличивает нагрузку во время выполнения и влияет на производительность игры. Подробнее о том, как использовать уровни проверки в игре…
Инструменты для захвата кадров
Используйте инструменты захвата кадров, чтобы записывать и воспроизводить вызовы Vulkan API, сделанные во время кадра игры. Эти инструменты позволяют:
- Просмотр информации об активных графических ресурсах и их визуализаций
- Просматривайте последовательность вызовов API, сделанных вашей игрой, и параметры API.
- Изучайте состояние графического конвейера во время вызова отрисовки.
- Визуализируйте результаты рендеринга до определенного вызова отрисовки в кадре.
Используйте инструмент RenderDoc с открытым исходным кодом, чтобы записывать кадры из игр, запущенных на устройствах Android. RenderDoc поддерживает захват кадров как Vulkan, так и OpenGL ES.
Для захвата кадров Vulkan также можно использовать Android GPU Inspector (AGI).
Инструменты для анализа эффективности
Используйте инструменты анализа производительности, чтобы выявить проблемы с рендерингом, которые приводят к снижению частоты кадров. Поставщики графических процессоров предлагают инструменты, которые позволяют профилировать игры и получать данные об эффективности, относящиеся к архитектуре их графических процессоров. Производительность и узкие места игры могут значительно различаться при рендеринге на графических процессорах разных производителей или даже на разных поколениях графических процессоров одного и того же производителя.
Вы также можете использовать Android GPU Inspector для сбора и анализа данных о производительности. В отличие от инструментов поставщиков, Android GPU Inspector совместим с графическими процессорами разных производителей. Однако Android GPU Inspector не поддерживает старые устройства Android и может быть несовместим с некоторыми новыми.
Как улучшить тестирование Vulkan с помощью CTS-D
Производители устройств Android используют Compatibility Test Suite (CTS), чтобы обеспечить совместимость своих устройств. CTS-D (Developer-Powered CTS) – это тесты, которые отправляют разработчики приложений для Android. Они позволяют убедиться, что будущие устройства Android будут соответствовать требованиям разработчиков и смогут запускать их приложения без ошибок.
Если вы обнаружите новую ошибку в приложении Vulkan, которая влияет на определенное устройство Android, вы можете отправить новое предложение по тестированию, описав проблему и способы ее проверки. Это позволит нам устранить проблему в следующем обновлении и предотвратить ее появление на других устройствах.
Пошаговые инструкции по отправке предложения теста приведены в статье Как отправить предложение теста CTS.