Repository navigation
Cross Compilation Wine Testing
SparkEngine can cross-compile its Windows D3D11 code paths on Linux using MinGW-w64, then run the resulting .exe binaries under Wine. Combined with DXVK (D3D11->Vulkan) or Wine's built-in WineD3D (D3D11->OpenGL) and Mesa Lavapipe (software Vulkan/OpenGL), this exercises the exact same _WIN32 code that MSVC compiles -- without Windows or a GPU.
Key files:
-
cmake/toolchains/mingw-w64-x86_64.cmake-- CMake toolchain -
tools/wine-run.sh-- Wine runner (auto-detects DXVK, Lavapipe) -
tools/test-windows-wine.py-- Automated 7-phase Wine test suite -
CMakePresets.json--linux-mingw-release/linux-mingw-debugpresets
D3D11 C++ (same #ifdef _WIN32 code paths as MSVC)
-> MinGW-w64 (x86_64-w64-mingw32-g++) -> .exe
-> Wine (translates Windows API calls to Linux syscalls)
-> DXVK (translates D3D11 -> Vulkan) [if installed]
-> WineD3D (translates D3D11 -> OpenGL) [fallback]
-> Lavapipe (software Vulkan on CPU) [no GPU needed]
-> llvmpipe (software OpenGL on CPU) [WineD3D fallback]
sudo apt-get install mingw-w64 wine64 mesa-vulkan-drivers| Package | Purpose | Size |
|---|---|---|
mingw-w64 |
Cross-compiler (x86_64-w64-mingw32-g++), Windows headers (d3d11.h, xinput.h, etc.), import libraries | ~80 MB |
wine64 |
Windows API translation layer, WineD3D (D3D11->OpenGL) | ~300 MB |
mesa-vulkan-drivers |
Lavapipe software Vulkan (CPU rendering) | ~30 MB |
| Package | Purpose |
|---|---|
dxvk |
D3D11->Vulkan translation (much faster than WineD3D for rendering) |
xvfb |
Virtual X11 framebuffer (needed for windowed mode without a display) |
libgl-dev |
OpenGL headers only for a manual experimental override; the canonical MinGW presets disable Vulkan and OpenGL and exercise D3D11 |
MinGW does not ship Microsoft's DirectXMath library. You must install them to the MinGW sysroot:
# Download from Microsoft's official GitHub repository
mkdir -p /tmp/dxmath && cd /tmp/dxmath
for f in DirectXMath.h DirectXMathConvert.inl DirectXMathMatrix.inl \
DirectXMathMisc.inl DirectXMathVector.inl DirectXCollision.h \
DirectXCollision.inl DirectXColors.h DirectXPackedVector.h \
DirectXPackedVector.inl; do
wget -q "https://raw.githubusercontent.com/microsoft/DirectXMath/main/Inc/$f"
done
# Install to MinGW sysroot
sudo cp DirectX*.h DirectX*.inl /usr/x86_64-w64-mingw32/include/x86_64-w64-mingw32-g++ --version # Should show GCC 13+
wine64 --version # Should show wine-9.0+
ls /usr/share/vulkan/icd.d/lvp_icd* # Lavapipe ICD file
ls /usr/x86_64-w64-mingw32/include/DirectXMath.h # DirectXMath# Configure using the preset
cmake --preset linux-mingw-release
# Build all targets (SparkEngine.exe, SparkEditor.exe, SparkTests.exe, etc.)
cmake --build build/linux-mingw-release --parallel $(nproc)| Target | File | Description |
|---|---|---|
SparkEngine.exe |
bin/SparkEngine.exe |
Engine runtime with D3D11 graphics |
SparkEditor.exe |
bin/SparkEditor.exe |
Editor with D3D11 + ImGui |
SparkTests.exe |
bin/SparkTests.exe |
Full unit test suite (2,500+ tests) |
SparkConsole.exe |
bin/SparkConsole.exe |
Standalone debug console |
SparkShaderCompiler.exe |
bin/SparkShaderCompiler.exe |
Offline shader compiler |
libSparkGameFPS.dll |
bin/libSparkGameFPS.dll |
FPS game module |
| Other game modules | bin/lib*.dll |
RPG, MMO, RTS, Racing, etc. |
| Feature | MSVC Build | MinGW Build |
|---|---|---|
| D3D11 | In-profile candidate only for Windows 11 x64/MSVC v143; blocked/uncertified | Development evaluation path outside stable-v1
|
| D3D12 | Experimental/outside stable-v1
|
Excluded (SPARK_NO_D3D12; MinGW headers lack required interfaces) |
| DXR Raytracing | Optional | Excluded (requires D3D12) |
| DirectXMath | Built-in | Requires manual header install (see above) |
| XAudio2 | Built-in | Linked via -lxaudio2_8
|
| dbghelp | Via #pragma comment(lib)
|
Linked explicitly in CMake |
| Entry point | wWinMain |
wWinMain with -municode linker flag |
| Static linking | N/A | -static-libgcc -static-libstdc++ |
# Quick run (no graphics needed)
tools/wine-run.sh build/linux-mingw-release/bin/SparkTests.exe
# Or manually:
export WINEPREFIX=$(pwd)/build/.wineprefix
export WINEDEBUG=-all
export LIBGL_ALWAYS_SOFTWARE=1
wine64 build/linux-mingw-release/bin/SparkTests.exeExpected result: ~2,504/2,509 tests pass (99.8%). The 5 expected failures are:
-
WARP_D3D11DeviceInit-- needs real D3D11 runtime (DXVK or native Windows) -
WARP_D3D11BufferCreation-- same -
WARP_D3D11FactoryCreate-- same -
StackTrace_FramesHaveAddresses-- stack walking differs under Wine -
LoadTest_FullEngine_3000Frames-- needs graphics context
If Wine reports a missing DLL (e.g., libwinpthread-1.dll), copy it from the MinGW sysroot:
cp /usr/x86_64-w64-mingw32/lib/libwinpthread-1.dll build/linux-mingw-release/bin/wine64 build/linux-mingw-release/bin/SparkConsole.exe
# Output: "Spark Engine Console v1.0.0" -- interactive console worksThe engine creates a Win32 window and initializes D3D11. Under Wine, this requires:
- An X11 display (Xvfb for headless environments)
- WineD3D (built into Wine) or DXVK for D3D11 translation
# Start virtual display
Xvfb :99 -screen 0 1920x1080x24 -ac &
export DISPLAY=:99
# Run engine with test frame limit
export WINEPREFIX=$(pwd)/build/.wineprefix
export WINEDEBUG=-all
export LIBGL_ALWAYS_SOFTWARE=1
wine64 build/linux-mingw-release/bin/SparkEngine.exe -test-frames 60Performance:
| Configuration | 60 Frames | FPS | Translation Path |
|---|---|---|---|
| DXVK + Lavapipe | ~0.5s | ~120 | D3D11 -> Vulkan -> Lavapipe (CPU) |
| WineD3D + llvmpipe | >120s | <0.5 | D3D11 -> OpenGL -> llvmpipe (CPU) |
DXVK provides ~20x speedup. Install DXVK with:
tools/setup-mingw-wine.sh --dxvk-only # Downloads from GitHub, no sudo neededYou can also use -window-size 640x480 for faster software rendering:
wine64 SparkEngine.exe -test-frames 60 -window-size 640x480wine64 build/linux-mingw-release/bin/SparkEngine.exe -headlessThe test-windows-wine.py script runs a comprehensive 7-phase test:
python3 tools/test-windows-wine.py --build-dir build/linux-mingw-releasePhases:
| Phase | Name | What It Tests |
|---|---|---|
| 0 | Prerequisites | Wine, MinGW, Lavapipe, build artifacts exist |
| 1 | Wine Setup | Wine prefix initialization, DXVK/VKD3D detection |
| 2 | Unit Tests | The configured CTest suite under Wine; use that run's discovery count and terminal summary as evidence |
| 3 | Engine Live | D3D11 initialization, frame rendering, headless mode |
| 4 | Editor Live | D3D11 + ImGui initialization, test-mode rendering |
| 5 | Stress Tests | Rapid start/stop, concurrent instances, bad args |
| 6 | Break Tests | SIGKILL, SIGTERM, corrupt prefix, missing Vulkan |
Output: JSON report at /tmp/spark-windows-wine-test/report.json
Both the engine and editor support a --test-frames N / -test-frames N command-line flag for automated testing:
# Engine (Windows): exit after 60 frames
wine64 SparkEngine.exe -test-frames 60
# Engine (Linux): exit after 60 frames
./SparkEngine -test-frames 60
# Editor: exit after 120 frames (with --test-mode to skip project browser)
wine64 SparkEditor.exe --test-mode --test-frames 120The flag works on both platforms:
-
Windows (
wWinMain): Parsed from the wide command line, enforced inRunWindowedMainLoop -
Linux (
main): Parsed fromargv, enforced inRunSDL2MainLoop
The tools/wine-run.sh script automates Wine environment setup:
tools/wine-run.sh <executable.exe> [args...]
tools/wine-run.sh --setup-only # Initialize Wine prefix only
tools/wine-run.sh --info # Print environment infoWhat it does:
- Initializes a Wine prefix at
build/.wineprefix - Auto-detects DXVK (D3D11->Vulkan) at standard paths
- Auto-detects VKD3D-Proton (D3D12->Vulkan)
- Finds Lavapipe ICD for software Vulkan
- Sets
LIBGL_ALWAYS_SOFTWARE=1for Mesa software rendering - Runs the
.exeunderwine64
If apt-get install hangs on network, download packages directly:
# Get download URLs
apt-get download --print-uris mingw-w64-x86-64-dev g++-mingw-w64-x86-64-posix \
gcc-mingw-w64-x86-64-posix gcc-mingw-w64-x86-64-posix-runtime \
gcc-mingw-w64-base binutils-mingw-w64-x86-64 mingw-w64-common \
libz-mingw-w64 2>&1 | grep "^'" | sed "s/' .*//" | sed "s/^'//"
# Download each URL with wget, then install:
sudo dpkg -i *.debMinGW doesn't ship DirectXMath. Install it manually (see Prerequisites above).
This is MSVC-only. The engine's targetver.h handles this automatically for MinGW by defining _WIN32_WINNT and WINVER directly.
MinGW targets Windows where SIGTRAP doesn't exist. The engine's Assert.h uses __builtin_trap() on MinGW instead.
MinGW on Linux uses a case-sensitive filesystem. Windows headers must use lowercase:
-
#include <windows.h>(not<Windows.h>) -
#include <winsock2.h>(not<WinSock2.h>) -
#include <xinput.h>(not<Xinput.h>) -
#include <shlobj.h>(not<ShlObj.h>)
MinGW's libstdc++ doesn't support std::wstring paths in fstream. Convert to narrow string first:
#if defined(_MSC_VER)
std::wofstream ofs(wideFilename, std::ios::out);
#else
std::string narrow(wideFilename.begin(), wideFilename.end());
std::wofstream ofs(narrow.c_str(), std::ios::out);
#endifUse __builtin_return_address(0) on GCC/MinGW.
On 64-bit Windows (both MSVC and MinGW), size_t is uint64_t. Guard size_t overloads:
#if !defined(_WIN64) && !defined(__LP64__) && !defined(__x86_64__)
void Value(size_t v) { /* ... */ }
#endifMinGW needs -municode for wWinMain (Unicode entry point). This is set in CMakeLists.txt.
WineD3D translates D3D11->OpenGL, which combined with llvmpipe is extremely slow (~minutes per frame for shader compilation). Install DXVK for D3D11->Vulkan translation:
sudo apt-get install dxvk
# Or download from: https://github.com/doitsujin/dxvk/releasesCopy from MinGW sysroot:
cp /usr/x86_64-w64-mingw32/lib/libwinpthread-1.dll build/linux-mingw-release/bin/The build-linux-mingw-wine CI job in .github/workflows/build.yml runs this automatically:
- Installs MinGW, Wine, Mesa Lavapipe
- Cross-compiles with the MinGW toolchain
- Runs tests under Wine
-
continue-on-error: true(non-blocking, advisory)
| Optimization | Speedup | Status |
|---|---|---|
| DXVK (D3D11->Vulkan) | ~20x | Done — setup-mingw-wine.sh --dxvk-only
|
Low resolution (-window-size 640x480) |
~4x | Done — engine flag |
-test-frames N flag |
N/A | Done — automated frame-limited exits |
| Optimization | How | Status |
|---|---|---|
| DXVK state cache |
DXVK_STATE_CACHE_PATH persists compiled pipelines |
Done in wine-run.sh |
| GPU auto-detection |
detect_gpu() in wine-run.sh skips Lavapipe if real GPU found |
Done |
- GPU passthrough in CI — GitHub Actions runners with GPUs could run real D3D11 hardware tests
- Shader pre-warm — the engine already lazy-loads shaders (only BasicVertex + BasicPixel at startup), complex scenes will benefit from DXVK pipeline cache
Wine GUI (WIN32) applications often return exit code 255 instead of 0 when stdout/stderr are piped or redirected. The test script uses wine_rc_ok(rc) to treat both 0 and 255 as success. This is a known Wine behavior with wWinMain applications.
Published from 2b03dc797148. Edit the canonical source in wiki/.
- Documentation
- Docs route
- Wiki index
- Guides
- Tutorials
- Samples
- Examples
- API Reference
- API route
- Reference
- Build Guide
- Dependencies
- FAQ
- Changelog
- Roadmap
- Contributing
- Code of Conduct
- Home
- FAQ
- Getting Started
- Quick-Start Tutorial
- Making Your First Game
- Making Your First Multiplayer Game
- Artist Workflow Guide
- Editor Walkthrough
- Migration Guide
- How SparkEngine Works
- Architecture Overview
- Engine Architecture Flowchart
- Creating a Game Module
- Game Modules (catalog)
- Entity Component System
- Rendering and Graphics
- Physics
- Cloth Simulation
- Audio
- Input System
- Camera System
- Scripting with AngelScript
- Visual Scripting
- AI and Navigation
- Animation
- 2D Systems
- Networking
- Dedicated Server
- Multiplayer Quick Start
- Area Server Architecture
- Scene Management
- Large World Support
- Collaborative Editing
- Coroutine System
- Event System
- Event Response System
- Job System
- UI System
- UI Layout Extensions
- Localization
- Dialogue System
- Destruction System
- Replay System
- Achievement System
- Loading System
- Mod System
- Content Delivery
- Tween System
- Memory Integrity
- Gameplay Systems
- Terrain and Procedural Generation
- Save System
- Persistence System
- Day Night Cycle and Weather
- Cinematic Sequencer
- Runtime Prefabs
- SparkEditor
- Editor Tutorials
- SparkConsole
- SparkDaemon
- Shader Pipeline
- Asset Pipeline
- Asset Validation
- Asset Migration
- Game Packaging
- Online Services
- DataTable System
- Loot and Crafting System
- CSG System
- Font System
- Timer Manager
- Movie Render Pipeline
- HLOD and World Partition
- Remote Debug System
- Selection Manager
- Asset Dependency Graph
- Editor Automation
- File Watcher
- Project Templates
- System Requirements
- VR Support
- Mobile Platform
- Accessibility
- Platform Input
- Platform Certification
- Cross-Compilation: Wine Testing
- RHI Abstraction Layer
- D3D11 Backend
- D3D12 Backend
- Vulkan Backend
- OpenGL Backend
- Metal Backend
- DXR Raytracing
- Hybrid Ray Tracing
- Upscaling (DLSS/FSR)
- Render Graph
- Shader Graph
- GPU Particles
- GPU-Driven Rendering
- Volumetric Fog
- Volumetric Clouds
- Global Illumination
- Virtual Texturing
- Water Rendering
- Clustered Lighting
- Material System
- Post-Processing
- Shadow System
- Particle System
- Decal System
- Sky and Atmosphere
- Foliage System
- Mesh Shaders
- Neural Rendering
- Configuration Reference
- Performance Tips
- Benchmark Framework
- Threading Model
- Fuzz Policy and Parser Security
- Memory Safety
- Memory Management Patterns
- Build System and CMake Modules
- Profiler and Debugging
- Performance Profiling Guide
- Telemetry System
- Crash Reporting
- Golden Image Testing
- Utilities
- Testing
- Fuzz Policy and Parser Security
- Codebase Statistics
- Codebase Health
- Error Handling Patterns
- Hot Reload Overview
- Troubleshooting
- Contributing
- Workflow Patterns
- Build Optimizations
- CI Reproducible Builds
- GitHub API and PR Checks
- Git Rebase Conflicts
- Clang-Format
- Code Quality Violations
- AI Bloat Pattern
- MinGW + Wine Cross-Compilation
- Live Editor Testing
- Engine & Renderer Landscape
- DuetOS Portability Catalog
- Five-Engine Analysis
- Eleven-Engine Analysis
- ThorVG / Unity Graphics Analysis
- Advanced Techniques Catalog
- Third-Party Library Evaluation
- Engine Viability Evaluation
- Engine Feature Recommendations
- Project Recommendations
- Mac Compatibility Analysis
- Codebase Observations
- Codebase Bloat Audit
- Test Suite Audit
- Documentation Coverage Audit
- ThirdParty Dependencies Audit
- Load Test Baseline
- Gameplay Systems Status
- SparkGame Module Status
- Stub and Abandoned Features
- Memory Integrity System
- Memory Safety Evaluation
- Hardware Acceleration Systems
- Jolt Physics Integration
- GPU/CPU Separation Plan
- Daemon Services Architecture
- Reflection & Polymorphism Refactoring Plan
- SparkBuild In-Tree
- Wine No-JobSystem Breakthrough
- Wine Role and Fallback Tiers