Device and device context

With the desired adapter selected, we can move on to creating the DirectX 11 device and device context.

The DirectX 11 device (ID3D11Device) is the object responsible for creating objects for use by the DirectX 11 renderer on the desired adapter, and is therefore mostly encountered in initialization and where objects are either created or destroyed.

The DirectX 11 device context (ID3D11DeviceContext) is the object responsible for submitting commands to the adapter to execute. This includes render commands, but also data transfer updates etc. This is the object primarily used during the rendering process.

In order to create the device, we need not just the adapter, but also specify which feature levels we would like to be able to use. A feature level is a list of minimum requirements the hardware needs to be capable of delivering on at least in order to function. Hardware that cannot fulfill the list of requirements for a specific feature level will not be allowed to be created with that feature level.

A list of feature levels allowed can be found here.

In DirectX 11 we do not specify a feature level directly, but instead specify an array of feature levels. The runtime will then automatically process each feature level in the array in order and see if it is supported on the adapter. The first feature level found to be compatible will then be used in actually creating the device, and the feature level that passed the creation of the device will be returned in the parameter marked &outFeatureLevel.

In the case of a development build, specifying D3D11_CREATE_DEVICE_DEBUG is highly recommended. This will significantly slow down the DirectX 11 runtime, but will provide useful information on invalid or suboptimal usage of the API in Visual Studio's output window. This will allow for big mistakes to be tracked down easily.

D3D_FEATURE_LEVEL featureLevels[] = {
    D3D_FEATURE_LEVEL_11_1,
    D3D_FEATURE_LEVEL_11_0,
};
D3D_FEATURE_LEVEL outFeatureLevel = D3D_FEATURE_LEVEL_9_1;
for ( uint32_t i = 0; i < adapterCount; i++ )
{
    result = D3D11CreateDevice (
        (IDXGIAdapter*)adapters[i],
        D3D_DRIVER_TYPE_UNKNOWN,
        NULL,
#if DEBUG_RENDERER
        D3D11_CREATE_DEVICE_DEBUG,
#else
        0,
#endif
        featureLevels,
        STATIC_ARRAY_SIZE(featureLevels),
        D3D11_SDK_VERSION,
        &renderer->device,
        &outFeatureLevel,
        &renderer->deviceContext
    );
    if ( SUCCEEDED ( result ) )
        break;
}

if ( !renderer->device )
    RETURN_ERROR(-1, "Failed to create device" );