cg profiles,什麼是profiles,以及如何使用CGC編譯Cg語言

計算機只能理解和執行由0、1序列(電壓序列)構成的機器語言,所以彙編語言 和高級語言程序都需要進行翻譯才能被計算機所理解,擔負這一任務的程序稱爲語言處理程序,通常也被稱爲編譯程序。例如C或者C++ 編寫的程序,需要首先編譯成可執行文件(.exe文件),然後才能在GPU上運行,且一旦編譯後,除非改變程序代碼,否則不需要重新編譯,這種方式稱爲靜 態編譯(static coompilation)。靜態編譯最重要的特徵是:一旦編譯爲可執行文件,在可執行文件運行期間不再需要源碼信息。而動態編譯(dynamic compilation)與之相反,編譯程序和源碼都要參與到程序的運行過程中。


    Cg語言通常採用動態編譯的方式,即,在宿主程序運行時利用Cg運行庫( Cg Runtime library)動態編譯Cg代碼,使用動態編譯的方式,可以將Cg程序當作一個腳本,隨時修改隨時運行,節省大量的時間,在OGRE圖形引擎中就是採用 這樣的方法。Cg語言同樣支持靜態編譯方式,即,Cg源碼編譯成彙編代碼後,這部分目標代碼被鏈接到宿主程序最後的可 執行程序中。使用靜態編譯的好處是隻要發佈可執行文件即可,源碼不會被公開。


    Cg編譯器首先將Cg程序翻譯成可被圖形API(OpenGL和Direct3D)所接受的形式,然後應用程序使用適當的OpenGL和Direct3D 命令將翻譯後的Cg程序傳遞給圖形處理器,OpenGL和Direct3D驅動程序最後把它翻譯成圖形處理器所需要的硬件可執行格式。NVIDIA提供的 Cg編譯器爲cgc.exe。


    Cg程序的編譯不但依賴於宿主程序所使用的三維編程接口,而且依賴於圖形硬件環境,因爲圖形硬件自身的限制,不一定支持某種Cg語句,例如,如果你所使用 的GPU並不支持循環控制指令,那麼在Cg程序中編寫的循環控制語句將無法通過編譯。被特定的圖形硬件環境或AIP所支持的Cg語言子集,被稱爲Cg Profiles。需要注意的是: profile分爲頂點程序的profile和片段程序的profile,這是因爲頂點着色器和片段着色器原本就不是工作在同一個硬件。


    Cg Profiles是Cg語言的重要組成部分,在使用Cg語言編寫着色程序時,首先要考慮的一點就是“當前的圖形硬件環境支持那個Cg Profile”,這直接關係到您所編寫的着色程序是否可以在當前的圖形硬件上運行。


4.3.1 CGC編譯命令 
 
 
    如果Cg Toolkit安裝正確,在NVIDIA Corporation/Cg/bin文件夾下會看到cgc.exe文件。首先打開命令行窗口,輸入“cgc –h”(引號不用輸入),如果安裝正確,則會出現圖 12所示的提示信息。
Cg程序編譯的命令形式爲:


                                        cgc [options] file

    [options]表示可選配置項,file表示Cg程序文件名。可選配置項包括編譯時選擇使用的profile、着色程序的入口函數名稱,以及着色程序文件名。比較典型的編譯方式是:

        cgc –profile glslv –entry main_v test.cg


    -profile是profile配置項名;glslv是當前所使用的profile名稱;-entry着色程序的入口函數名稱配置項;main_v是頂 點着色程序的入口函數名;test.cg是當前的着色程序文件名。編譯器指定的着色程序入口函數名默認爲main,通常爲了將頂點/片段着色程序入口函數 名區別開來,而並不使用默認名稱。在下面所有的例子中,main_v表示頂點着色程序入口函數名,main_f表示片段着色程序入口函數名。


 需要強調如下幾點:
1.    着色程序分爲頂點着色程序和片段着色程序,profile也分爲頂點profile和片段profile,所以編譯頂點着色程序時必須選用當前圖形硬件支 持的頂點profile,同理,編譯片段着色程序時必須選用當前圖形硬件支持的片段profile。下面所示使用片段profile fp20編譯頂點着色程序是不對的。
 

cgc –profile fp20 glslv –entry main_v test.cg

 


    所以,如果您的着色程序中同時存在頂點着色程序和片段着色程序,在編譯前切記分別選擇各自的profile。
2.    選擇profile 如果不被當前圖形硬件所支持,編譯時會出現錯誤。被編譯的着色程序中,如果存在不被所選擇的profile所支持的語句,則編譯時會出現錯誤。例 如,tex2D(sampler2D tex , float3 sz ,float2 dsdx , float2 dsdy )不被fp20所支持,如果你的編譯形式爲:
 

cgc –profile fp20 –entry main_f test.cg

 


    則會出現錯誤提示信息:
    error C3004: function “tex2D” not supported in this profile。
    改用fp30,進行編譯就會通過。
 

cgc –profile fp30 –entry main_f test.cg

 


    尤其需要注意的是,循環語句for,while只被vs_2_x, vp30, vp40,fp40等少量的profiles所支持。在CgUsersManual中提到:


