Enumerazione delle funzionalità del motore GPU
A partire da Windows 8.1, un driver miniport di visualizzazione deve implementare la funzione DxgkDdiGetNodeMetadata, usata per eseguire query sulle funzionalità del motore di un nodo GPU.
Queste informazioni consentono di valutare il modo in cui i carichi di lavoro vengono pianificati e distribuiti tra i nodi e migliorano la possibilità di eseguire il debug delle applicazioni.
Funzionalità del motore dell'interfaccia del driver di dispositivo (DDI)
Questa interfaccia offre le funzionalità del motore di un nodo GPU specificato:
Un puntatore alla funzione DxgkDdiGetNodeMetadata viene fornito dal membro DxgkDdiGetNodeMetadata della struttura DRIVER_INITIALIZATION_DATA .
Architettura dei nodi GPU
Ogni scheda di visualizzazione nel sistema dispone di diversi motori disponibili per pianificare le attività. Ogni motore viene assegnato a un solo nodo, ma ogni nodo può contenere più di un motore se tale nodo è associato a più schede, ad esempio nella configurazione dell'adattatore di visualizzazione collegato (LDA), in cui più GPU fisiche sono collegate per formare un'unica GPU virtuale più veloce.
Nodi diversi rappresentano i core di elaborazione asimmetrica della GPU, mentre i motori all'interno di ogni nodo rappresentano i core di elaborazione simmetrica tra schede. Ovvero, un nodo 3D contiene solo motori 3D identici su più schede e mai un tipo di motore diverso.
Poiché i motori vengono sempre raggruppati in nodi in base al tipo di motore, è possibile eseguire query sulle informazioni sul tipo di motore in base a un nodo specificato. I tipi di motore che il driver miniport visualizzato può specificare sono elencati nell'enumerazione DXGK_ENGINE_TYPE .
Implementazione di esempio della funzione dei metadati del nodo
Questo codice mostra come un driver miniport di visualizzazione può implementare alcuni dei tipi di motore che possono essere restituiti dalla funzione 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;
}