Windows XPDM PV Display Driver and Miniport

Implementing an XPDM Display Driver for the new Display Handler.

Refer to: RFC Display Handler Architecture.pdf

Purpose: Information dump for notes while writing the new Windows XPDM PV Display driver. Eventually this will evolve into a full-blown reference/design document for the driver.


Questions and Assumptions about the modified XPDM display driver and miniport


Desktop: A desktop is a collection of extended displays

How many desktops can there be? If I have 2 running guests, can I simultaneously display both guests (one on each monitor)? Description of Full Screen Compositor indicates "no"? ANSWER: Pinned display: Always attached to a VM, even after switching away from that VM Shared display: physical display moves back and forth between VMs during hot switching. BUT as far as the VM is concerned, the displays are always attached, even after a hot switch.

However the VM is not guaranteed to be the same resolution as the displays (i.e. the display handler might reduce the size of the VM to make room for banner markings).

I assume that this happens behind the VM's back. That is, the Display Handler will tell the VM driver the USABLE size of the display, not necessarily the ACTUAL size of the display. For example, if the display is physically 1920x1080, but the Display Handler wishes to reserve a 100 pixel tall banner at the top, the Display Handler will report back to the VM driver that the display is 1820x1080. ANSWER: Confirmed correct. VM driver can select a different resolution than Display Handler requests. If VM resolution doesn't match Display Handler resolution, Display Handler will scale. This should be avoided.

If the user selects “cloned”, all of the monitors will belong to the same display, and the desktop will consist of only one display.

Does this happen at the VM driver level, or Display Handler level? For a cloned display, with the VM driver present 2 monitors to the OS? Present 1 monitor to the OS, but manage the second behind the OS's back? Or present and manage a single monitor and let the Display Handler worry about how it gets cloned? ANSWER: All happens in the display handler. VM driver never needs to clone a display.

The proposed Display Handler would contain a dumb-buffer renderer

I assume from this, that hooking and implementing DDI, DDRAW and D3D accelerations in the VM driver is not planned at this time. ANSWER: Correct. BUT there will be HW cursor support.

No support is planned for changes in monitor orientation in this version of the Display Handler.

I assume from this that supporting rotated framebuffers is not planned at this time. ANSWER: correct.

The Display Handler will be able to support more than one GPU, but initial support for the UIVM is one GPU at a time. The UIVM will provide a means to select which graphics device to use.

I'm assuming the above can be ignored for now. Does "graphics device" here mean GPU or Display Controller? Since there is no acceleration, the number of GPUs is irrelevant, and could even be zero. The management of the display controllers should fall to the new Display Handler, shouldn't it? I don't anticipate the VM driver needing to "Select which graphics device to use" until it implements accelerated drawing. ANSWER: Always hidden from the VM driver, even with acceleration.

The Display Handler however has to send a lot of information at very high frequencies. Using event based communications would destroy the overall performance of the system.

For an unaccelerated VM display driver, there shouldn't be any need for high frequency communication between the VM driver and the Display Handler, should there? Again, I don't see this feature being useful until accelerated drawing is implemented. ANSWER: Dirty rectangles must be sent. To implement this, we create a "channels" for the framebuffer, event channel, and dirty rectangle implementation.

This mechanism provides a simple API (socket-style, address / port connections) for creating shared memory. This shared memory can be used for simple framebuffer data

Is it the intent then, during VM driver initialization, that this shared memory would be used for the framebuffer, instead of the standard video memory typically exposed through the QEMU VGA device? That is, instead of the VM driver querying the bios for the framebuffer location and size, it would allocate framebuffer memory from the Display Handler through this new API? I am assuming the answer to this is "yes". ANSWER: yes. We will not communicate with the QEMU device

Provide simple API for setting up shared memory with the guest. This API uses an address/port style connection.

VM display driver will use this mechanism to allocate and map video memory from the Display Handler, to Windows. ANSWER: yes.

Provide simple API for setting up ring buffer communications on-top of shared memory provided by the shared memory API.

Irrelevant for now, as there is no accelerated drawing, so no need for a ring buffer. Unless the intent is for communication to the display controller will go through a ring buffer? Assuming the answer is "no". ANSWER: yes, HW cursor and Dirty Rectangle information go in the ring buffer. Resolution control information also.

In order to support the Display Handler, a new Input Server will also need to be added.

I am assuming that the Input Server is pretty much irrelevant to the VM display driver. ANSWER: correct.

QEMU is needed to not only provide basic OS support, but also provides video support for the initial configuration of the VM, as well as the boot process of the VM when PV drivers cannot be used.

I assume that once the VM driver takes over, QEMU moves out of the picture, and the VM interacts with the Display Manager instead of the VESA BIOS. ANSWER: correct.

Udev support will be built into Disman. This will provide hot-plug & hot-unplug support.

This is an event that comes from the Display Manager, and must be communicated up to the XPDM driver, and on to Windows? ANSWER: yes.

The renderer is the entity that physically talks to the hardware.

The VM driver will not talk directly to the renderer. ANSWER: correct.

When a monitor is added and the “mode” is “extended”...

