Installation

Client

The Looking Glass Client receives frames from the Host to display on your screen. It also handles input, and can optionally share the system clipboard with your guest OS through Spice.

First you must build the client from source code, see Building.

libvirt Configuration

This article assumes you already have a fully functional libvirt domain with PCI passthrough working on a dedicated monitor.

If you use virt-manager, this guide also applies to you, since virt-manager uses libvirt as its back-end.

If you are using QEMU directly, this does not apply to you.

Add the following to your libvirt machine configuration inside the ‘devices’ section by running virsh edit <VM> where <VM> is the name of your virtual machine.

<shmem name='looking-glass'>
  <model type='ivshmem-plain'/>
  <size unit='M'>32</size>
</shmem>

The memory size (show as 32 in the example above) may need to be adjusted as per the Determining Memory section.

Spice Server

If you would like to use Spice to give you keyboard and mouse input along with clipboard sync support, make sure you have a <graphics type='spice'> device, then:

  • Find your <video> device, and set <model type='none'/>

    • If you can’t find it, make sure you have a <graphics> device, save and edit again

    • On older libvirt versions, just disable the device in Windows Device Manager

  • Remove the <input type='tablet'/> device, if you have one

  • Create an <input type='mouse'/> device, if you don’t already have one

  • Create an <input type='keyboard' bus='virtio'/> device to improve keyboard usage

    • This requires the vioinput driver from virtio-win to be installed in the guest

If you want clipboard synchronization please see Clipboard Synchronization

AppArmor

For libvirt versions before 5.10.0, if you are using AppArmor, you need to add permissions for QEMU to access the shared memory file. This can be done by adding the following to /etc/apparmor.d/local/abstractions/libvirt-qemu:

/dev/shm/looking-glass rw,

then, restart AppArmor.

sudo systemctl restart apparmor

Memballoon

The VirtIO memballoon device enables the host to dynamically reclaim memory from your VM by growing the balloon inside the guest, reserving reclaimed memory. Libvirt adds this device to guests by default.

However, this device causes major performance issues with VFIO passthrough setups, and should be disabled.

Find the <memballoon> tag and set its type to none:

<memballoon model="none"/>

QEMU Commands

If you are using libvirt/virt-manager, then this does not apply to you.

Add the following to the commands to your QEMU command line, adjusting the bus parameter to suit your particular configuration:

-device ivshmem-plain,memdev=ivshmem,bus=pcie.0 \
-object memory-backend-file,id=ivshmem,share=on,mem-path=/dev/shm/looking-glass,size=32M

The memory size (shown as 32M in the example above) may need to be adjusted as per Determining Memory section.

Determining Memory

You will need to adjust the memory size to be suitable for your desired maximum resolution, with the following formula:

width x height x 4 x 2 = total bytes

total bytes / 1024 / 1024 = total megabytes + 10

For example, for a resolution of 1920x1080 (1080p):

1920 x 1080 x 4 x 2 = 16,588,800 bytes

16,588,800 / 1024 / 1024 = 15.82 MB + 10 = 25.82 MB

You must round this value up to the nearest power of two, which for the provided example is 32MB.

Shared Memory File Permissions

The shared memory file used by IVSHMEM is found in /dev/shm/looking-glass. By default, it is owned by QEMU, and does not give read/write permissions to your user, which are required for Looking Glass to run properly.

You can use systemd-tmpfiles to create the file before running your VM, granting the necessary permissions which allow Looking Glass to use the file properly.

Create a new file /etc/tmpfiles.d/10-looking-glass.conf, and populate it with the following:

#Type Path               Mode UID  GID Age Argument

f /dev/shm/looking-glass 0660 user kvm -

Change UID to the user name you will run Looking Glass with, usually your own.

Clipboard Synchronization

Looking Glass can synchronize the clipboard between the host and guest using the SPICE guest agent.

1. Install the SPICE guest tools from https://www.spice-space.org/download.html#windows-binaries.

  1. Configure your VM to enable the SPICE guest agent:

  • QEMU

-device virtio-serial-pci \
-chardev spicevmc,id=vdagent,name=vdagent \
-device virtserialport,chardev=vdagent,name=com.redhat.spice.0
  • libvirt

<channel type="spicevmc">
  <target type="virtio" name="com.redhat.spice.0"/>
  <address type="virtio-serial" controller="0" bus="0" port="1"/>
</channel>
<!-- No need to add a VirtIO Serial device, it will be added automatically -->

Usage

The client command is the binary file: looking-glass-client. This command should run after the Windows Host Application has started.

You may run the client directly from the build directory. Alternatively, to install the client for all users, you can run

