简体   繁体   English

DirectX11 D3D11_MAP的差异

[英]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 . 我有一个需要被只有每帧更新它的某些部分顶点缓冲区,所以我创建它作为D3D11_USAGE_DYNAMICD3D11_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. 由于有很多顶点(大约150k),所以我不想遍历整个缓冲区,而只想遍历标记为要更新的部分。

To do so, I tag each "region" with a DirtyVertexBuffer flag and then skip untagged regions. 为此,我用DirtyVertexBuffer标志标记每个“区域”,然后跳过未标记的区域。 To update the buffer I use D3D11_MAP_WRITE_NO_OVERWRITE . 要更新缓冲区,我使用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 ? 我的问题是:为什么D3D_MAP_WRITE_NO_OVERWRITE必要在这里,而不是D3D_MAP_WRITE_DISCARD

If I use the latter, the vertex buffer seems to be "zeroed" (only regions that changed are rendered). 如果使用后者,则顶点缓冲区似乎被“清零”(仅呈现已更改的区域)。 MSDN says: MSDN说:

D3D11_MAP_WRITE_DISCARD D3D11_MAP_WRITE_DISCARD

Resource is mapped for writing; 资源被映射用于写入; the previous contents of the resource will be undefined. 资源的先前内容将是不确定的。

D3D11_MAP_WRITE_NO_OVERWRITE 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? 但是由于我已经映射了资源,难道不应该将整个缓冲区从VRAM复制到系统RAM,然后在取消映射时又回到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). 当使用D3D11_USAGE_DYNAMICD3D11_CPU_ACCESS_WRITE ,CPU将只能进行写操作(很清楚)。 Then, on every call to ID3D11DeviceContext::Map , a temporary buffer (something created with a _aligned_malloc ), which state is undefined. 然后,在每次调用ID3D11DeviceContext::Map ,都会使用一个临时缓冲区(使用_aligned_malloc创建的_aligned_malloc ),该缓冲区的状态未定义。

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. 然后,当使用D3D11_MAP_WRITE_DISCARD ,将丢弃先前的顶点缓冲区,这意味着仅保留已更改的部分,因为它们存在于该临时缓冲区中。

In other hand, while using D3D11_MAP_WRITE_NO_OVERWRITE , the previous vertex buffer is kept and only the parts that changed are written. 另一方面,在使用D3D11_MAP_WRITE_NO_OVERWRITE ,将保留先前的顶点缓冲区,并且仅写入已更改的部分。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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