C++界面開發(fā)程序Qt使用教程:在Vulkan,Metal和Direct3D上運(yùn)行Qt Quick-第2部分
Qt是目前最先進(jìn)、最完整的跨平臺(tái)C++開發(fā)工具。它不僅完全實(shí)現(xiàn)了一次編寫,所有平臺(tái)無差別運(yùn)行,更提供了幾乎所有開發(fā)過程中需要用到的工具。如今,Qt已被運(yùn)用于超過70個(gè)行業(yè)、數(shù)千家企業(yè),支持?jǐn)?shù)百萬設(shè)備及應(yīng)用。
macOS上的Metal
在macOS 10.13或10.14設(shè)置QSG_RHI = 1(以及QSG_INFO = 1)并運(yùn)行示例程序,可以看到如下的結(jié)果:
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
Qt 6的目標(biāo),是默認(rèn)使用目標(biāo)平臺(tái)上主流的、支持最好的圖形API(同時(shí)也允許應(yīng)用程序選擇其他圖形API),在macOS上啟用QRhi的渲染方式后,系統(tǒng)會(huì)默認(rèn)使用Metal來渲染Qt Quick。
類似于在QtGui、QPA,和其他一些平臺(tái)插件中添加Vulkan實(shí)例和Surface構(gòu)建Vulkan渲染后臺(tái)的方式,QRhi的Metal后臺(tái)依賴于Qt 5.12前后引入的cocoa平臺(tái)插件中的Metal的支持。帶QSurface::MetalSurface標(biāo)志的QWindow將獲得一個(gè)NSView,NSView背后是一個(gè)CAMertalLayer。這就是QRhi的Metal后端架構(gòu)。(要使能QRhi的渲染路徑,并且QQuickWindow獲得正確的QSurface::SurfaceType標(biāo)記值,才能正常運(yùn)行)
有一個(gè)非常重要的特性,即能夠使用獨(dú)立的渲染線程運(yùn)行Qt Quick。之前由于macOS 10.14中的NSOpenGLContext以及相關(guān)API中存在一個(gè)的多線程問題,Qt在macOS上禁用了獨(dú)立的OpenGL渲染線程,而把默認(rèn)值改為“basic”。這導(dǎo)致Qt Quick動(dòng)畫的平滑度有所降低。對于Metal,我們沒有(根據(jù)我們目前的認(rèn)知)發(fā)現(xiàn)任何多線程的問題,因此我們又可以開啟獨(dú)立的渲染線程了。(通過設(shè)置QSG_RENDER_LOOP環(huán)境變量,可以改寫渲染線程的設(shè)置;這個(gè)變量可與QSG_RHI配合使用)
我們之前提到了RenderDoc,它可以調(diào)試Qt應(yīng)用程序的幀渲染,支持OpenGL、Vulkan以及Direct3D的運(yùn)行態(tài)。對于Metal,可以使用XCode及其內(nèi)置的GPU幀快照器。
有一個(gè)實(shí)用方法可以用XCode快速打開待調(diào)試的Qt項(xiàng)目,在命令行執(zhí)行make xcodeproj && open *.xcodeproj(如果還沒有執(zhí)行qmake則可以執(zhí)行qmake -spec macx-xcode)。按下Cmd-R,然后會(huì)立即啟動(dòng)調(diào)試器。在Qt開發(fā)期間我們會(huì)經(jīng)常這樣使用。為了防止Metal GPU獲取失敗,即使Qt Quick已經(jīng)設(shè)置為Metal渲染,還是要檢查 “Product ->Scheme->Edit scheme…”,并將GPU幀獲取獲改為Metal。
在XCode中調(diào)試構(gòu)建應(yīng)用程序時(shí)會(huì)啟用Metal驗(yàn)證,這意味著當(dāng)Metal API使用不當(dāng)時(shí),XCode將(理想情況下)返回提示性警告并中斷程序執(zhí)行。與其他平臺(tái)不同的是,如果不通過XCode進(jìn)行調(diào)試,則無法啟用Metal API驗(yàn)證。(與Vulkan和D3D不同,設(shè)置環(huán)境變量QSG_RHI_DEBUG_LAYER無效)
iOS上的Metal
iOS或者tvOS上是什么情況?
在編寫本文時(shí),(iOS和tvOS的)平臺(tái)插件中缺少與Metal相關(guān)的管道,這也意味著QRhi的Metal后端還沒有在這些平臺(tái)上進(jìn)行測試。這就是為什么Qt 5.14新特性頁面關(guān)于Qt Quick的部分只提到macOS。預(yù)計(jì)在不久的將來,可能5.15中,會(huì)增加相關(guān)的支持。
macOS上的Vulkan
如何通過MoltenVK使用Vulkan呢?
正如在第1部分中提到的,使用Vulkan發(fā)起渲染,然后依靠MoltenVK在運(yùn)行時(shí)將API調(diào)用和SPIR-V著色器代碼轉(zhuǎn)換為Metal和Metal著色語言也是一種選擇。這需要一個(gè)支持Vulkan的Qt庫,這在Apple平臺(tái)上不是現(xiàn)成提供的。關(guān)鍵是使用configure參數(shù)-I來設(shè)置并確保可以在運(yùn)行時(shí)使用環(huán)境變量QT_VULKAN_LIB并找到對應(yīng)的庫。
必須要注意,這個(gè)方式(在macOS上通過MoltenVK使用Vulkan)只是“盡我們能力”去支持。在Apple平臺(tái)上首要的渲染方式是通過Metal
使用QSG_RHI_BACKEND=vulkan (使用適當(dāng)配置的Qt 5.14庫)運(yùn)行演示應(yīng)用程序,結(jié)果如下:
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上運(yùn)行時(shí)遇到了問題,在使用線程渲染循環(huán)時(shí)遇到了死鎖和崩潰。在升級到更新的(1.0.121)Vulkan SDK(其中包括MoltenVK)時(shí)導(dǎo)致了一系列新的問題,依然無法啟動(dòng)應(yīng)用程序。在這里,在一個(gè)帶有10.14的Mac Mini和一個(gè)半新版本的Vulkan SDK / MoltenVK上,結(jié)果卻非常好,正如屏幕截圖所示。
Windows平臺(tái)
Windows是我們擁有最多選項(xiàng)的平臺(tái)。在4個(gè)主要的QRhi后端(Vulkan、Metal、D3D11、OpenGL)中,至少有三個(gè)可以在Windows上使用:Direct3D 11、Vulkan和OpenGL。
這就引出了一個(gè)顯而易見的問題:為什么只有3個(gè)而不是4個(gè),Direct3D 12不就是第四個(gè)嗎?
目前還沒有D3D12的后臺(tái)。以后會(huì)增加它因?yàn)橛羞@個(gè)計(jì)劃,但目前還沒有實(shí)施。回到我們的主題,需要注意一件事,在Qt 5.8中添加的實(shí)驗(yàn)性質(zhì)的Qt Quick的D3D12直接渲染后端在Qt 6中被棄用了(因?yàn)槲覀儠?huì)以一種全新的方式來解決多圖形API的問題)。
在Windows上設(shè)置QSG_RHI=1時(shí)的默認(rèn)值是Direct3D 11。與往常一樣,如果需要Vulkan或OpenGL,則需要使用QSG_RHI_BACKEND進(jìn)行修改。
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.1,而不是11.0。主要是因?yàn)槲覀冃枰猇SSetConstantBuffers1(以及相關(guān)的PS和CS變量)。這應(yīng)該不會(huì)出現(xiàn)問題,除非想在沒有安裝平臺(tái)更新的純Windows 7上運(yùn)行。說到Windows 7,需要注意,目前基于D3D11的渲染后臺(tái)在Qt 5.14的Windows 7上不能正常工作,因此在5.14的新特性頁面上只提到了Windows 10。這是以后需要補(bǔ)充的地方(但前提是Qt6仍然會(huì)支持Windows 7)。
要啟用Direct3D調(diào)試功能,請將環(huán)境變量QSG_RHI_DEBUG_LAYER設(shè)置為1。這也適用于Vulkan,只要調(diào)試功能可用(例如已安裝了Vulkan SDK)。Qt能方便地將消息定向到調(diào)試輸出(就好像它們是通過qDebug輸出的一樣)。
Vulkan和OpenGL能在Windows上正常工作,為了避免文章太長,這里就不附截圖了。
與Vulkan和Metal一樣,QRhi的OpenGL后端也是構(gòu)建在一些(但不是全部)現(xiàn)有的OpenGL類庫的平臺(tái)管道之上的,比如QOpenGLContext、QOpenGLFunctions,以及Windows平臺(tái)插件(WGL、EGL)中的底層管道。因此,原來直接運(yùn)行在OpenGL上的Qt Quick應(yīng)用程序的所有內(nèi)容,在新的渲染平臺(tái)上都有。(比如desktop, ANGLE, Software三選一參數(shù)以及各種環(huán)境變量,如QT_OPENGL)
說到ANGLE,我們的期望在Qt6中把它從直接依賴庫中刪除。這需要進(jìn)一步調(diào)查以完全確保我們不會(huì)失去對特殊用例的支持,但是現(xiàn)在的計(jì)劃是讓QRhi-based渲染路徑在Windows上支持Direct3D 11、OpenGL(通過WGL)和Vulkan,這就已經(jīng)能夠滿足應(yīng)用開發(fā)了。
這就是這篇文章的全部內(nèi)容。在第3部分中,我們將最終開始深入研究QRhi是什么以及如何處理著色器。
想要購買Qt正版授權(quán)的朋友可以點(diǎn)擊""哦~~~