简体   繁体   中英

Differences of DirectX11 D3D11_MAP

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM