2

IDXGIFactory 接口的引用告诉我,为了创建交换链,我可能会使用与创建 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 这样的方法,它会使适配器成为设备的父级。但事实并非如此。为什么适配器是设备的父级?

4

1 回答 1

3

问题的根源可以追溯到 DXGI 1.0 (Direct3D 10) 和 DXGI 1.1 (Direct3D 11)。如果您尝试在同一过程中使用两者IDXGIFactory创建的a ,事情会很快变成梨形。CreateDXGIFactoryCreateDXGIFactory1

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

文档中的第二步应该dxgiDevice->GetAdapter不是dxgiDevice->GetParent. 我会为此提交一个文档错误。

如果使用,这更容易做到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 进行了清理,您不能使用 QIIDXGIDeviceID3D12Device.

参考

DirectX 图形基础结构 (DXGI):
Direct3D 11 创建设备的最佳实践剖析

于 2015-07-11T16:06:02.333 回答