DirectX 11,使用 UpdateSubresource 更新常量缓冲区时抛出异常

DirectX 11, exception thrown when updating constant buffer with UpdateSubresource

所以我是 DirectX 的新手,正在尝试学习基础知识,但我 运行 遇到了常量缓冲区的一些问题。我正在尝试将具有三个矩阵的结构发送到顶点着色器,但是当我尝试使用 UpdateSubresource 更新缓冲区时,我得到 "Exception is thrown at 0x710B5DF3 (d3d11.dll) in Demo.exe: 0xC0000005: Access violation reading location 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);

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

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

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

(1) 启用调试设备。参见 this blog post。这将在运行时生成额外的调试输出,提示您遇到上述问题。

(2) 如果函数 return 是 HRESULT,您必须在运行时检查它是成功还是失败。如果忽略 return 值是安全的,它将 return void。参见 this page

如果您执行了上述任一或两个操作,您将捕获上面 CreateBuffer 中的 returned 错误,该错误导致 ConstantBuffer 在您调用时仍然是 nullptr UpdateSubresource.

它失败的原因是您不能通常 创建一个同时为D3D11_USAGE_DEFAULTD3D11_CPU_ACCESS_WRITE 的常量缓冲区。默认使用内存通常位于 CPU 无法访问的视频内存中。由于您使用的是 UpdateSubresource 而不是 Map,您应该只使用:

Buffer.CPUAccessFlags = 0;

You should take a look at DirectX Tool Kit and it's associated tutorials.