WDDM 枚举子设备
2021-06-30
496
0
枚举子设备是通过子函数BddDdiQueryChildRelations实现的
InitialData.DxgkDdiQueryChildRelations = BddDdiQueryChildRelations;
函数原型为:
NTSTATUS DxgkddiQueryChildRelations(
IN_CONST_PVOID MiniportDeviceContext,
PDXGK_CHILD_DESCRIPTOR ChildRelations,
ULONG - ChildRelationsSize:
)
- MiniportDeviceContext:为类实例。
- ChildRelations :DXGK_CHILD_DESCRIPTOR 指针类型的数组,由调用者分配内存并且其内容被清空为0.
- ChildRelationsSize:指定了ChildRelations的个数,这个数量等于BddDdiStartDevice中的*pNumberOfChildren+1,我们在DxgkDdiQueryChildRelations中填充除过最后一个结构体外的所有数据(因为最后一个全空为0)。
其调用类成员函数QueryChildRelations来实现。
NTSTATUS BASIC_DISPLAY_DRIVER::QueryChildRelations(_Out_writes_bytes_(ChildRelationsSize) DXGK_CHILD_DESCRIPTOR* pChildRelations,
_In_ ULONG ChildRelationsSize)
{
PAGED_CODE();
BDD_ASSERT(pChildRelations != NULL);
// The last DXGK_CHILD_DESCRIPTOR in the array of pChildRelations must remain zeroed out, so we subtract this from the count
ULONG ChildRelationsCount = (ChildRelationsSize / sizeof(DXGK_CHILD_DESCRIPTOR)) - 1;
BDD_ASSERT(ChildRelationsCount <= MAX_CHILDREN);
for (UINT ChildIndex = 0; ChildIndex < ChildRelationsCount; ++ChildIndex)
{
pChildRelations[ChildIndex].ChildDeviceType = TypeVideoOutput;
pChildRelations[ChildIndex].ChildCapabilities.HpdAwareness = HpdAwarenessInterruptible;
pChildRelations[ChildIndex].ChildCapabilities.Type.VideoOutput.InterfaceTechnology = m_CurrentModes[0].Flags.IsInternal ? D3DKMDT_VOT_INTERNAL : D3DKMDT_VOT_OTHER;
pChildRelations[ChildIndex].ChildCapabilities.Type.VideoOutput.MonitorOrientationAwareness = D3DKMDT_MOA_NONE;
pChildRelations[ChildIndex].ChildCapabilities.Type.VideoOutput.SupportsSdtvModes = FALSE;
// TODO: Replace 0 with the actual ACPI ID of the child device, if available
pChildRelations[ChildIndex].AcpiUid = 0;
pChildRelations[ChildIndex].ChildUid = ChildIndex;
}
return STATUS_SUCCESS;
}
下面我们来解释一下DXGK_CHILD_DESCRIPTOR结构体,其内容为:
typedef struct _DXGK_CHILD_DESCRIPTOR {
DXGK_CHILD_DEVICE_TYPE ChildDeviceType;
DXGK_CHILD_CAPABILITIES ChildCapabilities;
ULONG AcpiUid;
ULONG ChildUid;
} DXGK_CHILD_DESCRIPTOR, *PDXGK_CHILD_DESCRIPTOR;
- AcpiUid:如果是ACPI设备,指定了其ID.
- ChildUid:子设备的实例ID.
- ChildDeviceType:子设备类型,总共有4种:
- TypeUninitialized:无任何意义的设备类型。
- TypeVideoOutput:视频输出设备类型,用于提供视频源的设备类型(不包括显示器,屏幕等显示设备)。
- TypeOther:非视频输出设备类型,主要包括的设备有电视调谐器、交叉开关和MPEG2编解码器都等子设备。
- TypeIntegratedDisplay:永久连接到集成显示器的设备类型。
- ChildCapabilities:子设备的特性。
可以前三个公用体对应三个设备类型,最后一个成员DXGK_CHILD_DEVICE_HPD_AWARENESS用于描述热插拨的特性。typedef struct _DXGK_CHILD_CAPABILITIES { union { DXGK_VIDEO_OUTPUT_CAPABILITIES VideoOutput; struct { UINT MustBeZero; } Other; DXGK_INTEGRATED_DISPLAY_CHILD IntegratedDisplayChild; } Type; DXGK_CHILD_DEVICE_HPD_AWARENESS HpdAwareness; } DXGK_CHILD_CAPABILITIES, *PDXGK_CHILD_CAPABILITIES;
- HpdAwareness值等于HpdAwarenessInterruptible,表示外部设备连接或断开时子设备可以产生中断。
typedef struct _DXGK_VIDEO_OUTPUT_CAPABILITIES {
D3DKMDT_VIDEO_OUTPUT_TECHNOLOGY InterfaceTechnology;
D3DKMDT_MONITOR_ORIENTATION_AWARENESS MonitorOrientationAwareness;
BOOLEAN SupportsSdtvModes;
} DXGK_VIDEO_OUTPUT_CAPABILITIES, *PDXGK_VIDEO_OUTPUT_CAPABILITIES;
- InterfaceTechnology:表示连接的接口类型。如VGA,HDMI,这里根据设置可以内部连接或其它类型的连接。
- MonitorOrientationAwareness:描述视频输出设备(在显示适配器上)检测连接的外部显示设备的方向(旋转角度)变化的能力。
- SupportsSdtvModes:指示视频输出是否支持标准清晰度电视(SDTV)模式。