This is an event that comes from Display Manager and needs to be communicated back to the VM driver, and to Windows? ANSWER: Correct.

If the user changes the resolution of a display, and the display overlaps with other displays...

What is the mechanism for triggering this event? Typically display resolution changes come from Windows, and Windows tells the driver. Is this "change-resolution" command coming from the Display Manager? ANSWER: IT comes from the Display Manager. We have to force Windows to change.

[Dumb Buffer Renderer] Renders any overlays that are drawn on the desktop

Do we intend to implement overlays in the Windows driver at this time? ANSWER: No.

If the guest has more displays than the host,

How would this situation come about? ANSWER: user unplugs a monitor. Display Handler notifies the driver, but the driver can't respond.

If the guest has only one monitor, and the host has many, the guest will be cloned to the other host monitors

This happens outside of the VM display driver, right? Nothing to do in the driver, right? ANSWER: Correct.


Design Considerations

Init

  • "Device" detection. Discover the existance of the Display Handler
    • Detection failure? What do we do if the new Display Handler can't be contacted?
      • Assume fail to load. Windows should fall back to the VGA driver.
  • Create communications channel
  • Allocate shared memory
  • Set up Control Channel
  • Share Control with display-dll
  • Create communications event
  • Create thread to monitor messages from display handler
    • PsCreateSystemThread()
  • Mechanism to signal Windows when we need its attention
    • Generate some kind of SW Interrupt and catch it in HwInterrupt()?
  • Discover number of displays from Display Handler, report to Windows.
    • dh_display_list_packet
    • VideoPortCreateSecondaryDisplay for additional displays
    • IOCTL_VIDEO_MAP_VIDEO_MEMORY
    • IOCTL_VIDEO_SET_CURRENT_MODE
    • IOCTL_VIDEO_RESET_DEVICE
    • IOCTL_VIDEO_SHARE_VIDEO_MEMORY
    • IOCTL_VIDEO_VALIDATE_CHILD_STATE_CONFIGURATION
    • IOCTL_VIDEO_GET_CHILD_STATE
    • IOCTL_VIDEO_SWITCH_DUALVIEW
      • Triggered by ChangeDisplaySettings ()
        • This has to come from user-mode? Options:
        • Catch it in the minport, signal the display driver, which signals a user-mode app, which forces a ChangeDisplaySettings() call
        • Set it up in the miniport, but catch it in the display driver (since technically it is running in kernel space), pass that up to a user-mode app, which forces a ChangeDisplaySettings() call. Use the miniport to set up a shared-memory area that the user mode app can read directly. When it sees the flag, it forces a ChangeDisplaySettings() call.
        • Is there any way to do this WITHOUT a user-mode helper app?
        • Investigate solutions from other sources.
    • dh_add_display_packet
    • dh_set_display_packet
    • Per-Display init
      • Framebuffer Channel
      • HW Cursor Channel
      • Dirty Rectangle Channel
      • Event Channel Channel
    • Create communications mechanism between miniport and display driver for the above channels
    • dh_display_advertised_list_packet
    • local address-to-physical address conversion in the display driver

Modeset

  • Request modes from Display Handler.
  • Present to Windows.
  • Allow Windows to pick which in wants to use
  • Instruct Display Handler to set this mode
    • dh_set_display_packet
  • Guest display removal
    • dh_display_no_longer_available
  • Hot-unplug
    • dh_remove_display_packet

Display Handler Re-init

  • Catch this in the miniport
  • dh_remove_display_packet OR complete disconnection from Display Handler
    • Poll Display Handler until it comes alive again?
  • Re-init miniport.
  • Send message to our system tray app to re-paint or re-modeset

Surface Creation

  • Surfaces must be engine managed, to force Windows to notify the driver for every change to the frame buffer.
  • Surface formats must be in standard windows bitmap format, so drawing operations can be punted back to Windows.
  • Current XenVesa driver needs this implemented. It would be better to use a different starting driver, which may already have device managed surfaces, HW cursor, and dirty rectangles already implemented.
  • Do we need to do any coordinate-transformation between our surfaces, and the surfaces seen by Display Manager?

Acceleration

  • No acceleration planned at this time.
  • Overlay is relatively easy to support.
  • Full direct-draw support will be difficult with respect to dirty rectangles
    • Surface locking allows applications to draw directly to video memory
    • Could notify Display Manager when surface is locked and unlocked, allowing it to do scraping during the locked phase.

Dirty Rectangles

  • Mostly written in other drivers.
  • Insert dirty rectangle information in Ring/Message buffer and signal Display Manager.

HW Cursor

  • Mostly written in other drivers.
  • Create Cursor
    • PACKET_TYPE_EVENT_UPDATE_CURSOR
  • Move Cursor
    • PACKET_TYPE_EVENT_MOVE_CURSOR

Asynchronous Events

  • Monitor hotplug/unplug
  • Resolution change
  • Pass up to a user mode app (system tray app), which forces a display resolution change.
    • Investigate other solutions that avoid the system tray app.

General

  • XenVesa is not a good base.
  • Starting driver might better be something based on the IGX virtual driver, which already has surface management, HW Cursor, and dirty rectangle support built in.