D3D12CreateDevice 抛出 _com_error

D3D12CreateDevice throws _com_error

即使指定了适配器,以下代码中的 D3D12CreateDevice 也会引发 _com_error 异常:

#include "d3dx12.h"

int main() {
    ID3D12Device* device;
    D3D12CreateDevice(nullptr, D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&device));
}

在 test.exe 中的 0x00007FFB1E315549 抛出异常:Microsoft C++ 异常:_com_error 在内存位置 0x0000002906BC90E0。

但是 Microsoft 的 this 示例程序并未从 D3D12CreateDevice 中抛出 _com_error。 D3D12CreateDevice 行为很奇怪,因为如果我将 HelloTriangle 文件夹重命名为 HelloTriangle2,异常会再次出现。

我检查了 D3D12CreateDevice 的 HRESULT,它 returns 0(ZERO) 是成功的。但我仍然得到 _com_error。我的适配器通过硬件支持 DX12。

运行时可以在内部使用异常,只要它们没有传播到函数之外,它仍然是正确的。如果您从该异常继续,它可能 return。您没有检查 D3D12CreateDevice 中的 HRESULT,您应该检查 returning 中的内容。

主要区别在于示例代码使用的是明确枚举的适配器,它已被验证支持 Direct3D 12,而您的代码依赖于默认设备。

// Helper function for acquiring the first available hardware adapter that supports Direct3D 12.
// If no such adapter can be found, *ppAdapter will be set to nullptr.
_Use_decl_annotations_
void DXSample::GetHardwareAdapter(IDXGIFactory2* pFactory, IDXGIAdapter1** ppAdapter)
{
    ComPtr<IDXGIAdapter1> adapter;
    *ppAdapter = nullptr;

    for (UINT adapterIndex = 0; DXGI_ERROR_NOT_FOUND != pFactory->EnumAdapters1(adapterIndex, &adapter); ++adapterIndex)
    {
        DXGI_ADAPTER_DESC1 desc;
        adapter->GetDesc1(&desc);

        if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE)
        {
            // Don't select the Basic Render Driver adapter.
            // If you want a software adapter, pass in "/warp" on the command line.
            continue;
        }

        // Check to see if the adapter supports Direct3D 12, but don't create the
        // actual device yet.
        if (SUCCEEDED(D3D12CreateDevice(adapter.Get(), D3D_FEATURE_LEVEL_11_0, _uuidof(ID3D12Device), nullptr)))
        {
            break;
        }
    }

    *ppAdapter = adapter.Detach();
}

如果您的系统没有支持 Direct3D 12 的设备,那么示例代码将使用您的代码也没有使用的 WARP 软件设备。

因此您的默认视频设备可能不支持 Direct3D 12,并且您的系统上什至可能没有任何支持它的视频设备。也就是说,在 Direct3D 运行时内抛出的 C++ 异常仍然会触发调试器中断,因此您必须继续它们。

有关创建 Direct3D 12 设备的详细演练,请参阅 Anatomy of Direct3D 12 Create Device

You may also want to make use of DeviceResources to handle all the logic for device creation.