Direct3D 的進化史

jobbole發表於2013-08-23

伯樂線上導讀:本文作者 Alex St. John 和 Craig Eisler、 Eric Engstrom 三位一起建立了早期的微軟 DirectX 技術平臺。1992-1997年Alex在微軟的工作,後來成為 DirectX 技術佈道師。感謝@淺水清流的熱心翻譯。如果其他朋友也有不錯的原創或譯文,可以嘗試推薦給伯樂線上

我在Direct3D上工作了很多年,多年來技術有了極大的發展。多年來,現代圖形處理器(GPU)發生了巨大的變化,擁有了我曾經以為在有生之年不可能見到的運算速度和能力。現代GPU的演變是在很多充滿魅力的市場驅動下進行的,其中我覺得最重要並且有趣的是,在Direct3D的影響下,新一代的GPU支援數以千計的處理核心,數十億電晶體(超過CPU)而且在大多數應用中都要快很多倍。我可以講很多關於D3D的趣聞和政治傳說,但是我更想記錄下D3D的由來以及對現代GPU架構的深遠影響。

本文使用的是1995年Direct3D第一次釋出時的老文件。這份文件包含了對3D硬體加速架構的願景,在很大程度上主導了現代GPU演變成為今天我們所見的強大得另人難以置信並且用途普遍的無所不在的消費型超級計算機。

D3DOVER

我進入計算圖形學不是對遊戲感興趣,而是對想了解物理模擬計算。為了瞭解如何模擬量子力學、化學和生物系統,在20世紀80年代中後期,我開始參與Siggraph研究3D圖形學。模擬光和材質互相作用在Siggraph曾經風靡一時,在此期間我學習了3D。瞭解3D數學和光照模擬,讓我通過我在職業早期建立的PostScript RIP(光柵影像處理器),成為了在出版業的圖形和色彩專家。我曾經和劍橋大學的工程師一起開發了在連續色調印刷發明之前印刷彩色圖形的軟體方案。我的專業背景獲得了微軟的青睞,在1990年初我獲邀參與為Windows 95和Windows NT重新設計具備與當時表現卓越的蘋果競爭的能力的列印架構。峰迴路轉之後,我的職業生涯到了回到3D的時候,我開始主動和幾個朋友為Windows重新設計支援實時遊戲和視訊架構的圖形和多媒體架構,這最終導致遊戲成為了微軟的一個重要戰略。在索尼推出3D遊戲機PS1之後,為Windows找個一個3D解決方案,成為了負責開發Directx的我們義不容辭的責任。

對我來說,制定微軟在遊戲市場3D戰略的挑戰是一個經濟問題。微軟應該採取什麼樣的策略,去建立一個充滿活力競爭激烈的市場給消費者帶來實惠並且引導未來的發展。在那個時代,3D實時渲染的複雜度遠遠超出了當時的硬體能力,找出一個遠離數學的理想方案讓任何hack都能構建出足夠好的3D應用看起來是不可能,我們有希望改變世界。

當時唯一的商業解決方案是為CAD設計的3D硬體。這些工作站需要花費數十萬美元。雖然OpenGL API 是當時市場上唯一的3D API標準,但是它並不是為3D遊戲設計的。例如,紋理對映是渲染逼真的圖形的一個重要技術,但是CAD優先考慮的是功能而不是看起來cool。同樣,豐富的動態光影效果對提高遊戲的表現力很重要,但是對CAD並不重要。而高精度的模型對於CAD重要,但是對遊戲並不重要。最重要的是OpenGL並沒有為實時高度互動的圖形而設計的離線緩衝區來避免渲染過程中撕裂紋理。這並不是說OpenGL並不能適應這些遊戲所需的特性,而是它的實際市場是昂貴的工作站而不是$200的遊戲顯示卡。

在20世紀90年代計算機的RAM非常昂貴,正因為如此,早期消費型顯示卡選擇了記憶體需求最小的方案。Sony在優化PS1的3D硬體時,沒有依賴記憶體密集型的Z-buffer,而是使用多邊形區域排序演算法,雖然會在活動的骨骼間產生醜陋的交點。“畫家演算法”對3D渲染來說非常快速,並且幾乎不要額外的記憶體。對於遊戲開發來說這是一個醜陋而務實的做法,但是這種做法對CAD來說是不可接受的。

在制定Direct3D架構時,我們面臨的類似艱難選擇不勝列舉。我們希望當時領先的顯示卡廠商,ATI、Cirrus、Trident、S3、Matrox 和其他廠商能彼此競爭,快速更新3D顯示卡,而無需在一片混亂中建立市場。微軟的OpenGL團隊信賴Michael Abrash的技術方案,一個被稱為3DDDI(3D Device Driver Interface)的驅動程式模型。3DDDI是一個非常簡單的驅動模型,只支援硬體加速3D光柵化。3D場景光照變換的複雜數學運算被留到了CPU。3DDDI使用“功能位”來指定額外的渲染功能(比如過濾),消費型顯示卡廠商可以選擇實現一部分。3DDDI的問題是在邀請遊戲廠商參與時,事情失去了控制。這麼多“功能位”,遊戲廠商要麼選擇支援各種“未知”的硬體特性,利用一切可能的方式充分挖掘顯示卡的能力(硬體廠商可能會選擇支援不同的硬體特性導致使用者的硬體配置難以預測,為了在任何裝置上都良好的表現,遊戲將不得不準備大量的美術資源)或者遊戲只使用一組所有硬體都支援的簡單常見的3D特性,但是沒有硬體公司提供的最新特性,在市場上就會缺乏表現力。OpenGL的人在微軟沒有意識到這是個大問題,因為在他們的世界裡,所有人都使用支援他們需要的所有特性,價值$100,000的昂貴工作站。

認識到我們不可能從OpenGL團隊得到我們想要的東西之後,我們決定建立一個新的,只為遊戲而設計的3D API。這些API什麼都不做,但是我們需要通過制定明確的驅動程式架構,來建立一個競爭激烈而有序的市場。在這方面,D3D API不是OpenGL API的替代品,它是一個驅動API,創造出來的一個經濟戰略目的,是引導消費型顯示卡市場進行激烈而有序的競爭。換句話說,D3D API更多出於經濟目的,而不是技術目的。在這方面D3D API的幾個革命性的有趣之處是,API什麼都沒有做,而是制定它所依賴的驅動程式架構。

當我們決定收購一隻團隊打造Direct3D時,我被特許參與評審候選企業是否有足夠的技術能力幫助我們制定我們所需要的API。正如我以前所說,我們考核了Epic Games ( UnReal 引擎廠商), Criterion (後來被EA收購), Argonaut 和 Rendermorphics。我們選擇了總部設在倫敦的Rendermorphics,因其創始人Servan Kiondijian對如何設計一個儘可能兼具相容性和創新的3D驅動程式架構有一個非常明確願景。Direct3D的第一個版本非常的簡陋,但是API迅速向在未來有巨大潛力的方向演進。

我在這一時期的主要記憶是,我作為常駐DirectX團隊的3D專家,被要求為D3D選擇一個座標系標準。我選擇了左手座標系,一部分原因出於個人喜好。我至今還記得,因為這是一個輕率的決定,此後帶來無數的麻煩,因為其他3D建模工具都採用了OpenGL標準的右手座標系。當時沒有人會想到,Autodesk和Maya的建模工具會成為遊戲開發行業的建模的標準工具。微軟已經有了收購SoftImage取代Autodesk和Maya的計劃。Whoops…

早期的Direct3D HAL(Hardware Abstraction Layer) 以一種有趣的方式設計,它以垂直的3個階段構成。

最高層是幾何變換層,中間層專用於光照計算,底層進行光柵化過程,生成畫素影像。這種垂直驅動架構背後的目的是讓硬體廠商在實現一個相對一致的特性要求進行創新。他們可以細分他們的產品,設計更加高效的3D管線,從而獲取更高的效能,並且和現有產品保持相容,否則就會需要配置一個龐大的矩陣進行相容性測試,或是需要大量的冗餘美術資源。由於Rendermorphics建立Direct3D API時提供了一個“相當高效的”無需硬體加速的軟體實現,遊戲開發者可以把重心放在Direct3D API上,而無需關注無數不相容的硬體特性組合。至少理論上是這樣。可惜和3DDDI驅動程式規範一樣,Direct3D仍然包含了“功能位”設計,允許加入垂直架構之外的硬體特性。雖然我極力反對讓Direct3D傾向於堆積“功能位”,但是小組受到了來至微軟OpenGL組的巨大競爭壓力,硬體提供商支援他們。

硬體廠商為了讓自己的產品可以更有優勢,威脅將會支援和促進遊戲廠商使用OpenGL,因為OpenGL驅動程式模型支援“功能位”,他們可以設計別人不具備的硬體特性。這很常見(現在還是),硬體廠商贊助遊戲廠商使用他們與基礎功能不相容的硬體特性,迫使消費者不斷更新他們的顯示卡來玩遊戲啊廠商最新的PC遊戲。遊戲廠商討厭不斷變化的“功能位”,因為它們複雜並且不相容,但是又希望通過支援“非標準”3D特性獲取遊戲廠商的贊助。

總的來說,我認為這種趨勢破壞了PC遊戲市場的健康發展,並且主張抵制這種趨勢,無論OpenGL或是OEM廠商的人怎麼想。我相信建立一個穩定的消費市場,比安撫OEM廠商更加重要。就是這樣,我是Direct3D垂直管線的強力倡導者,我們預計隨著時間的推移,只實現D3DAPI的功能將會越來越普遍。我坦白承認,這種觀點隱含對在其他領域創新的重大約束,引導市場被放在Direct3D團隊的第一位。

最終我的估計相對準確。Direct3D固定管線,如大家所知的,通過在DirectX 7.0上進行的健康的激烈競爭,產生了內容豐富、增長迅速的PC遊戲市場。在2000年初,PC遊戲市場贏來了爆發性的增長,成為了全球上最大的遊戲市場。這也導致GPU體系結構此後發生了許多有趣的變化。

最終Direct3D HAL是一個光柵化驅動模型加微軟的OpenGL團隊所倡導的“功能位”,顯示卡廠商將通過加速底層渲染管線的效率和新增差異化特性與對手展開競爭。引入的垂直分層架構的結果是,促使所有硬體廠商以更接近通用CPU架構的方式新增特性到GPU中,即以一致的方式進行快速浮點計算。因此消費型GPU經過多年的發展,越來越像CPU,但是有個主要的區別。因為3D管線還是剛性的固定管線,Direct3D體系結構很少需要像CPU一樣針對分支程式碼的優化。GPU實現驚人的效能和高度並行,很大程度上得益於Direct3D圖形管線內部很少甚至根本沒有分支程式碼。因此不是發展成為一個類似於Intel CPU那樣將大量電晶體用於高效的分支預測的巨大的單片CPU核心,Direct3D的GPU擁有數百至數千簡單的沒有分支預測的CPU核心。他們可以達到驚人的吞吐量,以令人難以置信的速度執行,如果不遇到分支程式碼或是隨機記憶體訪問,流水線就不會被打斷。

通過支援DirectX 7.0,GPU底層的平行計算被從遊戲中隱藏。遊戲開發只需要知道一些硬體比另一些硬體效能更強,但是無需關係這些如何實現。早期的固定管線取得了輝煌的成果,使幾十家顯示卡廠商採取各種方法提高效能、降低成本而不是陷入混亂的競爭中。它的影像不夠漂亮,精度也不夠高,但是已經足以在2000年初建立一個活躍的遊戲市場。

在我討論現代Direct3D的演變之前,我想強調幾個早期Direct3D體系結構的重要思想對現代GPU的影響。在1990年的早期到中期,RAM相對昂貴,這導致消費型顯示卡採用了需要RAM較少的技術。這個觀點對我將來很多負面故事的(well-deserved)The Talisman 架構的影響很大。

Talisman依賴各種圖形學上的tricks,儘可能的降低對視訊記憶體的需求,並不是一種常規做法。為了建立一個面向大眾的消費型顯示卡市場,Direct3D團隊受到了Rendermorphics創始人做出的一個艱難選擇的嚴重影響。我們決定採用在3D上更通用更簡單但是依賴更多視訊記憶體的Z-buffer,來實現更好的顯示效果。Rendermorphics在使用了軟體Z-buffer的Rendermorphics引擎上實現了很好的3D效能,這給了我們信心去賭注,用一個更簡單通用的3D API和驅動程式模型,並且相信硬體市場和RAM的價格會降下來。

但是請注意,我們在設計的Direct3D的時候,我們沒有了解到微軟研究院“祕密”的Talisman計劃,他們也沒有預計到一小群先行者,會設計了一個新的遊戲3D API標準,並且在他們奇怪倡議被部署之前啟動了它。總之這是一個巨大的賭注,Direct3D為遊戲開發者提供了簡潔和優雅的Z-buffer,值得去冒這個險,消費型3D顯示卡市場在早期很難以合理的價位支援它。

儘管支援Z-buffer是一個巨大的賭注,但是我們還是有兩個架構上的問題需要解決。首先是PC匯流排一般很慢,第二是從顯示卡讀取資料比寫入資料到顯示卡慢的多。這通常意味著,我們的設計API需要儘可能緊湊封裝資料傳送給GPU的處理,和儘可能減少,將GPU處理完的資料複製回CPU處理。這通常意味著的Direct3D API進行了優化,資料打包和傳送一次完成。當然這是一個不幸的約束,因為有很多華麗的3D效果,可以通過混合CPU高效的分支預測和GPU強大的浮點運算能力達到令人難以置信的並行渲染效能。

該約束正面作用之一是,它迫使GPU向更通用的方向發展,以補償無法有效地與CPU共享資料。恰恰相反,Intel可能希望控制匯流排速度的發展,因為其他協處理器越來越多的取代CPU在PC中的核心地位和功能,這對Intel是個威脅。有理由相信,Intel故意限制了PC匯流排效能的提高,以防他們的CPU在多媒體應用市場上出現替代品。回想一下我以前的部落格,推出DirectX的主要原因是防止Intel通過虛擬化支援所有Windows多媒體應用。如果Intel採用了可以使協處理器快速共享RAM的匯流排架構,那麼GPU不大可能如今天這樣支援豐富的分支預測和浮點計算。

為了克服PC匯流排效能的限制,大量技術投入到了用CPU壓縮和簡化傳送到GPU的DirectX資源,以減少匯流排頻寬的效能限制,和儘量減少需要從GPU返回CPU的操作。早期的固定3D管線在後來造成了有趣的後果,當我們開始探索通過網際網路分發3D資源。

我們認識到早期支援壓縮紋理,將極大提高匯流排效能和降低對視訊記憶體的需求,問題是在一個沒有標準3D紋理格式的年代,我不想過早的將一個微軟指定強加給行業。為了克服這個問題,我們抱著沒有標準格式的的想法前進。這個想法是我們提出的DirectX諸多專利的一個,我們提出一個GPU可以編碼和解碼不明格式的紋理,而DirectX的API將允許應用程式如同原始點陣圖一樣讀取和寫入紋理。Direct3D驅動程式進行編碼和解碼,而應用程式沒有必要知道驅動是如何工作的。

直到到1998年,顯示卡廠商開始為DirectX6.0制定高標準的3D紋理格式,我們將其中之一(S3)列入Direct3D許可。

http://www.microsoft.com/en-us/news/press/1998/mar98/s3pr.aspx

DirectX 6.0 是被列入釋出版作業系統版本(Windows 98)的第一個版本。直到那時,DirectX實際上只是一個內部庫,被一個Windows遊戲使用。直到第一個版本的之後的第5代,DirectX才正是成為Windows API。

DirectX7.0 是最後一代依靠在DirectX2.0時代就已經奠定基礎的固定管線的Direct3D API。這是Direct3D非常微妙的一個過渡期,有以下幾個原因;

  • 1)原來的DirectX團隊創始人都離開了,
  • 2)Talisman和微軟支援OpenGL的內部原因都被否決
  • 3)微軟帶來了遊戲行業的資深人士,如Blackley、Kevin Bacchus、Stuart Moulder等進入公司高層
  • 4)遊戲已經成為公司的戰略重點

DirectX 8.0是Direct3D一個迷人的標誌性過渡版本,因為Talisman專案的失敗和OpenGL支援戰略的利益受損,許多3D開發人員從這2個專案加入到Direct3D的工作中來。這個結果是非常有趣的。現在回頭看,我不會做出和他們一樣的選擇,但是回想起來,在我看來一切都以最佳方式在工作。

Direct3D 8.0以幾個有趣的方式影響了20世紀末的顯示卡市場。微軟在很大程度上統一對OpenGL的結論,並且發現自己發展Direct3D要比Kronos的集團標準委員會推動的OpenGL要快。隨著SGI死亡,OpenGL標準的控制落到了那些希望標準允許創造差異化競爭和迫使微軟支援他們想推動的3D特性的3D硬體OEM的手裡。最後的結果是,Direct3D和OpenGL變得更加複雜,他們在此期間趨於收斂。從DirectX8.0到DirectX11.0,遊戲開發商停止採納新的3D特性。建立遊戲引擎變得如此複雜,以至於市場上只剩下幾家領先的引擎開發商,包括Epic的Unreal Engine和id Software公司的Quake engine。

如果我一直在Direct3D工作,我會堅決抵制微軟被3D顯示卡OEM廠商牽著鼻子追逐OpenGL的特性,而是專注於讓遊戲開發商有一致的品質和消費體驗。我會反對引入shader,保持儘可能垂直整合硬體廠商之間的功能,以確保符合Direct3D驅動程式層的支援。同樣,我也強烈反對放棄支援DirectDraw。3D的傢伙們失去了控制,並且認定採用3D API之後不會有人需要純2D的API,沒有認識到簡單的2D API滿足了大量需求而且易於使用,畢竟大多數開發者不是天才,並不能輕鬆理解和使用3D API。強制市場接受3D API造成了巨大的准入門檻。微軟後來發現了這一錯誤,並且從新引入了DirectDraw,也就是新的Direct2D API。基本上 Direct3D 8.0 的天才設計讓它輝煌,強大並且對普通開發人員沒用。

在DirectX 8.0開始開發時,我正在創辦我的第一家公司WildTangent Inc,並且不再關注DirectX3D的進展。然而,幾年之後我回到了夢想開始的地方,並且重新開始學習3D,最新的DirectX11.1。回過頭看看這些很有趣,DirectX8的主要設計做了哪些改變,導致了今天幾乎難以理解的Direct3D API。還記得3級流水線的DirectX2,旋轉,燈光和光柵化分為三個基本階段?這裡是一個現代的 DirectX 11.1 三維管線圖。

是的,它增加到了9-13級,其中包含一些可選項如compute shader。作為一個擁有極其資深的背景並且非常低階別的3D圖形程式設計人員,我不好意思承認我學習 Direct3D 11.1 學得非常的痛苦。Direct3D API變得非常的不可理解和難以學習。我無法想象沒有和我一樣深厚的3D圖形背景的人該如何開始入手學習現代可程式設計3D渲染管線。這條管線驚人的強大而且難以使用,但是極少數最聰明的人都在從事3D圖形。在我趕上現代Direct3D的過程中,我發現我敬畏現代GPU的驚人力量,它們會發展到哪一步,同時震驚、厭惡3D管線已經發展到絕對的混亂。在過去的幾年中,Direct3D API已經成為OEM要求的3D特性傾銷地。

如果我不是享受著長達十年參與DirectX的回報,毫無疑問,我會酸溜溜的寫些什麼亂七八糟的我的前輩建立了偉大而優雅的消費型3D圖形顯示的悠久歷史。然而,古怪的是當時間定格到了現在,我必須承認,我不能確認但這畢竟是件壞事。PC遊戲市場的停滯,和微軟與OEM推動Direct3D API的背後是XBox的成功。大量零散的3D API並不是個大問題,如果和遊戲機一樣,開發者只需要支援一種硬體配置。早期的DirectX 8.0支援Shader Model 1.0是第一代Xbox的圖形API的基礎。作為第一代XBox的選擇,NVIDIA晶片在PC 3D圖形晶片市場擁有了巨大的優勢。DirectX 9.0和更先進的Shader Model2.0,是XBox360的基礎,微軟重新選擇了ATI設計3D晶片,AMD這個時候在PC圖形市場擁有了巨大優勢。從某種意義上說OEM自己絞死了自己。通過成功影響微軟和OpenGL標準組織採取高度錯綜複雜的圖形管線,以支援他們所有特性,他們迫使自己去歸納他們的GPU架構,而顯示卡晶片市場會圍繞一種架構合併… 無論微軟為它的遊戲機選哪個。

最終的結果是,PC遊戲的零售市場接近於死亡。這對於開發一個高產值的遊戲來說,簡直是個太太昂貴,太沒有安全感,太不穩定的平臺,除了MMOG。微軟和OEM的同謀毀掉了眾所周知的搖錢樹。這對微軟來說沒什麼大不了的,因為微軟很高興通過XBox控制了PC遊戲前端業務。

從很早的DirectX視覺的角度來看,我認為這個結果是一個愚蠢且短視的災難。微軟應該保持DirectX團隊的紀律,把戰略重心放在Direct3D API,他們可以確保沒有其他遊戲機和XBox同一個時代,通過XBox加強PC遊戲市場,而不是無意之中破壞它。雖然祝賀微軟開發了首款美國產的成功的遊戲機,但是我會計算如果微軟保持一個有凝聚力的跨平臺戰略,從索尼,任天堂和移動平臺所能獲得的回報。我說這些是從過去的角度來看,因為今天,我不能肯定,我對所以的結果感到不滿。

索尼和微軟的新一代遊戲機已經恢復到PC架構!下一代GPU將是大規模並行,與CPU共享私有快取的通用處理器。事實上,GPU架構變得如此通用,是因為在DirectX 11中加入了一個稱為DirectCompute的新流水線階段,允許CPU繞過整個Direct3D圖形管線直接程式設計。隨著DirectCompute的引入,簡單的3D程式設計以一個意想不到的形式返回。現代GPU已經變得如此強大和靈活,直接採用GPU程式設計開發3D引擎是一個越來越實用和有吸引力的程式設計選擇。從我的角度來看,我預計在短短數代的時間裡,傳統的Direct3D和OpenGL API將會消失,新的引擎將會親睞與採用如Nvidia的CUDA和微軟的AMP之類的獨立的shader語言來編寫更豐富,更多樣化的特效。

今天,作為一個3D物理引擎開發者,我從來沒有如此興奮,因為現代GPU程式設計純粹而強大,並且相對容易程式設計,而無需學習錯綜複雜的Direct3D和OpenGL API的3D管道。如果今天是我負責Direct3D的戰略,我會主張拋棄傳統的3D管線,快速轉向豐富的GPU程式設計環境。我個人從來沒有想過,我早期工作過的Direct3D,在幾十年中,促進演變出了一種新的無處不在的處理器,可以支援在1980年我所學到的那種令人難以置信的逼真的光照和物理模型,我從沒想過電腦能強大到在我的職業生涯中出現實時渲染模型。

Direct3D API 的遺產:

  • 左手座標系,我在DirectX2.0做的糟糕決定
  • 伴隨Windows 95問世的COM API
  • 各向異性過濾,在Direct3D中發現的Talisman的最後遺蹟
  • Shaders, 在DirectX8.0中引入,標誌著固定管線的結束和可程式設計渲染管線的問世

相關文章