SOLVED! I'll leave it posted, but answer was annoyingly obvious. Why is it that I always find the answer immediately after I post?
The problem is the byte width in the constant buffer description. The size of XMMATRIX is 64. I set the size to 16. Changed to 64 and now it works fine. Although it does make me wonder… why does this not cause the DESKTOP version to crash?
I am getting into DirectX. And by getting into, I mean literally just slogging my way through beginner instruction videos on YouTube. See code, copy code, and hopefully compile/run code. I have been working on these DirectX tutorials on my PC, but I recently bought a laptop and wanted to practice on my laptop as well. I used GitHub to clone my Visual Studio project from the desktop to my laptop. The code on my desktop runs fine. But when I try to run the exact same code on the laptop, I receive an error. The code that generates the error is in the Map(), CopyMemory(), Unmap() section for constant buffers. If I comment this section out in the laptop version, it runs fine (albeit nothing shows up on the screen - as expected). But if I try to run this section, it immediately crashes out with the error “Unhandled exception at 0x00…. (ntdll.dll) in DX11.exe: A heap has been corrupted.”
This is the function where the error occurs:
void Graphics::RenderFrame()
{
float color[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
deviceContext->ClearRenderTargetView(backBuffer.Get(), color);
deviceContext->ClearDepthStencilView(depthStencilView.Get(), D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
deviceContext->IASetInputLayout(vertexShader.GetInputLayout());
deviceContext->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
deviceContext->RSSetState(rasterizerState.Get());
deviceContext->OMSetDepthStencilState(depthStencilState.Get(), 0);
deviceContext->VSSetShader(vertexShader.GetShader(), NULL, 0);
deviceContext->PSSetShader(pixelShader.GetShader(), NULL, 0);
UINT offset = 0;
float aspectRatio = static_cast<float>(pWindow->GetHeight()) / static_cast<float>(pWindow->GetWidth());
DirectX::XMMATRIX worldMatrix = DirectX::XMMatrixIdentity();
DirectX::XMVECTOR eyePos = DirectX::XMVectorSet(3.0f + xOffset, 3.0f + yOffset, -5.0f + zOffset, 0.0f);
DirectX::XMVECTOR lookAt = DirectX::XMVectorSet(0.0f, 0.0f, 0.0f, 0.0f);
DirectX::XMVECTOR up = DirectX::XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f);
DirectX::XMMATRIX viewMatrix = DirectX::XMMatrixLookAtLH(eyePos, DirectX::XMVectorSet(0.0f, 0.0f, 1.0f, 0.0f), up);
DirectX::XMMATRIX projMatrix = DirectX::XMMatrixPerspectiveFovLH(DirectX::XMConvertToRadians(90.0f), aspectRatio, 0.1f, 1000.0f);
CBuffer_VS data;
data.matrix = worldMatrix * viewMatrix * projMatrix;
data.matrix = DirectX::XMMatrixTranspose(data.matrix);
D3D11_MAPPED_SUBRESOURCE ms;
deviceContext->Map(constantBuffer.GetBuffer().Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &ms);
CopyMemory(ms.pData, &data, sizeof(CBuffer_VS));
deviceContext->Unmap(constantBuffer.GetBuffer().Get(), 0);
deviceContext->VSSetConstantBuffers(0, 1, constantBuffer.GetBuffer().GetAddressOf());
deviceContext->IASetVertexBuffers(0, 1, vertexBuffer.GetBuffer().GetAddressOf(), reinterpret_cast<const UINT *>(vertexBuffer.GetStridePointer()), &offset);
deviceContext->IASetIndexBuffer(indexBuffer.GetBuffer().Get(), DXGI_FORMAT_R32_UINT, 0);
deviceContext->DrawIndexed(indexBuffer.GetBufferSize(), 0, 0);
swapChain->Present(1, 0);
}
In particular, the problem section is:
D3D11_MAPPED_SUBRESOURCE ms;
deviceContext->Map(constantBuffer.GetBuffer().Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &ms);
CopyMemory(ms.pData, &data, sizeof(CBuffer_VS));
deviceContext->Unmap(constantBuffer.GetBuffer().Get(), 0);
And although not shown in the code snippets above, I have used HRESULTs in all areas possible to ensure that it returns S_OK. So I don't seem to generate any errors based on the return values from these functions.
And lastly, here is the code for the constant buffer stuff:
struct CBuffer_VS
{
DirectX::XMMATRIX matrix;
};
class ConstantBuffer
{
public:
ConstantBuffer() {}
void CreateBuffer(Microsoft::WRL::ComPtr<ID3D11Device> device);
Microsoft::WRL::ComPtr<ID3D11Buffer> GetBuffer() { return constantBuffer; }
private:
Microsoft::WRL::ComPtr<ID3D11Buffer> constantBuffer;
};
void ConstantBuffer::CreateBuffer(Microsoft::WRL::ComPtr<ID3D11Device> device)
{
D3D11_BUFFER_DESC bd;
ZeroMemory(&bd, sizeof(bd));
bd.Usage = D3D11_USAGE_DYNAMIC;
bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
bd.MiscFlags = 0;
bd.ByteWidth = 16;
bd.StructureByteStride = 0;
device->CreateBuffer(&bd, NULL, constantBuffer.GetAddressOf());
}
My desktop specs are:
Intel Core i7-7700K CPU @ 4.20GHz, Windows 10 Pro 64 bit, GeForce GTX 1060 6 GB
My laptop specs are:
Intel Core i7-10870H CPU @ 2.20GHz, Windows 11 Pro 64 bit, GeForce RTX 3070
Any help is appreciated.