WDDM display miniport driver tasks to support Miracast wireless displays
To support Miracast wireless displays, Windows Display Driver Model (WDDM) display miniport drivers that run in kernel mode need to do the following tasks.
Supporting the Miracast interface
If the display miniport driver supports Miracast displays, it must report the DXGK_MIRACAST_DISPLAY_INTERFACE structure, which has pointers to driver-implemented Miracast functions, when the Microsoft DirectX graphics kernel subsystem calls the DxgkDdiQueryInterface function.
If the operating system's DirectX graphics kernel subsystem (Dxgkrnl.sys) does not call the DxgkDdiQueryInterface function to query the Miracast display interface, then it does not support Miracast wireless displays, and the display miniport driver should not report any Miracast target.
The driver should not report more than one Miracast target on any full WDDM graphics device, otherwise the operating system fails to start the adapter.
After Dxgkrnl calls DxgkDdiQueryInterface to query the Miracast display interface, the driver can then report the target type as D3DKMDT_VOT_MIRACAST during device initialization when Dxgkrnl calls the DxgkDdiQueryChildRelations function.
The Miracast target should remain in a disconnected state until Dxgkrnl starts a Miracast connected session. When a Miracast session is starting, and a monitor is connected to the Miracast sink or the driver receives an I/O request from the Miracast user-mode driver because a new monitor has connected to the Miracast sink, the display miniport driver should report a monitor arrival hot-plug detection (HPD) awareness value to the operating system by calling the DxgkCbIndicateChildStatus function. In this call the driver should set these values:
|Type||StatusMiracast constant value of the DXGK_CHILD_STATUS_TYPE enumeration|
|Miracast.MiracastMonitorType||Value that indicates the connection type. If the Miracast sink is embedded in the monitor or TV, this should be set to the D3DKMDT_VOT_MIRACAST constant value of the D3DKMDT_VIDEO_OUTPUT_TECHNOLOGY enumeration.|
These are the Miracast functions that the display miniport driver implements:
Creates a context to start a kernel-mode instance of a Miracast display device.
Creates a context to start a kernel-mode instance of a Miracast display device.
Queries the Miracast capabilities of the current display adapter.
Miracast session start
When the Miracast session has been started, the operating system calls the DxgkDdiQueryChildStatus function. The display miniport driver should set DXGK_CHILD_STATUS.Type to a value of StatusMiracast and should use the Miracast child structure in DXGK_CHILD_STATUS. If a monitor is connected to the Miracast sink, the driver should set Miracast.Connected to D3DKMDT_VOT_MIRACAST.
The driver must specify the value of D3DKMDT_VIDEO_SIGNAL_INFO.VsyncFreqDivider, which is the ratio of the VSync rate of a monitor that displays through a Miracast connected session to the VSync rate of the Miracast sink. For example, if the Miracast sink vertical refresh rate is 240 Hz and the VSync interrupt frequency of the connected display is 30 Hz, the driver should set VsyncFreqDivider to 8.
Handling interrupts for completed encode chunks
The data for a single frame transmitted across the wireless Miracast connection can be broken into one or more encode chunks. Each time the GPU finishes encoding one of these chunks, it must generate an interrupt. In response to this interrupt, the display miniport driver must call the DxgkCbNotifyInterrupt function and complete the MiracastEncodeChunkCompleted child structure in the DXGKARGCB_NOTIFY_INTERRUPT_DATA structure, including setting the DXGK_INTERRUPT_TYPE interrupt type to DXGK_INTERRUPT_MICACAST_CHUNK_PROCESSING_COMPLETE.
As part of the interrupt handling, the driver can optionally specify the MiracastEncodeChunkCompleted.pPrivateDriverData and PrivateDataDriverSize members in the DXGKARGCB_NOTIFY_INTERRUPT_DATA structure. The user-mode driver can access this private driver data in the MIRACAST_CHUNK_DATA.PrivateDriverData member.
If, over a period of time, the display miniport driver generates more packets with chunk data than the user-mode display driver consumes, then the available free memory space for new chunks can run out. In this case the display miniport driver returns STATUS_NO_MEMORY in MiracastEncodeChunkCompleted.Status, and it must call the DxgkCbNotifyDpc function to notify the operating system's GPU scheduler about the error condition. A call to the GetNextChunkData function will return the STATUS_CONNECTION_RESET status code, and subsequent calls will start receiving chunks that were submitted after the reset operation. Because some chunks will have been lost, we recommend that the driver generate and transmit a new I-frame.
Restrictions on source modes
A WDDM display miniport driver, to handle constraints of the pixel pipeline, typically restricts source modes that are exposed to the operating system. The driver does this by only populating the list of source modes with modes that are exposed by the monitor that the pixel pipeline also supports. For example, the driver doesn't modify the EDID based on pixel pipeline constraints.
Similarly, for Miracast displays the display miniport driver restricts the set of source modes that are exposed to the operating system when it enumerates the set of source and target modes. For Miracast displays the GPU encode capabilities, network properties, and sink decode capabilities can reduce the number of source modes that the Miracast pixel pipeline can support.
If a display miniport driver calls the DXGK_VIDPNSOURCEMODESET_INTERFACE::pfnAddMode function to attempt to add a 3-D stereo mode to a source that's connected to a Miracast target, the function call will fail.
Calling operating system-provided callback functions
These are the Miracast kernel-mode callback functions that the operating system provides:
Sends an asynchronous message to the user-mode display driver.
Reports info about an encode chunk.
Sending messages asynchronously from kernel-mode to user-mode
Any message that the display miniport driver sends to its associated user-mode driver when it calls the DxgkCbMiracastSendMessage function won't be delivered until the Miracast connected session has started. Therefore, if the user-mode driver's StartMiracastSession function has not yet been called, the sent message is deferred until StartMiracastSession returns. If a message is sent after the StopMiracastSession function is called, then the message is dropped by the operating system, and the DxgkCbMiracastSendMessageCallback function is called with the error status set in pIoStatusBlock->Status.
Modifying an existing display miniport driver to support Miracast displays
When the DxgkDdiStartDevice function is called, the display miniport driver needs to add a new Miracast target and should mark the target's hot-plug detection (HPD) awareness value as HpdAwarenessInterruptible so that the operating system won't poll this target. Also, when the DxgkDdiQueryChildRelations function is called, the driver should report D3DKMDT_VOT_MIRACAST as its connection type.
The driver should not report more than one Miracast target on any full WDDM graphics device. If a driver reports more than one Miracast target, the operating system fails the starting of the adapter. The driver should also not report any monitor on this target if the Miracast connected session is not started.
The driver also needs to report a correct DXGK_MIRACAST_DISPLAY_INTERFACE structure, with pointers to functions that are in kernel-mode address space, when the DirectX graphics kernel subsystem calls the DxgkDdiQueryInterface function.
When a Miracast session is starting, and a monitor is connected the the Miracast sink, the display miniport driver should set the DXGK_CHILD_STATUS.Type member to the StatusMiracast constant value, and should also set DXGK_CHILD_STATUS.Miracast.Connected to TRUE, to report a monitor arrival HPD to the operating system. The driver should set the DXGK_CHILD_STATUS.Miracast.MiracastMonitorType member to the correct monitor type that's connected to the sink. If the sink is part of the monitor, this member should be set to D3DKMDT_VOT_MIRACAST.
If the driver knows the EDID of the monitor, it should report this EDID when the operating system calls the DxgkDdiQueryDeviceDescriptor function.
Depending on hardware capabilities, the Miracast sink mode list, and network bandwidth, the driver should reports the correct source mode, target mode, rotation mode, and scaling mode. For the target mode, driver should report the correct VSyncFreqDivider member value in D3DKMDT_VIDEO_SIGNAL_INFO. The operating system matches the target mode against the monitor mode and prunes any mode that isn't supported by the monitor.