네이티브 및 독점 엔진

Android에서 Vulkan 시작하기

Vulkan은 Android의 기본 저수준 그래픽 API입니다. Vulkan은 자체 게임 엔진 및 렌더기를 구현하는 게임에 최적의 성능을 제공합니다.

게임 엔진에서 Vulkan을 성공적으로 구현하려면 다음을 실행해야 합니다.

  • Vulkan과 함께 사용할 Android 기기를 식별합니다.
  • 이전 Android 기기 지원의 장단점을 이해합니다.
  • Android 빌드 타겟에 Vulkan을 추가합니다.
  • 셰이더 컴파일러를 선택하여 Vulkan용 SPIR-V를 만듭니다.
  • 런타임에 사용 가능한 Vulkan API 버전을 확인합니다.
  • Vulkan 프로필, 프레임 속도, 사전 회전을 사용하여 Vulkan 렌더링 작업을 최적화하는 방법을 알아봅니다.
  • 디버깅 및 성능 분석을 위한 그래픽 도구를 선택합니다.

Vulkan의 최소 기기 사양 선택

Vulkan은 Android 7.0(API 수준 24)부터 Android에서 사용할 수 있습니다. Android 7.0 이상을 실행하는 Android 기기 중 일부는 Vulkan을 지원하지 않습니다. 게임에서 지원하는 Vulkan 지원 Android 기기를 확인해야 합니다.

추천

Vulkan 지원의 최소 요구사항으로 다음 사양을 참고하세요.

  • 기기에서 Android 10.0(API 수준 29) 이상을 실행합니다.
  • 기기에서 Vulkan API 버전 1.1 이상을 지원합니다.
  • 기기에 2022 Android 기준 프로필과 호환되는 하드웨어 기능이 있습니다.

이전 기기 지원

게임이 다양한 수준의 그래픽 기능을 갖춘 광범위한 기기에서 실행되도록 설계된 경우 Vulkan의 최소 기기 사양 선택에서 권장하는 것보다 오래된 기기를 지원해야 할 수 있습니다. 이전 기기 지원을 빌드하기 전에 Vulkan이 게임에 이점을 제공하는지 평가하세요. 그리기 호출이 많고 OpenGL ES를 사용하는 게임은 OpenGL ES 내에서 그리기 호출을 하면 비용이 많이 들기 때문에 상당한 드라이버 오버헤드가 발생할 수 있습니다. 이러한 게임은 그래픽 드라이버에서 프레임 시간의 상당 부분을 소비하여 CPU의 제약을 받을 수 있습니다. 또한 게임에서는 OpenGL ES에서 Vulkan으로 전환하여 CPU 및 전원 사용량도 크게 줄일 수 있습니다. 인스턴싱을 효과적으로 사용하여 그리기 호출을 줄일 수 없는 복잡한 장면이 게임에 있는 경우 특히 유용합니다. 이전 기기를 타겟팅할 때는 OpenGL ES 렌더링 지원을 대체로 포함하세요. 대상 기기 목록의 일부 기기에는 게임을 안정적으로 실행할 수 없는 Vulkan 구현이 있을 수 있습니다.

이전 Vulkan 지원 기기는 성능과 기능이 부족하거나 안정성 문제가 있으므로 지원하지 않는 것이 좋습니다.

성능 및 기능

이전 Vulkan 지원 Android 기기에는 게임 실행에 필요한 기능에 관한 렌더링 성능이나 하드웨어 지원이 없을 수 있습니다. 게임에 고화질 그래픽이 있고 Vulkan이 Android에서 타겟팅하는 유일한 API인 경우에 특히 그렇습니다. 대부분의 이전 기기는 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 버전에는 NDK 출시 시점에 사용할 수 있는 Vulkan 헤더만 포함됩니다. NDK의 Vulkan 헤더를 사용하는 경우 Vulkan 버전 1.3을 지원하는 헤더 파일이 포함된 NDK 버전 25 이상을 사용하세요. Vulkan SDK에는 최신 버전의 헤더가 있습니다.

셰이더 코드를 SPIR-V로 컴파일

