在 c11 中用 clang 编译的程序中调用 DX12 函数时出现问题
Problem calling DX12 functions in a program compiled with clang in c11
为了学习,我尝试在纯 c11 中使用 clang 正确调用 DirectX12 API。我设法编译了所有内容,但有时 vtable 指针似乎被损坏并更改了它们不应该指向的位置。
ID3D12DeviceVtbl* tbl; //tracking the vtable pointer for debugging purposes
D3D_FEATURE_LEVEL featureLevel = D3D_FEATURE_LEVEL_11_0;
if (D3D12CreateDevice(NULL, featureLevel, &IID_ID3D12Device, (void**)&g_pd3dDevice) != S_OK)
{
return false;
}
{
tbl = g_pd3dDevice->lpVtbl;
D3D12_DESCRIPTOR_HEAP_DESC desc ;
desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
desc.NumDescriptors = NUM_BACK_BUFFERS;
desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
desc.NodeMask = 1;
// works fine
if (g_pd3dDevice->lpVtbl->CreateDescriptorHeap(g_pd3dDevice,&desc, &IID_ID3D12DescriptorHeap, (void**)&g_pd3dRtvDescHeap) != S_OK)
return false;
// works fine
SIZE_T rtvDescriptorSize = g_pd3dDevice->lpVtbl->GetDescriptorHandleIncrementSize(g_pd3dDevice,D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
// works fine
D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle = g_pd3dRtvDescHeap->lpVtbl->GetCPUDescriptorHandleForHeapStart(g_pd3dRtvDescHeap);
// after the line above executes, g_pd3dDevice->lpVtbl now points to somewhere new and invalid
}
{
D3D12_DESCRIPTOR_HEAP_DESC desc ;
desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
desc.NumDescriptors = 1;
desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
// g_pd3dDevice->lpVtbl can't find CreateDescriptorHeap
if (g_pd3dDevice->lpVtbl->CreateDescriptorHeap(g_pd3dDevice,&desc, &IID_ID3D12DescriptorHeap, (void**)&g_pd3dSrvDescHeap) != S_OK)
{
return false;
}
// tbl->CreateDescriptorHeap is still a valid pointer however.
}
如评论中所述,在 D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle = g_pd3dRtvDescHeap->lpVtbl->GetCPUDescriptorHandleForHeapStart(g_pd3dRtvDescHeap);
行之后,g_pd3dDevice->lpVtbl
指针更改并指向无效的某处,我不明白为什么。
我正在使用以下选项进行编译:
clang.exe -std=c11 -pedantic-errors -g -D CINTERFACE .\main.c
您遇到了 C 绑定中的一个已知错误...请参阅 ,其中解释了 GetCPUDescriptorHandleForHeapStart
的错误。
There were similar issues with the C-bindings with Direct3D9Ex. The basic issue is that almost all users use C++ for DirectX since it naturally maps to COM. The C bindings are mostly automatically generated; they are not well tested or maintained.
为了学习,我尝试在纯 c11 中使用 clang 正确调用 DirectX12 API。我设法编译了所有内容,但有时 vtable 指针似乎被损坏并更改了它们不应该指向的位置。
ID3D12DeviceVtbl* tbl; //tracking the vtable pointer for debugging purposes
D3D_FEATURE_LEVEL featureLevel = D3D_FEATURE_LEVEL_11_0;
if (D3D12CreateDevice(NULL, featureLevel, &IID_ID3D12Device, (void**)&g_pd3dDevice) != S_OK)
{
return false;
}
{
tbl = g_pd3dDevice->lpVtbl;
D3D12_DESCRIPTOR_HEAP_DESC desc ;
desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
desc.NumDescriptors = NUM_BACK_BUFFERS;
desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
desc.NodeMask = 1;
// works fine
if (g_pd3dDevice->lpVtbl->CreateDescriptorHeap(g_pd3dDevice,&desc, &IID_ID3D12DescriptorHeap, (void**)&g_pd3dRtvDescHeap) != S_OK)
return false;
// works fine
SIZE_T rtvDescriptorSize = g_pd3dDevice->lpVtbl->GetDescriptorHandleIncrementSize(g_pd3dDevice,D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
// works fine
D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle = g_pd3dRtvDescHeap->lpVtbl->GetCPUDescriptorHandleForHeapStart(g_pd3dRtvDescHeap);
// after the line above executes, g_pd3dDevice->lpVtbl now points to somewhere new and invalid
}
{
D3D12_DESCRIPTOR_HEAP_DESC desc ;
desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
desc.NumDescriptors = 1;
desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
// g_pd3dDevice->lpVtbl can't find CreateDescriptorHeap
if (g_pd3dDevice->lpVtbl->CreateDescriptorHeap(g_pd3dDevice,&desc, &IID_ID3D12DescriptorHeap, (void**)&g_pd3dSrvDescHeap) != S_OK)
{
return false;
}
// tbl->CreateDescriptorHeap is still a valid pointer however.
}
如评论中所述,在 D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle = g_pd3dRtvDescHeap->lpVtbl->GetCPUDescriptorHandleForHeapStart(g_pd3dRtvDescHeap);
行之后,g_pd3dDevice->lpVtbl
指针更改并指向无效的某处,我不明白为什么。
我正在使用以下选项进行编译:
clang.exe -std=c11 -pedantic-errors -g -D CINTERFACE .\main.c
您遇到了 C 绑定中的一个已知错误...请参阅 GetCPUDescriptorHandleForHeapStart
的错误。
There were similar issues with the C-bindings with Direct3D9Ex. The basic issue is that almost all users use C++ for DirectX since it naturally maps to COM. The C bindings are mostly automatically generated; they are not well tested or maintained.