“In other profiles, for and while loops may only be used if the compiler can fully unroll them (that is, if the compiler can determine the iteration count at compile time)”,


    這句話的意思是“在其他的profiles中,for和while循環只有當確切的知道循環次數時才能被使用”。但經過試驗,通常在其他profiles編譯含義for,while語句時會出現錯誤提示信息:
            error c6003:instruction limit of exceeded……
      

    因此,如果沒有確切的把握,不要在低級的profiles中使用循環控制語句。


3.    被編譯的着色程序文件名必須加上.cg後綴。如果沒有加後綴,寫成如下的形式:
 

cgc –profile glslv –entry main_v test

 


    則會出現錯誤提示信息:fatal error C9999: Can’t open file:test


4.    另外cgc還提供一種比較特殊的功能:就是將Cg語言所寫的着色程序轉換爲使用GLSL或HLSL所編寫的程序。例如,將代碼寫成如下形式,表示編譯文件 test.cg中的頂點着色程序,入口函數名爲main_v,並將頂點着色程序轉換爲glsl程序,然後保存成文件direct.glsl。

cgc –profile glslv –o direct.glsl –entry main_v  test.cg

 


5.    還有一個非常隱蔽的編譯情況是:如果着色程序中的某些變量並沒有爲最終的輸出做出貢獻,則編譯時會將該部分代碼忽略(會檢查語法錯誤,但並不編譯成彙編代 碼)。通常這一點不會造成太大的影響,但是如果這些變量剛好是從外部宿主程序中傳入的變量,並且在着色程序中沒有被使用,則宿主程序傳入變量的接口函數可 能會報錯“找不到該變量”。這種情況比較少遇到,但並非不存在,且一旦遇上問題的原因難以查明,故而我在此寫上,希望可以有所幫助。


    基於GPU編程,最令人崩潰的一點是:無法跟蹤調試着色程序!這一點目前還沒有解決方案出現。對於一個着色程序,語法錯誤可以通過編譯器發現,而代碼邏輯 錯誤只能是人爲查找。常會遇到這種情況,一段代碼編譯通過,但是運行結果不在預期之中,如果是C++/JAVA程序就可以進行跟蹤調試,但是着色程序不能 被調試,只能一行代碼一行代碼的進行邏輯分析。


    所以,編譯着色程序要非常注意邏輯的嚴密性,和代碼的組織結構,這是爲了更加容易的暴露錯誤和維護代碼。一個良好的習慣是加入註釋語句。


4.4 CG Profiles


    Profile在英文中的意思是“側面、輪廓”, 文獻[1]第三頁寫到:A Cg profile defines a subset of the full Cg language that is supported on a particular hardware platform or API(CgUsersManual 21頁)。

   

    即一個Cg profile定義了一個“被特定圖形硬件或API所支持的Cg語言子集”,從前面的分析我們可以知道,任意一種shader language都是基於可編程圖形硬件的(寄存器、指令集等),這也就意味着:不同的圖形硬件對應着不同的功能子集。Profile按照功能可以劃分爲 頂點Profile和片斷Profile,而頂點profile和片段profile又基於OpenGL和DirectX的不同版本或擴展,劃分爲各種版 本。從某種意義上而言,OpenGL和DirectX的發展歷程成就了Cg語言。


當前Cg compiler所支持的profiles有:


    OpenGL ARB vertex programs
Runtime profile: CG_PROFILE_ARBVP1
Compiler option: _profile arbvp1
    OpenGL ARB fragment programs
Runtime profile: CG_PROFILE_ARBFP1
Compiler option: _profile arbfp1
    OpenGL NV40 vertex programs
Runtime profile: CG_PROFILE_VP40
Compiler option: _profile vp40
    OpenGL NV40 fragment programs
 Runtime profile: CG_PROFILE_FP40
Compiler option: _profile fp40
    OpenGL NV30 vertex programs
Runtime profile: CG_PROFILE_VP30
Compiler option: _profile vp30
    OpenGL NV30 fragment programs
 Runtime profile: CG_PROFILE_FP30
Compiler option: _profile fp30
    OpenGL NV2X vertex programs
Runtime profile: CG_PROFILE_VP20
Compiler option: _profile vp20
    OpenGL NV2X fragment programs
 Runtime profile: CG_PROFILE_FP20
Compiler option: _profile fp20
    DirectX 9 vertex shaders
Runtime profiles: CG_PROFILE_VS_2_X
               CG_PROFILE_VS_2_0
Compiler options:-profile vs_2_x
               -profile vs_2_0
    DirectX 9 pixel shaders
Runtime profiles: CG_PROFILE_PS_2_X
              CG_PROFILE_PS_2_0
Compiler options: -profile ps_2_x
                  -profile ps_2_0
    DirectX 8 vertex shaders
Runtime profiles: CG_PROFILE_VS_1_1
Compiler options:-profile vs_1_1
    DirectX 8 pixel shaders
Runtime profiles: CG_PROFILE_PS_1_3
              CG_PROFILE_PS_1_2
CG_PROFILE_PS_1_1
Compiler options: -profile ps_1_3
                  -profile ps_1_2
                  -profile ps_1_2
                  -profile ps_1_1

附:截止到2009年10月,出現的profile已經不止上面這些種類了,尤其是現在DirectX已經出到了11的版本。上面的profile是可以在當前大多數機器上使用的。

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