Skip to main content
Hydra supports rendering games at higher resolutions than the original Nintendo Switch hardware, providing sharper visuals on modern displays.

Available Resolution Options

Hydra offers multiple resolution presets plus custom resolution support:
enum class Resolution : u32 {
    Invalid = 0,
    
    Auto,        // Automatic based on window/display
    _720p,       // 1280x720 (Native handheld)
    _1080p,      // 1920x1080 (Full HD)
    _1440p,      // 2560x1440 (2K/QHD)
    _2160p,      // 3840x2160 (4K/UHD)
    _4320p,      // 7680x4320 (8K)
    AutoExact,   // Exact window size
    Custom,      // User-defined resolution
};

720p

1280 x 720Native Switch handheld resolution

1080p

1920 x 1080Full HD, native Switch docked

1440p

2560 x 14402K/QHD, great for gaming monitors

2160p

3840 x 21604K Ultra HD

4320p

7680 x 43208K (experimental)

Custom

Any resolutionUser-defined dimensions

How Resolution Scaling Works

Hydra scales game rendering through multiple stages:
1

Game Renders to Virtual Framebuffer

The game renders at its intended resolution (720p or 1080p)
2

Resolution Scaling Applied

Hydra’s renderer scales the output to the target resolution
3

Display Composition

The scaled image is composed for the host display
4

Final Presentation

The frame is presented through Metal to the display

Resolution Selection Logic

The emulator determines the final resolution based on your settings:
src/core/horizon/os.cpp
uint2 round_up_to_nearest_standard_resolution(uint2 surface_resolution) {
    static uint2 standard_resolutions[] = {
        {1280, 720}, {1920, 1080}, {2560, 1440}, 
        {3840, 2160}, {7680, 4320}
    };
    
    for (u32 i = 0; i < sizeof_array(standard_resolutions); i++) {
        const auto& resolution = standard_resolutions[i];
        if (surface_resolution.x() <= resolution.x() &&
            surface_resolution.y() <= resolution.y())
            return resolution;
    }
    
    return standard_resolutions[sizeof_array(standard_resolutions) - 1];
}
In Auto mode, Hydra rounds up to the nearest standard resolution that fits your display or window.

Resolution Modes

Automatic Resolution Selection
case Resolution::Auto:
    return round_up_to_nearest_standard_resolution(surface_resolution);
  • Automatically selects best resolution for your display
  • Rounds up to nearest standard resolution
  • Ideal for most users
  • Changes with window size

Handheld vs Docked Mode

The Nintendo Switch has different display behaviors in handheld and docked modes:
src/core/horizon/os.cpp
uint2 OS::GetDisplayResolution() const {
    if (GetAppletMode() == AppletMode::Handheld) {
        return {1280, 720}; // Handheld display resolution is fixed
    }
    
    switch (CONFIG_INSTANCE.GetDisplayResolution()) {
        case Resolution::Auto:
            return round_up_to_nearest_standard_resolution(surface_resolution);
        // ... other modes
        case Resolution::AutoExact:
            return surface_resolution;
    }
}
Handheld Mode: Resolution is always locked to 720p (1280x720) to match the Switch’s physical screen.Docked Mode: Resolution can be scaled up to improve visual quality.

Viewport and Scaling

The Metal renderer handles viewport transformation and scaling:
src/core/hw/tegra_x1/gpu/engines/3d.cpp
auto scale_x = transform.scale_x;
auto scale_y = transform.scale_y;

res.rect.origin.x() = transform.offset_x - scale_x;
res.rect.origin.y() = transform.offset_y - scale_y;
res.rect.size.x() = scale_x * 2.0f;
res.rect.size.y() = scale_y * 2.0f;

Aspect Ratio Handling

Hydra maintains the correct aspect ratio during scaling:
src/core/horizon/display/driver.cpp
auto scale_x = f32(width) / src_size.x();
auto scale_y = f32(height) / src_size.y();

