Можно ли передать D3D11_CREATE_DEVICE_DISABLE_GPU_TIMEOUT с D3D_FEATURE_LEVEL_11_0?

MSDN на D3D11_CREATE_DEVICE_DISABLE_GPU_TIMEOUT говорит :

Direct3D 11: это значение не поддерживается до версии Direct3D 11.1.

Означает ли это версию среды выполнения или уровень функций?

Могу ли я передать флаг D3D11CreateDevice, но передать только уровень функций 11_0?

Уровень функций не имеет значения и зависит только от установленной версии среды выполнения? Что произойдет, если я передам флаг среде выполнения DX 11.0? Будет ли это просто молча игнорироваться? Или мне сначала нужно как-то определить версию среды выполнения DX, а затем передать флаг, только если версия среды выполнения DX не ниже 11.1?


person Peter    schedule 14.09.2016    source источник


Ответы (3)


«Правильный» способ определить, есть ли у вас среда выполнения Direct3D 11.1, будет следующим:

#include <d3d11_1.h>
#include <wrl/client.h>

#pragma comment(lib,"d3d11.lib")

bool IsDirect3D11_1OrGreater()
{
    Microsoft::WRL::ComPtr<ID3D11Device> device;

    HRESULT hr = D3D11CreateDevice(
        nullptr,
        D3D_DRIVER_TYPE_NULL,
        nullptr,
        0,
        nullptr,
        0,
        D3D11_SDK_VERSION,
        device.GetAddressOf(),
        nullptr,
        nullptr
        );

    if (FAILED(hr))
        return false;

    Microsoft::WRL::ComPtr<ID3D11Device1> device1;
    return SUCCEEDED(device.As(&device1));
}

Затем вы звоните IsDirect3D11_1OrGreater. Если это так, то вы можете безопасно использовать такой флаг, как D3D11_CREATE_DEVICE_DISABLE_GPU_TIMEOUT, для которого требуется среда выполнения Direct3D 11.1.

Имейте в виду, что вы не должны использовать D3D11_CREATE_DEVICE_DISABLE_GPU_TIMEOUT как само собой разумеющееся. Его действительно следует использовать только для программ, интенсивно использующих DirectCompute, которые могут сильно загружать GPU и потенциально могут привести к тому, что система перестанет реагировать на пользовательский интерфейс. Используйте его с осторожностью.

Это также означает, что вашему приложению потребуется карта Direct3D Feature Level 11.0 или выше для использования DirectCompute 5.0 — или — для этого потребуется Direct3D Feature Level 10.0 и необходимо выполнить CheckFeatureSupport(D3D11_FEATURE_D3D10_X_HARDWARE_OPTIONS, ...) вызов и убедиться, что D3D11_FEATURE_DATA_D3D10_X_HARDWARE_OPTIONS.ComputeShaders_Plus_RawAndStructuredBuffers_Via_Shader_4_x верно для DirectCompute 4.0.

Если IsDirect3D11_1OrGreater возвращает false, вы должны сообщить пользователю:

This application requires the DirectX 11.1 Runtime. It is supported on
Windows 7 Service Pack 1 with KB2670838 or later Windows operating systems.

См. также DirectX 11.1 и Windows 7 и DirectX 11.1 и обновление Windows 7.

person Chuck Walbourn    schedule 16.09.2016
comment
Это утверждает, что среда выполнения D3D11.1 доступна на Win7SP1 + KB2670838, но передача флага D3D11_CREATE_DEVICE_DISABLE_GPU_TIMEOUT не удалась. Есть идеи, почему? - person Peter; 21.09.2016
comment
Извините, мне нужно перепроверить это на моей установке Windows 7. Флаг известен, но, возможно, для него требуются более новые драйверы, которые не поддерживаются для Win7SP1+KB2670838. Согласно MSDN DirectX 11.1 на Win7SP1+KB2670838 предоставляет все «программное обеспечение» функции, но не все, что требует драйверов WDDM 1.2, не поддерживаются в Win7SP1. - person Chuck Walbourn; 21.09.2016
comment
Я подтвердил, что вы действительно можете использовать флаг D3D11_CREATE_DEVICE_DISABLE_GPU_TIMEOUT в Windows 7 с пакетом обновления 1 с установленным KB 2670838. - person Chuck Walbourn; 22.09.2016
comment
К сожалению, это не всегда работает, см. комментарий ниже. - person Peter; 29.09.2016
comment
Хм, здесь тоже должна быть зависимость от поведения драйвера. Похоже, вам нужно создать устройство с флагом, и если это не удастся, повторите попытку без него. Я предполагаю, что ваше приложение не работает без установленного флага? - person Chuck Walbourn; 29.09.2016

Речь идет о версии во время выполнения, поэтому вам нужна Windows 8, по крайней мере, чтобы эта функция была включена.

Вы можете запросить устройство только с уровнем функций 11, имея этот флаг, только что попробовал, и это сработало отлично.