make install

To install for the local user only, run

cmake -DCMAKE_INSTALL_PREFIX=~/.local .. && make install

Default Key Bindings

By default, Looking Glass uses the Scroll Lock key as the escape key for commands, as well as the input capture mode toggle; this can be changed using the -m switch if you desire a different key. Below are a list of current key bindings:

Command

Description

ScrLk

Toggle capture mode

ScrLk + Q

Quit

ScrLk + R

Rotate the output clockwise by 90° increments

ScrLk + T

Show frame timing information

ScrLk + I

Spice keyboard & mouse enable toggle

ScrLk + O

Toggle overlay

ScrLk + D

FPS display toggle

ScrLk + F

Full screen toggle

ScrLk + V

Video stream toggle

ScrLk + N

Toggle night vision mode

ScrLk + F1

Send Ctrl + Alt + F1 to the guest

ScrLk + F2

Send Ctrl + Alt + F2 to the guest

ScrLk + F3

Send Ctrl + Alt + F3 to the guest

ScrLk + F4

Send Ctrl + Alt + F4 to the guest

ScrLk + F5

Send Ctrl + Alt + F5 to the guest

ScrLk + F6

Send Ctrl + Alt + F6 to the guest

ScrLk + F7

Send Ctrl + Alt + F7 to the guest

ScrLk + F8

Send Ctrl + Alt + F8 to the guest

ScrLk + F9

Send Ctrl + Alt + F9 to the guest

ScrLk + F10

Send Ctrl + Alt + F10 to the guest

ScrLk + F11

Send Ctrl + Alt + F11 to the guest

ScrLk + F12

Send Ctrl + Alt + F12 to the guest

ScrLk + Insert

Increase mouse sensitivity in capture mode

ScrLk + Del

Decrease mouse sensitivity in capture mode

ScrLk + LWin

Send LWin to the guest

ScrLk + RWin

Send RWin to the guest

You can also find this list at any time by holding down Scroll Lock.

Command Line Options

A full list of command line options is available with the --help or -h options.

Example: looking-glass-client --help

Common options include -s for disabling spice, -S for disabling the screen saver, and -F to automatically enter full screen.

Options may be provided with a short form, if available, or long form. Boolean options may be specified without a parameter to toggle their state.

Examples:

  • looking-glass-client -F (short)

  • looking-glass-client win:fullScreen (long)

  • looking-glass-client -f /dev/shm/my-lg-shmem (short with parameter)

  • looking-glass-client app:shmFile=/dev/shm/my-lg-shmem (long with parameter)

Configuration Files

By default, the application will look for and load the config files in the following locations and order:

  • /etc/looking-glass-client.ini

  • ~/.looking-glass-client.ini

  • $XDG_CONFIG_HOME/looking-glass/client.ini (usually ~/.config/looking-glass/client.ini)

Config options are merged from all files. Same options appearing in more than one file will be overridden by the latest loaded one (E.g. an option appearing in ~/.config/looking-glass/client.ini will override the same option appearing in ~/.looking-glass-client.ini). When first launched, the Looking-Glass client will create the folder $XDG_CONFIG_HOME/looking-glass/ if it does not yet exist.

The format of this file is the commonly known INI format, for example:

[win]
fullScreen=yes

[egl]
nvGain=1

Command line arguments will override any options loaded from the config files.

Overlay Mode

Looking-Glass is utilizing an overlay layer to draw various widgets (such as the FPS display). An “Overlay Mode” can be toggled (see Default Key Bindings) that allows editing and modifying widgets properties, such as their position and size. To use the Overlay Mode:

  • Enable one or more widgets (such as the FPS display)

  • Enter Overlay Mode by using its keybinding (the screen will turn darker to indicate Overlay Mode is active)

  • Drag the widgets you enabled to your preferred position

  • Change the widget size (if the widget allows you) by dragging the lower right edge

  • Change any other properties a widget has and are modifiable

  • Exit Overlay Mode by pressing ESC or using the Overlay-Mode keybinding again

Modifications done in Overlay Mode are persistent and are stored in a special config file $XDG_CONFIG_HOME/looking-glass/imgui.ini. Please refrain from editing this file manually as your changes might be overwritten by the client.

Configuration Widget

The Configuration Widget is accessible through the Overlay mode. The widget has multiple tabs that allow setting a variety of modes and parameters for the application.

Settings tab

  • Performance Metrics: Enabling this will turn on the Metrics Graphs Widget. Multiple graphs can be enabled and they will stack vertically.

  • EGL: Modify EGL features such as the algorithm used for scaling and enabling night vision mode.