Vulkan API는 셰이더 프로그램이 SPIR-V 바이너리 중간 형식으로 제공될 것으로 예상합니다. 이 규칙은 OpenGL Shading Language(GLSL)로 작성된 소스 코드를 텍스트 문자열로 제출할 수 있는 OpenGL ES와 다릅니다. 셰이더 컴파일러를 사용하여 셰이더 언어(예: GLSL 또는 상위 수준 셰이더 언어(HLSL))로 작성된 코드를 가져와 Vulkan에서 사용할 수 있도록 SPIR-V 모듈로 컴파일합니다.

shaderc 컴파일러를 사용하면 GLSL로 작성된 셰이더 프로그램을 SPIR-V로 컴파일할 수 있습니다. 게임에서 HLSL을 사용하는 경우 DirectXShaderCompiler가 SPIR-V 출력을 지원합니다. 일반적으로 게임의 애셋 빌드 프로세스의 일부로 셰이더 프로그램을 오프라인으로 컴파일하고 SPIR-V 모듈을 런타임 애셋의 일부로 포함합니다.

런타임에 Vulkan API 호출

Vulkan API를 호출하려면 게임에서 Vulkan API 호출의 함수 포인터를 가져와야 합니다. 가장 간단한 방법은 Android NDK에 포함된 libvulkan.so 공유 라이브러리에 연결하는 것입니다. 라이브러리 연결에는 두 가지 단점이 있습니다. 추가 함수 디스패치 오버헤드, 그리고 Vulkan API 함수 포인터가 자동으로 확인되는 제한입니다.

Vulkan API 함수를 호출하면 제어가 Vulkan 로더라는 구성으로 관리되는 디스패치 테이블을 통해 전달됩니다. Android는 LunarG 로더가 아닌 자체 Vulkan 로더 구현을 사용합니다. 이 로더 시스템은 Vulkan API의 계층 아키텍처의 일부입니다. 빌드 시간에 시스템 라이브러리에 연결하면 지정된 API 호출에 대한 디스패치 수준이 추가됩니다. 오버헤드는 작지만 Vulkan 호출을 많이 실행하는 게임에서는 눈에 띌 수 있습니다.

시스템 라이브러리는 일반적으로 핵심 API의 일부로 간주되는 Vulkan 함수 포인터만 확인합니다. 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 드라이버에서 API 버전을 지원한다고 보장하는 것은 아닙니다. Android 13을 실행하는 기기는 Vulkan API 버전 1.1만 지원할 수 있습니다.

Vulkan을 초기화할 때 다음보다 큰 API 버전을 요청하지 마세요.

지원되는 가장 높은 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 프로필은 Vulkan 기기가 프로필과 호환되기 위해 지원해야 하는 일련의 필수 기능, 확장 프로그램, 최소 매개변수 한도를 정의하는 JSON 파일입니다. 기기가 특정 Vulkan 프로필(예: 2022 Android 기준 프로필)과 호환되는지 확인하려면 오픈소스 Vulkan 프로필 API 라이브러리를 사용하세요. 프로필 JSON 파일을 직접 파싱하고, 관련 Vulkan API를 사용하여 기기 기능을 쿼리해 프로필 호환성을 확인할 수도 있습니다.

Vulkan 프로필

Android는 Android를 실행하는 각 기기에서 사용할 수 있는 기능과 확장 프로그램을 정의하는 Vulkan 프로필을 사용합니다.

Android 기준 프로필 (ABP)은 Vulkan 프로필을 빌드하기 위한 첫 번째 시도입니다. ABP2021ABP2022는 당시 활성 기기의 85% 이상을 대상으로 하는 이전 프로필입니다. 앞으로 새로운 ABP는 없습니다.

Android용 Vulkan 프로필 (VPA)은 소프트웨어 개발자의 요구사항을 반영하고 하드웨어 개발자가 제공하는 즉시 일관된 기능을 제공하는 것을 목표로 하는 새로운 미래지향적인 프로필입니다. VPA15_minimums는 Android 15의 첫 번째 프로필이며 각 주요 Android 출시를 지원하기 위해 매년 새로운 VPA가 제공됩니다.

프레임 속도 구현

적절한 프레임 속도는 고품질 게임플레이 환경을 제공하는 데 필수적입니다. Android Game Development Kit에는 게임에서 최적의 프레임 속도를 달성하는 데 도움이 되는 Frame Pacing 라이브러리가 포함되어 있습니다. 자세한 구현 세부정보는 Vulkan 렌더기에 Android Frame Pacing 통합을 참고하세요.

사전 회전 구현

