從本篇教程開始,我們暫停代碼的學習,先來了解一下D3D11的管線,這些管線不涉及具體的硬件,而是着重於理解能夠支持D3D11的管線實現。
參考資料:
http://fgiesen.wordpress.com/2011/07/01/a-trip-through-the-graphics-pipeline-2011-part-1/
通過前面的教程,我們知道,要用D3D11畫一個三角形,我們需要做以下步驟:
這些步驟大致分為四個階段,初始化階段,數據裝配階段,shader執行階段,以及合並輸出階段。這些步驟最終會在D3D11硬件設備上上執行。
我們知道,顯卡都有驅動程序,也就是driver,通過driver,windows系統才能和顯卡硬件進行交互,完成渲染任務。
通常顯卡(GPU)的driver有D3D driver和OpenGL driver。 由於微軟各代D3D 之間並不完全兼容,所以D3D driver有分為D3D9 driver,D3D10 driver,D3D11 driver, D3D12 driver 等等。
首先是我們的3D應用程序, 它通過調用D3D11 API函數,實現創建資源(比如頂點緩沖),設置狀態(比如深度模版狀態),調用drawIndex函數等等。
D3D運行庫會跟蹤我們設置的狀態,驗證函數的參數是否正確,驗證shader代碼以及shader鏈接庫, 編譯shader(把shader從原始的HLSL編譯成DX ASM, dx的匯編格式shader),另外它還有內存管理以及設備管理的功能。DX運行庫的會把應用程序的調用最終傳送到用戶模式driver(UMD)中,從某種程度上來說,我們可以把DX運行庫看成一個包裝器,它是應用程序和UMD之間的接口。
UMD(user mode driver)是指用戶模式driver,它其實就是一些動態鏈接庫(dll),完全運行在cpu端。GPU廠商都願意把更多的功能寫入UMD,因為其僅是一個dll,容易調試、可以實現多線程操作(比如一個線程編譯shader,一個線程處理紋理),即使UMD崩潰了,也不會引起系統藍屏,因為它和我們普通的應用程序沒有本質區別。
UMD主要功能:編譯shader(把DX ASM編譯成特殊的IL,中間語言,再編譯成對應硬件的機器碼),轉化應用程序的狀態設置和drawcall到硬件識別的packet,並把packet放入到command buffer,另外UMD也有一些內存管理功能,比如虛擬地址管理。
UMD最終會產生GPU中各個引擎的workload,比如圖形引擎,視頻編解碼引擎,DMA引擎,computer引擎等等,這些workload都以command buffer的形式傳到KMD中,再傳給相應的硬件引擎,讓它們去做這些工作。
在UMD中,BLT操作管理是處理2D功能,主要就是buffer操作,比如stretch blt,color buffer clear,msaa resolve,內存copy等待。地址庫決定memory的布局,比如tile mode,對齊方式,swizzle操作等待。
UMD中還有特殊硬件處理層和特殊軟件處理層,因為現在driver都是統一架構的,一套driver驅動不同代的顯卡,所以UMD中特殊硬件處理層就是對特殊硬件進行一些操作,比如某代顯卡有bug,可能就要在這個特殊處理層中進行一些補救操作。針對某些特殊軟件的優化就放在特殊軟件處理層中處理,比如某些跑分程序。
在UMD和KMD之間還有DXGI,這是微軟的DirectX圖形基礎架構,它的設計主要是進行一些底層的操作,它可以看作是KMD的運行庫,現在微軟把越來越多的底層管理放入到了DXGI中。比如顯存管理,commandbuffer的調度,同步操作,present后緩沖到前緩沖,顯示器的管理等等。3D應用程序也可以直接訪問DXGI一部分功能,比如枚舉系統中使用的顯卡。
KMD( kernel mode driver),是指Kernel模式driver,KMD負責直接和硬件打交道,可能在系統中有多個UMD實例,但KMD只能有一個。一旦KMD崩潰,操作系統可能會出現藍屏錯誤,KMD主要功能包括:
1、在多個應用程序使用GPU的情況下,KMD通過slice time分時操作來管理應用程序。
比如在一個時間片內一個app進行物理內存操作,另一個時間片內另一個app初始化GPU,設置顯示模式等,在不同app間切換時,就需要context switch,響應中斷等。
2、ASCI的初始化,一套driver會對應多代的顯卡,ASIC這兒就是指不同代的顯卡,它們可能架構不同,KMD要針對當前的硬件,選擇合適的ASCI設置。
3. 電源管理,GPU內存資源的分配,回收。
4. command buffer提交到GPU硬件,以便GPU硬件開始buffer中的packet。
下圖為d3d11 api和driver的交互框圖,從中我們可以清晰的理解D3d api如何轉化為硬件的packet,並被提交到硬件引擎的ring buffer。
