D3D11CreateDeviceAndSwapChain не удается

В настоящее время у меня есть цикл 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;
        }

Ясно, что D3D11CreateDeviceAndSwapChain в цикле for возвращает значение, отличное от успеха, и самое странное, что когда я запускаю эту программу на другом ПК, она работает нормально! Я обновил все свои драйверы, перезагрузил компьютер и удалил все антивирусное программное обеспечение, но все равно не повезло. Любые идеи?


person Tim Ogunmakin    schedule 06.01.2016    source источник
comment
Итак, какое значение он возвращает? Кроме того, определено ли _DEBUG? Не во всех системах установлены необходимые SDKLayers, необходимые для работы флага D3D11_CREATE_DEVICE_DEBUG.   -  person MooseBoys    schedule 07.01.2016
comment
Значение возвращает FAILED после того, как я проверяю его с помощью if (FAILED(hr)). Я не уверен, где это будет определено, вы говорите о том, что я написал вверху? #ifdef _DEBUG createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG; #endif   -  person Tim Ogunmakin    schedule 07.01.2016
comment
Да, вы передаете флаг DEBUG в createDeviceFlags?   -  person MooseBoys    schedule 07.01.2016
comment
Да, я нажимаю createDeviceFlags, когда ставлю там точку останова.   -  person Tim Ogunmakin    schedule 07.01.2016
comment
какой номер ошибки содержится в hr?   -  person Sly_TheKing    schedule 12.01.2016


Ответы (4)


Вы не указали, какую ОС вы используете, но наиболее вероятной причиной сбоя является то, что в вашей системе не установлен правильный уровень отладки Direct3D SDK. В этом случае, если вы попытаетесь создать устройство с помощью D3D11_CREATE_DEVICE_DEBUG, это не удастся. Быстрый тест: если ваша сборка выпуска успешно создает устройство, а сборка отладки — нет.

Чтобы установить правильные уровни SDK для вашей ОС:

  • Windows 7 RTM -> устаревший DirectX SDK сделает это
  • Windows 7 SP1 с KB2670838 обновление (он же DirectX 11.1) -> необходимо установить Windows 8.x SDK; устаревшая версия DirectX SDK устарела
  • Windows 8 или Windows 8.1 -> Windows 8.x SDK устанавливает его
  • Windows 10 -> Теперь это Feature On Demand для Windows 10. Обратите внимание, что если вы обновили версию 10240 до 10586, вам необходимо снова включить FOD.

См. уровень отладки Direct3D SDK. Трюки

Другая возможность заключается в том, что в вашей системе нет видеокарты Feature Level 10.0 или более поздней, но, учитывая, что код пытается использовать WARP, он будет работать с этим.

См. анатомию Direct3D 11 Создать устройство

Вам следует ознакомиться с набором инструментов DirectX и Шаблон игры Direct3D Win32.

person Chuck Walbourn    schedule 07.01.2016

Наконец-то исправил проблему.

Microsoft выпустила обновление для Windows 10, которое автоматически удаляет поддержку DirectX11. Его необходимо снова включить. Если кто-то столкнется с этой проблемой в Windows 10, для повторного включения DirectX11 перейдите по ссылке:

Настройки -> Приложения -> Управление -> Добавить дополнительную поддержку графики

(очевидно, мне нужно подождать 21 час, чтобы принять свой собственный ответ...)

person Tim Ogunmakin    schedule 08.01.2016
comment
DirectX 11 присутствует в Windows 10. Это уровень отладки (как я отметил в своем ответе), который отсутствует. Среды выполнения DirectX 11 и DirectX 12 всегда присутствуют в Windows 10, как и устройство WARP11. Устройство DEBUG для DirectX 11, устройство DEBUG для DirectX 12 и WARP12 требуют установки функции Graphics Tools по требованию. FOD специфичен для вашей сборки #, и обновление до новой сборки # делает FOD недействительным. - person Chuck Walbourn; 08.01.2016
comment
В последней версии Windows (1903) он находится в разделе «Настройки» / «Приложения и функции» / «Дополнительные функции» / «Графические инструменты» (137M «Это добавляет поддержку графических инструментов DirectX»), но, похоже, что-то установило его автоматически ... (Visual Studio? SDK? ) - person Simon Mourier; 07.08.2019

Как вы сказали, тот же код отлично работает на другой машине, это означает, что либо у вас есть проблема с вашим графическим процессором, попробуйте запустить с помощью WARP или эталонного устройства, удалите D3D_DRIVER_TYPE_HARDWARE из списка и повторите попытку.

Попробуйте использовать

D3D_DRIVER_TYPE driverTypes[] =
    {
        D3D_DRIVER_TYPE_WARP,
        D3D_DRIVER_TYPE_REFERENCE,
    };

и любезно прочитайте подробности о типах драйверов здесь разница между драйверами WARP, эталонными драйверами и программными драйверами?

person Muhammad Zeeshan    schedule 07.01.2016

Из моего скудного понимания DX11 и COM:

  1. Согласно rastertek.com, вот соответствующий фрагмент кода и объяснение:

Обратите внимание, что если у пользователя нет видеокарты DirectX 11, этот вызов функции не сможет создать устройство и контекст устройства. Кроме того, если вы сами тестируете функциональность DirectX 11 и у вас нет видеокарты DirectX 11, вы можете заменить D3D_DRIVER_TYPE_HARDWARE на D3D_DRIVER_TYPE_REFERENCE, и DirectX будет использовать ваш процессор для рисования вместо оборудования видеокарты. Обратите внимание, что это работает на 1/1000 скорости, но это хорошо для людей, у которых еще нет видеокарт DirectX 11 на всех их машинах.

// 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.

  1. В соответствии с другим вопросом stackoverflow выбранный ответ может быть вам полезен в будущем, а также в MSDN есть статья о DX11 HRESULT коды возврата и COM обработка ошибок.

Лучшее, что вы можете сделать прямо сейчас, — это найти значение HRESULT, передав каждое перечисление из статьи MSDN в оператор if. Например:

if (hr == E_OUTOFMEMORY) {
//do whatever
}
person htmlboss    schedule 06.01.2016
comment
Код OP уже пытается создать устройство на HW, WARP и Ref и разрешает уровень функций 10. Независимо от аппаратной поддержки, это обычно должно быть успешным, когда он попадает в комбинацию FL 10.1 + WARP. - person MooseBoys; 07.01.2016