2020年1月27日 星期一

使用 Map() 與 UpdateSubresource() 更新 Constant buffer 的差異

使用 Map() 與 UpdateSubresource() 更新 Constant buffer 的差異

前言

  在 Direct3D11 裡提供兩種更新 Constant buffer 資料的方法,分別是 Map() 與 UpdateSubresource() ,在 Direct3D11 的官方範例中的入門範例( Direct3D11Tutorials )裡採用的是 UpdateSubresource() ,但其它範例卻用 Map() 來更新,到底兩者的差異在哪?在此把學習的過程做個紀錄。

內容

  Map() 與 UpdateSubresource()  兩者在 Create 的時候有些不一樣, Map() 的 Usage 使用的是 D3D11_USAGE_DYNAMIC ,而 UpdateSubresource() 的 Usage 使用的是 D3D11_USAGE_DEFAULT ,由於 Usage 無法在 Create 後改變,所以在 Create 時其實就確定了更新的方法。就 [ Windows dev center ] D3D11_USAGE enumeration 裡對 D3D11_USAGE_DYNAMIC 的描述非常符合 Constant buffer 的情形(  CPU 寫 GPU 讀  ) ,那 UpdateSubresource() 又是怎麼回事?

  這兩者的差異我並沒有真的去測試差異,但就我所知,GPU讀  D3D11_USAGE_DEFAULT 的速度比 D3D11_USAGE_DYNAMIC 快,但這是在不考慮寫資料的狀況下,如果同時考慮 CPU 寫與 GPU 讀的話,請使用  D3D11_USAGE_DYNAMIC ,但是如果只是偶而更新資料的話就可以使用 D3D11_USAGE_DEFAULT 。可是 Constant buffer 很難保證它不會常常更新,所以適合的更新方法其實是 Map() , UpdateSubresource() 其實是不適合的更新方式,或者是說 UpdateSubresource() 並不適合用在 Constant buffer ,而且之後的 Direct3D12 也是採用 Map() 的方式更新 Constant buffer ,所以全部使用 Map() 的方法是較好的做法,把 UpdateSubresource() 視為優化的方法(確定不常更新)。

參考資料

[ gamedev.net ] Constant buffer UpdateSubResource vs Map
[ Windows dev center ] D3D11_USAGE enumeration

沒有留言:

張貼留言