簡體   English   中英

DirectX11 D3D11_MAP的差異

[英]Differences of DirectX11 D3D11_MAP

我有一個需要被只有每幀更新它的某些部分頂點緩沖區,所以我創建它作為D3D11_USAGE_DYNAMICD3D11_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_DYNAMICD3D11_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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM