Vulkan 포맷은 메모리 배치 방식을 설명하는 데 사용됩니다. 이 장에서는 Vulkan의 다양한 형식에 대한 개괄적인(high-level) 개요와 형식 사용 방법에 대한 몇가지 로지스틱(logistical) 정보를 제공하는 것을 목표로 합니다. 모든 세부 사항은 Vulkan 사양서 포맷 챕터와 크로노스 그룹 데이터 포맷 사양에 이미 잘 명시되어 있습니다.
VkFormat
의 가장 일반적인 사용 사례는 VkImage
를 생성할 때입니다. VkFormat
은 잘 정의되어 있기 때문에 VkBufferView
, 정점 입력 속성, SPIR-V 이미지 포맷 매핑, 하위 단계 가속 구조(BLAS)에서 삼각형 지오메트리 생성, 기타 등등의 메모리 레이아웃을 설명할 때에도 사용됩니다.
"포맷 지원"은 포맷당 단일 바이너리 값이 아니라 각 포맷에 대해 지원되는 기능을 설명하는 VkFormatFeatureFlagBits 집합이 있다는 점을 이해하는 것이 중요합니다.
지원되는 포맷은 구현에 따라 다를 수 있지만 최소한의 포맷 기능 세트는 보장됩니다. 애플리케이션은 지원되는 포맷 속성을 쿼리(query)할 수 있습니다.
Note
|
VK_KHR_get_physical_device_properties2 와 VK_KHR_format_feature_flags2는 모두 포맷 기능을 쿼리하기 위한 또 다른 방법을 공개합니다. |
이 예제는 VK_FORMAT_R8_UNORM
포맷이 VkImageCreateInfo::tiling
용으로 VK_IMAGE_TILING_LINEAR
로 작성된 VkImage
로부터 샘플링을 지원하는지 확인하는 코드입니다. 이를 위해 VK_FORMAT_R8_UNORM
의 linearTilingFeatures
플래그를 쿼리하고 VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT
가 구현에서 지원되는지 확인합니다.
// Using core Vulkan 1.0
VkFormatProperties formatProperties;
vkGetPhysicalDeviceFormatProperties(physicalDevice, VK_FORMAT_R8_UNORM, &formatProperties);
if ((formatProperties.linearTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) != 0) {
// 지원함
} else {
// 지원하지 않음
}
// Vulkan 1.1 핵심 또는 VK_KHR_get_physical_device_properties2 사용
VkFormatProperties2 formatProperties2;
formatProperties2.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2;
formatProperties2.pNext = nullptr; // 확장 기능을 위해 사용됨
vkGetPhysicalDeviceFormatProperties2(physicalDevice, VK_FORMAT_R8_UNORM, &formatProperties2);
if ((formatProperties2.formatProperties.linearTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) != 0) {
// 지원함
} else {
// 지원하지 않음
}
// VK_KHR_format_feature_flags2 사용
VkFormatProperties3KHR formatProperties3;
formatProperties3.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3_KHR;
formatProperties3.pNext = nullptr;
VkFormatProperties2 formatProperties2;
formatProperties2.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2;
formatProperties2.pNext = &formatProperties3;
vkGetPhysicalDeviceFormatProperties2(physicalDevice, VK_FORMAT_R8_UNORM, &formatProperties2);
if ((formatProperties3.linearTilingFeatures & VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT_KHR) != 0) {
// 지원함
} else {
// 지원하지 않음
}
포맷에는 다양한 변형이 있으며, 대부분은 포맷 이름으로 그룹화되어 있습니다. 이미지를 다루는 경우 VkImageAspectFlagBits 값은 클리어나 복사와 같은 작업을 위해 데이터의 어느 부분에 액세스하고 있는지를 나타내는 데 사용됩니다.
D
또는 S
성분을 가진 포맷. 이러한 포맷은 불투명하다고 간주되며, 깊이/스텐실 이미지와의 복사에 관해 특별한 규칙이 있습니다.
일부 포맷은 깊이와 스텐실 성분을 모두 가지고 있으며, VK_IMAGE_ASPECT_DEPTH_BIT
와 VK_IMAGE_ASPECT_STENCIL_BIT
로 각각 따로 접근할 수 있습니다.
Note
|
Vulkan 1.2에서 승격된 VK_KHR_separate_depth_stencil_layouts 와 VK_EXT_separate_stencil_usage를 사용하면 깊이와 스텐실 성분 간에 보다 세밀하게 제어할 수 있습니다. |
깊이 포맷에 대한 자세한 내용은 깊이 챕터에서도 확인할 수 있습니다.
압축 이미지 포맷은 한 영역 내에 여러 화소를 상호 의존적으로 인코딩하여 표현하는 포맷입니다.
포맷 | 활성화 방법 |
---|---|
|
|
|
|
|
|
VK_KHR_sampler_ycbcr_conversion 와 VK_EXT_ycbcr_2plane_444_formats은 다중 평면 포맷을 Vulakn에 추가하였습니다. VK_IMAGE_ASPECT_PLANE_0_BIT
, VK_IMAGE_ASPECT_PLANE_1_BIT
, VK_IMAGE_ASPECT_PLANE_2_BIT
로 각 평면에 개별적으로 접근할 수 있습니다.
패킹된 포맷은 주소 정렬을 위한 것입니다. 예를 들어, VK_FORMAT_A8B8G8R8_UNORM_PACK32
와 VK_FORMAT_R8G8B8A8_UNORM
은 매우 비슷해 보이지만 사양서의 정점 입력 추출 섹션의 공식을 사용하면 달라집니다.
attribAddress = bufferBindingAddress + vertexOffset + attribDesc.offset;
VK_FORMAT_R8G8B8A8_UNORM
의 경우 attribAddress
는 성분 크기(8비트)의 배수여야 하며, VK_FORMAT_A8B8G8R8_UNORM_PACK32
에서는 패킹된 크기(32비트)의 배수여야 합니다.
현재 VK_ANDROID_external_memory_android_hardware_buffer
확장 기능으로만 지원되고 있습니다. 이 확장 기능을 사용하면 안드로이드 애플리케이션이 구현에서 정의된 외부 포맷을 가져와서 VkSamplerYcbcrConversion과 함께 사용할 수 있습니다. 이러한 외부 포맷에는 허용되는 많은 제한 사항이 있으며, 이는 사양서에 기재되어 있습니다.