第一次机会例外

时间:2013-11-07 06:24:08

标签: directx directx-11

我正在学习使用DirectX11学习游戏编程的教程。当我运行示例代码时,它给了我这个错误:

First-chance exception at 0x76E12EEC in Chapter1.exe: Microsoft C++ exception: Platform::COMException ^ at memory location 0x0307E824. HRESULT:0x887A0004

问题似乎出现在以下代码中的featureLevel和creationFlag中:

hr = D3D11CreateDevice(
            nullptr,
            D3D_DRIVER_TYPE_HARDWARE,
            nullptr,
            creationFlags, 
            featureLevels, 
            ARRAYSIZE(featureLevels),
            D3D11_SDK_VERSION, 
            &device, 
            &featureLevel,
            &context);  
    ThrowIfFailed(hr);

但是,如果我将creationFlags和featureLevels的值更改为0和nullptr,则代码可以正常工作。我在Windows 8.1和Windows SDK 8.0中使用Visual Studio 2012。

以下是相关代码:

UINT creationFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;

#if defined(_DEBUG)
    // For debugging
    creationFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif

    D3D_FEATURE_LEVEL featureLevels[] = 
    {
        D3D_FEATURE_LEVEL_11_1,
        D3D_FEATURE_LEVEL_11_0,
    };

我读到了第一次机会异常,它并不意味着代码确实存在问题,但它并没有消失。我该怎么办?

1 个答案:

答案 0 :(得分:3)

问题

您只传递了D3D_FEATURE_LEVEL_11_1D3D_FEATURE_LEVEL_11_0,因此D3D11CreateDevice()函数失败,返回HRESULT而非S_OK并且您的ThrowIfFailed(hr);函数抛出你有例外。

如果您的GPU仅支持DirectX 10,则无法创建DirectX 11硬件设备和上下文:Createdevice*()功能将失败。为了能够在低级硬件上使用DirectX 11 API(但不是DirectX 11功能),Microsoft引入了feature levels

如何解决?

只需使用传统的设备创建方式。 您将需要传递具有所有可能功能级别的数组

D3D_FEATURE_LEVEL arrFeatLevels [] =
{
    D3D_FEATURE_LEVEL_11_1,
    D3D_FEATURE_LEVEL_11_0,
    D3D_FEATURE_LEVEL_10_1,
    D3D_FEATURE_LEVEL_10_0,
    D3D_FEATURE_LEVEL_9_3,
    D3D_FEATURE_LEVEL_9_2,
    D3D_FEATURE_LEVEL_9_1,
};

因此,DirectX API将自动选择支持率最高的一个。 (设备创建后,您可以通过查看返回的&featureLevel来找到选择的那个):

if(featureLevel >= D3D_FEATURE_LEVEL_11_0)
    std::cout << "Yay! we using D3D11! :) " << std::endl;
else if( featureLevel >= D3D_FEATURE_LEVEL_10_0)
    std::cout << "Oh noes! only D3D10 available! :(" <<std::endl;
else
    std::cout << "Man, where did you take that old videocard? =\ " <<std::endl;

请注意,DirectX 11功能(例如Shader Model 5,曲面细分着色器;计算着色器)在功能级别低于D3D_FEATURE_LEVEL_11_0的设备/上下文中不可用。同样,DirectX 10功能(例如几何着色器)在功能级别低于D3D_FEATURE_LEVEL_10_0时将不可用。 所有硬件支持的功能都将照常运行。

此外,还有一种方法可以测试硬件不支持的功能。您可以创建模拟WARP device的软件:传递D3D_DRIVER_TYPE_WARP。它非常慢,不适用于生产代码,但它允许开发人员测试和调试D3D11功能,即使他们没有顶级硬件。

在哪里可以找到我的GPU功能?

在GPU制造商的网站上。或者只使用GPU-Z(显示DX支持)或GPU Caps Viewer(显示许多OpenGL功能)等工具。

快乐的编码!=)