В противном случае это было бы проблематично, поскольку карты NVidia поддерживают 11.1 только с их поколения 900x.

person mrvux    schedule 14.09.2016
comment
Итак, что произойдет, если среда выполнения будет 11.0? Должен ли я сначала каким-то образом обнаруживать обновление платформы Win7 и не передавать флаг, если он отсутствует? - person Peter; 14.09.2016
comment
Для пояснения: карты Geforce серии 900 на базе чипов Maxwell 2-го поколения (GM2xx) поддерживают уровень функций 12_0. . 1-е поколение (GM1xx) поддерживает только 11_0. 960M основан на GM107 (1-го поколения) - person Ivan Aksamentov - Drop; 14.09.2016
comment
Да, это все, к сожалению, у меня больше нет машины с Windows 7, поэтому я не могу попробовать. - person mrvux; 14.09.2016
comment
Я нашел машину с Windows 7 без DX11.1. Передача флага завершается с ошибкой HRESULT: [0x80004005], Module: [General], ApiCode: [E_FAIL/Unspecified error], Message: Unspecified error. Удивительно, но KB2670838 и IE10 уже были установлены, а d3d11.dll имела версию 6.2.9200.16570, но DX11.1 все еще не был установлен. - person Peter; 14.09.2016
comment
Хорошо, тогда это решает - person mrvux; 14.09.2016
comment
Несколько замечаний: для KB2670838 требуется пакет обновления 1 (SP1) для Windows 7. На самом деле это не так уж сильно блокирует, поскольку Windows 7 RTM полностью не поддерживается, а программы VS 2015 C++ даже не могут работать на нем. См. это блог и это. - person Chuck Walbourn; 15.09.2016
comment
@ChuckWalbourn Это на машине с установленным пакетом обновления 1 для Windows 7 и KB2670838. Но d3d11_1.dlld3d11_*sdklayers.dll тоже) нет. Ваш чек IsDirect3D11_1OrGreater() возвращает true. - person Peter; 21.09.2016
comment
но если я передаю флаг, он терпит неудачу (возвращает false) там. (Работает и возвращает true в Win10.) - person Peter; 21.09.2016
comment
Вам вернут E_INVALIDARG или E_FAIL? Теперь я подозреваю, что в системе есть DirectX 11.1, но Windows 7 не поддерживает драйверы WDDM 1.2. Я не ожидал, что для флага тайм-аута потребуются новые драйверы, но это может быть. Обратите внимание, что d3d11_*sdklayers.dll устанавливается Windows 8 SDK для Windows 7 SP1+KB2670838. Устаревший DirectX SDK не поддерживает DirectX 11.1 или более позднюю версию. - person Chuck Walbourn; 21.09.2016
comment
Я получаю E_FAIL. Я нашел еще две машины с Win7SP1+KB2670838. В обоих dxdiag.exe отчетах Drivers for Driver Model: WDDM 1.1. Оба возвращают true для вашего IsDirect3D11_1OrGreater(). Передача флага проходит успешно на M2 (NVidia, различные SDK установлены), но не работает на M3 (ATI, без SDK) так же, как и на начальном M1 (также Win7SP1+KB, ATI, без SDK, WDDM1.1). - person Peter; 22.09.2016
comment
(M1 — это NVidia.) - person Peter; 22.09.2016

Это относится к версии во время выполнения.

Вы можете определить версию ОС, но вам может быть проще проверить установленную версию среды выполнения DirectX .dll, попробовав LoadLibrary на:

{ 
    "d3d11.dll",
    "d3d11_1.dll",
    "d3d11.dll",
    "d3d11_1sdklayers.dll",
    "d3d11_2sdklayers.dll",
    "d3d11_3sdklayers.dll",
    "d3d12.dll"
}

последовательно, пока не произойдет сбой (возвращает NULL). Или в обратном порядке, пока не получится. Это тот же хак, что и при создании устройства с максимальным уровнем возможностей.

person Ivan Aksamentov - Drop    schedule 14.09.2016
comment
Никогда не используйте определение версии ОС для проверки функции. См. Что такое номер версии? . По умолчанию вы даже не получите истинный номер версии ОС в Windows 8.1 или Windows 10. См. Явное безумие. Проверка LoadLibrary DLL также проблематична, но, по крайней мере, это лучший вариант, чем пытаться сделать вывод из версии ОС. Простое решение — создать устройство 11, QI устройство 11.1. Если это работает, у вас 11.1 или выше. - person Chuck Walbourn; 15.09.2016
comment
В данном случае да. Вы никогда не должны решать с помощью зависимости LoadLibrary, которую можно решить более надежно с помощью прямой проверки функций. В этом случае вызов QueryInterface для ID3D11Device1 вне ID3D11Device является самым надежным и прямым способом узнать, есть ли у вас среда выполнения Direct3D 11.1. Да, это означает, что вы создаете устройство без флага, а затем делаете это снова, когда знаете, что оно работает. - person Chuck Walbourn; 16.09.2016