复制D3D11子资源数据

时间:2018-08-16 16:51:27

标签: c++ hook direct3d11

我对Direct3D 11有一个快速问题。我实现了D3D DrawIndexed挂钩,该挂钩可将当前顶点缓冲区从GPU复制到CPU,修改某些数据并将其复制回GPU。

也许我忘记了一些东西,但是即使我不修改任何数据,而只是将数据复制到CPU并返回,结果还是完全损坏了渲染。

代码段为:

m_pDeviceContext->IAGetIndexBuffer(&indexBuffer, &format, &offset);

// copy current region of the index buffer from GPU to CPU
D3D11_BOX box;
box.left = offset + StartIndexLocation * sizeof(unsigned __int16);
box.right = offset + (StartIndexLocation + IndexCount) * sizeof(unsigned __int16);
box.top = box.front = 0;
box.bottom = box.back = 1;
m_pDeviceContext->CopySubresourceRegion(cpuBuffer, 0, 0, 0, 0, indexBuffer, 0, &box);

D3D11_MAPPED_SUBRESOURCE mappedResource = { 0 };
hRes = m_pDeviceContext->Map(cpuBuffer, 0, D3D11_MAP_READ, 0, &mappedResource);
if (hRes == S_OK) {
    // now read all indexes and find the min and max index
    std::vector<unsigned __int16> indexes((unsigned __int16*)mappedResource.pData, (unsigned __int16*)mappedResource.pData + IndexCount);
    auto minmax = std::minmax_element(indexes.begin(), indexes.end());
    m_pDeviceContext->Unmap(cpuBuffer, 0);

    // get the vertex buffer
    UINT stride, offset;
    CComPtr<ID3D11Buffer> vertexBuffer;
    m_pDeviceContext->IAGetVertexBuffers(0, 1, &vertexBuffer, &stride, &offset);

    // copy the region where the min index and max index points to
    box.left = BaseVertexLocation + *minmax.first * stride;
    box.right = BaseVertexLocation + *minmax.second * stride + stride;
    m_pDeviceContext->CopySubresourceRegion(cpuBuffer, 0, 0, 0, 0, vertexBuffer, 0, &box);

    // now I am able to Map/Unmap cpuBuffer and access the data in memory - the data are correct
    // ...

    // copy data back to GPU vertex buffer
    // it results in corrupted rendering - it seems that data are copied to wrong location
    box.right = box.right - box.left;
    box.left = 0;
    m_pDeviceContext->CopySubresourceRegion(vertexBuffer, 0, BaseVertexLocation + *minmax.first * stride, 0, 0, cpuBuffer, 0, &box);

最后一个CopySubResourceRegion是否有任何原因会复制到错误的位置,从而破坏原始的顶点缓冲区?

我假设顶点按索引排序,这就是为什么我在最小值和最大值之间复制区域。

编辑:我测试了以下简单的代码段,即使顶点缓冲区未修改,即使从GPU复制到CPU再复制回GPU也会导致渲染损坏。我启用了D3D调试层,并且在操作过程中未记录任何错误。

box.left = 0;
box.right = desc.ByteWidth;
m_pDeviceContext->CopySubresourceRegion(cpuBuffer, 0, 0, 0, 0, vertexBuffer, 0, &box);
m_pDeviceContext->CopySubresourceRegion(vertexBuffer, 0, 0, 0, 0, cpuBuffer, 0, &box);

0 个答案:

没有答案