如何編寫顯卡驅動?
題主是一點陣圖形引擎開發者,主要從事OpenGL,目前對GPU底層的詳細架構和工作原理還未掌握,希望可以通過編寫顯卡驅動的過程對GPU工作的各個階段有深入的理解,題主有看到一本講解CUDA的書,大致看了一下感覺還是不能透徹理解,同時也看了一本windows驅動開發的書,書里並沒講顯卡驅動的細節,希望各位NVIDIA的GPU架構師大神們可以推薦一下比較具體的學習資源和流程
補充一下,昨天看到龔大大回答的一個問題關於vbo是否會佔用內存以及可能發生的問題,龔大大提到需要根據驅動判斷,目前題主參考若干開源引擎初步實現圖形引擎各個模塊,由於GPU底層方面知識缺失嚴重,對於針對GPU的渲染優化方面異常乏力
謝 @Belleve 邀。
先潑幾桶冷水。
1. 底層詳細架構和工作原理,掌握和不掌握對圖形引擎開發沒有幫助。2. 編寫顯卡驅動對GPU工作的各個階段有深入了解幫助有限。
3. CUDA尚且不理解,就別下到驅動了。4. 以前Win DDK有一個ATI的驅動,後來刪掉了,顯卡驅動就那麼幾家做,其他人了解也沒用。5. 你說你從事OpenGL,標籤卻是OpenGL ES。到底是哪個,先說清楚,平台不同驅動不同。好,如果到此還沒熄滅的話,你可以從這裡開始
Windows Vista Display Driver Model先搞清楚win上驅動的框架WDDM,然後看Windows Display Driver Model (WDDM) Design Guide (Windows Drivers)了解各個部分分別要求做什麼。接著看AMD的硬體文檔Home - AMD從公開資料上你能找到的信息也就到此為止了。具體往下,就是跟具體硬體相關的。要麼你找Linux下的開源驅動,要麼就進硬體廠商。
做圖形開發的沒必要懂驅動做圖形驅動的沒必要懂圖形over
看一下WDDM就知道了。
圖形驅動的主要職能就是負責調配顯卡使用、管控各項資源(紋理、Buffer、Shader)、Shader的編譯與優化、渲染狀態的一致性驗證、從API到硬體Microcode的轉譯、數據從內存到GPU/顯存的傳送、響應硬體的反饋。
用兩個字概括就是,打雜。
題主你的需求和驅動關係都不太大。你還是要了解顯卡的Functional Spec,以及一些GPU架構方面的常識,這些都更重要一些。這個問題是個開放問題,開放問題的好處就是可以各種install b...硬體,驅動(OS kernel)和應用軟體(user mode)是三個不同領域,每塊都有其領域知識。看自己的悟性吧,如果我告訴你一個寫了若干年WDDM driver的未必會用DXSDK實現個shadow map,你肯定不行,但這是事實。
去看那本巨厚的 windows driver 的書吧,可能還需要看一下 windows internals 方便理解。
不過,這絕對是事倍功半的做法。OpenGL (ES) 的規範好好看幾遍就啥都有了,剩下N記和A記,ES的話PowerVR的開發者文檔掃一遍就挺感人了,驅動和硬體實現細節等需要了再找零碎資料看。如果題主感興趣的話,我可以和你分享分享我對整個圖形驅動的一些研究和了解。從EGL, Mesa開源3d圖形庫,內核直接渲染API(drm),GPU工作原理來簡單的描述一下這個過程。希望對你有幫助。
EGL: 從名字就可以看出,這是openGL的擴展,目的是和本地窗口系統進行交互,獲得顯示的目的地,相關的配置,以及維護繪圖過程中的上下文。代碼量並不多,核心功能只有兩千多行代碼,能夠支持x11,windows等操作系統的窗口系統。Mesa:這是用戶態的圖形驅動庫,也是對openGL標準的一個具體實現,如果你是做圖形引擎的,那麼你就會直接調用庫中的函數。注意,這是用戶態的邏輯,所有gl開頭的函數方法的實現都在庫中有具體的實現。Mesa一開始只有軟體實現,並不支持硬體加速,但是隨著顯卡圖形繪製管道的可編程型,同時AMD部分顯卡驅動的開源,尤其是直接渲染DRM的加入,Mesa就加入了硬體加速的實現。Mesa中由於歷史原因,在一開始默認只支持單進程的圖形繪製,認為只有一個圖形程序在運行,但是隨著發展,我們會要求同時在屏幕上的多個窗口繪製,為了保證和歷史的兼容,Mesa加入了上下文機制,同時裡面有一個分發表,注意這個分發表是就是各個驅動具體的實現所填充的函數地址。這樣在我們繪製圖形時,首先你需要獲取一個display,然後獲取相應的配置,RGB形式,是否支持模板,幀率等等。接著就是為當前創建一個繪製上下文。具體還有的很多的函數,這裡就不一一說了,但是需要明白的是,所有的這些邏輯都是基於libdrm.so提供的介面來實現的,通過ioctl來調用內核態的drm。DRM: 直接渲染管理,提供對顯存的管理,中斷,如何給GPU發命令等等,核心代碼12萬行。如果要明白GPU底層的工作原理,可以閱讀這部分代碼,沒有什麼參考資料,只能自己研究代碼,如果有什麼問題,可以給我留言。希望對各位有幫助。做顯卡驅動開發的來答一發,
首先聲明:顯卡驅動和圖形學半毛錢關係都沒有,你所需要的這些知識都在顯卡內部就封裝好了,如果想要了解的話可以讀顯卡的手冊。顯卡驅動做的工作是將你調用的函數進行組裝,組裝成命令流。然後寫入顯卡ringbuffer記錄的下一個命令地址,而顯卡自己會有兩個寄存器,分別指向當前執行地址和ringbuffer寫入地址,只要執行不超過寫入就一直執行。而顯卡指令提供的命令方式其實和opengl的函數差距也不是特別大,頂多就是關於緩存什麼的需要顯卡驅動來管理一下。所以如果你要做顯卡驅動的話,接觸的更多是驅動方面相關的知識,圖形學的知識幾乎用不到。
來,老規矩,看驅動代碼
https://github.com/Microsoft/graphics-driver-samples顯卡驅動不可能是一個人能寫出來的,我覺得你如果只是想對開發有幫助看看這個文檔就夠了
https://fgiesen.wordpress.com/2011/07/09/a-trip-through-the-graphics-pipeline-2011-index/Nvidia的驅動是閉源的,你看不到具體細節。如果實在想知道,可以看envytools的文檔,但確實對你開發圖形幫助不大。要了解GPU內部的工作細節的話可以去做emulator,各大GPU硬體廠商應該都會有這個職位,用C++去實現GPU 的feature。
推薦閱讀:
※某些設備上顯存是內存的一部分,這時OpenGL能否直接使用內存中的紋理?
※Opengl 的片段著色器的Blend的疑惑 片段著色器的Alpha Blend次序?
※OpenGL ES 在不同架構上的指令優化是否真的完美?
※OpenGL 與 OpenGL ES2 之間有何區別?