【问题标题】:Can D3D11_CREATE_DEVICE_DISABLE_GPU_TIMEOUT be passed with D3D_FEATURE_LEVEL_11_0?D3D11_CREATE_DEVICE_DISABLE_GPU_TIMEOUT 可以与 D3D_FEATURE_LEVEL_11_0 一起传递吗?
【发布时间】:2016-09-14 13:11:13
【问题描述】:

MSDN on D3D11_CREATE_DEVICE_DISABLE_GPU_TIMEOUT 说:

Direct3D 11:直到 Direct3D 11.1 才支持此值。

这是指运行时版本还是功能级别?

我可以将标志传递给D3D11CreateDevice,但只能通过功能级别 11_0?

功能级别是否无关紧要,仅取决于安装的运行时版本?如果我将标志传递给 DX 运行时 11.0,会发生什么情况?它会被默默地忽略吗?还是我必须先以某种方式检测 DX 运行时版本,然后仅在 DX 运行时版本至少为 11.1 时才传递标志?

【问题讨论】:

标签: directx direct3d direct3d11


【解决方案1】:

确定您是否拥有 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-heavy 程序,这些程序可以随意占用 GPU,并可能导致系统对 UI 无响应。谨慎使用。

这也意味着您的应用程序需要 Direct3D 功能级别 11.0 或更高版本的卡才能使用 DirectCompute 5.0 - 或者 - 它需要 Direct3D 功能级别 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 and Windows 7DirectX 11.1 and Windows 7 Update

【讨论】:

  • 这声称 D3D11.1 运行时在 Win7SP1+KB2670838 上可用,但在那里传递 D3D11_CREATE_DEVICE_DISABLE_GPU_TIMEOUT 标志失败。知道为什么吗?
  • 抱歉,我需要在我的 Windows 7 设置上仔细检查。该标志是“已知的”,但它可能需要 Win7SP1+KB2670838 不支持的较新驱动程序。根据MSDN Win7SP1+KB2670838 上的 DirectX 11.1 提供所有“软件”功能,但不提供任何需要 Win7SP1 不支持的WDDM 1.2 驱动程序的功能。
  • 我已经确认您实际上可以在安装了 KB 2670838 的 Windows 7 Service Pack 1 上使用 D3D11_CREATE_DEVICE_DISABLE_GPU_TIMEOUT 标志。
  • 遗憾的是,它并不总是有效,请参阅comment below
  • 嗯,这里也一定有驱动行为依赖。听起来您必须使用标志创建设备,如果失败,请在没有它​​的情况下重试。我假设您的应用程序在没有设置标志的情况下失败?
【解决方案2】:

这是关于运行时版本,因此您至少需要 Windows 8 才能启用此功能。

您可以在拥有此标志的同时请求仅功能级别 11 的设备,刚刚尝试过并且效果很好。

否则会出现问题,因为 NVidia 卡从 900x 代起才支持 11.1。

【讨论】:

  • 那么如果运行时是 11.0 会发生什么?我是否必须先以某种方式检测 Win7 平台更新,并确保在它丢失时不传递标志?
  • 澄清一下:900 series Geforce 基于第二代 Maxwell 芯片 (GM2xx) 的卡支持功能级别 12_0。第一代 (GM1xx) 仅支持 11_0。 960M 基于 GM107(第一代)
  • 是的,就是这样,可惜没有windows 7机器,所以我无法尝试。
  • 我发现一台没有DX11.1的windows 7机器。传递标志失败,HRESULT: [0x80004005], Module: [General], ApiCode: [E_FAIL/Unspecified error], Message: Unspecified error。奇怪的是KB2670838和IE10已经安装了,d3d11.dll的版本是6.2.9200.16570,但是DX11.1还没有安装。
  • 好的,那就解决它
【解决方案3】:

它指的是运行时版本。

您可能会检测到操作系统版本,但您可以通过检查已安装的 DirectX 运行时 .dll 版本来更轻松地检查,方法是尝试打开 LoadLibrary

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

依次直到失败(返回NULL)。或者以相反的顺序,直到成功。这与创建具有最高功能级别的设备相同。

【讨论】:

  • 切勿使用操作系统版本检测来检查功能。见What’s in a version number?。默认情况下,您甚至不会在 Windows 8.1 或 Windows 10 上获得“真正的”操作系统版本号。请参阅 Manifest MadnessLoadLibrary DLL 检查也存在问题,但至少比尝试从操作系统版本推断它更好。一个简单的解决方案是创建一个 11 设备,QI 一个 11.1 设备。如果它有效,则您拥有 11.1 或更高版本。
  • 在这种情况下,是的。你永远不应该使用 LoadLibrary 依赖来解决,你可以通过直接的功能检查来更稳健地解决。在这种情况下,从ID3D11Device 调用QueryInterface 以获得ID3D11Device1 是查看您是否拥有Direct3D 11.1 运行时的最可靠和直接的方法。是的,这意味着您创建没有标志的设备,然后在您知道它有效时再做一次。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-05-21
  • 2018-09-19
  • 1970-01-01
  • 2011-08-15
  • 2018-02-16
  • 2020-06-30
  • 2014-11-15
相关资源
最近更新 更多