将已有IDXGIAdapter传入D3D11CreateDevice创建设备遇E_INVALIDARG的解决方法
解决D3D11CreateDevice传入IDXGIAdapter返回E_INVALIDARG的问题
核心原因与修复步骤
1. 强制设置DriverType为D3D_DRIVER_TYPE_UNKNOWN
当显式传入IDXGIAdapter时,D3D11CreateDevice的driverType参数必须指定为D3D_DRIVER_TYPE_UNKNOWN,不能使用D3D_DRIVER_TYPE_HARDWARE或其他类型。这是因为指定适配器后,系统会直接绑定该适配器的驱动,无需再自动检测驱动类型,参数不匹配会直接触发E_INVALIDARG。
错误示例:
HRESULT hr = D3D11CreateDevice(adapter, D3D_DRIVER_TYPE_HARDWARE, nullptr, 0, featureLevels, ARRAYSIZE(featureLevels), D3D11_SDK_VERSION, &pDevice, &featureLevel, &pContext);
正确示例:
HRESULT hr = D3D11CreateDevice(adapter, D3D_DRIVER_TYPE_UNKNOWN, nullptr, 0, featureLevels, ARRAYSIZE(featureLevels), D3D11_SDK_VERSION, &pDevice, &featureLevel, &pContext);
2. 验证适配器对象的合法性
确保你的getAdapter函数返回的IDXGIAdapter是有效且未被错误释放的对象:
- 枚举适配器时,需通过
IDXGIFactory1::EnumAdapters1正确获取,确保指针引用计数正常(必要时调用AddRef)。 - 可调用
IDXGIAdapter::GetDesc打印设备名称,确认是目标NVIDIA GPU:
DXGI_ADAPTER_DESC desc = {}; adapter->GetDesc(&desc); wprintf(L"目标适配器: %s\n", desc.Description);
3. 确保Feature Levels数组合法
传入的功能级别数组必须包含适配器支持的D3D11级别,建议按从高到低排列,覆盖主流版本:
const D3D_FEATURE_LEVEL featureLevels[] = { 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 };
系统会自动选择第一个适配器支持的级别,数组不能为空或包含无效值。
4. 检查适配器是否支持D3D11设备
通过IDXGIAdapter::CheckInterfaceSupport验证适配器是否兼容ID3D11Device:
LARGE_INTEGER umdVersion = {}; HRESULT hr = adapter->CheckInterfaceSupport(__uuidof(ID3D11Device), &umdVersion); if (FAILED(hr)) { // 适配器不支持D3D11,需更换或处理 }
5. 对齐CUDA与DX11的适配器匹配
确保通过CUDA获取的设备和DXGI枚举的适配器是同一硬件:
- 使用
cuD3D11GetDevice可从DXGI适配器获取对应CUDA设备ID,或通过cuD3D11GetAdapter从CUDA设备反向获取DXGI适配器,以此验证你的getAdapter函数返回对象的正确性。
完整示例代码片段
IDXGIAdapter* GetCudaCompatibleAdapter() { IDXGIAdapter* adapter = nullptr; IDXGIFactory1* factory = nullptr; HRESULT hr = CreateDXGIFactory1(__uuidof(IDXGIFactory1), (void**)&factory); if (FAILED(hr)) return nullptr; for (UINT i = 0; factory->EnumAdapters1(i, &adapter) != DXGI_ERROR_NOT_FOUND; i++) { DXGI_ADAPTER_DESC1 desc = {}; adapter->GetDesc1(&desc); // 筛选NVIDIA厂商适配器(VendorId 0x10DE) if (desc.VendorId == 0x10DE) { // 验证D3D11支持 LARGE_INTEGER umdVersion; if (SUCCEEDED(adapter->CheckInterfaceSupport(__uuidof(ID3D11Device), &umdVersion))) { // 验证CUDA兼容性 CUdevice cudaDevice; hr = cuD3D11GetDevice(&cudaDevice, adapter); if (SUCCEEDED(hr)) { factory->Release(); return adapter; } } } adapter->Release(); } factory->Release(); return nullptr; } // 通过指定适配器创建D3D11设备 ID3D11Device* CreateDeviceWithAdapter(IDXGIAdapter* adapter) { ID3D11Device* device = nullptr; ID3D11DeviceContext* context = nullptr; D3D_FEATURE_LEVEL featureLevel; const D3D_FEATURE_LEVEL featureLevels[] = { D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1, D3D_FEATURE_LEVEL_10_0 }; HRESULT hr = D3D11CreateDevice( adapter, D3D_DRIVER_TYPE_UNKNOWN, nullptr, D3D11_CREATE_DEVICE_DEBUG, // 调试模式可开启,发布时移除 featureLevels, ARRAYSIZE(featureLevels), D3D11_SDK_VERSION, &device, &featureLevel, &context ); if (SUCCEEDED(hr)) { context->Release(); return device; } return nullptr; }
内容的提问来源于stack exchange,提问作者rbaleksandar
相关产品推荐
相关产品推荐

