WDDM显卡驱动
+ -

WDDM 枚举子设备

2021-06-30 367 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:子设备的特性。
    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;
    
    可以前三个公用体对应三个设备类型,最后一个成员DXGK_CHILD_DEVICE_HPD_AWARENESS用于描述热插拨的特性。
  • 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)模式。

0 篇笔记 写笔记

WDDM 枚举子设备
枚举子设备是通过子函数BddDdiQueryChildRelations实现的InitialData.DxgkDdiQueryChildRelations = BddDdiQueryChildRelations;函数原型为:NTSTATUS DxgkddiQueryChild......
作者信息
我爱内核
Windows驱动开发,网站开发
好好学习,天天向上。
取消
感谢您的支持,我会继续努力的!
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

您的支持,是我们前进的动力!