Зачем использовать один и тот же IDXGIFactory для устройства и цепочки подкачки


Ссылка на интерфейс IDXGIFactory говорит мне, что для создания цепочки подкачки я мог бы использовать ту же фабрику, которая использовалась для создания устройства Direct3D:

Поскольку вы можете создать устройство Direct3D без создания цепочки подкачки, вам может потребоваться получить фабрику, которая используется для создания устройства, чтобы создать цепочку подкачки.

Он также дает следующий код exmaple:

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 2

1 ответ:

Корень проблемы восходит к DXGI 1.0 (в Direct3D 10) и DXGI 1.1 (в Direct3D 11). Если вы попытаетесь использовать IDXGIFactory, созданный как CreateDXGIFactory, так и CreateDXGIFactory1 в одном и том же процессе, все пойдет довольно быстро.

Другая проблема заключается в том, что существует неявная фабрика, созданная при использовании "устройства по умолчанию" с 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, и вы не можете использовать QI для получения IDXGIDeviceиз ID3D12Device.

Ссылки

Графическая инфраструктура DirectX (DXGI): рекомендации
Анатомия Direct3D 11 создание устройства