如果Shader程式能像CPU端的程式允許逐行偵錯,那就太棒了
PIX偵錯
D3D12 (PC/XBOX)是主要受惠平台,不支援Vulkan及GL系列
先決條件 - Shader編譯必須使用偵錯flag,不然會缺乏偵錯符號
- 如果是使用D3DCompile()之類的函式,下達D3DCOMPILE_DEBUG (/Zi) + D3DCOMPILE_SKIP_OPTIMIZATION (/Od)即可,兩個缺一個都不行,因為不下/Od的話就是預設/O3 (最佳化)
- 那如果是透過外部執行檔(dxc.exe)來編譯,下達 -Zi -Od即可
那如果非要偵錯/O3最佳化過的shader呢?
也不是沒有辦法,產生PDB檔案即可 (編譯時還是需要/Zi)
- 透過dxc.exe編譯的話,下-Fd指令、後面接著一個檔案名稱或路徑,PDB資訊就會匯出到那個檔案、或者自動在指定的路徑生成檔案。
- 使用D3DCompile的話,會比較麻煩一點,可參考這個cpp,行261~283的部分
然後回到PIX,把對應的PDB設定上去就行了 (點擊 here 選擇檔案)
擷取一張GPU Capture並按下開始分析之後,可以點擊要偵錯的Shader:
TA,點開來之後,就能看到豐富的資訊了
偵錯Pixel Shader
由於Pixel最終輸出會在Output Merger Stage (OM),所以先回到RTV 0那邊
選擇想要偵錯的像素,按下右邊的"Debug Pixel"
就可以逐行偵錯啦~
有點visual studio的感覺了,有自動變數可以看,點擊"constants"分頁也可以看你的constant buffer:
即時修改shader程式並套用
透過Debug那個分頁的編輯器來做就行了,修改後按下F6套用,例如:
修改過的shader會有鉛筆圖案提醒
這時再回到OM那邊看,確實變成紅色啦:
偵錯Vertex Shader
在VS Output那邊右鍵一個三角形,然後選其中一個頂點Debug即可,會跳到你vertex shader的進入點:
偵錯Compute Shader
雖然也能看得到輸出的目標 (UAV Texture),但沒有辦法像PS一樣選擇一個像素來debug pixel
必須直接從shader那邊偵錯
不過至少,可以在左上角設定Thread ID,指定想要偵錯的部分,記住不要超過numthreads的定義就好
偵錯光追Shader
主要是在DispatchRays()這個呼叫
偵錯頁面就不再貼了,和Compute shader很像,可以指定thread ID
而主頁面這邊的DXR Invocations可以看到哪些位置有hit、哪些miss
小缺點無法逐步執行hit shader跟miss shader,有點可惜
------------------------------------------------------------------------------------------------------
大致上就寫到這~
不過這些還只是冰山一角而已
越摸會越發現這個工具的強大之處!