c++ - D3D11 : E_OUTOFMEMORY when mapping vertex buffer

标签 c++ unity3d directx

在我的 Unity 游戏中,我必须通过 native 代码修改大量图形资源,如纹理和顶点缓冲区,以保持良好的性能。

当代码在很短的时间内多次调用 ID3D11ImmediateContext::Map 时(我的意思是非常短 - 从并行运行的不同线程调用),问题就开始了。映射成功与否没有规律可循。方法调用看起来像

ID3D11DeviceContext* sU_m_D_context;


void* BeginModifyingVBO(void* bufferHandle)
{
    ID3D11Buffer* d3dbuf = static_cast<ID3D11Buffer*>(bufferHandle);

    D3D11_MAPPED_SUBRESOURCE mapped;
    HRESULT res = sU_m_D_context->Map(d3dbuf, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped);

    assert(mapped.pData);

    return mapped.pData;
}


void FinishModifyingVBO(void* bufferHandle)
{
    ID3D11Buffer* d3dbuf = static_cast<ID3D11Buffer*>(bufferHandle);

    sU_m_D_context->Unmap(d3dbuf, 0);
}



std::mutex sU_m_D_locker;

void Mesh::ApplyBuffer()
{
    sU_m_D_locker.lock();

    // map buffer
    VBVertex* mappedBuffer = (VBVertex*)BeginModifyingVBO(this->currentBufferPtr);

    memcpy(mappedBuffer, this->mainBuffer, this->mainBufferLength * sizeof(VBVertex));

    // unmap buffer
    FinishModifyingVBO(this->currentBufferPtr);

    sU_m_D_locker.unlock();

    this->markedAsChanged = false;
}

其中 d3dbuf 是动态顶点缓冲区。我不知道为什么,但有时结果是 E_OUTOFMEMORY,尽管有很多空闲内存。我尝试用互斥锁包围代码 - 没有效果。

这真的是内存问题还是不太明显的问题?

最佳答案

没有一个设备上下文方法是线程安全的。如果您要从多个线程使用它们,您将需要手动同步所有 调用,或者使用多个(延迟的)上下文,每个线程一个。参见 Introduction to Multithreading in Direct3D 11 .

错误检查也应该更好:您需要始终检查返回的 HRESULT 值,因为在失败的情况下,像 assert(mapped.pData); 之类的东西可能仍然会成功。

关于c++ - D3D11 : E_OUTOFMEMORY when mapping vertex buffer,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50232163/

相关文章:

c++ - 编码(marshal)处理 - 将 std::vector<char> 转换为 string^ 反之亦然

c++ - 如何将键盘事件发送到 Windows 中的各种应用程序?

c++ - 如何破解 ffmpeg 以将 I 帧视为关键帧?

c# - 用鼠标绘制线渲染器然后从起点缩短它(飞行控制样式)

ios - 为什么 Unity iOS 应用程序如此庞大?

directx - 使用 DirectX11 像素着色器在 GPU 中从 DXGI_FORMAT_B8G8R8A8_UNORM 到 NV12 的颜色转换

C++从字符串中间提取数字

c# - Collider 并不总是检测到 OnTriggerEnter

c# - WinForms 中的 3D?

c++ - 在 ID3DBlob 中初始化 PS 的 DirectX11 CreatePixelShader 中出现访问冲突