为什么在设备和交换链中使用相同的IDXGIFactory

时间:2015-07-11 13:37:50

标签: c++ directx direct3d dxgi

IDXGIFactory interface的引用告诉我,为了创建交换链,我可能会使用与创建Direct3D设备相同的工厂:

  

因为您可以在不创建交换链的情况下创建Direct3D设备,所以您可能需要检索用于创建设备的工厂以创建交换链。

它还提供以下代码:

IDXGIDevice * pDXGIDevice;
hr = g_pd3dDevice->QueryInterface(__uuidof(IDXGIDevice), (void **)&pDXGIDevice);

IDXGIAdapter * pDXGIAdapter;
hr = pDXGIDevice->GetParent(__uuidof(IDXGIAdapter), (void **)&pDXGIAdapter);

IDXGIFactory * pIDXGIFactory;
pDXGIAdapter->GetParent(__uuidof(IDXGIFactory), (void **)&pIDXGIFactory);

这篇文章很随意,当试图完全理解它时,出现了以下两个问题,而第一个问题是主要问题(关于这个主题的标题):

为什么我必须使用与创建Direct3D设备相同的工厂来创建交换链?工厂实例是否维护一个重要的内部状态,或者只是为了避免创建另一个消耗资源的工厂实例?

此外,在代码示例中,我努力使用以下代码行:

hr = pDXGIDevice->GetParent(__uuidof(IDXGIAdapter), (void **)&pDXGIAdapter);

对我而言,IDXGIAdapter是IDXGIDevice的父级是不合逻辑的。否则我希望IDXGIAdapter有一个类似CreateDevice的方法,它会使适配器成为设备的父节点。但事实并非如此。为什么适配器是设备的父级?

1 个答案:

答案 0 :(得分:3)

问题的根源可以追溯到DXGI 1.0(Direct3D 10)和DXGI 1.1(Direct3D 11)。如果您尝试在同一过程中使用由IDXGIFactoryCreateDXGIFactory创建的CreateDXGIFactory1,那么事情就会很快变成梨状。

另一个问题是,当您使用Direct3D 10.x或11.x设备创建的“默认设备”时,会创建一个隐式工厂。上面的“魔术代码序列”允许您隐式创建工厂。

文档中的第二步应为dxgiDevice->GetAdapter而不是dxgiDevice->GetParent。我将提交一份doc bug。

如果使用Microsoft::WRL::ComPtr

,这样做会更容易
    // First, retrieve the underlying DXGI Device from the D3D Device
    ComPtr<IDXGIDevice1> dxgiDevice;
    DX::ThrowIfFailed(m_d3dDevice.As(&dxgiDevice));

    // Identify the physical adapter (GPU or card) this device is running on.
    ComPtr<IDXGIAdapter> dxgiAdapter;
    DX::ThrowIfFailed(dxgiDevice->GetAdapter(dxgiAdapter.GetAddressOf()));

    // And obtain the factory object that created it.
    ComPtr<IDXGIFactory1> dxgiFactory;
    DX::ThrowIfFailed(dxgiAdapter->GetParent(__uuidof(IDXGIFactory1), &dxgiFactory));

Direct3D 12

请注意,整个区域已使用Direct3D 12进行清理,您无法使用QI从IDXGIDevice获取ID3D12Device

<强>参考

DirectX Graphics Infrastructure (DXGI): Best Practices
Anatomy of Direct3D 11 Create Device