float dst_scale;
if (scale_x > scale_y) {
    dst_scale = scale_y;
    const auto dst_width = src_size.x() * dst_scale;
    // Center horizontally
} else {
    dst_scale = scale_x;
    const auto dst_height = src_size.y() * dst_scale;
    // Center vertically
}
The display driver automatically letterboxes or pillarboxes the image to maintain the correct aspect ratio.

Performance Impact

Higher resolutions require more GPU processing power:
Performance: Fastest
  • Native Switch handheld resolution
  • ~0.9 million pixels
  • Minimal GPU load
  • Best for integrated graphics
Use when:
  • Running on older Macs
  • Maximizing frame rate
  • Using integrated graphics
Performance: Fast
  • Native Switch docked resolution
  • ~2.1 million pixels (2.3x more than 720p)
  • Moderate GPU load
  • Good balance of quality and performance
Use when:
  • Standard gaming setup
  • Modern Mac with decent GPU
  • Want crisp visuals without heavy load
Performance: Moderate
  • 2K/QHD resolution
  • ~3.7 million pixels (4x more than 720p)
  • Noticeable GPU load
  • Requires capable GPU
Use when:
  • High-end Mac with dedicated GPU
  • QHD display
  • Want enhanced visual quality
Performance: Heavy
  • Ultra HD resolution
  • ~8.3 million pixels (9x more than 720p)
  • Significant GPU load
  • Requires powerful GPU
Use when:
  • Mac Studio or high-end MacBook Pro
  • 4K display
  • GPU headroom available
Performance: Very Heavy
  • Experimental
  • ~33.2 million pixels (36x more than 720p)
  • Extreme GPU load
  • Requires top-tier GPU
Use when:
  • Testing/benchmarking only
  • Mac Studio Ultra
  • Not recommended for actual gameplay

Visual Quality Tradeoffs

Lower Resolutions (720p-1080p)

Pros:
  • Higher frame rates
  • Lower GPU usage
  • Better battery life (laptops)
  • Cooler temperatures
Cons:
  • Less sharp on large displays
  • More visible aliasing
  • Softer textures

Higher Resolutions (1440p-4K)

Pros:
  • Sharper image quality
  • Better detail visibility
  • Reduced aliasing
  • Clearer UI elements
Cons:
  • Lower frame rates
  • Higher GPU usage
  • More power consumption
  • Increased heat

Texture and Blit Scaling

The Metal renderer handles texture scaling during blit operations:
src/core/hw/tegra_x1/gpu/renderer/metal/renderer.cpp
float2 scale = float2(
    src_rect.size.x() / src_width,
    src_rect.size.y() / src_height
);

BlitParams params = {
    .src_scale = scale,
    // ...
};
1

For Best Performance

  • Resolution: 720p or 1080p
  • Mode: Fixed resolution
  • Good for: Older Macs, integrated graphics, battery life
2

For Balanced Quality

  • Resolution: Auto or 1080p
  • Let Hydra choose appropriate resolution
  • Good for: Most users, modern Macs
3

For Maximum Quality

  • Resolution: 1440p or 4K
  • Requires powerful GPU
  • Good for: High-end Macs, 4K displays, screenshots

Configuration

Set your resolution preference in the configuration:
config.toml
[graphics]
display_resolution = "1080p"  # or "auto", "720p", "1440p", "2160p", "custom"

# For custom resolution:
# display_resolution = "custom"
# custom_display_resolution = [2560, 1440]
Start with Auto mode and adjust based on your display and performance requirements.

Troubleshooting

If experiencing low frame rates:
  1. Lower the resolution (try 1080p or 720p)
  2. Check GPU usage in Activity Monitor
  3. Close other GPU-intensive applications
  4. Ensure your Mac isn’t thermal throttling
If the image looks blurry:
  • Increase resolution to match your display
  • Use AutoExact mode for pixel-perfect scaling
  • Check your display’s native resolution
  • Some games may have internal resolution limits
Black bars around the image:
  • This is normal for aspect ratio preservation
  • Switch games run at 16:9 aspect ratio
  • Ultra-wide displays will show pillarboxing
  • Cannot be removed without distorting the image

Build docs developers (and LLMs) love