Debug and factory

When starting writing your Direct3D 12 application, commonly the first step is to create an IDXGIFactory object. Before doing so, you might want to make sure you are running Direct3D 12 with Debug layers enabled, however. This can be done by doing the following:

ID3D12Debug* debug;
result = D3D12GetDebugInterface ( &IID_ID3D12Debug, (void**)&debug);
if ( !SUCCEEDED(result) )
{
    return; // Failure!
}
debug->lpVtbl->EnableDebugLayer(debug);

This code will query the ID3D12Debug object from the runtime, allowing you to specify a state for the debug layer to be either enabled or disabled. It is encouraged to do this as soon as possible when you want to enable the debug functionality, as it is otherwise easy for calls to DirectX or DXGI functions to not fall under debug reporting, making it harder to debug those functions.

Right up next, it is time to create the IDXGIFactory object. As you might notice from DirectX code, these classes commonly have variants with numerical suffices and a single non-suffixed version. The suffixed versions are updated versions of the interface, expanding the class with additional functionality.

In the case of DirectX 12, the functions we are going to need are not included yet until IDXGIFactory2. However, we will be using IDXGIFactory4, as this version also includes the EnumWarpAdapter function, which will become relevant at a later stage. It is not required, but can provide significant advantages.

result = CreateDXGIFactory2(
#if DEBUG_RENDERER
    DXGI_CREATE_FACTORY_DEBUG,
#else
    0,
#endif
    &IID_IDXGIFactory4,
    (void**)&renderer->dxgiFactory
);
if ( FAILED(result) )
    return; // Failure!

In order to create the factory, we are using the CreateDXGIFactory2 function. CreateDXGIFactory and CreateDXGIFactory1 are legacy versions of this functions performing the same purpose in theory, but intended for earlier versions of DirectX. (10 and 11 respectively) CreateDXGIFactory2 included the ability for flags to be passed, which we are using in order to create a debug version of the DXGI factory.

In the second parameter, you will note that we are passing &IID_IDXGIFactory4. This indicates that the object we intend to create is a IDXGIFactory4 object.

Note: If you are working in C++ instead of C, an alternative (and potentially more type-safe) approach is to replace the last 2 input parameters with IID_PPV_ARGS(&renderer->dxgiFactory). This will automatically deduce the variable type of renderer->dxgiFactory, pass the UID for that type, and then pass the pointer to the object itself.