Enumerando recursos do mecanismo de GPU
A partir de Windows 8.1, um driver de miniporto de exibição deve implementar a função DxgkDdiGetNodeMetadata, que é usada para consultar as funcionalidades do mecanismo de um nó de GPU.
Essas informações ajudam na avaliação de como as cargas de trabalho são agendadas e distribuídas entre nós e melhora a capacidade de depurar aplicativos.
DDI (interface do driver de dispositivo) de funcionalidades do mecanismo
Essa interface fornece os recursos do mecanismo de um nó de GPU especificado:
Um ponteiro para a função DxgkDdiGetNodeMetadata é fornecido pelo membro DxgkDdiGetNodeMetadata da estrutura DRIVER_INITIALIZATION_DATA .
Arquitetura de nó de GPU
Cada adaptador de exibição no sistema tem vários mecanismos diferentes disponíveis para agendar tarefas. Cada mecanismo é atribuído a apenas um nó, mas cada nó pode conter mais de um mecanismo se esse nó estiver associado a vários adaptadores, como na configuração do LDA (adaptador de exibição vinculado), em que várias GPUs físicas são vinculadas para formar uma GPU virtual única e mais rápida.
Nós diferentes representam os núcleos de processamento assimétrico da GPU, enquanto os mecanismos dentro de cada nó representam os núcleos de processamento simétricos entre adaptadores. Ou seja, um nó 3D contém apenas mecanismos 3D idênticos em vários adaptadores e nunca um tipo de mecanismo diferente.
Como os mecanismos são sempre agrupados em nós por tipo de mecanismo, as informações de tipo de mecanismo podem ser consultadas com base em um nó especificado. Os tipos de mecanismo que o driver de miniporto de exibição pode especificar estão listados na enumeração DXGK_ENGINE_TYPE .
Exemplo de implementação da função de metadados de nó
Esse código mostra como um driver de miniporto de exibição pode implementar alguns dos tipos de mecanismo que podem ser retornados pela função 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;
}