Vulkan のフォーマットは、メモリのレイアウトを記述するために使用されます。この章では、Vulkan のフォーマットのバリエーションに関する概要と、それらを使用する方法に関する情報を提供します。詳細は、Vulkan Spec フォーマット章 と Khronos Data Format Specification の両方に明記されています。
VkFormat
の最も一般的な使用例は、VkImage
を作成する場合です。VkFormat
はうまく定義されているため、VkBufferView
、頂点入力属性、SPIR-V イメージフォーマットのマッピング、ボトムレベル高速化構造での三角形ジオメトリ作成などのためのメモリレイアウトを記述する場合にも使用されます。
「フォーマットの対応」は、フォーマットごとに単一のバイナリ値ではなく、各フォーマットが VkFormatFeatureFlagBits のセットを持ち、それぞれがそのフォーマットでサポートされている機能を記述していることが重要です。
サポートされるフォーマットは実装によって異なる可能性がありますが、フォーマット機能の最小セットは保証されています。アプリケーションは、サポートされているフォーマットのプロパティをクエリすることができます。
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
が実装によりサポートされているかどうかを確認します。
// 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.0コアまたは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 値は、クリアやコピーなどの操作のために、データのどの部分にアクセスするかを表すために使用されます。
いくつかのフォーマットは、深度成分とステンシル成分の両方を持ち、 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 を使用すると、深度とステンシル成分間でより細かく制御できるようになります。 |
深度フォーマットについての詳しい情報は、深度の章にあります。
圧縮イメージは、1つの領域内に複数の画素を相互依存的にエンコードして表現する形式です。
フォーマット | 有効化方法 |
---|---|
|
|
|
|
|
|
VK_KHR_sampler_ycbcr_conversion と VK_EXT_ycbcr_2plane_444_formats は multi-planar フォーマット を Vulkan に追加しました。
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
は非常に似ていますが、仕様の Vertex Input Extraction セクションの数式を使用すると、以下のようになります。
attribAddress = bufferBindingAddress + vertexOffset + attribDesc.offset;
VK_FORMAT_R8G8B8A8_UNORM
では attribAddress
はコンポーネントサイズ (8 bits) の倍数でなければならず、VK_FORMAT_A8B8G8R8_UNORM_PACK32
ではパックサイズ (32 bits) の倍数である必要があります。
現在、VK_ANDROID_external_memory_android_hardware_buffer
拡張機能でのみサポートされています。この拡張機能を使うと、Android アプリケーションが実装で定義された外部フォーマットをインポートし、 VkSamplerYcbcrConversion で使用できるようになります。これらの外部フォーマットで許可されるものには多くの制限があり、仕様に記載されています。