最近想給引擎加乙個準確定位各渲染模組消耗的功能,因此翻閱資料,自己實現了乙個簡短的gpu時鐘。在引擎中整合如下:
值得注意的是,使用硬體查詢後,回讀顯示卡中的值會導致cpu/gpu的等待,因而會損失一些時間。因此這個功能只能算作開發時的除錯工具之用(真正產品不會有人關心gpu時間...)
我昨晚花了少量時間做了乙個簡單的實現,現在在這裡貼出來,基本是全部**,摘回去可直接使用~ 如有設計上的疏忽還請見諒!
改計時器使用十分方便,整合好之後,測量每個階段的時間,只需補上3條**,即可~
d3d文件中提到了有這樣乙個硬體查詢型別:d3dquerytype_timestamp
改硬體查詢會在查詢的地方,返回乙個uint64型別的當前的gpu tick值,因此,可以使用這個來取得每個模組的開始和結束tick,在每幀結束的時候getdata,計算出每乙個階段的耗時
此外,d3dquerytype_timestampfreq這個查詢型別,可以返回時鐘頻率,這時我們便可以通過 (結束tick - 開始tick) / 時鐘頻率 來得出gpu中這一段的耗時了。
因此,我們可以實現乙個簡單的gputimer類:
class gkgputimer很簡單float gettime()
//init d3dquery
void init(idirect3ddevice9* pdevice);
void destroy();
//mark the timestamp
void start();
void stop();
//get timestep when finish a frame
void update();
private:
idirect3dquery9* m_peventstart;
idirect3dquery9* m_peventstop;
idirect3dquery9* m_peventfreq;
float m_felapsedtime;
bool m_skip; // judge if should get data
};
一對init(),destroy(),在裝置建立和丟失的時候對d3d物件進行重建和釋放
一對start(),stop(),在需要測量的**段兩邊放置,分別取得開始和結束的timestamp和freq
乙個update(),在每幀結束的時候,從gpu取得測量值,計算之後儲存於m_felapsedtime中
m_skip用於判斷是否應該從gpu取值,因為由於渲染流程的改變,有些計時器可能在一些情況下並不會測量。
下面看一下簡單的實現
(注: genv->pcvmanager->r_profilegpu == 1 是我引擎中的引數,為1時表示開啟gpu計時)
gkgputimer::gkgputimer()最後,就是整合到渲染流程中了,我實現了幾個簡單函式,在渲染流程的恰當階段呼叫即可void gkgputimer::init(idirect3ddevice9* pdevice)
void gkgputimer::destroy()
void gkgputimer::start()
m_skip = false;
}void gkgputimer::stop()
m_skip = false;
}void gkgputimer::update()
else
}m_skip = true;
}
(注:ms_gputimers為我渲染器的乙個靜態成員)
typedef std::mapgkgputimermap;
//使用了map結構,因此在設定計時器的時候就特別方便了,比如:build gpu timers when init renderer
void gkrendererd3d9::buildgputimers()
//init gpu timers when device reset
void gkrendererd3d9::initgputimers(idirect3ddevice9* pdevice)}//
release gpu timers when device lost
void gkrendererd3d9::destorygputimers()}//
getdata from gpu when a frame end
void gkrendererd3d9::updategputimers()}}
gkrendererd3d9::ms_gputimers[l"ssao
"].start();
//ssao render process...
gkrendererd3d9::ms_gputimers[l"新增完畢後,在想要拿時間的地方,ssao
"].stop();
gkrendererd3d9::ms_gputimers[l"即可。ssao
"].gettime()
自此,gputimer全部完成,用了不到200行**。
使用上,就是
ms_gputimers.insert( gkgputimermap::value_type( l"三條**,當然如果加上一些巨集技巧,可以更加工程化一些~測量名", gkgputimer()) );
gkrendererd3d9::ms_gputimers[l"
測量名"].start();
gkrendererd3d9::ms_gputimers[l"
測量名"].stop();
利用D3DQUERY實現簡單的GPU計時器
最近想給引擎加乙個準確定位各渲染模組消耗的功能,因此翻閱資料,自己實現了乙個簡短的gpu時鐘。在引擎中整合如下 值得注意的是,使用硬體查詢後,回讀顯示卡中的值會導致cpu gpu的等待,因而會損失一些時間。因此這個功能只能算作開發時的除錯工具之用 真正產品不會有人關心gpu時間.我昨晚花了少量時間做...
D3的簡單語法
選擇 選擇單個元素用 select 選擇第乙個元素 選擇多個元素用 selectall 選擇 插入 刪除元素 insert 在選擇集前面插入元素 d3.select body insert p moon remove 刪除元素 d3.select moon remove 文字屬性樣式操作 資料連線 ...
用unity3d實現簡單chat對話
本文是解釋鷹大的多人聯網例項example1思路,由於自己理解的問題,不足地方請斧正。華麗的分割線 主線流程 1.awake 設計遊戲視窗 獲取玩家名字 function awake 2.ongui 判斷是否顯示聊天視窗建立聊天視窗處理回車 獲取輸入焦點 function ongui gui.ski...