Vulkan 1.3 が 2022/01 に発表され、各種グラフィックスドライバの対応も完了したので現在は利用可能な状況にあります。さて、今回コアに昇格した拡張機能は23個もあり、 Vulkan 1.3 対応の状況ならば使用可能となりました。これらの機能が何を示すのかの概要と、私の感想と共に紹介していきます。
コア昇格した拡張機能のリスト
- VK_KHR_copy_commands2
- VK_KHR_dynamic_rendering
- VK_KHR_format_feature_flags2
- VK_KHR_maintenance4
- VK_KHR_shader_integer_dot_product
- VK_KHR_shader_non_semantic_info
- VK_KHR_shader_terminate_invocation
- VK_KHR_synchronization2
- VK_KHR_zero_initialize_workgroup_memory
- VK_EXT_4444_formats
- VK_EXT_extended_dynamic_state
- VK_EXT_extended_dynamic_state2
- VK_EXT_image_robustness
- VK_EXT_inline_uniform_block
- VK_EXT_pipeline_creation_cache_control
- VK_EXT_pipeline_creation_feedback
- VK_EXT_private_data
- VK_EXT_shader_demote_to_helper_invocation
- VK_EXT_subgroup_size_control
- VK_EXT_texel_buffer_alignment
- VK_EXT_texture_compression_astc_hdr
- VK_EXT_tooling_info
- VK_EXT_ycbcr_2plane_444_formats
- コアに昇格した機能群
- VK_KHR_copy_commands2
- VK_KHR_dynamic_rendering
- VK_KHR_format_feature_flags2
- VK_KHR_maintenance4
- VK_KHR_shader_integer_dot_product
- VK_KHR_shader_non_semantic_info
- VK_KHR_shader_terminate_invocation
- VK_KHR_synchronization2
- VK_KHR_zero_initialize_workgroup_memory
- VK_EXT_4444_formats
- VK_EXT_extended_dynamic_state
- VK_EXT_extended_dynamic_state2
- VK_EXT_image_robustness
- VK_EXT_inline_uniform_block
- VK_EXT_pipeline_creation_cache_control
- VK_EXT_pipeline_creation_feedback
- VK_EXT_private_data
- VK_EXT_shader_demote_to_helper_invocation
- VK_EXT_subgroup_size_control
- VK_EXT_texel_buffer_alignment
- VK_EXT_texture_compression_astc_hdr
- VK_EXT_tooling_info
- VK_EXT_ycbcr_2plane_444_formats
- まとめ
コアに昇格した機能群
それではこれらの拡張機能を順番に確認していきましょう。
VK_KHR_copy_commands2
Vulkan のバッファ・イメージをコピーするコマンドに対する拡張です。新しい関数では、拡張機能固有情報を渡すために使用できる構造を使ってコピーパラメータが指定できるようになります。
ドキュメントにはこのような表現で書いてあるのでとても分かりづらいですが、要するにコピーパラメータ構造体に Vulkan ではおなじみの sType, pNext というメンバを持たせて、今後の機能拡張ができるようになった、ということです。
VK_KHR_dynamic_rendering
この拡張機能は、レンダーパス(VkRenderPass) やフレームバッファ(VkFramebuffer)を作成せずに、シングルのレンダーパスを作成できるようにするものです。
Vulkan の描画準備で大変面倒なレンダーパスやフレームバッファの支度が軽減されるので、簡単な描画プログラムを作る際にはかなり楽になりそうです。
VK_KHR_format_feature_flags2
この拡張機能は VkFormatFeatureFlagBits2型で定義されるフラグが利用可能なことを示します。これまで VkFormatFeatureFlagBits 型としてフラグは定義されていたのですが、現時点までに 29ビット分が既に使用される状態となっています。この拡張機能の導入でフラグは 64bit に拡張されます。
VK_KHR_maintenance4
従来にもあった maintenance3 と同じように、ちょっとした機能の追加を示すものです。VkPipelineLayout オブジェクトをすぐに破棄したり、SPIR-V 1.2実行モードサポート、VkImageオブジェクトを作らずにVkImage用メモリの要件を調査/取得できるようになったり、とあります。
とても便利になる、といったものではありませんが、ほんの少し実装や管理が楽になるという場面はありそうです。
VK_KHR_shader_integer_dot_product
SPIR-V 命令で整数内積命令のサポートを追加します。主にニューラルネットワークの推論処理や、学習といった場面で活用するものですが、通常のコンピュート処理で使用することもできます。
VK_KHR_shader_non_semantic_info
シェーダーモジュールにおいて、 SPV_KHR_non_semantic_info 拡張が使えることを示します。
このSPV_KHR_non_semantic_info 拡張とは、シェーダーモジュールから安全に機能を削除できる拡張命令セットを提供する機能です。普段は実行されないが、分析ツールやデバッグなどで条件を満たしたときに関数などを実行したい、ということができるようになります。
VK_KHR_shader_terminate_invocation
シェーダーモジュールにおいて、SPV_KHR_terminate_invocation 拡張が使えることを示します。命令としては OpTerminateInvocation で、実行されると即座にシェーダー呼び出しを終了します。
この命令はフラグメントシェーダーで有効になります。
VK_KHR_synchronization2
長らく Vulkan には同期処理の難易度が高いままでしたが、本拡張機能によりメモリバリアという構造によって扱いやすくなります。また、タイムラインセマフォの機能も追加されます。
これまではパイプラインバリアやメモリアクセスのフラグといったものを適切に設定して、リソース同期を行い、さらに同期プリミティブを用いてキューの制御もおこなってきました。これが本拡張機能により、実装が大変楽になります。すこし DirectX12 の API の使い勝手に近づいたともいえると感じています。
VK_KHR_zero_initialize_workgroup_memory
シェーダーのワークグループメモリ変数でゼロ(null)初期化が使えるようになります。ゼロ初期化されたメモリを使うことで、信頼できないコンテンツを実行する可能性のあるアプリケーションで使用されます。
未初期化状態で使用すると、悪意あるプログラムから以前の書き込みデータを読み取られてしまうよ、というのを防止ということですね。
VK_EXT_4444_formats
各 RGB 要素が 4bit で示される画像フォーマットを利用可能になります。
他のグラフィックAPIでは使用可能なフォーマットなので、それに合わせるために使えるようになりました。Vulkanを使って、他のグラフィックAPIの再現が出来るようになります(WineとかOpenGL, DirectXの実装など)
VK_EXT_extended_dynamic_state
パイプラインステートオブジェクトは事前に様々なパラメータを固定化してオブジェクトを作りますが、一部のパラメータを動的に変更可能にします。バーテックスバッファ、カリングモード、DepthBoundsTestフラグ、デプステスト有効フラグ、FrontFace の設定、プリミティブトポロジー、シザー、ステンシルの設定、ビューポートの設定といったものを動的変更可能なパラメータにします。
動的に設定できるようになった項目を見ると、随分と DirectX9 やレガシーなOpenGLを再現するのに便利になったと感じました。動的になることでパフォーマンスのペナルティは少し発生すると思いますが、アプリケーションはかなり作りやすくなる印象があります。
VK_EXT_extended_dynamic_state2
パイプラインステートオブジェクトは事前に様々なパラメータを固定化してオブジェクトを作りますが、一部のパラメータを動的に変更可能にします。デプスバイアス、LogicOp、パッチコントロールポイントの設定、プリミティブリスタート有効フラグ、ラスタライザーの破棄フラグ、が動的変更なパラメータになります。
VK_EXT_extended_dynamic_state の内容をさらに拡張した感じです。先の拡張が DirectX9 世代とすると、こちらはその先の DirectX11 世代のものに近い印象です。
VK_EXT_image_robustness
画像の範囲外読み取りに関する処理で、厳しい要件を追加します。未定義の値を返さずに、範囲外の読み取りをRGBA=(0,0,0,1)を返すようなものになります(RGBA=(1,1,1,1)という設定もある)。
VK_EXT_inline_uniform_block
ディスクリプタセットのレベルでシェーダーにデータを渡すための拡張機能です。ユニフォームブロックをディスクリプタセットで直接バックアップする機能を提供します。プッシュ定数と比較すると、ユニフォームデータを再利用することができる可能性があります。
VK_EXT_pipeline_creation_cache_control
この拡張機能は、パイプライン作成コストの予測可能性を向上することが目的で、VkPipelineCreateInfoやVkPipelineCacheCreateInfo にフラグを追加します。ドライバー内に実行コスト高となる危険な情報を、実行前にアプリケーションに情報を提供することです。
そもそもパイプラインの作成はコストの掛かる操作です。Vulkanは開発者から処理を隠蔽するようなことを極力避けているので、パイプライン作成のコストをどのように隠蔽するかはアプリケーション開発者に委ねられています。本機能によって、パイプラインの作成コストを作成前に知ることが可能になります。
VK_EXT_pipeline_creation_feedback
この拡張機能は、パイプラインの作成に関するフィードバックをアプリケーションに提供する仕組みを提供します。パイプラインの作成に掛かった時間を受け取るパラメータが利用可能になります。
目的は効果的なパイプラインキャッシュが作れるようにすることです。
VK_EXT_private_data
この拡張機能は Vulkanのオブジェクトに任意のデータをアタッチできるようにするものです。
DirectXのSetPrivateData に近いものかなと思います。ライブラリを開発していると、void* のメンバをユーザーが自由に使えるものとして提供することがありますが、それに似た使い方が Vulkan でも出来るようになると考えています。
VK_EXT_shader_demote_to_helper_invocation
シェーダーモジュールにおいて、 SPV_EXT_demote_to_helper_invocation 拡張が使えることを示します。フラグメントシェーダーで、 OpDemoteToHelperInvocationEXT 命令が実行されると、シェーダー呼び出しを demote し、結果をフレームバッファに出力しません。HLSL の discard 命令に近いものとなります。
VK_EXT_subgroup_size_control
この拡張機能は、サブグループサイズの変更を許可するものです。これまでは決められたサイズで動作する都合で、大きなワークロードは分割したり、余る分は非アクティブとして処理したり等で対処していました。この拡張機能により、パイプラインごとにサイズを変更するといったことも可能になります。
VK_EXT_texel_buffer_alignment
この拡張機能では、 uniform/storage テクセルバッファに対するアライメント要求が追加となります。
VK_EXT_texture_compression_astc_hdr
この拡張機能は、ATSCテクスチャ圧縮のHDRサポートを示します。これまでの ASTC テクスチャでは LDR のサポートでした。
VK_EXT_tooling_info
プログラムでツールを識別するための情報が提供されます。アプリケーション開発者が利用している開発ツールへのクエリを提供するものです。
VK_EXT_ycbcr_2plane_444_formats
この拡張機能は、動画のエンコードとデコードによく使用されるフォーマット(YCbCr)を提供します。これまでは拡張機能としても本フォーマットはサポートされていませんでした。
Vulkan でも動画に関するフォーマットや機能が追加されてきていますが、フォーマットに対する拡張です。Vulkan Video Extension は 2021/04頃から提案が始まっています。
まとめ
多くの拡張機能がコアに昇格して、便利になったものもあれば複雑になってきたものなどあるだろうと感じます。しかし、扱いやすかった頃の API に少し近づいてきている印象の方が私には強いかなと感じました。
私の理解不足もあると思いますので、間違い、不適切なものがあれば、そっと教えて頂けますと幸いです。
コメント