I have a vertex buffer that some parts of it need to be updated only once every frame, so I created it as D3D11_USAGE_DYNAMIC
with D3D11_CPU_ACCESS_WRITE
.
Since there are a lot of vertices (around 150k), I don't want to iterate over the entire buffer, only on the parts that were tagged to update.
To do so, I tag each "region" with a DirtyVertexBuffer
flag and then skip untagged regions. To update the buffer I use D3D11_MAP_WRITE_NO_OVERWRITE
. The code is:
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);
My question is: Why is D3D_MAP_WRITE_NO_OVERWRITE
necessary here, instead of D3D_MAP_WRITE_DISCARD
?
If I use the latter, the vertex buffer seems to be "zeroed" (only regions that changed are rendered). MSDN says:
D3D11_MAP_WRITE_DISCARD
Resource is mapped for writing; the previous contents of the resource will be undefined.
D3D11_MAP_WRITE_NO_OVERWRITE
Resource is mapped for writing; the existing contents of the resource cannot be overwritten (see Remarks).
but since I mapped the resource, shouldn't the entire buffer be copied from VRAM to system RAM and then, when I unmap it, go back to the VRAM?
After some thinking, I think I found the answer, can someone confirm this?
When using D3D11_USAGE_DYNAMIC
and D3D11_CPU_ACCESS_WRITE
, the CPU will have access only for writing (ok, that is very clear). Then, on every call to ID3D11DeviceContext::Map
, a temporary buffer (something created with a _aligned_malloc
), which state is undefined.
Then, when using D3D11_MAP_WRITE_DISCARD
, the previous vertex buffer is discarded, meaning that only the parts that changed are kept, since they are present in that temporary buffer.
In other hand, while using D3D11_MAP_WRITE_NO_OVERWRITE
, the previous vertex buffer is kept and only the parts that changed are written.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.