Skip to content

Latest commit

 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

d3d8-wine-softrender

Run Direct3D 8 games on Linux without a GPU — using software rendering via llvmpipe + d3d8to9.

The Problem

Direct3D 8 games (2000-2003 era) often fail to run under Wine because:

  1. Wine's built-in D3D8→wined3d translation has bugs/incompatibilities with software renderers
  2. Games request D3DCREATE_HARDWARE_VERTEXPROCESSING which fails without a real GPU
  3. Games try to set fullscreen resolutions that don't match the virtual display
  4. Even when the game has fallback chains (HW→MIXED→SW), wined3d still rejects the device creation

The Solution

This toolkit combines three things:

  • d3d8to9 — converts D3D8 API calls to D3D9 (MIT licensed, by crosire)
  • llvmpipe — Mesa's software OpenGL renderer (ships with most Linux distros)
  • Wine's D3D9 — Wine's D3D9 support is far more mature than D3D8, so routing D3D8→D3D9→wined3d→llvmpipe works

The d3d8to9 DLL sits next to the game executable, intercepting all D3D8 calls and translating them to D3D9 before passing to Wine. This sidesteps Wine's buggy D3D8 layer entirely.

Requirements

  • Linux with X11 (Xvfb works for headless)
  • Wine (tested with Wine 9.0)
  • Mesa llvmpipe (usually pre-installed, libgl1-mesa-dri:i386)
  • MinGW cross-compiler for building d3d8to9 (i686-w64-mingw32-gcc)

Debian/Ubuntu

sudo apt install wine libgl1-mesa-dri:i386 cmake \
    i686-w64-mingw32-gcc i686-w64-mingw32-g++ i686-w64-mingw32-windres \
    xvfb xdotool scrot

Fedora

sudo dnf install wine mesa-dri-drivers.i686 cmake \
    mingw32-gcc mingw32-gcc-c++ mingw32-windres \
    xorg-x11-server-Xvfb xdotool scrot

Arch Linux

sudo pacman -S wine mesa cmake mingw-w64-gcc xorg-server-xvfb xdotool scrot

Quick Start

1. Build d3d8to9

git clone https://github.com/crosire/d3d8to9.git
cd d3d8to9
mkdir build && cd build
cmake .. -DCMAKE_TOOLCHAIN_FILE=path/to/i686-w64-mingw32.cmake -DCMAKE_BUILD_TYPE=Release
make -j$(nproc)

The output is d3d8.dll — a D3D8→D3D9 proxy.

2. Install the proxy DLL

Copy d3d8.dll into the same directory as the game executable:

cp d3d8.dll /path/to/game/d3d8.dll

Wine will load the local DLL instead of its built-in D3D8 implementation.

3. Set up the display

If running headless (no physical display), start Xvfb at a resolution the game expects:

Xvfb :99 -screen 0 800x600x16 &

Tip: Match the Xvfb resolution to the game's display mode. Most D3D8 games default to 800x600 or 1024x768. Check the game's config files or try common resolutions.

4. Run the game

DISPLAY=:99 LIBGL_ALWAYS_SOFTWARE=1 wine /path/to/game/game.exe
  • LIBGL_ALWAYS_SOFTWARE=1 forces Mesa/llvmpipe software OpenGL rendering
  • DISPLAY=:99 points to the Xvfb display

Headless Script

For automated/CI use, use the included launcher script:

./scripts/run-d3d8-game.sh /path/to/game.exe [resolution] [timeout]

Example — run a game for 30 seconds and capture screenshots:

./scripts/run-d3d8-game.sh /opt/games/Hamsterball/Hamsterball.exe 800x600 30

Screenshots are saved to ./screenshots/ as PNG files.

How It Works

Game (D3D8 calls)
    │
    ▼
d3d8.dll (d3d8to9 proxy)    ← sits next to game.exe, intercepts D3D8 API
    │
    ▼  translates D3D8 → D3D9
    │
Wine d3d9.dll                ← Wine's mature D3D9 implementation
    │
    ▼  translates D3D9 → OpenGL
    │
wined3d                      ← Wine's OpenGL translation layer
    │
    ▼  OpenGL calls
    │
llvmpipe / Mesa              ← software OpenGL renderer (no GPU needed)
    │
    ▼
Xvfb / Display               ← virtual or real X11 display

Performance

llvmpipe is a software renderer — it runs everything on the CPU. Expect:

  • Title screens / menus: Fully usable
  • Simple 3D scenes: Playable on modern CPUs (2D games, low-poly 3D)
  • Complex 3D / shaders: Very slow (1-10 FPS)

For better performance on machines with a GPU, simply omit LIBGL_ALWAYS_SOFTWARE=1 and the game will use hardware acceleration through d3d8to9 + Wine's D3D9 stack.

Troubleshooting

"D3DERR_NOTAVAILABLE" error

  • Make sure d3d8.dll (the proxy) is in the same directory as the game .exe
  • Make sure Xvfb is running at a resolution the game supports
  • Try MESA_GL_VERSION_OVERRIDE=4.5 if the game needs a specific GL version

Black screen or no display

  • Verify llvmpipe is working: DISPLAY=:99 LIBGL_ALWAYS_SOFTWARE=1 glxinfo | grep renderer
  • Should show llvmpipe (LLVM ...) — if not, install libgl1-mesa-dri:i386

Game crashes on launch

  • Some games need 32-bit color depth: Xvfb :99 -screen 0 1024x768x32
  • Try Wine virtual desktop: winecfg → Graphics → "Emulate a virtual desktop"

Resolution change fails

  • Match Xvfb resolution to the game's display mode
  • Check game config files (often .ini or registry) for resolution settings

Extremely slow rendering

  • This is expected with llvmpipe — it's CPU-only rendering
  • Use a real GPU if available (omit LIBGL_ALWAYS_SOFTWARE=1)
  • Try reducing the game's graphics settings

Credits

License

The scripts and tooling in this repository are MIT licensed. d3d8to9 is separately licensed under MIT by crosire.

About

Run Direct3D 8 games on Linux without a GPU — d3d8to9 + llvmpipe software rendering for Wine

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages