托幾個大駭客的福,firmware 2.0及以下的PS3可以使用“部分”GPU(Nvidia RSX)的功能。最近花不少時間在這上面,也讓自己對GPU底層和工具鏈有個大概瞭解。
在PS3裡,在最底層有個提供硬體功能介面的作業系統,姑且稱之為Level 1。其上的任何作業系統都使用需要通過Level 1的API和硬體介面進行互動,姑且稱之為Level 2。以這個概念,目前PS3上啟動並執行預設作業系統(GameOS)和其他第三方可提供的作業系統(OtherOS)都是Level 2 OS。SONY出於很複雜的目的,在一定程度上開發了第三方作業系統的可能性,稱之為OpenPlatform。具體來說它是安排了一個自己的職員,專門為PS3維護linux核心。由於核心必須是開放的,儘管其中只有很少對於Level 1 OS的系統調用且沒有注釋,還是給了駭客們機會,這裡有一個收集並描述Level 1 API的wiki:http://wiki.ps2dev.org/ps3:hypervisor
一切的hacking都從這些API開始。通過摸索、實驗、逆向工程分析dump,並利用nouveau開源驅動項目,最終駭客們找到了一些解決辦法來駕馭GPU。
Nvidia系列GPU都有一個FIFO的環形隊列(command buffer)供存放GPU指令。這塊存在於系統記憶體的地區大約是64KB(還是2MB記不清?)。有一個類似於程式指標PC的指標(寄存器),指向FIFO。而另一個指標(寄存器)則標註著目前GPU的隊列尾。一旦這兩個指標不匹配,前者就會一個個將隊列中的指令DMA到GPU,直到和後者重合。所以我們要做的就是把正確的指令填入這個FIFO,以期待最後GPU會把我們的指令一一執行。
由於實現一套driver和圖形API的代價太大,幾乎很難以個人力量完成。所以沒有driver,沒有圖形API,沒有任何資源管理,所有的一切都只有FIFO和指令。這有點類似官方SDK中的libgcm庫,可以繞過PSGL的下層,對command buffer進行一些操作,如傳入先行編譯的指令隊列等。
其實最令人感到不適的還不是圖形API的缺失。由於硬體指令是不公開的,所以這裡需要通過nouveau的項目資源,以及一些dump來分析NV40系列的指令。有些可以正常使用,另一些則不然(如vp中的ADD和fp中的MOVR,總是無法正確輸出float4的色彩)。還沒完,即使完全掌握了這些硬體指令,沒有一個assembler或進階語言編譯器的話,寫shader會變得無比痛苦。所以目前的工具鏈是這樣的:在PC上寫完Cg,使用Cg編譯器輸出vp20和fp30的彙編代碼。在PS3 Linux上已經有寫好的assembler,可以將彙編代碼翻譯成硬體指令。所以寫一個shader會在兩個平台上來回切換,忙的不亦樂乎。
我想以後的工作可以包括一些簡單的資源管理和隊列管理的工作,包括顯存分配、資源緩衝和換出,這樣一個簡單的"driver"可以大大增強目前的創造能力,以及今後對於Cell的開發的可視化能力。
最後放一張screenshot,利用SDL可以近乎完美使用SIXAXIS進行操縱。