Changes in the Settings tab are not persistent and will change back to their default values when the client is restarted.

EGL Filters tab

The EGL Filters tab is a GUI for enabling, configuring and ordering the post-processing filter stack. Each filter can be expanded to open its settings. Filters can also be re-ordered by dragging them up or down. Filters application is cumulative, and order is important (e.g. applying CAS before FSR might have different results than the reverse). Users are encouraged to experiment with the order and parameters to achieve optimal results. The currently available filters include:

  • Downscaler: Filter for downscaling resolution. Can be used to undo the poor upscaling that some games implement such that it can then be better upscaled using FSR (see below). The filter has a pixel-size setting that is used to set the effective downscaling ratio and can be set to use different downscaling algorithms.

  • AMD FidelityFX Super Resolution (FSR): Filter implementing a rendering technique for upscaling resolution. FSR works by accepting the original frames (on the guest) at lower resolution, then applying a spatial upscaling algorithm in the client to make the final result look as though it is rendered in high-resolution. The FSR filter interface allows for fine tuning the sharpness factor of the algorithm and shows the equivalent quality mode based on the ratio between the original frame resolution and the client resolution.

  • AMD FidelityFX Contrast Adaptive Sharpening (CAS): Filter that increases visual quality by applying a sharpening algorithm to the frame. CAS can sometimes restore detail lost in a typical upscaling application. The CAS filter interface has an adjustable sharpness control.

The filter stack settings and order can be saved to presets so that it can be conveniently recalled at a later time. As filter settings are usually application specific, multiple presets can be defined for each case scenario. To save a preset, click on “Save preset as…” and enter a preset name. Presets are recalled by selecting them in the “Preset name” pull down. Presets are persistent and are stored on disk at $XDG_CONFIG_HOME/looking-glass/presets.

Warning

Please refrain from modifying any files under the presets folder. Those files are meant to be modified only by the Looking-Glass client.

Note

Although presets are persistent, the client will not remember which preset was used last session, so a preset needs to be recalled once the client starts.

Full Command Line Options

The following is a complete list of options accepted by this application

Long

Short

Value

Description

app:configFile

-C

NULL

A file to read additional configuration from

app:renderer

-g

auto

Specify the renderer to use

app:license

-l

no

Show the license for this application and then terminate

app:cursorPollInterval

1000

How often to check for a cursor update in microseconds

app:framePollInterval

1000

How often to check for a frame update in microseconds

app:allowDMA

yes

Allow direct DMA transfers if supported (see README.md in the module dir)

app:shmFile

-f

/dev/shm/looking-glass

The path to the shared memory file, or the name of the kvmfr device to use, e.g.: kvmfr0

Long

Short

Value

Description

win:title

Looking Glass (client)

The window title

win:position

center

Initial window position at startup

win:size

1024x768

Initial window size at startup

win:autoResize

-a

no

Auto resize the window to the guest

win:allowResize

-n

yes

Allow the window to be manually resized

win:keepAspect

-r

yes

Maintain the correct aspect ratio

win:forceAspect

yes

Force the window to maintain the aspect ratio

win:dontUpscale

no

Never try to upscale the window

win:shrinkOnUpscale

no

Limit the window dimensions when dontUpscale is enabled

win:borderless

-d

no

Borderless mode

win:fullScreen

-F

no

Launch in fullscreen borderless mode

win:maximize

-T

no

Launch window maximized

win:minimizeOnFocusLoss

no

Minimize window on focus loss

win:fpsMin

-K

-1

Frame rate minimum (0 = disable - not recommended, -1 = auto detect)

win:ignoreQuit

-Q

no

Ignore requests to quit (i.e.: Alt+F4)

win:noScreensaver

-S

no

Prevent the screensaver from starting

win:autoScreensaver

no

Prevent the screensaver from starting when guest requests it

win:alerts

-q

yes

Show on screen alert messages

win:quickSplash

no

Skip fading out the splash screen when a connection is established

win:rotate

0

Rotate the displayed image (0, 90, 180, 270)

win:uiFont

DejaVu Sans Mono

The font to use when rendering on-screen UI

win:uiSize

14

The font size to use when rendering on-screen UI

win:jitRender

no

Enable just-in-time rendering

win:showFPS

-k

no

Enable the FPS & UPS display

Long

Short

Value

Description

input:grabKeyboard

-G

yes

Grab the keyboard in capture mode

input:grabKeyboardOnFocus

no

Grab the keyboard when focused

input:releaseKeysOnFocusLoss

yes

On focus loss, send key up events to guest for all held keys

input:escapeKey

