D3D11CreateDeviceAndSwapChain 未能成功
D3D11CreateDeviceAndSwapChain Fails to succeed
我目前有一个 for 循环,一旦 hr 成功就应该中断它,但它没有成功,这在以后给我带来了问题。
HRESULT hr = S_OK;
UINT createDeviceFlags = 0;
#ifdef _DEBUG
createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif
D3D_DRIVER_TYPE driverTypes[] =
{
D3D_DRIVER_TYPE_HARDWARE,
D3D_DRIVER_TYPE_WARP,
D3D_DRIVER_TYPE_REFERENCE,
};
UINT numDriverTypes = ARRAYSIZE(driverTypes);
D3D_FEATURE_LEVEL featureLevels[] =
{
D3D_FEATURE_LEVEL_11_0,
D3D_FEATURE_LEVEL_10_1,
D3D_FEATURE_LEVEL_10_0,
};
UINT numFeatureLevels = ARRAYSIZE(featureLevels);
DXGI_SWAP_CHAIN_DESC sd;
ZeroMemory(&sd, sizeof(sd));
sd.BufferCount = 1;
sd.BufferDesc.Width = _WindowWidth;
sd.BufferDesc.Height = _WindowHeight;
sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
sd.BufferDesc.RefreshRate.Numerator = 60;
sd.BufferDesc.RefreshRate.Denominator = 1;
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
sd.OutputWindow = _hWnd;
sd.SampleDesc.Count = 1;
sd.SampleDesc.Quality = 0;
sd.Windowed = TRUE;
for (UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++)
{
_driverType = driverTypes[driverTypeIndex];
hr = D3D11CreateDeviceAndSwapChain(nullptr, _driverType, nullptr, createDeviceFlags, featureLevels, numFeatureLevels,
D3D11_SDK_VERSION, &sd, &_pSwapChain, &_pd3dDevice, &_featureLevel, &_pImmediateContext);
if (SUCCEEDED(hr))
break;
}
很明显,for 循环中的 D3D11CreateDeviceAndSwapChain 返回的值不是成功的,奇怪的是,当我 运行 这个程序在另一台 PC 上运行时,它工作正常!我已经更新了所有驱动程序,重新启动了我的电脑并卸载了所有防病毒软件,但仍然没有成功。有什么想法吗?
以我自己对DX11和COM的浅薄了解:
- 根据rastertek.com,这里有一个相关的代码片段和解释:
Note that if the user does not have a DirectX 11 video card this function call will fail to create the device and device context. Also if you are testing DirectX 11 functionality yourself and don't have a DirectX 11 video card then you can replace D3D_DRIVER_TYPE_HARDWARE with D3D_DRIVER_TYPE_REFERENCE and DirectX will use your CPU to draw instead of the video card hardware. Note that this runs 1/1000 the speed but it is good for people who don't have DirectX 11 video cards yet on all their machines.
// Create the swap chain, Direct3D device, and Direct3D device context.
result = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, &featureLevel, 1,
D3D11_SDK_VERSION, &swapChainDesc, &m_swapChain, &m_device, NULL, &m_deviceContext);
if(FAILED(result))
{
return false;
}
尝试将驱动程序类型标志更改为 D3D_DRIVER_TYPE_REFERENCE 以进行调试。如果可行,您可能没有 DX11 GPU。
- 根据另一个 Whosebug question, the selected answer might be of some future use to you and also MSDN has an article on DX11 HRESULT return codes and COM error handling。
您现在可以做的最好的事情是通过将 MSDN 文章中的每个枚举传递到 if 语句来找到 HRESULT 的值。例如:
if (hr == E_OUTOFMEMORY) {
//do whatever
}
您没有说明您使用的是哪个 OS,但失败的最可能原因是您的系统没有安装正确的 Direct3D SDK 调试层。在这种情况下,如果您尝试使用 D3D11_CREATE_DEVICE_DEBUG
创建设备,它将失败。快速测试您的 Release 版本是否成功创建设备,但您的 Debug 版本没有。
为您的 OS 安装正确的 SDK 层:
- Windows 7 RTM -> 旧版 DirectX SDK 可以做到
- Windows 7 SP1 带有 KB2670838 更新(又名 DirectX 11.1)-> 您必须安装 Windows 8.x开发工具包;旧版 DirectX SDK 版本已过时
- Windows 8 或 Windows 8.1 -> Windows 8.x SDK安装它
- Windows 10 -> 现在这是 Windows 10 的 Feature On Demand。请注意,如果您从 10240 升级到 10586,那么你需要re-enable FOD。
见Direct3D SDK Debug Layer Tricks
另一种可能性是您的系统没有 Feature Level 10.0 或更高版本的视频卡,但如果代码尝试使用 WARP,它就可以使用它。
见Anatomy of Direct3D 11 Create Device
You should take a look at the DirectX Tool Kit and the Direct3D Win32 Game Template.
正如您所说,相同的代码在其他机器上 运行 是完美的,这意味着您的 gpu 有问题,请尝试 运行 使用 WARP 或参考设备,删除 D3D_DRIVER_TYPE_HARDWARE 从列表中重试。
尝试使用
D3D_DRIVER_TYPE driverTypes[] =
{
D3D_DRIVER_TYPE_WARP,
D3D_DRIVER_TYPE_REFERENCE,
};
并请在此处阅读有关驱动程序类型的详细信息What's the difference between WARP drivers,reference drivers and software drivers?
问题终于解决了。
Microsoft 发布了 Windows10 的更新,自动删除了对 DirectX11 的支持。它必须是 re-enabled。如果有人在 Windows 10 中遇到此问题,请转到 re-enable DirectX11:
设置 -> 应用程序 -> 管理 -> 添加额外的图形支持
(显然我需要等待 21 小时才能接受我自己的答案...)
我目前有一个 for 循环,一旦 hr 成功就应该中断它,但它没有成功,这在以后给我带来了问题。
HRESULT hr = S_OK;
UINT createDeviceFlags = 0;
#ifdef _DEBUG
createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif
D3D_DRIVER_TYPE driverTypes[] =
{
D3D_DRIVER_TYPE_HARDWARE,
D3D_DRIVER_TYPE_WARP,
D3D_DRIVER_TYPE_REFERENCE,
};
UINT numDriverTypes = ARRAYSIZE(driverTypes);
D3D_FEATURE_LEVEL featureLevels[] =
{
D3D_FEATURE_LEVEL_11_0,
D3D_FEATURE_LEVEL_10_1,
D3D_FEATURE_LEVEL_10_0,
};
UINT numFeatureLevels = ARRAYSIZE(featureLevels);
DXGI_SWAP_CHAIN_DESC sd;
ZeroMemory(&sd, sizeof(sd));
sd.BufferCount = 1;
sd.BufferDesc.Width = _WindowWidth;
sd.BufferDesc.Height = _WindowHeight;
sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
sd.BufferDesc.RefreshRate.Numerator = 60;
sd.BufferDesc.RefreshRate.Denominator = 1;
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
sd.OutputWindow = _hWnd;
sd.SampleDesc.Count = 1;
sd.SampleDesc.Quality = 0;
sd.Windowed = TRUE;
for (UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++)
{
_driverType = driverTypes[driverTypeIndex];
hr = D3D11CreateDeviceAndSwapChain(nullptr, _driverType, nullptr, createDeviceFlags, featureLevels, numFeatureLevels,
D3D11_SDK_VERSION, &sd, &_pSwapChain, &_pd3dDevice, &_featureLevel, &_pImmediateContext);
if (SUCCEEDED(hr))
break;
}
很明显,for 循环中的 D3D11CreateDeviceAndSwapChain 返回的值不是成功的,奇怪的是,当我 运行 这个程序在另一台 PC 上运行时,它工作正常!我已经更新了所有驱动程序,重新启动了我的电脑并卸载了所有防病毒软件,但仍然没有成功。有什么想法吗?
以我自己对DX11和COM的浅薄了解:
- 根据rastertek.com,这里有一个相关的代码片段和解释:
Note that if the user does not have a DirectX 11 video card this function call will fail to create the device and device context. Also if you are testing DirectX 11 functionality yourself and don't have a DirectX 11 video card then you can replace D3D_DRIVER_TYPE_HARDWARE with D3D_DRIVER_TYPE_REFERENCE and DirectX will use your CPU to draw instead of the video card hardware. Note that this runs 1/1000 the speed but it is good for people who don't have DirectX 11 video cards yet on all their machines.
// Create the swap chain, Direct3D device, and Direct3D device context.
result = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, &featureLevel, 1,
D3D11_SDK_VERSION, &swapChainDesc, &m_swapChain, &m_device, NULL, &m_deviceContext);
if(FAILED(result))
{
return false;
}
尝试将驱动程序类型标志更改为 D3D_DRIVER_TYPE_REFERENCE 以进行调试。如果可行,您可能没有 DX11 GPU。
- 根据另一个 Whosebug question, the selected answer might be of some future use to you and also MSDN has an article on DX11 HRESULT return codes and COM error handling。
您现在可以做的最好的事情是通过将 MSDN 文章中的每个枚举传递到 if 语句来找到 HRESULT 的值。例如:
if (hr == E_OUTOFMEMORY) {
//do whatever
}
您没有说明您使用的是哪个 OS,但失败的最可能原因是您的系统没有安装正确的 Direct3D SDK 调试层。在这种情况下,如果您尝试使用 D3D11_CREATE_DEVICE_DEBUG
创建设备,它将失败。快速测试您的 Release 版本是否成功创建设备,但您的 Debug 版本没有。
为您的 OS 安装正确的 SDK 层:
- Windows 7 RTM -> 旧版 DirectX SDK 可以做到
- Windows 7 SP1 带有 KB2670838 更新(又名 DirectX 11.1)-> 您必须安装 Windows 8.x开发工具包;旧版 DirectX SDK 版本已过时
- Windows 8 或 Windows 8.1 -> Windows 8.x SDK安装它
- Windows 10 -> 现在这是 Windows 10 的 Feature On Demand。请注意,如果您从 10240 升级到 10586,那么你需要re-enable FOD。
见Direct3D SDK Debug Layer Tricks
另一种可能性是您的系统没有 Feature Level 10.0 或更高版本的视频卡,但如果代码尝试使用 WARP,它就可以使用它。
见Anatomy of Direct3D 11 Create Device
You should take a look at the DirectX Tool Kit and the Direct3D Win32 Game Template.
正如您所说,相同的代码在其他机器上 运行 是完美的,这意味着您的 gpu 有问题,请尝试 运行 使用 WARP 或参考设备,删除 D3D_DRIVER_TYPE_HARDWARE 从列表中重试。
尝试使用
D3D_DRIVER_TYPE driverTypes[] =
{
D3D_DRIVER_TYPE_WARP,
D3D_DRIVER_TYPE_REFERENCE,
};
并请在此处阅读有关驱动程序类型的详细信息What's the difference between WARP drivers,reference drivers and software drivers?
问题终于解决了。
Microsoft 发布了 Windows10 的更新,自动删除了对 DirectX11 的支持。它必须是 re-enabled。如果有人在 Windows 10 中遇到此问题,请转到 re-enable DirectX11:
设置 -> 应用程序 -> 管理 -> 添加额外的图形支持
(显然我需要等待 21 小时才能接受我自己的答案...)