nvwgf2umx.dll计算机有时崩溃



我现在收到一个非常奇怪的错误。我目前正在用DirectX 11编写一个小项目,并使用ATL CComPtr的COM组件。在一个实例中,我在CComPtr中包装ID3D11Buffer。在我的大多数应用程序中,这很好,没有出现崩溃,但是,由于某种原因,在这个非常特殊的实例中,我偶尔会崩溃。

ZeroMemory(&bd, sizeof(bd));
bd.Usage = D3D11_USAGE_DYNAMIC;
bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
bd.ByteWidth = sizeof(MiscCBuffer);
bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
bd.MiscFlags = 0;
hr = device->CreateBuffer(&bd, nullptr, &_gcVoxelBuffer);
if (FAILED(hr)) { 
throw std::exception("[E] Creating constant buffer in TerrainComponent onAwake."); 
}

这是我用来创建常量缓冲区的代码。CPU缓冲区的值是这样设置的

float dimX = _instanceDimensions.x;
float dimY = _instanceDimensions.y;
float dimZ = _instanceDimensions.z;
_cVoxelBuffer.misc.x = dimX;
_cVoxelBuffer.misc.y = dimY;
_cVoxelBuffer.misc.z = dimZ;
_cVoxelBuffer.misc.w = 0;

MiscCBuffer结构体只保存一个XMFLOAT4。最后,为了用CPU数据更新GPU上的常量缓冲区,我使用以下代码:

updateD11Buffer(_gcVoxelBuffer, _cVoxelBuffer, context);
template <class T>
updateD11Buffer(const CComPtr<ID3D11Buffer>& gcBuffer, const T& cbuffer, const CComPtr<ID3D11DeviceContext>& ctx){
D3D11_MAPPED_SUBRESOURCE mappedResource;
ZeroMemory(&mappedResource, sizeof(D3D11_MAPPED_SUBRESOURCE));
ctx->Map(gcBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
memcpy(mappedResource.pData, &cbuffer, sizeof(cbuffer));
ctx->Unmap(gcBuffer, 0);
}

至于错误本身,有时在程序第一次启动时发生。它可以连续成功发射10次,然后在接下来的3次失败。

在ECS_Simulation.exe中的0x00007FFB003B273B (nvwgf2umx.dll)抛出异常:0xC0000005:访问违反读取位置0x000001BE69F9F000.

我试着在网上阅读,但是很多关于nvwgf2umx.dll崩溃与访问违规来自发货的游戏标题的帖子,其他关于访问违规的帖子通常是由NULL指针引起的。在我的情况下,我已经检查了_gcVoxelBuffer和_gcVoxelBuffer。

此外,D3D Context对象指向一个有效的位置,并且据我所知,CPU端缓冲区对象也是有效的。

我不确定这是不是真正的问题,但这是一个问题。

而不是尝试:

template <class T>
updateD11Buffer(const CComPtr<ID3D11Buffer>& gcBuffer, const T& cbuffer, const CComPtr<ID3D11DeviceContext>& ctx)
{
D3D11_MAPPED_SUBRESOURCE mappedResource = {};
if (SUCCEEDED(ctx->Map(gcBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource))
{
memcpy(mappedResource.pData, &cbuffer, sizeof(cbuffer));
ctx->Unmap(gcBuffer, 0);
}
}

zerommemory是古老的Win32模式。对于c++ 11或更高版本的编译器,统一初始化更容易使用。

注意,更灵活的设计应该是:

template <class T>
updateD11Buffer(ID3D11Buffer* gcBuffer, const T& cbuffer, ID3D11DeviceContext* ctx)
{
...
}
// call using updateD11Buffer(_gcVoxelBuffer.Get(), _cVoxelBuffer, context.Get());

这个版本没有强制使用特定的智能指针,也没有"厚厚的语法森林"。

PS: ATL的CComPtr有点过时了,有一些怪癖。例如,&_gcVoxelBuffer假设_gcVoxelBuffer总是为空,因此您可以轻松获得资源泄漏。

你应该看看WRL的ComPtr,它是"ATL 2.0"。请看这篇文章

相关内容

  • 没有找到相关文章

最新更新