Skip to content

v0.2.0

Choose a tag to compare

@github-actions github-actions released this 26 Jul 10:50
· 231 commits to main since this release

Render resolution scaling

render.scale in mtld3d.conf separates the resolution a game renders at from the resolution it displays at. Any value in (0, 1.0] works: 0.75 is a good first try, 0.5 renders a quarter of the pixels and is noticeably soft because the interface and text scale along with the world. MetalFX's spatial scaler enlarges the frame on present, which is edge-aware and sharper than the plain stretch the display would otherwise do. It is a way to trade pixel count for frame rate on a GPU that has headroom.

A render target or depth buffer a game creates at exactly the back-buffer size is treated as part of the same image and scales with it, so a game that draws its world into a target of its own and blits the result still rasterizes fewer pixels. Targets at other sizes, like shadow maps and post-process chains, keep the resolution the game chose. Readback through LockRect, GetDC and GetRenderTargetData resolves with the same scaler, so what a game reads back matches what is on screen.

Values above 1.0 are rejected, because rendering more pixels than are displayed needs a downscale on present and MetalFX only enlarges. On a GPU without MetalFX the scale is held at 1.0 rather than falling back to a blurrier scaler, and says so once in the log.

The knob composes with color.hdr.enable. The BT.2446-A inverse tone map now runs at render resolution and MetalFX finishes the frame in its HDR colour processing mode, so a scaled HDR frame is both sharper and cheaper than it was at full resolution: the ICtCp and PQ math covers fewer pixels, and MetalFX replaces a full-resolution shader pass.

Fullscreen is a borderless window, never a display mode change

A fullscreen device now takes over its window instead of the desktop. It saves the window's style and rect, strips the decoration, stretches the window over the monitor, and puts all of it back on the way out. Previously the device never touched the window at all, so a game that asked for 1024x768 fullscreen got a 1024x768 window sitting in the corner of the desktop.

Switching the desktop mode is the letter of the spec, but Wine's Mac driver hands the request to CGDisplaySetDisplayMode, so a fullscreen game would reconfigure the user's screen, rearrange every other window, and pay for a second mode change on the way out. A monitor-covering borderless window buys the property the mode change was there for: the guest's coordinate space matches the client rect, so GetClientRect, mouse input and the back buffer stay in agreement.

The trade-off is that the back buffer follows the window, so the resolution a game picks in its own video options has no effect in fullscreen, or in a maximized window. render.scale is the render-resolution control in both cases.

Also in this release

  • The README leads with installation and recommends running under x87sidecar. D3D9-era games do their floating-point math in x87, which Rosetta 2 translates slowly.
  • Every conformance classification was re-derived from Wine's d3d9 test suite, its raw failure messages and the implementation. The previous "zero real failures" headline was wrong: 46 sites covering 13 distinct defects were filed as expected or caps when they are intend-to-fix work. Counts and classifications each have one authoritative home now, and drift fails the test suite instead of going unnoticed.
  • Compiler and clippy warnings are gated in make check through cargo's build.warnings, so a plain cargo clippy reports findings without hard-failing at the first crate.
  • Cursor entry points record the calling thread, which is what decides whether Wine forwards a cursor change to its Mac driver at all.

Installing

Download mtld3d.tar.xz below. It serves both install routes: wine/ mirrors a Wine installation's lib/wine/ with every PE marked builtin, and native/ holds the unmarked d3d9.dll for the DLL-override route required on CrossOver. INSTALL.md is inside the bundle, and configuration lives in mtld3d.conf.

Full changelog: v0.1.0...v0.2.0