何に注意するか
ash
を用いる, 以前から用いているコードベースで新しく Vulkan Video を叩く場合,
依存する ash
のバージョンが古いままでないか確認すること.
2024-04 に crates.io にリリースされた 0.38.0+1.3.281
以降を用いること.
- ash = "0.37.0"
+ ash = "0.38.0"
これはかなりの breaking change になるので注意.
しないとどうなるか
例えば vkGetPhysicalDeviceVideoCapabilitiesKHR
の呼び出しが,
バッファオーバーランからのスタック/ヒープ破壊に繋がり,
原因の調査が難航する可能性がある.
crates.io のリリースの更新(2024-04)よりも前は
crates.io における ash
のリリースはかなり長い間更新されておらず,
2024-03 以前では, GitHub にある新しめのブランチ/コミットを指定して用いる必要があった:
ash = { git = "https://github.com/ash-rs/ash/", rev = "f2979c8" }
直接の原因
ash
の 0.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
までの ash
3 では:
#[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 のベータドライバによる書込みが, バッファオーバーランに繋がっていた.
参考資料