Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

dmaivel/sharedgl

Open more actions menu

Repository files navigation

SharedGL license

SharedGL is an OpenGL 4.6 implementation that enables 3D acceleration for Windows and Linux guests within QEMU/KVM by streaming OpenGL commands over shared memory or sockets.

Click to hide: Preview

preview

Click to reveal: Table of contents
  1. How it works
  2. Building the server
  3. Running the server
  4. Connecting the guest
  5. Troubleshooting
  6. Showcase

How it works

SharedGL has two halves:

  • Server (sglrenderer) which runs on the host, Linux only. Receives OpenGL commands and renders them in a window on the host.
  • Client (ICD / libGL) which runs in the guest. Installed inside the VM so that OpenGL applications there transparently forward their calls to the server.

The two halves communicate through one of two transports:

Transport Speed Setup
Shared memory Faster Default, requires an ivshmem device on the VM and a kernel driver in the guest.
Network socket Slower No drivers, no VM config. It works anywhere with a network connection, so it's not restricted to just VMs.

You pick the transport when you start the server. The rest of this README follows that order: build the server, run it, then connect a guest.

Building the server

Dependencies

Name Version
CMake 3.15+
libepoxy Latest
SDL2 2.24.0+

Prebuilt tarball

If you just want to run the Linux server, you can download the Linux release tarball instead of building from source.

Build

git clone https://github.com/dmaivel/sharedgl.git
cd sharedgl
mkdir build && cd build
cmake ..
cmake --build . --target sglrenderer --config Release

The server can only be built and run on a Linux host.

If you also want the Linux client library (libGL) for use on the host or to copy into a Linux guest, build the sharedgl-core target instead. libx11 is required for this.

Build options

Pass these to cmake with -D..., or edit them via ccmake build.

Option Values Default Description
LINUX_LIB32 ON/OFF OFF Build the Linux client library as 32-bit. Does not affect the server.

Running the server

usage: sglrenderer [-h] [-v] [-o] [-n] [-x] [-g MAJOR.MINOR]
                   [-r WIDTHxHEIGHT] [-m SIZE] [-p PORT]
Flag Description
-h Show help
-v Print sample VM configuration for the current settings
-o Enable FPS overlay on clients
-n Use networking instead of shared memory
-x Remove the shared memory file (useful for cleanup)
-g MAJOR.MINOR Report a specific OpenGL version (default: 4.6)
-r WxH Max resolution (default: 1920x1080)
-m SIZE Max memory in MiB (default: 32)
-p PORT Port when -n is used (default: 3000)

The server must be running on the host before you start the guest. If you extracted a Linux release tarball, run ./sglrenderer from the extracted root.

Connecting the guest

Choosing a transport

Before you install anything in the guest, decide how the guest will reach the server:

  • Shared memory: default, faster. You'll need to add an ivshmem device to the VM and install a kernel driver in the guest.
  • Networking: driverless, simpler, much slower. Start the server with -n, and set SGL_NETWORK_ENDPOINT=<host-ip>:<port> as an environment variable inside the guest.

VM configuration for shared memory

Run sglrenderer -v to get configuration snippets matched to your current settings. For reference:

libvirt:

<!-- SAMPLE, place inside <devices> -->
<devices>
    ...
    <shmem name="sharedgl_shared_memory">
        <model type="ivshmem-plain"/>
        <size unit="M">??</size>
    </shmem>
</devices>

qemu:

# SAMPLE
qemu-system-x86_64 \
  -object memory-backend-file,size=??M,share,mem-path=/dev/shm/sharedgl_shared_memory,id=sharedgl_shared_memory

Windows guest

A Windows guest needs two things: a kernel driver (for shared memory only) and the OpenGL client library (the ICD).

1. Kernel driver

Pick one of the three options below.

Option A: Stock VirtIO IVSHMEM driver (single client only)

  1. Download and extract the upstream VirtIO Win drivers.
  2. Go to ...\virtio-win-upstream\Win10\amd64\.
  3. Right-click ivshmem.inf and choose Install.

Option B: Stock VirtIO IVSHMEM driver + runtime patch (multi-client)

Same driver as Option A, but patched at runtime by ntoseye to allow multiple clients. The patch must be re-applied every time the VM boots.

  1. Follow Option A to install the stock driver.
  2. Install and run ntoseye (see its README if you hit issues).
  3. In the ntoseye console, run:
    lm ivshmem                          # prints start address
    s <start> 4883792000740a 0x3000     # prints match address
    f <match> 4883792000eb0a            # applies the patch
    continue
    quit
    

Option C: Bundled ksgldrv driver (multi-client, Windows 10)

Requires enabling test-signing once:

bcdedit.exe -set testsigning on

Then either install from a release or build from source:

Install from release (release 0.4.0)
  1. Download and extract the latest Windows release.
  2. Right-click ksgldrv.inf and choose Install.
Build from source (Visual Studio Developer Command Prompt)

Install the WDK first, then:

:: from the sharedgl directory
mkdir build
cd build
cmake -DCMAKE_GENERATOR_PLATFORM=x64 -DWINKERNEL=ON ..
cmake --build . --target ksgldrv --config Release
cd ..
xcopy .\scripts\kcertify.bat .\build\Release\kcertify.bat
xcopy .\scripts\ksgldrv.inf .\build\Release\ksgldrv.inf
cd build\Release
call kcertify.bat 10_X64

