Skip to content

GameCube

codingncaffeine edited this page Jun 6, 2026 · 2 revisions

GameCube (Dolphin)

Status on Linux: hidden / experimental — not currently selectable. GameCube is hidden from the Linux UI pending performance validation. The Dolphin core integrates and runs, but it is disabled out of caution (frozen GPU clocks on the current test machine cap it well below full speed). The console does not appear in the console picker; the handler and core remain in the backend. The notes below are kept as reference for the technical background. See the Hidden set in ConsolePickerWindow.axaml.cs.

Required Configuration

Dolphin libretro has specific requirements on Linux:

Setting Value Why
dolphin_gfx_backend OGL The Linux dolphin_libretro.so has no Direct3D backend; it uses OpenGL/Vulkan natively, and only a GL context is set up
dolphin_renderer Hardware GPU rendering
CPU core JIT64 (auto-picked) Full-speed recompilation; picked at runtime from the core's valid list, with CachedInterpreter as the safe fallback
dolphin_fastmem disabled Avoids exception-handling conflicts
dolphin_fastmem_arena disabled Prevents a 4 GB arena reservation inside the .NET process
dolphin_main_cpu_thread disabled Single-threaded: the CPU runs on the retro_run thread, so no shared GL context is needed

Linux note: The Windows build byte-patched d3d11.dll's D3D11CreateDevice during context_reset to force Dolphin through OpenGL. On Linux there is no d3d11.dll and the core has no D3D backend, so dolphin_gfx_backend=OGL alone is sufficient — the D3D-blocking hooks (OnBeforeContextReset / OnAfterContextReset) are no-ops. See GameCubeHandler.cs.

Shader Compilation (the Linux 1fps fix)

Dolphin can't create its shader-compiler worker thread against the frontend's surfaceless EGL context ("Failed to create shared context for shader compiling"). With the default specialized shader mode, every new shader compiles inline on the emu thread — a 0–1fps slideshow until a scene's shaders are done (the Linux GameCube 1fps bug).

Fix: dolphin_shader_compilation_mode = 1 (synchronous ubershaders) — the only mode that needs no worker thread. Ubershaders compile a small fixed set on demand, cached globally and persistently (Saves/User/Cache/Shaders/OpenGL-uber-pipeline-*.cache). Measured 0–1fps → ~57.8fps on Mario Kart Double Dash once the cache warmed; fresh scenes still dip while it fills. dolphin_wait_for_shaders = disabled so boot isn't stalled precompiling the full set.

Init Sequence

The order of operations matters:

  1. Set core options (all values are passed as strings — Dolphin's option parser rejects numeric types)
  2. Call retro_load_game
  3. After load returns, call retro_set_controller_port_device for all 4 ports — Dolphin's BootCore expects every port configured before retro_run, or the input subsystem is left partially initialised and retro_run crashes. Calling before load is silently ignored.

Teardown

  • The core library is not dlclosed for Dolphin — its internal threads take too long to fully exit, and premature unloading causes a driver AV.
  • context_destroy is called normally (unlike N64).

Performance Notes

  • FPS dips at startup are normal — Dolphin's JIT cache and ubershader cache take time to warm up.
  • On a machine with unconstrained GPU clocks, stable 60fps after the first few seconds. (On the current frozen-clock test machine the ceiling is lower, which is why the console stays hidden.)

GL Overlay Presentation

At high internal resolutions (4x–6x), a CPU readback path becomes the bottleneck — at 6x (3840x2880) it moves ~42 MB per frame across the PCIe bus.

On Linux the game runs in the --game-host process and presents through the native Wayland toplevel (X11/SDL fallback). The GL overlay path blits the core's FBO directly to the presented surface, and the in-game overlay (pause HUD, cog menu, save/load slots, cheats panel, recording controls) is drawn straight into the game window via GL — see GlOsd.cs. Readback, where used, goes through the never-blocking 4-slot PBO ring so the GPU never stalls.

Visual Upgrades

Dolphin renders at native 640x480 (480p). Internal resolution upscaling dramatically improves polygon clarity:

Option Native Upscaled (suggested)
dolphin_efb_scale 1 3 or 4 (1440p / 4K equivalent)
dolphin_max_anisotropy 0 4 (16x anisotropic)
dolphin_anti_aliasing 0 2 or 4

1x/2x removed: at native and 2x scale, Dolphin's framebuffer-indirection render lands tucked in the bottom-left corner of the managed FBO. The image fills the buffer correctly from ~3x up, so the handler filters the 1 and 2 choices out of dolphin_efb_scale. The Linux default is 4x (renders full-window out of the box). The cog-menu visual options are Internal Resolution, Anisotropic Filtering, and Anti-Aliasing.

All options take effect immediately without restarting the game.

AMD / Intel GPU Compatibility Mode

Some AMD Radeon (notably integrated/laptop chips) and Intel GL drivers misrender Dolphin libretro's framebuffer indirection — the game ends up tucked into the bottom-left corner of the window with the rest blank. NVIDIA's GL driver tolerates the FBO indirection fine; AMD/Intel sometimes don't.

Fix: open Preferences → Cores / Extras and enable the GameCube: render to default framebuffer (AMD/Intel GPU compatibility) checkbox under the Compatibility section.

What it changes when enabled:

  • get_current_framebuffer returns 0 (the default backbuffer) instead of the frontend's managed FBO
  • Frame readback uses FBO 0 instead of the managed FBO
  • The GL overlay path is automatically disabled (it's incompatible with rendering directly to the default backbuffer) — the handler sets UseGLOverlay => !UseDefaultFramebuffer

Tradeoff: the in-game GL overlay (cog menu, save/load slots, cheats panel, recording controls) is disabled for GameCube while this is on. You can still launch games, save/load via keyboard shortcuts (F5/F7), and exit via the close button — you just lose the on-screen pill UI.

NVIDIA users should leave this off. Enabling it on NVIDIA hardware swaps to the readback path and produces the same bottom-left bug as a side effect — the symptom appears on whichever hardware doesn't match the active mode.

Clone this wiki locally