LoginSignup
2
0

Vulkan Video を Rust で叩く際は ash のバージョンに注意

Last updated at Posted at 2024-04-14

何に注意するか

ash を用いる, 以前から用いているコードベースで新しく Vulkan Video を叩く場合,
依存する ash のバージョンが古いままでないか確認すること.

2024-04 に crates.io にリリースされた 0.38.0+1.3.281 以降を用いること.

Cargo.toml
- ash = "0.37.0"
+ ash = "0.38.0"

これはかなりの breaking change になるので注意.

しないとどうなるか

例えば vkGetPhysicalDeviceVideoCapabilitiesKHR の呼び出しが,
バッファオーバーランからのスタック/ヒープ破壊に繋がり,
原因の調査が難航する可能性がある.

crates.io のリリースの更新(2024-04)よりも前は

crates.io における ash のリリースはかなり長い間更新されておらず,
2024-03 以前では, GitHub にある新しめのブランチ/コミットを指定して用いる必要があった:

Cargo.toml
ash = { git = "https://github.com/ash-rs/ash/", rev = "f2979c8" }

直接の原因

ash0.37.3+1.3.251 では, Rust バインディング生成に用いられた Vulkan Video の仕様がかなり古いこと.

詳細

2024-03 時点まで, crates.io でリリースされていた ash 0.37.3+1.3.251 では,
Rust コードの生成に用いられた Vulkan Video の仕様が古く,
最新の NVIDIA ベータドライバでの実装が期待する最新の仕様のものと異なるメモリレイアウトが用いられてしまい,
スタック/ヒープ破壊に繋がる場合があった.

これは Vulkan Video の H.264 や H.265 などエンコード関連の仕様がまだ provisional1であり,
依然 Khronos Group により変更がなされていることに起因していた.

これは例えば vkGetPhysicalDeviceVideoCapabilitiesKHR の出力先となる, VkVideoEncodeCapabilitiesKHR で顕在化していて, ドライバによる書込みがオーバーランしスタック/ヒープ破壊に繋がっていた.

現時点で最新の仕様2では:

// Provided by VK_KHR_video_encode_queue
typedef struct VkVideoEncodeCapabilitiesKHR {
    VkStructureType                         sType;
    void*                                   pNext;
    VkVideoEncodeCapabilityFlagsKHR         flags;
    VkVideoEncodeRateControlModeFlagsKHR    rateControlModes;
    uint32_t                                maxRateControlLayers;
+   uint64_t                                maxBitrate;
    uint32_t                                maxQualityLevels;
    VkExtent2D                              encodeInputPictureGranularity;
    VkVideoEncodeFeedbackFlagsKHR           supportedEncodeFeedbackFlags;
} VkVideoEncodeCapabilitiesKHR;

一方これは 0.37.3+1.3.251 までの ash3 では:

#[repr(C)]
pub struct VideoEncodeCapabilitiesKHR {
    pub s_type: StructureType,
    pub p_next: *mut c_void,
    pub flags: VideoEncodeCapabilityFlagsKHR,
    pub rate_control_modes: VideoEncodeRateControlModeFlagsKHR,
    pub max_rate_control_layers: u32,
-   // 🤯
    pub max_quality_levels: u32,
    pub input_image_data_fill_alignment: Extent2D,
    pub supported_encode_feedback_flags: VideoEncodeFeedbackFlagsKHR,
}

最新の仕様では uint64_t maxBitrate があるが,
Rust コードにはそれがなく, 構造体の大きさが異なることがわかる.

この ash::vk::VideoEncodeCapabilitiesKHR のポインタを愚直に vkGetPhysicalDeviceVideoCapabilitiesKHR に出力先として渡すことで,
NVIDIA のベータドライバによる書込みが, バッファオーバーランに繋がっていた.

参考資料

  1. Khronos Finalizes Vulkan Video Extensions for Accelerated H.264 and H.265 Encode - Khronos Blog - The Khronos Group Inc

  2. VkVideoEncodeCapabilitiesKHR(3)

  3. VideoEncodeCapabilitiesKHR in ash::vk - Rust

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0