【问题标题】:Handling DisplayInformation::DisplayContentsInvalidated in D3D12在 D3D12 中处理 DisplayInformation::DisplayContentsInvalidated
【发布时间】:2021-01-05 10:41:07
【问题描述】:

在 C++/CX D3D12 的 VS2019 项目模板中,订阅了 DisplayInformation::DisplayContentsInvalidated 事件(记录在 here),当此事件触发时,项目模板中的代码会尝试验证 D3D12 设备。用于验证的标准是 default 适配器是否已更改:

// This method is called in the event handler for the DisplayContentsInvalidated event.
void DX::DeviceResources::ValidateDevice()
{
    // The D3D Device is no longer valid if the default adapter changed since the device
    // was created or if the device has been removed.

    // First, get the LUID for the default adapter from when the device was created.

    DXGI_ADAPTER_DESC previousDesc;
    {
        ComPtr<IDXGIAdapter1> previousDefaultAdapter;
        DX::ThrowIfFailed(m_dxgiFactory->EnumAdapters1(0, &previousDefaultAdapter));

        DX::ThrowIfFailed(previousDefaultAdapter->GetDesc(&previousDesc));
    }

    // Next, get the information for the current default adapter.

    DXGI_ADAPTER_DESC currentDesc;
    {
        ComPtr<IDXGIFactory4> currentDxgiFactory;
        DX::ThrowIfFailed(CreateDXGIFactory1(IID_PPV_ARGS(&currentDxgiFactory)));

        ComPtr<IDXGIAdapter1> currentDefaultAdapter;
        DX::ThrowIfFailed(currentDxgiFactory->EnumAdapters1(0, &currentDefaultAdapter));

        DX::ThrowIfFailed(currentDefaultAdapter->GetDesc(&currentDesc));
    }

    // If the adapter LUIDs don't match, or if the device reports that it has been removed,
    // a new D3D device must be created.

    if (previousDesc.AdapterLuid.LowPart != currentDesc.AdapterLuid.LowPart ||
        previousDesc.AdapterLuid.HighPart != currentDesc.AdapterLuid.HighPart ||
        FAILED(m_d3dDevice->GetDeviceRemovedReason()))
    {
        m_deviceRemoved = true;
    }
}

但是,在我看来 default 适配器可能不是 elected 适配器,正如您在这段代码中看到的那样,因为它确保适配器可以创建一个D3D12 设备在选择之前,并且上面的验证代码中不存在相同的检查:

// This method acquires the first available hardware adapter that supports Direct3D 12.
// If no such adapter can be found, *ppAdapter will be set to nullptr.
void DX::DeviceResources::GetHardwareAdapter(IDXGIAdapter1** ppAdapter)
{
    ComPtr<IDXGIAdapter1> adapter;
    *ppAdapter = nullptr;

    for (UINT adapterIndex = 0; DXGI_ERROR_NOT_FOUND != m_dxgiFactory->EnumAdapters1(adapterIndex, &adapter); adapterIndex++)
    {
        DXGI_ADAPTER_DESC1 desc;
        adapter->GetDesc1(&desc);

        if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE)
        {
            // Don't select the Basic Render Driver adapter.
            continue;
        }

        // Check to see if the adapter supports Direct3D 12, but don't create the
        // actual device yet.
        if (SUCCEEDED(D3D12CreateDevice(adapter.Get(), D3D_FEATURE_LEVEL_11_0, _uuidof(ID3D12Device), nullptr)))
        {
            break;
        }
    }

    *ppAdapter = adapter.Detach();
}

这是否无意中依赖默认适配器作为选择的适配器,或者我们可以根据默认适配器的更改做出更广泛的假设?

DisplayInformation::DisplayContentsInvalidated的真正含义是什么?这是在告诉我什么?为什么这表明该设备可能无效?在哪些情况下会触发此事件并且设备会无效或不会无效?

由于我们也在此处检查DeviceRemovedReason,是否存在默认适配器未更改但设备因DisplayInformation::DisplayContentsInvalidated 而被删除的情况?

我们真的需要处理这个吗?如果我完全忽略此事件并继续尝试渲染会发生什么?我不会最终处理此事件触发在记录的“设备丢失场景”中根据this document 指示的任何问题吗?

【问题讨论】:

  • “和上面的验证码中不存在同样的检查”是什么意思?是不是表示previousDefaultAdapter 和currentDxgiFactory 不匹配?能否提供一个简单的样本供我们测试?
  • 我的意思是验证代码不会调用D3D12CreateDevice 来查看是否可以像GetHardwareAdapter 函数那样使用默认适配器创建D3D12 设备。我不清楚为什么默认设备在这里是相关的。目前尚不清楚这种验证的基础是什么。
  • 这个简单的例子可以通过DirectX 12 App (Universal Windows C++/CX)项目模板在VS2019中新建项目轻松获取。

标签: visual-studio uwp direct3d


【解决方案1】:

我们仍在调查您的问题并获取一些信息。

关于何时触发 DisplayContentInvalidated 事件,通常会在各种活动(包括更改主显示器或显示器配置以任何其他方式发生更改)时调用它。这还包括图形是否出现某些类型的问题,应该能够利用此事件来处理此类情况。

关于模板,我们最终运行了一些测试,我们确实看到该项目使用了它发现的第一个可以处理 DirectX12 的适配器,而不是选定的适配器。经过进一步测试,我们删除了该特定检查,发现应用程序确实继续按预期运行。适配器可能不是用于在应用程序启动时创建设备的适配器。因此,确实,此检查似乎确实可以按照指示被忽略。但是,在代码中包含此事件可能不会有什么坏处,因为它可以在任何情况下提供额外的功能。

任何其他详细信息都可能在我们的文档中找到。但是,该模板似乎是为了演示 DirextX12 的某些功能及其各种 API,因此忽略 DisplayContentInvalidated 事件通常不会导致任何问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-16
    • 2021-10-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多