Qtブログ(日本語)

Qt RHI:QtQuickのVulkan/Metal/Direct3D対応 - Part 2

作成者: Qt Group 日本オフィス|Dec 5, 2019 2:30:07 AM
この記事はQt Quick on Vulkan, Metal, and Direct3D - Part 2の抄訳です。

最初の投稿で中断したところからお話ししましょう。 前回は、Linux上のQt Quick アプリケーションを OpenGLとVulkan上で実行する例を見てきました。 また、RenderDocVulkanフレームキャプチャを確認しました。これは、Qt開発作業中の重要なツールであるだけでなく、Qt Quickがフレームをレンダリングする方法をより深く掘り下げて理解したい人(または、アプリケーションのレンダリングにおけるトラブルシューティング)にも役立ちます。 この投稿では、Qt 5.14macOSおよびWindows提供するものについて焦点を当てています。

Metal on macOS

特筆することではないかもしれませんが、macOS 10.13または10.14QSG_RHI = 1(およびQSG_INFO = 1)を指定してqt5-cinematic-experienceデモを実行すると、次のようになります。

qt.scenegraph.general: Using QRhi with backend Metal
  graphics API debug/validation layers: 0
  QRhi profiling and debug markers: 0
qt.scenegraph.general: threaded render loop
qt.scenegraph.general: Using sg animation driver
qt.scenegraph.general: Animation Driver: using vsync: 16.67 ms
qt.rhi.general: Metal device: Intel(R) HD Graphics 615
qt.scenegraph.general: MSAA sample count for the swapchain is 1. Alpha channel requested = no.
qt.scenegraph.general: rhi texture atlas dimensions: 4096x2048
qt.rhi.general: got CAMetalLayer, size 2560x1440


そのプラットフォームで一番良くサポートされているグラフィックスAPIをデフォルトとする、というQt 6の目的に沿って(必要に応じてアプリケーションが独自の設定をすることも可能にしつつ)、macOSのQt QuickでQRhiベースのレンダリングパスを有効にし、デフォルトでMetalを使用します 。

QtGuiモジュール、QPA、およびいくつかのプラットフォームプラグインでサポートされるようになったVulkanインスタンスおよびサーフェス上に Vulkanベースのレンダリングパスが構築されたのと同様に、QRhiのMetalバックエンドはQt 5.12で導入されたcocoaプラットフォームプラグインのMetalサポートに依存します。 QSurface :: MetalSurfaceを使用したQWindowは、内部でCAMetalLayerを使用するNSViewを取得します。それがまさにQRhiのMetalバックエンドに必要なものなのです。 (これらがすべて機能しているのは、QRhiが有効な場合 QQuickWindowが常に適切なQSurface :: SurfaceTypeを取得するためです。)

ここで重要な機能の1つは、Qt Quickのスレッド化されたレンダーループで実行できることです。これが素晴らしいのはなぜかというと、 macOS 10.14では特定のNSOpenGLContextおよび関連APIのスレッドの問題により、QtはmacOS上のOpenGLでスレッド化されたループを無効にし、代わりに”basic”ループをデフォルト設定としています。これにより、Qt Quickアニメーションの滑らかさは多少落ちてしまいます。 Metalの場合(現在分かっている範囲では)スレッド化しても問題はありません。そのため、スレッド化されたレンダーループを再びデフォルトに設定できます。 (レンダリングループのデフォルトの選択は、QSG_RENDER_LOOP環境変数を設定することでオーバーライドできます。この変数は、QSG_RHIとの組み合わせでもサポートされます)

OpenGL、Vulkan、またはDirect3D上での実行時におけるQtアプリケーションのフレームレンダリングをデバッグするためのツールとして RenderDocを紹介しました。 Metalの場合、XCodeとその組み込みGPUフレームキャプチャを使用できます。



デバッグの準備ができているXCodeでQtプロジェクトをすばやく開く便利な方法の1つは、ターミナルからmake xcodeproj && open * .xcodeproj(またはqmakeがまだ実行されていない場合はqmake -spec macx-xcode)を実行することです。 Cmd-Rを押すと、デバッガーが起動します。 私たちもQtの開発中によく使っています。 Qt QuickがMetal経由でレンダリングするように設定されている場合でも、Metal GPUキャプチャが利用できない場合は、製品->スキーム->スキームの編集...をチェックし、GPUフレームキャプチャをMetalに変更します。



XCodeでアプリケーションのデバッグビルドを実行すると、Metal検証が有効になります。つまり、Metal APIが誤った方法で使用されると、XCodeは警告を出してプログラムの実行を中断します。 他のプラットフォームとは異なり、XCodeを介してデバッグしない場合、Metal API検証は有効にできません。 (VulkanやD3Dとは異なり、QSG_RHI_DEBUG_LAYERを設定しても効果はありません)

Metal on iOS


iOS または tvOSについて

この記事の編集時点では、プラットフォームプラグインの、Metal関連の部分が不足しています。これは、これらのプラットフォームでQRhiのMetalバックエンドがまだテストされていないことも意味します。 そのため、Qt 5.14新機能ページのQt QuickセクションではmacOSのみに言及しています。 サポートは近い将来、おそらく5.15に追加される予定です。

Vulkan on macOS

MoltenVKを経由するValkanについて

パート1で述べたように、Vulkanを介してレンダリングを要求し、MoltenVKに依存して実行時に、API呼び出しとSPIR-VシェーダーをMetalとMetal Shading Languageに変換することも選択可能です。 これには、Vulkan対応のQtビルドが必要ですが、Appleプラットフォームではそのままでは使用できません。 詳細については、この投稿を参照してください。重要なのは、-Iをconfigureに渡して、QT_VULKAN_LIBを設定することにより、確実に実行時にライブラリが見つかるようにすることです。