Android 기기는 여러 방향으로 표시할 수 있습니다. 기기 방향은 렌더링 노출 영역의 방향과 다를 수 있습니다. Android의 OpenGL ES와 달리 Vulkan은 둘 사이의 불일치를 처리하지 않습니다. Vulkan을 사용할 때 방향 프로세스의 작동 방식과 방향 차이를 처리하는 최적의 방법을 이해하려면 Vulkan 사전 회전으로 기기 회전 처리를 참고하세요.

Vulkan 렌더링 문제 해결 및 프로파일링

Vulkan 렌더링 코드의 렌더링 문제 및 성능 문제를 진단하는 데 도움이 되는 여러 도구를 사용할 수 있습니다.

Vulkan의 디버깅 및 프로파일링 도구에 관한 자세한 내용은 도구 및 고급 기능 섹션을 확인하세요.

Vulkan 유효성 검사 계층

Vulkan 유효성 검사 계층은 Vulkan API 호출을 검사하고 잘못되거나 최적화되지 않은 사용에 관한 경고나 오류를 제공하도록 사용 설정할 수 있는 런타임 라이브러리입니다. 이러한 유효성 검사 계층은 기본적으로 활성화되지 않습니다. 유효성 검사 프로세스가 런타임 오버헤드를 추가하고 게임 성능에 영향을 미치기 때문입니다. 게임에서 유효성 검사 계층을 사용하는 방법에 관한 자세한 내용은 유효성 검사 계층으로 디버깅을 참고하세요.

프레임 캡처 도구

프레임 캡처 도구를 사용하여 게임 프레임 중에 발생한 Vulkan API 호출을 기록하고 재생합니다. 이 도구를 사용하면 다음을 실행할 수 있습니다.

  • 활성 그래픽 리소스에 관한 정보 및 시각화를 확인합니다.
  • 게임에서 발생하는 API 호출 시퀀스와 API 매개변수를 확인합니다.
  • 그리기 호출 시 그래픽 파이프라인의 상태를 탐색합니다.
  • 프레임에서 특정 그리기 호출까지 렌더링 결과를 시각화합니다.

오픈소스 RenderDoc 도구를 사용하여 Android에서 실행되는 게임에서 프레임을 캡처하세요. RenderDoc은 Vulkan 및 OpenGL ES의 프레임 캡처를 모두 지원합니다.

Android GPU 검사기(AGI)를 사용하여 Vulkan 프레임을 캡처할 수도 있습니다.

성능 분석 도구

성능 분석 도구를 사용하면 프레임 속도를 최적화하지 못하는 게임의 렌더링 문제를 조사할 수 있습니다. 개별 GPU 공급업체는 게임을 프로파일링하고 GPU 아키텍처와 관련된 성능 데이터를 제공하도록 설계된 도구를 제공합니다. 게임의 성능 특성과 병목 현상은 서로 다른 공급업체의 GPU에서 렌더링하거나 또는 동일한 공급업체의 서로 다른 GPU 세대에서 렌더링할 때도 상당히 달라질 수 있습니다.

Android GPU 검사기를 사용하여 성능 데이터를 수집하고 분석할 수도 있습니다. 공급업체 도구와 달리 Android GPU 검사기는 다양한 공급업체의 여러 GPU와 호환됩니다. 하지만 Android GPU 검사기는 이전 Android 기기를 지원하지 않으며 모든 최신 기기와 호환되지 않을 수도 있습니다.

CTS-D로 Vulkan 테스트 개선

Android 기반 기기 제조업체는 호환성 테스트 모음 (CTS)을 사용하여 기기의 호환성을 보장합니다. 개발자 기반 CTS (CTS-D)는 향후 Android 기기가 사용 사례를 충족하고 버그 없이 애플리케이션을 원활하게 실행할 수 있도록 Android 애플리케이션 개발자가 제출한 테스트입니다.

특정 Android 지원 기기에 영향을 미치는 Vulkan 애플리케이션으로 새로운 버그를 트리거한다면 문제와 이를 확인하는 방법을 설명하는 새로운 테스트 제안서를 제출할 수 있습니다. 이렇게 하면 향후 기기 업데이트에서 문제가 해결되고 다른 기기에서 동일한 버그가 발생하지 않습니다.

테스트 제안서를 제출하는 방법에 관한 단계별 안내는 CTS 제출 프로세스를 확인하세요.