:: requires admin, or right-click ksgldrv.inf and choose Install
pnputil -i -a ksgldrv.inf

The default target is 10_X64. For other or additional Windows versions, pass them to kcertify.bat (e.g. kcertify.bat 10_X64,10_NI_X64). See the OS version list.

2. Client library (ICD)

Install from a release or build from source.

Install from release (>= 0.3.1)
  1. Download and extract the latest Windows release.
  2. Run wininstall.bat as administrator.

Any OpenGL application (32-bit or 64-bit) will now route through SharedGL.

Build from source (Visual Studio Developer Command Prompt)
:: from the sharedgl directory
mkdir build
cd build
:: add -DWINKERNEL=OFF if you hit WDK errors
cmake -DCMAKE_GENERATOR_PLATFORM=x64 ..
cmake --build . --target sharedgl-core --config Release
cmake -DCMAKE_GENERATOR_PLATFORM=Win32 ..
cmake --build . --target sharedgl-core --config Release
cd ..
xcopy .\scripts\wininstall.bat .\build\Release\wininstall.bat
cd build\Release
call wininstall.bat

Linux guest

Although it's possible to use SharedGL with Linux guests, there is little reason to given first-class 3D acceleration support via virtio/virgl.

A Linux guest needs a kernel module (for shared memory only) and the client library.

1. Kernel module

Build inside the guest, then load with the provided installer:

cd kernel/linux
make
./install.sh

If the module doesn't auto-load on boot, add sharedgl to your modprobe config.

2. Client library

Build sharedgl-core as described in Building the server, or use the packaged client libraries from the Linux release tarball. Then point your loader at the client directory:

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/path/to/sharedgl/lib
glxgears

Use lib32/ instead of lib/ for 32-bit applications. Some applications also need LD_PRELOAD set to the same directory.

Linux host (no VM)

The Linux client library also works directly on the host, useful for debugging without a VM. Build sharedgl-core or use the packaged tarball, set LD_LIBRARY_PATH as shown in the Linux guest section, and run your application.

Environment variables

Once the client is installed, these variables tune its behavior. SGL_NETWORK_ENDPOINT is required when the server is running in networking mode; the rest are optional. Variables marked host inherit from the server when not overridden.

Boolean env vars can only be enabled by setting them to true, not 1 or on.

Variable Values Default Platform Description
SGL_NETWORK_ENDPOINT IP:Port Windows, Linux Required in the guest when networking is enabled.
SGL_WINED3D_DONT_VFLIP boolean false Windows Set to true when running DirectX apps through WineD3D so the framebuffer renders right-side up.
SGL_RUN_WITH_LOW_PRIORITY boolean false Windows Runs the client at IDLE_PRIORITY_CLASS. Can improve smoothness on VMs with fewer vCPUs than host cores, or when using networking.
GL_VERSION_OVERRIDE D.D host Windows, Linux Override the reported OpenGL version.
GLX_VERSION_OVERRIDE D.D 1.4 Linux Override the reported GLX version.
GLSL_VERSION_OVERRIDE D.D Windows, Linux Override the reported GLSL version.

Troubleshooting

Client logs glimpl_init: failed to find memory

The VM doesn't have a shared memory device attached. Add the ivshmem config from VM configuration for shared memory, or switch to networking.

Server logs `err: failed to open shared memory 'sharedgl_shared_memory'

The shared memory file already exists with different permissions. Shut down the VM, run sudo ./sglrenderer -x to remove it, then start the server and VM again. Running the server with sudo is a shorter-term workaround.

Application stalls in the VM (process starts but hangs)

  • Confirm the server is running on the host. If it is and the app still stalls, shut down the VM, run sudo ./sglrenderer -x, restart the server, then boot the VM.
  • Confirm the driver is installed (VirtIO IVSHMEM or ksgldrv on Windows; sharedgl.ko on Linux).

Blank window in the VM

The shared memory device likely isn't sized to cover all the memory the server allocates. Check the <size> in your VM config against the server's -m value.

Crashes like IOT instruction or No provider of glXXX found.

  • Try a lower reported GL version: -g 2.0 or env vars
  • Give the server more memory: -m 256

GLFW apps report "Entry point retrieval is broken"

Use LD_PRELOAD with the client library.

Linux guest crashes with SIGILL

The client library was built on a host with a different CPU than the guest sees.

Showcase

Click to reveal: Running SuperTuxKart in a Windows virtual machine
2024-06-28.19-58-59.mp4
Click to reveal: Running a DirectX sample via WineD3D in a Windows virtual machine
2024-07-07.20-21-06.mp4
Click to reveal: Running minetest in a Windows virtual machine (old)
winminetest.mp4
Click to reveal: Running glxgears in a Windows virtual machine (old)
wingears.mov
Click to reveal: Running glxgears in a Linux virtual machine (old)
glxgears.mov
Click to reveal: Running a compute shader in a Linux virtual machine (old)
compute.mov

Packages

 
 
 

Contributors

Languages

Morty Proxy This is a proxified and sanitized view of the page, visit original site.