首页 > 解决方案 > DirectX 11,使用 UpdateSubresource 更新常量缓冲区时引发异常

问题描述

因此,我对 DirectX 非常陌生,并且正在尝试学习基础知识,但我的常量缓冲区遇到了一些问题。我正在尝试将具有三个矩阵的结构发送到顶点着色器,但是当我尝试使用 UpdateSubresource 更新缓冲区时,我得到“在 Demo.exe 中的 0x710B5DF3 (d3d11.dll) 处引发异常:0xC0000005:访问冲突读取位置0x0000003C”。

我的结构:

struct Matracies
{
   DirectX::XMMATRIX projection;
   DirectX::XMMATRIX world;
   DirectX::XMMATRIX view;
};
Matracies matracies;

缓冲区创建:

ID3D11Buffer*  ConstantBuffer = nullptr;
D3D11_BUFFER_DESC Buffer;
memset(&Buffer, 0, sizeof(Buffer));

Buffer.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
Buffer.Usage = D3D11_USAGE_DEFAULT;
Buffer.ByteWidth = sizeof(Matracies);
Buffer.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;

D3D11_SUBRESOURCE_DATA data;
data.pSysMem = &matracies;
data.SysMemPitch = 0;
data.SysMemSlicePitch = 0;

Device->CreateBuffer(&Buffer, &data, &ConstantBuffer);
DeviceContext->VSSetConstantBuffers(0, 1, &ConstantBuffer);

更新缓冲区:

DeviceContext->UpdateSubresource(ConstantBuffer, 0, 0, &matracies, 0, 0);

我不确定哪些信息与解决此问题相关,所以如果有任何遗漏,请告诉我。

标签: bufferdirectx-11

解决方案


欢迎来到 DirectX 的毛茸茸的世界!

调试任何 DirectX 程序的前两个步骤是:

(1) 启用调试设备。请参阅此博客文章。这将在运行时生成额外的调试输出,提供有关上述问题的提示。

(2) 如果一个函数返回一个HRESULT,你必须在运行时检查它是成功还是失败。如果忽略返回值是安全的,它将返回void。请参阅此页面

如果您完成了上述任何一项或两项操作,您将捕获从CreateBuffer上面返回的错误,导致ConstantBuffer您调用UpdateSubresource.

它失败的原因是您通常不能创建一个既是D3D11_USAGE_DEFAULT又是 的常量缓冲区D3D11_CPU_ACCESS_WRITE。DEFAULT 使用内存通常位于 CPU 无法访问的视频内存中。由于您使用UpdateSubresource的是相对于Map,您应该只使用:

Buffer.CPUAccessFlags = 0;

您应该查看DirectX Tool Kit及其相关教程。


推荐阅读