Ссылка 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, который сделал бы адаптер родителем устройства. Но это не тот случай. Почему адаптер является родителем устройства?
Корень проблемы восходит к 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 Создать устройство