-m

70 = KEY_SCROLLLOCK

Specify the escape key, see <linux/input-event-codes.h> for valid values

input:ignoreWindowsKeys

no

Do not pass events for the windows keys to the guest

input:hideCursor

-M

yes

Hide the local mouse cursor

input:mouseSens

0

Initial mouse sensitivity when in capture mode (-9 to 9)

input:mouseSmoothing

yes

Apply simple mouse smoothing when rawMouse is not in use (helps reduce aliasing)

input:rawMouse

no

Use RAW mouse input when in capture mode (good for gaming)

input:mouseRedraw

yes

Mouse movements trigger redraws (ignores FPS minimum)

input:autoCapture

no

Try to keep the mouse captured when needed

input:captureOnly

no

Only enable input via SPICE if in capture mode

input:helpMenuDelay

200

Show help menu after holding down the escape key for this many milliseconds

Long

Short

Value

Description

spice:enable

-s

yes

Enable the built in SPICE client for input and/or clipboard support

spice:host

-c

127.0.0.1

The SPICE server host or UNIX socket

spice:port

-p

5900

The SPICE server port (0 = unix socket)

spice:input

yes

Use SPICE to send keyboard and mouse input events to the guest

spice:clipboard

yes

Use SPICE to synchronize the clipboard contents with the guest

spice:clipboardToVM

yes

Allow the clipboard to be synchronized TO the VM

spice:clipboardToLocal

yes

Allow the clipboard to be synchronized FROM the VM

spice:scaleCursor

-j

yes

Scale cursor input position to screen size when up/down scaled

spice:captureOnStart

no

Capture mouse and keyboard on start

spice:alwaysShowCursor

no

Always show host cursor

spice:showCursorDot

yes

Use a “dot” cursor when the window does not have focus

Long

Short

Value

Description

egl:vsync

no

Enable vsync

egl:doubleBuffer

no

Enable double buffering

egl:multisample

yes

Enable Multisampling

egl:nvGainMax

1

The maximum night vision gain

egl:nvGain

0

The initial night vision gain at startup

egl:cbMode

0

Color Blind Mode (0 = Off, 1 = Protanope, 2 = Deuteranope, 3 = Tritanope)

egl:scale

0

Set the scale algorithm (0 = auto, 1 = nearest, 2 = linear)

egl:debug

no

Enable debug output

Long

Short

Value

Description

opengl:mipmap

yes

Enable mipmapping

opengl:vsync

no

Enable vsync

opengl:preventBuffer

yes

Prevent the driver from buffering frames

opengl:amdPinnedMem

yes

Use GL_AMD_pinned_memory if it is available

Long

Short

Value

Description

wayland:warpSupport

yes

Enable cursor warping

wayland:fractionScale

yes

Enable fractional scale

Host

The Looking Glass Host captures frames from the guest OS using a capture API, and sends them to the Client—be it on the host OS (hypervisor) or another Virtual Machine—through a low-latency transfer protocol over shared memory.

You can get the host program in two ways:

Windows

To begin, you must first run the Windows VM with the changes noted above in either the libvirt Configuration or QEMU Commands sections.

Installing the IVSHMEM Driver

Windows will not prompt for a driver for the IVSHMEM device, instead, it will use a default null (do nothing) driver for the device. To install the IVSHMEM driver you will need to go into the device manager and update the driver for the device “PCI standard RAM Controller” under the “System Devices” node.

A signed Windows 10 driver can be obtained from Red Hat for this device from the below address:

https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/upstream-virtio/

Please note that you must obtain version 0.1.161 or later.

If you encounter warnings or errors about driver signatures, ensure secure boot is turned off in the bios/UEFI settings of your virtual machine.

Installing the Looking Glass Service

After installing your IVSHMEM driver, we can now install the Looking Glass Host onto our Windows Virtual Machine.

  1. First, run looking-glass-host-setup.exe as an administrator (Why?)

  2. You will be greeted by an intro screen. Press Next to continue.

  3. You are presented with the GPLv2 license. Please read and agree to the license by pressing Agree.

  4. You can change the install path if you wish, otherwise press Next to continue.

  5. You may enable or disable options on this screen to configure the installation. The default values are recommended for most users. Press Install to begin installation.

  6. After a few moments, installation will complete, and you will have a running instance of Looking Glass. If you experience failures, you can see them in the install log appearing in the middle of the window.

  7. Press Close to exit the installer.

Command line users can run looking-glass-host-setup.exe /S to execute a silent install with default options selected. Further configuration from the command line can be done with flags. You can list all available flags by running looking-glass-host-setup.exe /?.