使用 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
沒有留言:
張貼留言