August 10, 2020
There is a bug in the Microsoft-provided d3d12.h C language definitions for ID3D12DescriptorHeap
and ID3D12DescriptorHeap
.
When compiling a .c file in x64 with the original header declaration I do:
_rtvHeap: *ID3D12DescriptorHeap;
D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle = _rtvHeap->lpVtbl->GetCPUDescriptorHandleForHeapStart(_rtvHeap);
This succeeds, but returns (what turns out to be) an incorrect pointer for the HeapStart.
And this causes a crash later when calling ID3D12Device::CreateRenderTargetView with the returned rtvHandle, leaving the following error in the D3d12 debug layer output:
D3D12 ERROR: ID3D12Device::CreateRenderTargetView: Specified CPU descriptor handle ptr=... does not refer to a location in a descriptor heap. [ EXECUTION ERROR #646: INVALID_DESCRIPTOR_HANDLE]
The Microsoft-provided d3d12.h contains these declarations:
typedef struct ID3D12DescriptorHeapVtbl {
..
D3D12_CPU_DESCRIPTOR_HANDLE ( STDMETHODCALLTYPE *GetCPUDescriptorHandleForHeapStart )(
ID3D12DescriptorHeap * This);
D3D12_GPU_DESCRIPTOR_HANDLE ( STDMETHODCALLTYPE *GetGPUDescriptorHandleForHeapStart )(
ID3D12DescriptorHeap * This);
..
} ID3D12DescriptorHeapVtbl;
In both cases, the result should be passed as an output parameter, rather than a return value.
typedef struct ID3D12DescriptorHeapVtbl {
..
void ( STDMETHODCALLTYPE *GetCPUDescriptorHandleForHeapStart )(
ID3D12DescriptorHeap * This, D3D12_CPU_DESCRIPTOR_HANDLE *result);
void ( STDMETHODCALLTYPE *GetGPUDescriptorHandleForHeapStart )(
ID3D12DescriptorHeap * This, D3D12_GPU_DESCRIPTOR_HANDLE *result);
..
} ID3D12DescriptorHeapVtbl;
Thanks to Cara Ames for this answer at StackOverflow that helped me track this down: GetCPUDescriptorHandleForHeapStart stack corruption .
☙