D3D11:映射顶点缓冲区时E_OUTOFMEMORY
D3D11: E_OUTOFMEMORY when mapping vertex buffer
在我的Unity游戏中,我必须通过本机代码修改许多图形资源,如纹理和顶点缓冲区,以保持良好的性能。
当代码在很短的时间内多次调用 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,尽管有很多空闲内存。我试图用互斥体包围代码 - 没有效果。
这真的是记忆问题还是不太明显?
没有一个设备上下文方法是线程安全的。如果要从多个线程使用它们,则需要手动同步所有调用,或使用多个(延迟(上下文,每个线程一个。请参阅 Direct3D 11 中的多线程处理简介。
此外,错误检查应该更好:您需要始终检查返回的HRESULT
值,因为在失败的情况下,像assert(mapped.pData);
这样的东西仍然可能成功。
相关文章:
- C++字符*缓冲区的大小
- 为什么msgrcv()将垃圾字符馈送到缓冲区
- 使用动态分配的数组会导致代码分析发出虚假的C6386缓冲区溢出警告
- ostream过载时的缓冲区冲洗
- C++中的高效循环缓冲区,它将被传递给C样式数组函数参数
- Xaudio2在更改缓冲区或循环时弹出声音
- 为什么我在leetcode上收到AddressSanitizer:地址0x602000000058上的堆缓冲区溢出错误
- 如何将图像传输到c++(dll)中的缓冲区,然后在c#的缓冲区中读/写
- 如何在cpp.中使用协议缓冲区存储大缓冲区/数组(char/int)
- 多线程双缓冲区
- Android P-9.0.0_r53 Logcat主缓冲区超出定义大小
- 套接字读取后,我在缓冲区中看到意外输入
- std::带有自定义缓冲区的 iostream 不允许我写入
- 从返回的顶点缓冲区查询顶点结构
- Vulkan 中的动态顶点缓冲区格式设置
- OpenGL 16 位模板缓冲区?
- 在 leetcode 上提交解决方案时出现堆栈缓冲区溢出错误
- 在 openGL 中多次绑定缓冲区
- struct.error:解压缩 C++ 结构时,解包需要 288 字节的缓冲区
- 为什么缓冲区的内容在读取空 rdbuf 时被删除?