Question

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?

Was it helpful?

Solution

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top