Factory and adapters

Before being able to use DirectX 11 directly, we first need to determine the adapter we would like to run the DirectX 11 renderer on. To do this, we need to request the adapter(s) from DXGI. DXGI stands for DirectX Graphics Interface, and is what links the DirectX API to the machine and window on the screen.

To query the adapters from DXGI, we first need a DXGI factory object. This is done using the CreateDXGIFactory function. In this case we use CreateDXGIFactory2 in order to be able to create an IDXGIFactory4 and create it with the debug flag set. Previous versions of this function call had restrictions in this regard.

result = CreateDXGIFactory2(
#if DEBUG_RENDERER
    DXGI_CREATE_FACTORY_DEBUG,
#else
    0,
#endif
    &IID_IDXGIFactory4,
    (void**)&renderer->dxgiFactory
);
if ( FAILED(result) )
    RETURN_ERROR(-1, "CreateDXGIFactory2 failed (0x%08X)", result );

With the factory, we can now query adapters using the EnumAdapters1 function. Alternatively, we can query a WARP adapter using the EnumWarpAdapter function. “WARP” stands for Windows Advanced Rasterization Platform, and is a full DirectX 11-compliant renderer implemented in software.

In the code below we query up to 4 hardware adapters, and insert the WARP adapter if it exists and we still have space for it. If we do not have any more space for the WARP adapter, we overwrite the last hardware adapter with the WARP device.

If we exclusively want to run with WARP or hardware, we can disable either ALLOW_HARDWARE_ADAPTERS or ALLOW_WARP_ADAPTERS.

IDXGIAdapter1* adapters[4] = { NULL };
uint32_t adapterCount = 0;
#if ALLOW_HARDWARE_ADAPTERS
while ( adapterCount < (STATIC_ARRAY_SIZE(adapters)-1) && renderer->dxgiFactory->lpVtbl->EnumAdapters1 ( renderer->dxgiFactory, adapterCount, &adapters[adapterCount] ) != DXGI_ERROR_NOT_FOUND )
{
    adapterCount++;
}
#endif
#if ALLOW_WARP_ADAPTER
uint32_t warpIndex = RVM_MIN(adapterCount,STATIC_ARRAY_SIZE(adapters)-1);
if ( SUCCEEDED ( renderer->dxgiFactory->lpVtbl->EnumWarpAdapter ( renderer->dxgiFactory, &IID_IDXGIAdapter1, &(void*)adapters[warpIndex] ) ) )
{
    adapterCount = warpIndex + 1;
}
#endif