[英]Differences of DirectX11 D3D11_MAP
我有一個需要被只有每幀更新它的某些部分頂點緩沖區,所以我創建它作為D3D11_USAGE_DYNAMIC
與D3D11_CPU_ACCESS_WRITE
。
由於有很多頂點(大約150k),所以我不想遍歷整個緩沖區,而只想遍歷標記為要更新的部分。
為此,我用DirtyVertexBuffer
標志標記每個“區域”,然后跳過未標記的區域。 要更新緩沖區,我使用D3D11_MAP_WRITE_NO_OVERWRITE
。 代碼是:
VertexType *vertices;
D3D11_MAPPED_SUBRESOURCE mappedResource;
Vertex *vertex;
HRESULT result;
result = context->Map(m_vertexBuffer, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &mappedResource);
if (FAILED(result))
return;
vertices = (DirectX::VertexPositionNormalTexture*)mappedResource.pData;
for (auto &material : materials) {
if ((material.dirty & Material::Dirty::VertexBuffer) == 0) continue;
material.dirty &= ~Material::Dirty::VertexBuffer;
// Update vertex data
}
// release the access to the buffer
context->Unmap(m_vertexBuffer, 0);
我的問題是:為什么D3D_MAP_WRITE_NO_OVERWRITE
必要在這里,而不是D3D_MAP_WRITE_DISCARD
?
如果使用后者,則頂點緩沖區似乎被“清零”(僅呈現已更改的區域)。 MSDN說:
D3D11_MAP_WRITE_DISCARD
資源被映射用於寫入; 資源的先前內容將是不確定的。
D3D11_MAP_WRITE_NO_OVERWRITE
資源被映射用於寫入; 資源的現有內容不能被覆蓋(請參閱備注)。
但是由於我已經映射了資源,難道不應該將整個緩沖區從VRAM復制到系統RAM,然后在取消映射時又回到VRAM嗎?
經過一番思考,我想我找到了答案,有人可以確認嗎?
當使用D3D11_USAGE_DYNAMIC
和D3D11_CPU_ACCESS_WRITE
,CPU將只能進行寫操作(很清楚)。 然后,在每次調用ID3D11DeviceContext::Map
,都會使用一個臨時緩沖區(使用_aligned_malloc
創建的_aligned_malloc
),該緩沖區的狀態未定義。
然后,當使用D3D11_MAP_WRITE_DISCARD
,將丟棄先前的頂點緩沖區,這意味着僅保留已更改的部分,因為它們存在於該臨時緩沖區中。
另一方面,在使用D3D11_MAP_WRITE_NO_OVERWRITE
,將保留先前的頂點緩沖區,並且僅寫入已更改的部分。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.