DRM中的思路

linux已經有過fbdev管理圖形適配器的FB,但是不能處理現代基於3D加速GPU的圖形硬件。3D加速設備一般需要設置、管理一個在其硬件內部內存的指令序列,然後分發指令。

DRM暴露有設備節點在/dev/dri/cardX,libdrm封裝了對這個設備節點的操作。

DRM包含兩部分,generic DRM core,以及DRM Driver,DRM Driver是硬件相關部分。DRM core提供基礎框架,可以由不同的DRM Driver註冊,同時也提供給用戶態一個最小的ioctl調用組,硬件無關。DRM Driver負責硬件相關的ioctl調用。

如何提供接口:

DRM core主要提供通過ibdrm包裝的系統調用,而DRM Driver部分的ioctl調用一般封裝在libdrm-driver裏面。一般來說,硬件相關的接口像是內存映射、context管理、DMA操作、AGP管理、vblink控制、fence管理、內存管理和輸出管理應該在libdrm-driver。

權限的管理:

DRM事關顯示,需要安全,因此DRM有提供ioctl SET_MASTER,執行過此syscall的程序就可以成爲唯一的DRM-Master顯示管理程序,執行ioctl DROP_MASTER也可以放棄DRM-Master身份,一般X server就是DRM-Master。其他的非DRM-Master用戶態程序通過DRM-Auth,具體過程是:執行ioctl GET_MAGIC得到一個32bit魔數,然後傳給DRM-Master -> DRM-Master用此32位魔術ioctl AUTH_MAGIC給DRM設備 -> DRM設備給發起Auth的非DRM-Master應用持有的與此魔數對應的fd授權。

DRM中的GEM(Graphics Execution Manager)

DRI2/3的表述,每個渲染實體都開始持有自己的back buffer,並且從顯卡申請的內存也可以context切換出去後一直持有,這些被持有的內存就需要DRM在內核中管理起來,GEM就提供這些API,包括申請、釋放這些個GPU用的內存(可能集顯在內存,獨顯在顯卡),姑且稱顯存。

顯存在進程間傳遞:

申請了現存就可以得到一個32bit數,把這個數字告知另一個用戶態程序即可實現現存的傳遞、共享,這其實是有安全問題的,任何應用都可以隨便猜個數,然後讀、寫內容。不過這個問題後來通過引入DMA-BUF解決,DMA-BUF是用於在多設備間共享 DMA緩存的,比如說Video4Linux設備和顯示器就可以通過DMA-BUF實現0複製的數據傳輸,任意linux設備驅動都可以實現此API的生產和/或消費者,DMA-BUF一開始適用於集顯+獨顯的共享FB,然後用的愈加的多;提供有ioctl將GEM句柄與DMA-BUF fd相互轉換,轉成DMA-BUF的GEM對象就可以通過IPC socket的SCM_RIGHTS完成傳遞。DRI3在client和Xserver間傳buffer、Wayland都是這樣用的。

GPU-CPU間的內存同步:

現代計算機到處都是cache,cache對齊和保障CPU-GPU內存一致就需要考慮,也就有了對硬件實現的高度依賴,對於集顯,沒有獨立的內存,比較好說,基於UMA(Uniform Memory Architecture)劃分內存域進行管理;而獨顯則大多選擇將GEM的API實現在用戶態。

TTM(Translation Table Maps)

TTM出於GEM之前,設計用於管理GPU可能訪問的不同類型的內存的管理,獨立顯存(Video RAM即VRAM)、通過IOMMU訪問的系統RAM(即GART-Graphics Address Remapping Table)、以及CPU不能直接訪問的顯存;還有一個功能就是維護內存一致性。用戶態圖形程序要訪問顯存時,如向顯存中裝數據,TTM需要做映射使CPU可訪問,或通過GART讓GPU訪問系統內存,這些都需要處理內存一致性問題。

另一個重要的TTM概念是fences,內存屏障;這是一個管理CPU-GPU內存一致性的基礎機制,一塊共享內存,GPU使用完,其他想要使用這塊內存用戶態程序就可以得到提醒,其實就像是互斥鎖。

TTM想把獨顯、集顯用一致的方法統一管起來,但這導致TTM太複雜,API太多;GEM更簡單的、API比TTM更好的;不過TTM很適合獨顯、有IOMMU的場合,所以就把TTM包在了GEM的API下面。AMD和NVIDIA顯卡都這麼幹的。

Render Nodes

一開始DRM設備/dev/dri/cardX是特權操作(modsetting/其他顯示控制)和非特權操作(如渲染操作)公共使用的設備節點,致使僅部分可靠的用戶態程序(如X,作爲DRM-Master)纔有全部的DRM API的訪問權限,其他的用戶態程序想要使用GPU做渲染就只能先去DRM-Auth,然後才能執沒有特權操作的DRM API。這一設計需要如X server這樣的程序必須運行,而很多使用GPU渲染的程序並不是爲了顯示(比如我現在這樣的),不顯示就不需要這麼關注安全,畢竟只是用用硬件,得個結果,而這個結果不是爲了迷惑顯示器前的人;再這樣的考量下,Render Node的概念:把DRM用戶態API分成特權和非特權的,分開使用GPU,也就是添加了設備/dev/dri/renderDX。這樣想要利用GPU算力而不是爲了顯示的兄弟們就只要有此設備節點的訪問權限就能做計算了,而compositors,X server,以及其他需要modeset API或是特權操作的,還是必須使用/dev/dri/cardX設備節點,像之前一樣幹活。而Render Node也就不允許通過GEM flink一下就共享buffer的操作,需要轉成DMA-BUF fd來共享、傳遞。

發佈了37 篇原創文章 · 獲贊 4 · 訪問量 3376
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章