direct3ddxgi

What is the additional (Software) DXGI Adapter for?


I am talking about this particular paragraph:

Starting with Windows 8, an adapter called the "Microsoft Basic Render Driver" is always present. This adapter has a VendorId of 0x1414 and a DeviceID of 0x8c. This adapter also has the DXGI_ADAPTER_FLAG_SOFTWARE value set in the Flags member of its DXGI_ADAPTER_DESC2 structure. This adapter is a render-only device that has no display outputs. DXGI never returns DXGI_ERROR_DEVICE_REMOVED for this adapter.

This Adapter is always enumerated. But it has no output (displays) and thus no display modes? Does that mean I can't create a swapchain with it?

It is a render-only device, does that mean it has no compute capabilities?

What is this particular adapter actually used for when it has no outputs?


Solution

  • Microsoft Basic Render Driver is the modern replacement for the 'legacy VGA' fallback option. It is essentially WARP+VGA. I believe the docs are referencing to the fact that it has no "DXGI Output" object associated with it.

    For Direct3D 11, I talk about the recommendations are for dealing with MBR in applications in this blog post.

    For example:

    ComPtr<IDXGIDevice> dxgiDevice;
    if (SUCCEEDED(device.As(&dxgiDevice)))
    {
        ComPtr<IDXGIAdapter> adapter;
        if (SUCCEEDED(dxgiDevice->GetAdapter(&adapter)))
        {
            DXGI_ADAPTER_DESC desc;
            if (SUCCEEDED(adapter->GetDesc(&desc)))
            {
                if ( (desc.VendorId == 0x1414) && (desc.DeviceId == 0x8c) )
                {
                    // WARNING: Microsoft Basic Render Driver is active.
                    // Performance of this application may be unsatisfactory.
                    // Please ensure that your video card is Direct3D10/11 capable
                    // and has the appropriate driver installed.
                }
            }
        }
    }
    

    When doing device enumeration, you use the flag to filter it out, but know it can STILL end up being MBR if there's no other device on the system and you use 'default':

    // This method acquires the first available hardware adapter.
    // If no such adapter can be found, *ppAdapter will be set to nullptr.
    void GetHardwareAdapter(IDXGIAdapter1** ppAdapter)
    {
        *ppAdapter = nullptr;
    
        ComPtr<IDXGIAdapter1> adapter;
    
        ComPtr<IDXGIFactory6> factory6;
        HRESULT hr = m_dxgiFactory.As(&factory6);
        if (SUCCEEDED(hr))
        {
            for (UINT adapterIndex = 0;
                SUCCEEDED(factory6->EnumAdapterByGpuPreference(
                    adapterIndex,
                    DXGI_GPU_PREFERENCE_HIGH_PERFORMANCE,
                    IID_PPV_ARGS(adapter.ReleaseAndGetAddressOf())));
                adapterIndex++)
            {
                DXGI_ADAPTER_DESC1 desc;
                ThrowIfFailed(adapter->GetDesc1(&desc));
    
                if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE)
                {
                    // Don't select the Basic Render Driver adapter.
                    continue;
                }
    
            #ifdef _DEBUG
                wchar_t buff[256] = {};
                swprintf_s(buff, L"Direct3D Adapter (%u): VID:%04X, PID:%04X - %ls\n", adapterIndex, desc.VendorId, desc.DeviceId, desc.Description);
                OutputDebugStringW(buff);
            #endif
    
                break;
            }
        }
    
        if (!adapter)
        {
            for (UINT adapterIndex = 0;
                SUCCEEDED(m_dxgiFactory->EnumAdapters1(
                    adapterIndex,
                    adapter.ReleaseAndGetAddressOf()));
                adapterIndex++)
            {
                DXGI_ADAPTER_DESC1 desc;
                ThrowIfFailed(adapter->GetDesc1(&desc));
    
                if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE)
                {
                    // Don't select the Basic Render Driver adapter.
                    continue;
                }
    
    #ifdef _DEBUG
                wchar_t buff[256] = {};
                swprintf_s(buff, L"Direct3D Adapter (%u): VID:%04X, PID:%04X - %ls\n", adapterIndex, desc.VendorId, desc.DeviceId, desc.Description);
                OutputDebugStringW(buff);
    #endif
    
                break;
            }
        }
    
        *ppAdapter = adapter.Detach();
    }