このアプローチは、ベストエフォートベースでのみサポートされます。 Appleプラットフォームでは、Metal経由でレンダリングする方法が最も確実にサポートされるようになります。
QSG_RHI_BACKEND = vulkan(適切に構成されたQt 5.14ビルドを使用)でデモアプリケーションを実行すると、次のことがわかります。


qt.scenegraph.general: Using QRhi with backend Vulkan
  graphics API debug/validation layers: 0
  QRhi profiling and debug markers: 0
qt.scenegraph.general: threaded render loop
qt.scenegraph.general: Using sg animation driver
qt.scenegraph.general: Animation Driver: using vsync: 16.67 ms
qt.rhi.general: Physical device 0: 'Intel(R) UHD Graphics 630' 0.2.1835 (api 1.0.92 vendor 0x8086 device 0x3E9B type 1)
qt.rhi.general: using this physical device
qt.rhi.general: queue family 0: flags=0x7 count=1
qt.rhi.general: 17 device extensions available
qt.scenegraph.general: MSAA sample count for the swapchain is 1. Alpha channel requested = no.
qt.scenegraph.general: rhi texture atlas dimensions: 2048x1024
qt.rhi.general: Creating new swapchain of 2 buffers, size 1280x720, presentation mode 2


スレッド化されたレンダーループを使用すると、macOS 10.13でこれを実行する際に問題が発生し、ロックアップやクラッシュが発生することに注意してください。(MoltenVKを含む)Vulkan SDKを新しいバージョン(1.0.121)にアップグレードすると、新たな問題が発生してアプリケーションを起動できなくなりました。 (https://github.com/KhronosGroup/MoltenVK/issues/695に似たものを取得し続けていました)これについては後で調査します。macOS 10.14および二番目に新しいVulkan SDK / MoltenVKをインストールしたMac Miniでは、スクリーンショットに見られるように、結果はかなり良好です。


Windows

Windowsは、最も多くの選択肢があるプラットフォームです。 4つのメインQRhiバックエンド(Vulkan、Metal、D3D11、OpenGL)のうち、Direct3D 11、Vulkan、OpenGLの3つをWindowsで使用できます。
なぜ3つだけなのか、4つ目としてDirect3D12が入らないのかと、疑問に思われることとおもいます。
現時点ではD3D12バックエンドはありません。予定はされていますが、時期が決まっていないため、後から変更になる可能性があります。
ここでは、Qt 5.8に追加されたQt Quick用の試験的なD3D12バックエンドが、アーキテクチャ上非推奨となっていることに注意してください。(複数のグラフィックスAPIの問題にまったく新しい方法で取り組むため)。また、これは Qt 6で削除される場合があります。
Windowsにおいて、QSG_RHI = 1を設定するときのデフォルトはDirect3D 11です。通常どおり、VulkanまたはOpenGLが必要な場合は、QSG_RHI_BACKENDでオーバーライドします。


qt.scenegraph.general: Using QRhi with backend D3D11
  graphics API debug/validation layers: 0
  QRhi profiling and debug markers: 0
qt.scenegraph.general: threaded render loop
qt.scenegraph.general: Using sg animation driver
qt.scenegraph.general: Animation Driver: using vsync: 16.67 ms
qt.rhi.general: DXGI 1.2 = true, FLIP_DISCARD swapchain supported = true
qt.rhi.general: Adapter 0: 'NVIDIA GeForce RTX 2060' (flags 0x0)
qt.rhi.general: using this adapter
qt.rhi.general: Adapter 1: 'Microsoft Basic Render Driver' (flags 0x2)
qt.scenegraph.general: MSAA sample count for the swapchain is 1
qt.scenegraph.general: rhi texture atlas dimensions: 2048x1024


Direct3D 11.0ではなく11.1が必要であることに注目していただきたいのですが、これは主にVSSetConstantBuffers1(および関連するPSおよびCSバリアント)が必要であることが理由です。アップデートされていないプレーンなWindows 7上で実行したい場合を除き、これは問題ではありません。 Windows 7と言えばですが、Qt 5.14の時点ではWindows 7においてD3D11ベースのレンダリングが現在正しく機能しないため、5.14の新機能ページではWindows 10のみに言及しています。これは後から修正する必要があります(ただし、Windows 7がQt 6のサポート対象プラットフォームを維持する場合のみ)。


Direct3Dデバッグレイヤーを有効にするには、環境変数QSG_RHI_DEBUG_LAYERを1に設定します。これは、検証レイヤーが(インストールされているVulkan SDKから)使用可能な限りVulkanでも機能します。 Qtは、メッセージを(qDebugを介して出力されたかのように)簡便にデバッグ出力に送信します。


VulkanとOpenGLはWindowsで期待どおりに動作するはずなので、ここでこれ以上の説明はしません。


VulkanおよびMetalと同様に、QRhiのOpenGLバックエンドは、既存のOpenGLおよびプラットフォーム関連の機能(QOpenGLContext、QOpenGLFunctions、およびWindowsプラットフォームプラグインの基礎(WGL、EGL)など)の一部に基づいて構築されます。したがって、OpenGLで直接実行されているQt Quickアプリケーションに適用されるすべてが、ここにも適用されます。 (desktop /ANGLE/ software、QT_OPENGLなどの環境変数

ANGLEといえば、Qt 6で直接の依存関係から削除できることが期待されています。これは、特別なケースのサポートが失われないことを確認すべくさらに調査が必要ですが、今の計画ではDirect3D 11、OpenGL、およびVulkanをサポートする QRhiベースのレンダリングパスがあれば、Windows上のQt 6アプリケーションには十分でしょう。

今回はここまでです。パート3では、このQRhiの内容とシェーダーの処理方法について、より深いところまで見ていきましょう。