Поделиться через


Перечисление возможностей обработчика GPU

Начиная с Windows 8.1, драйвер минипорта дисплея должен реализовывать функцию DxgkDdiGetNodeMetadata, которая используется для запроса возможностей подсистемы узла GPU.

Эти сведения помогают оценить планирование и распределение рабочих нагрузок между узлами, а также улучшить возможность отладки приложений.

Интерфейс драйвера устройства (DDI) возможностей подсистемы

Этот интерфейс предоставляет возможности подсистемы указанного узла GPU:

Указатель на функцию DxgkDdiGetNodeMetadata предоставляется элементом DxgkDdiGetNodeMetadata структуры DRIVER_INITIALIZATION_DATA .

Архитектура узла GPU

Каждый видеоадаптер в системе имеет несколько различных модулей, доступных для планирования задач. Каждый модуль назначается только одному узлу, но каждый узел может содержать несколько модулей, если этот узел связан с несколькими адаптерами, например в конфигурации связанного видеоадаптера (LDA), где несколько физических GPU связаны для формирования одного более быстрого виртуального GPU.

Схема, показывающая архитектуру ядр и узлов GPU.

Разные узлы представляют асимметричные вычислительные ядра GPU, а подсистемы в каждом узле представляют симметричные ядра обработки в адаптерах. То есть трехмерный узел содержит только идентичные трехмерные модули на нескольких адаптерах и никогда не имеет другого типа двигателя.

Так как подсистемы всегда группируются в узлах по типу подсистемы, сведения о типе подсистемы можно запрашивать на основе указанного узла. Типы подсистемы, которые может указать драйвер мини-порта дисплея, перечислены в перечислении DXGK_ENGINE_TYPE .

Пример реализации функции метаданных узла

В этом коде показано, как драйвер минипорта дисплея может реализовать некоторые типы подсистем, которые могут быть возвращены функцией DxgkDdiGetNodeMetadata .

NTSTATUS
IHVGetNodeDescription(
        IN_CONST_HANDLE                     hAdapter,
        UINT                                NodeOrdinal,
        OUT_PDXGKARG_GETNODEMETADATA        pGetNodeMetadata
        )
{
    DDI_FUNCTION();
    PAGED_CODE();

    if(NULL == pGetNodeMetadata)
    {
        return STATUS_INVALID_PARAMETER;
    }

    CAdapter *pAdapter = GetAdapterFromHandle(hAdapter);

    //Invalid handle
    if(NULL == pAdapter)
    {
        return STATUS_INVALID_PARAMETER;
    }

    //Node ordinal is out of bounds. Required to return
    //STATUS_INVALID_PARAMETER
    if(NodeOrdinal >= pAdapter->GetNumNodes())
    {
        return STATUS_INVALID_PARAMETER;
    }

    switch(pAdapter->GetEngineType(NodeOrdinal))
    {
        //This is the adapter's 3-D engine. This engine handles a large number
        //of different workloads, but it also handles the adapter's 3-D 
        //workloads. Therefore the 3-D capability is what must be exposed.
        case GPU_ENGINE_3D:
        {
            pGetNodeMetadata->EngineType = DXGK_ENGINE_TYPE_3D;
            break;
        }

        //This is the adapter's video decoding engine
        case GPU_ENGINE_VIDEO_DECODE:
        {
            pGetNodeMetadata->EngineType = DXGK_ENGINE_TYPE_VIDEO_DECODE;
            break;
        }

        //This engine is proprietary and contains no functionality that
        //fits the DXGK_ENGINE_TYPE enumeration
        case GPU_ENGINE_PROPRIETARY_ENGINE_1:
        {
            pGetNodeMetadata->EngineType = DXGK_ENGINE_TYPE_OTHER;

            //Copy over friendly name associated with this engine
            SetFriendlyNameForEngine(pGetNodeMetadata->FriendlyName,
                                     DXGK_MAX_METADATA_NAME_LENGTH,
                                     PROPRIETARY_ENGINE_1_NAME);
            break;
        }
    }

    return STATUS_SUCCESS;
}