macOS での Vulkan for Qt
October 30, 2018 by 鈴木 佑 | Comments
この記事は The Qt Blog の Vulkan for Qt on macOS を翻訳したものaです。
執筆: Morten Johan Sørvig, 2018年05月30日
qtbase の dev ブランチ(Qt 5.12 になる予定)に Vulkan サポートが追加されました。こういった対応は、控えめに言っても多大な工数がかかるものですが、MoltenVK プロジェクトとこれまで Qt に対してなされた様々な作業により、スムーズに対応を行うことができました。ということで詳細を見てみましょう。
背景
昨年、Laszlo が Windows と Linux、Android の Qt の Vulkan 対応 という記事を書きました。これにより、QSurface::VulkanSurface に加え、クロスプラットフォームの QVulkanInstance や QVulkanWindow といったクラスが追加されました。
その後、いまから数か月前に、MoltenVK という Vulkan と Metal の変換ライブラリがオープンソース化されました。これを Qt として対応する というバグレポートが作成され、これには QWindow が内部で使用している NSView が CAMetalLayer を使うような変更が必要でした。
この作業を行った際に、すでに Metal を Qt で使う方法を模索し始めていて、CAMetalLayer をレイヤーとして利用できるように していました。さらに Metal 系のコードを Qt に埋め込む別の方法も研究していましたが、それはまた別の記事で紹介する事にしましょう。
// Snippet from Qt internal layer management code
@implementation QT_MANGLE_NAMESPACE(QNSView) (DrawingAPI)
- (NSViewLayerContentsRedrawPolicy)layerContentsRedrawPolicy
{
// We need to set this this excplicitly since the super implementation
// returns LayerContentsRedrawNever for custom layers like CAMetalLayer.
return NSViewLayerContentsRedrawDuringViewResize;
}- (void)updateMetalLayerDrawableSize:(CAMetalLayer *)layer
{
CGSize drawableSize = layer.bounds.size;
drawableSize.width *= layer.contentsScale;
drawableSize.height *= layer.contentsScale;
layer.drawableSize = drawableSize;
}- (void)layoutSublayersOfLayer:(CALayer *)layer
{
if ([layer isKindOfClass:CAMetalLayer.class])
[self updateMetalLayerDrawableSize:static_cast(layer)];
}- (void)viewDidChangeBackingProperties
{
CALayer *layer = self.layer;
if (!layer)
return;layer.contentsScale = self.window.backingScaleFactor;
// Metal layers must be manually updated on e.g. screen change
if ([layer isKindOfClass:CAMetalLayer.class]) {
[self updateMetalLayerDrawableSize:static_cast(layer)];
[self setNeedsDisplay:YES];
}
}@end
これらすべての準備ができ、残すは 貼り合わせるための platform plugin で、これにより(macOS で)QSurface::VulkanSurface が利用可能になります。ネイティブサーフェスとして Vulkan サーフェスを提供するなど Vulkan 関連のプラットフォーム固有の機能を抽象化した QPlatformVulkanInstance の実装も行っています。
どのようにつかえばいいの?
最小の方法
QWindow のサブクラスのコンストラクタで setSurfaceType(QSurface::VulkanSurface) を呼び出します。これにより QWindow::winId() で NSView にアクセスができるようになり、それを MoltenVK に渡すことができます。NSView はこのようにして MoltenVK の描画先として設定できます。詳細は MotelVK issue #78 もご覧ください。ちなみに私自身はこれを試したことがありません :)
Qt の API を使う方法
MoltenVK(をビルドした後)include 等の設定をすることで Vulkan サポートを有効にして Qt の configure とビルドをしてください。
./confgure -I /path/to/MoltenVK/Package/Release/MoltenVK/include
"Vulkan: yes" が configure の結果表示されるはずで、これにより QVulkan* クラスが利用可能になります。
それから、アプリやサンプルの起動前に、Qt に libMoltenVK.dylib の在り処を教えてあげてください。
export QT_VULKAN_LIB=
/path/to/MoltenVK/Package/Release/MoltenVK/macOS/libMoltenVK
Qt 内部で実行時に Vulkan ライブラリをロードしシンボルの解決をする箇所がこれを利用します。macOS では、MoltenVK.framework に対してリンクをしたいと思うかもしれませんが、その改善は今は置いておきます。
終わりに
「実験中」という警告をここで再度述べることで、この記事を締めたいと思います。特に、MoltenVK の内部動作の詳細について十分に把握できていないため、互換性まわりが今後問題になるかもしれません。もしなにかありましたら、QTBUG までお知らせください。
Blog Topics:
Comments
Subscribe to our newsletter
Subscribe Newsletter
Try Qt 6.5 Now!
Download the latest release here: www.qt.io/download.
Qt 6.5 is the latest Long-Term-Support release with all you need for C++ cross-platform app development.
Explore Qt World
Check our Qt demos and case studies in the virtual Qt World
We're Hiring
Check out all our open positions here and follow us on Instagram to see what it's like to be #QtPeople.
Näytä tämä julkaisu Instagramissa.Henkilön Qt (@theqtcompany) jakama julkaisu