RenderDoc(src,doc,ue4 doc,ue4文檔)是一個獨立的開源圖形調試器,通過采集和檢查GPU上運行的單個幀,來定位圖形bug和優化性能
RenderDoc支持任何在Win7、Win10、Linux或Android上使用Vulkan、D3D11、D3D12、OpenGL3.2+ & OpenGL ES2.0-3.2的應用程序
市面上大部分Android平台的GPU都是通用的,因此,RenderDoc作為通用的圖形調試器,對這些GPU都可以進行截幀
而不像高通和mali的截幀工具那樣,需要區分GPU(高通GPU只能snapdragon截幀工具,mali的只能用Mali Graphics Debugger)
RenderDoc允許開發者編寫python腳本來快速發現當前幀繪制中存在的問題、提高截幀分析效率和對使用的資源統計分析(Drawcall與紋理、shader program 信息的統計與分組等)
RenderDocPlugin(wiki,src)是UE4引擎中集成的一個插件(代碼在:Plugins\Developer\RenderDocPlugin),方便UE4拉起和調用RenderDoc工具
環境設置
① 安裝RenderDoc工具(缺省會安裝到C:\Program Files\RenderDoc)
② 在UE4編輯器的Plugins面板中搜索RenderDocPlugin,並勾選Enabled啟用該插件
③ 按照提示,重啟UE4編輯器,此時C:\Program Files\RenderDoc\renderdoc.dll會被加載到編輯器進程
④ 設置RenderDoc:在UE4編輯器的Project Settings面板中Plugins -- RenderDoc標簽中
這些設置項可在Output Log面板的Cmd(輸出到log)和游戲控制台(輸出到控制台窗口)中執行命令進行查看和修改
FrameCaptureSettings下的選項勾選得越多,抓取的幀中數據就越豐富,文件也越大,也會使得截取和分析幀的時間更久
renderdoc.BinaryPath // 查看RenderDoc的安裝路徑
renderdoc.BinaryPath "C:\Program Files\RenderDoc" // 設置RenderDoc的安裝路徑為C:\Program Files\RenderDoc
renderdoc.CaptureAllActivity 1 // 勾選CaptureAllActivity(獲取編輯器所有viewport和窗口的渲染數據,而不僅僅是當前viewport)
renderdoc.CaptureCallstacks // 查看CaptureCallstacks(獲取圖形API的調用堆棧)是否勾選
renderdoc.EnableCrashHandler 0 // 取消勾選EnableCrashHandler(截幀崩潰時是否使用RenderDoc的crash handler)
renderdoc.ReferenceAllResources // 查看ReferenceAllResources(獲取所有mesh、材質,紋理等渲染資源,開啟該選項會導致幀文件很大)是否勾選
renderdoc.SaveAllInitials 1 // 勾選SaveAllInitials(獲取所有mesh、材質,紋理等渲染資源的初始狀態,開啟該選項會導致幀文件很大)
renderdoc.ShowHelpOnStartup // 查看ShowHelpOnStartup(啟動編輯器時是否彈出RenderDoc的幫助對話框)是否勾選
⑤ 截幀后Shader只能看到匯編代碼片段,若想看到源代碼,需要打開Engine\Config\ConsoleVariables.ini配置文件,取消以下兩行的注釋
r.Shaders.Optimize=0 r.Shaders.KeepDebugInfo=1
⑥ UE4為了方便對幀的繪制過程進行分析,代碼中插入了很多Event調用,用來說明后面的渲染行為
可在控制台中執行ToggleDrawEvents命令來打開和關閉Event的調用
在UE4中插入Event主要是通過調用SCOPED_DRAW_EVENT、SCOPED_CONDITIONAL_DRAW_EVENT等宏來構造一個TDrawEvent<TRHICmdList>對象並調用Start方法,然后在對象析構時調用其Stop方法
相關的宏和代碼在:RealtimeGPUProfiler.h RealtimeGPUProfiler.cpp
Start / Stop方法會調用不同渲染API的RHI的PushEvent / PopEvent方法,由這些PushEvent來實現Event標記的添加。
如:Dx中會調用D3DPERF_BeginEvent / D3DPERF_EndEvent兩個API來實現;OGL中會調用glPushGroupMarketEXT / glPopGroupMarketEXT兩個API來實現。
編輯器截幀
編輯器中主要是通過RenderDocPlugin插件調用void FRenderDocPluginModule::CaptureFrame()函數來截幀,然后拉起RenderDoc進程
方法一:在編輯器非Play狀態下,點擊右上角按鈕進行截幀;Play狀態下,先Eject后,再點擊右上角按鈕進行截幀
方法二:通過renderdoc.CaptureFrame命令來截幀(支持編輯器和單機)
方法三:啟動RenderDoc,點擊菜單:File -- Attach to Running Instance
點擊Connect to App按鈕,讓RenderDoc和目標進程建立會話,然后點擊會話面板上的Capture Frame(s) Immediately按鈕進行截幀
注1:截取的幀會臨時保存在項目工程的Saved\RenderDocCaptures目錄中,截取成功后,會使用RenderDoc打開該臨時幀文件,若需要保留該文件需要手動進行保存
注2:RenderDoc的log文件在%Temp%\RenderDoc目錄中
PC客戶端截幀
方法一:從RenderDoc中拉起目標進程
① 啟動RenderDoc,點擊菜單:File -- Launch Application,然后填寫exe可執行路徑(注:如果游戲進程是被登錄器等作為子進程拉起,需要勾選"Capture Child Processes")
② Launch啟動游戲后,然后按F12進行截幀
方法二: 在啟動初期(任何圖形API都沒有調用的情況下),將RenderDoc注入到目標游戲進程
① 啟動RenderDoc,點擊菜單:File -- Inject into Process,搜索並選中目標進程,然后點擊Inject按鈕進行注入
為了抓啟動初期這個時間點,可以使用windbg調試運行進程(啟動后會立即中斷到windbg中),然后在RenderDoc中准備好后,在windbg中F5運行后,在RenderDoc中立即進行Inject
另外,對於非shipping版的游戲進程,可以帶上-WaitForDebugger啟動,這樣游戲會一直等待調試器Attach,然后在RenderDoc中Inject,最后拿windbg或vs Attach游戲並讓其繼續運行
② Launch啟動游戲后,然后按F12進行截幀
方法三:使用global process hooking來建立與RenderDoc之間的會話
① 在RenderDoc菜單Tools -- Settings面板的General標簽下勾選"Allow global process hooking - be careful"
② 點擊菜單:File -- Launch Application,填寫exe可執行路徑,然后點擊"Enable Global Hook"按鈕,讓hook鈎子對目標路徑進行監聽,一旦有進程啟動自動完成注入
③ 按照正常流程啟動游戲后,然后按F12進行截幀
注1:截取的幀缺省會保存在%Temp%\RenderDoc目錄中(可在RenderDoc菜單Tools -- Settings面板的General標簽下的Directory for temporary capture files中指定路徑)
注2:RenderDoc的log文件在%Temp%\RenderDoc目錄中
注3:PC客戶端的截幀方法同樣適合編輯器
Android截幀
1. 目標手機在開發者選項中打開如下這些開關
2. APP需可調試才能進行截幀,即App中AndroidManifest.xml的application標簽里必須包含android:debuggable="true"屬性
① 啟動RenderDoc的Server端並建立連接
點擊目標手機 1: Xiaomi Mi 10 (Offline),會啟動RenderDoc的Server端,並與PC上的RenderDoc客戶端建立了連接
RenderDoc的Server端界面如下:
注1:如果首次在Android手機上使用RenderDoc,會根據當前手機cpu架構,來自動安裝org.renderdoc.renderdoccmd.arm64.apk或org.renderdoc.renderdoccmd.arm32.apk
注2:如果當前手機在開發者選項未開啟“USB安裝”,可將apk拷貝到手機上手動安裝
安裝后的所在的android目錄
app目錄:/data/app/org.renderdoc.renderdoccmd.arm64
data目錄:/sdcard/Android/data/org.renderdoc.renderdoccmd.arm64
log文件:/sdcard/Android/data/org.renderdoc.renderdoccmd.arm64/files/RenderDoc/RenderDoc_2020.08.03_11.57.01.log
renderdoc.conf文件:/sdcard/Android/data/org.renderdoc.renderdoccmd.arm64/files/renderdoc.conf
注:點擊菜單“File” -- “Attach to Running Instance”彈出的Remote Host Manager面板中,可以看到RenderDoc的Server端已經在Xiaomi Mi 10手機上運行起來並與PC上的RenderDoc客戶端建立了連接
② 啟用手機要截幀的App
注1:注入成功后,游戲界面的頂端會顯示一些文字
注2:另外,可以在Remote Host Manager里面看到被RenderDoc的Server注入的進程列表
③ 點擊“Capture Frame(s) Immediately”按鈕來截幀
注1:截取的幀會保存在手機的/sdcard/Android/data/com.tencent.mf.fps1/files/RenderDoc目錄中,在關閉RenderDoc之前需要將它們保存到PC的目錄中
注2:RenderDoc的RenderDoc_YYYY.MM.DD_hh.mm.ss.log在%Temp%\RenderDoc目錄中
注3:RenderDoc_app_YYYY.MM.DD_hh.mm.ss.log在/sdcard/Android/data/com.tencent.mf.fps1/files/RenderDoc目錄中
注4:renderdoc.conf文件:/sdcard/Android/data/com.tencent.mf.fps1/files/renderdoc.conf
最后,無論編輯器、PC客戶端還是Android機,與RenderDoc建立會話后,后續也可以通過點擊會話面板上的Capture Frame(s) Immediately按鈕來快捷截幀