この記事は The Qt Blog の Vulkan Support in Qt 5.10 – Part 1 を翻訳したものです。
執筆: Laszlo Agocs, 2017年6月6日
すでに ご存知の方もいるか と思いますが、Qt 5.10 の新機能の一つとして Vulkan の基本部分の対応が行われています。Qt 5.9 のリリースも無事完了したので、Vulkan 対応の詳細(未対応の部分も含めて)を実際に見てみましょう。この新機能の紹介を楽しく、簡単にするために、短めの記事をいくつか書くことにしました。また紹介するすべての機能はすでに qtbase の dev ブランチにマージ済みですが、Qt 5.10 のリリースまでの間に変更される可能性があるということをここでお伝えしておきます。
OpenGL 以外の描画系の API の対応の開始は Qt 5.8 まで遡ります。この時期には様々な改善のための検討や実際の実装が行われました。主なフォーカスは Qt Quick とその描画エンジンである scenegraph で、プラットフォーム固有の機能を一切使用しないバックエンド(software)と特定のプラットフォーム/ウィンドウイングシステム(Direct3D 12)向けのバックエンドが追加されました。
D3D12 向けの実装の経験 上、こういった API への対応をはじめるのは簡単です。
というわけで、GitHub やその他の場所にあるいくつものプロジェクトですでに証明されているように、おなじような対応で Vulkan にも対応できるというわけです。
実際は、複数のプラットフォームが関わってくるので、もう少しおもしろい感じになります。Vulkan でウィンドウイングシステムを扱うためにはプラットフォーム固有のコードが必要で、クロスプラットフォーム対応のアプリケーションでは ifdefs やそれに似た形での対応をよく見かけます。
私たちは Qt というクロスプラットフォームのフレームワークを開発しているわけで、いつも通り、抽象化のレイヤーを導入することで固有のコードの隠蔽化を行うことになります。
つまり、以下のようなコードではなく、
QWindow *window;#if defined(VK_USE_PLATFORM_WIN32_KHR)
VkWin32SurfaceCreateInfoKHR createInfo;
createInfo.hwnd = (HWND) window->winId();
...
err = vkCreateWin32SurfaceKHR(...);
#elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
VkWaylandSurfaceCreateInfoKHR createInfo;
...
err = vkCreateWaylandSurfaceKHR(...);
#elif defined(VK_USE_PLATFORM_ANDROID_KHR)
VkAndroidSurfaceCreateInfoKHR createInfo;
...
err = vkCreateAndroidSurfaceKHR(...)
#elif defined(VK_USE_PLATFORM_XCB_KHR)
VkXcbSurfaceCreateInfoKHR createInfo;
...
err = vkCreateXcbSurfaceKHR(...)
#elif ...
こんな形にしようというわけです。
QWindow *window;VkSurfaceKHR surface = QVulkanInstance::surfaceForWindow(window);
これにより、ウィンドウシステム固有の処理は Qt のプラットフォーム対応プラグインの中で行われるため、ifdef は必要なくなります。
2つ目の重要な動機は、D3D12 の経験で分かったように、ほとんどのアプリケーションは高レベルで便利なウィンドウ用のクラスで幸せになれるということです。前回は QOpenGLWindow と同じような QD3D12Window クラスを導入しました。クラス継承に関するいくつかの制限が発生はしますが、QWindow ですべてをカバーするようにゼロから設計を見直す(そして上記のコードのように surface をいじくりまわす)必要はありません。
QWindow を直接利用すると、アプリケーションはすべての制御が可能なため、これは当然一番強力な方法ではありますが、後述のとおり、すべての機能が利用可能で安定した Vulkan 対応の QWindow というのは簡単ではありません(スワップチェーンや exposeEvent()、リサイズ、QPlatformSurfaceEvent の対応などなど)。というわけで、QVulkanWindow というクラスを導入することになります。
新しい QVulkan* クラスの詳細に移る前に、Qt 5.10 での Vulkan 対応をもう少し具体的にしましょう。
では、対応しているプラットフォームを見てみましょう。
Qt 5.10 では、以下の状況になります。
Qt の Vulkan 対応は Vulkan(ローダー)ライブラリに直接リンクはせずに、実行時に動的にシンボルの解決をします。このため、Vulkan の比較的新しめの(1.0.13 以降)ヘッダファイルのみが必要条件になります。
ビルド済みのパッケージの Vulkan 対応に関しては、少なくともいくつかのプラットフォームでは依然として解決しなければいけない問題を抱えています。が、Qt 5.10 までには解決していると思います。
以上でパート1はおしまいです。パート2 では実際の QVulkan クラスたちを紹介しますのでお楽しみに!