SharedGL

repository·master·Indexed 41 days ago

https://github.com/dmaivel/sharedgl

An OpenGL 4.6 implementation that enables 3D acceleration for Windows and Linux guests within QEMU/KVM. It works by streaming OpenGL commands from a guest client (ICD/libGL) to a host server (sglrenderer) via shared memory (ivshmem) or network sockets.

Tokens
2.3K
Snippets
7
Records
11
Agent score
51%

What's inside SharedGL

  1. How SharedGL works

    master

    SharedGL provides OpenGL 4.6 acceleration for Windows and Linux guests in QEMU/KVM by streaming commands from a guest client to a host server.

    Components

    • Server (sglrenderer): Runs on the Linux host. It receives OpenGL commands and renders them in a window on the host.
    • Client (ICD / libGL): Runs inside the guest VM. It intercepts OpenGL calls from guest applications and forwards them to the server.

    Transports

    TransportSpeedSetupRequirements
    Shared memoryFasterDefaultRequires an ivshmem device on the VM and a kernel driver in the guest.
    Network socketSlowerNo driversWorks anywhere with a network connection; no VM configuration required.
  2. Configure VM for Shared Memory transport

    master

    To use the faster shared memory transport, you must attach an ivshmem device to your VM. Use sglrenderer -v on the host to generate snippets tailored to your current server settings.

    libvirt Example

    Place inside the <devices> section:

    <shmem name="sharedgl_shared_memory">
        <model type="ivshmem-plain"/>
        <size unit="M">??</size>
    </shmem>

    QEMU Example

    qemu-system-x86_64 \
      -object memory-backend-file,size=??M,share,mem-path=/dev/shm/sharedgl_shared_memory,id=sharedgl_shared_memory
    <!-- libvirt sample -->
    <shmem name="sharedgl_shared_memory">
        <model type="ivshmem-plain"/>
        <size unit="M">??</size>
    </shmem>
  3. Build the SharedGL server (`sglrenderer`)

    master

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

    Dependencies

    Build Steps

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

    Build Options

    Use -D flags with cmake or ccmake:

    • LINUX_LIB32: Set to ON to build the Linux client library as 32-bit (does not affect the server).
  4. Set up a Linux guest

    master

    Linux guests require a kernel module (for shared memory) and the client library.

    1. Install Kernel Module

    Build the module inside the guest and install it:

    cd kernel/linux
    make
    ./install.sh

    If it doesn't auto-load, add sharedgl to your modprobe config.

    2. Install Client Library

    Build sharedgl-core (as described in the server build guide) or use the packaged libraries from the Linux release tarball. Point your loader to the library directory:

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

    Note: Use lib32/ for 32-bit applications. Some apps may require LD_PRELOAD pointing to the same directory.

    Linux Host (No VM)

    The Linux client library works directly on the host for debugging. Follow the same LD_LIBRARY_PATH steps above.

    # Install kernel module in guest
    cd kernel/linux
    make
    ./install.sh
    
    # Use client library
    export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/path/to/sharedgl/lib
    glxgears
  5. Set up a Windows guest

    master

    Windows guests require a kernel driver (for shared memory) and the OpenGL client library (ICD).

    1. Install Kernel Driver

    Choose one of three options:

    • Option A (Stock VirtIO IVSHMEM): Install ivshmem.inf from upstream VirtIO Win drivers. Supports only a single client.
    • Option B (Stock + Runtime Patch): Use the stock driver and apply a runtime patch using ntoseye to support multiple clients.
    • Option C (Bundled ksgldrv): A multi-client driver for Windows 10. Requires enabling test-signing via bcdedit.exe -set testsigning on. Build from source using the WDK or install from a release.

    2. Install Client Library (ICD)

    • From Release: Run wininstall.bat as administrator from the extracted Windows release.
    • From Source: Build sharedgl-core for both x64 and Win32 using Visual Studio, then run wininstall.bat from the build directory.
  6. Configure SharedGL client environment variables

    master

    Use these variables inside the guest to tune client behavior. Boolean variables must be set to true (not 1 or on).

    VariableValuesDefaultPlatformDescription
    SGL_NETWORK_ENDPOINTIP:PortWindows, LinuxRequired in guest when server uses -n mode.
    SGL_WINED3D_DONT_VFLIPbooleanfalseWindowsSet to true for DirectX apps via WineD3D to fix upside-down rendering.
    SGL_RUN_WITH_LOW_PRIORITYbooleanfalseWindowsRuns client at IDLE_PRIORITY_CLASS. Improves smoothness on low-vCPU VMs or networking.
    GL_VERSION_OVERRIDED.DhostWindows, LinuxOverride reported OpenGL version.
    GLX_VERSION_OVERRIDED.D1.4LinuxOverride reported GLX version.
    GLSL_VERSION_OVERRIDED.DWindows, LinuxOverride reported GLSL version.
  7. Generate VM configuration for shared memory

    master

    When using the default shared memory transport, you must configure your Virtual Machine (libvirt or QEMU) to access the shared memory segment created by sglrenderer.

    Use the -v flag with sglrenderer to print the exact configuration strings required for your current memory allocation settings.

    Example command:

    sglrenderer -m 64 -v

    This will output the necessary XML for libvirt (<shmem> block) and the command-line arguments for QEMU (-object memory-backend-file...).

    sglrenderer -v
  8. Run the `sglrenderer` server

    master

    The server must be running on the host before starting the guest. If using a prebuilt tarball, run ./sglrenderer from the root.

    CLI Reference

    sglrenderer [-h] [-v] [-o] [-n] [-x] [-g MAJOR.MINOR] [-r WIDTHxHEIGHT] [-m SIZE] [-p PORT]

    FlagDescription
    -hShow help
    -vPrint sample VM configuration for the current settings
    -oEnable FPS overlay on clients
    -nUse networking instead of shared memory
    -xRemove the shared memory file (useful for cleanup)
    -g MAJOR.MINORReport a specific OpenGL version (default: 4.6)
    -r WxHMax resolution (default: 1920x1080)
    -m SIZEMax memory in MiB (default: 32)
    -p PORTPort when -n is used (default: 3000)
  9. Initialize SharedGL via sharedgl_entry

    master

    SharedGL provides an automatic initialization mechanism using a constructor attribute. When the client library is loaded, sharedgl_entry is called automatically to initialize the OpenGL implementation (glimpl_init) and, on non-Windows platforms, the GLX implementation (glximpl_init). This ensures the ICD/libGL client is ready to forward OpenGL commands to the server without manual setup in your application code.

    // No manual call required if the library is loaded as a plugin/ICD.
    // The following is called automatically by the runtime:
    void __attribute__((constructor)) sharedgl_entry(void);
  10. Cleanup SharedGL via sharedgl_goodbye

    master

    SharedGL provides an automatic cleanup mechanism using a destructor attribute. When the client library is unloaded, sharedgl_goodbye is called automatically to perform necessary teardown via glimpl_goodbye().

    // No manual call required if the library is unloaded as a plugin/ICD.
    // The following is called automatically by the runtime:
    void __attribute__((destructor)) sharedgl_goodbye(void);
  11. Use the sglrenderer CLI

    master

    The sglrenderer process is the SharedGL server that runs on the host to receive and render OpenGL commands. It can operate using shared memory (default) or via a network server.

    Usage

    sglrenderer [options]

    Options

    FlagDescription
    -hDisplay help information
    -vDisplay virtual machine arguments (libvirt/QEMU) for shared memory setup
    -oEnables FPS overlay on clients
    -nEnable network server instead of using shared memory
    -xRemove the shared memory file
    -g [MAJOR.MINOR]Report a specific OpenGL version (e.g., -g 4.6)
    -r [WIDTHxHEIGHT]Set maximum resolution (e.g., -r 2560x1440)
    -m [SIZE]Max amount of megabytes the program may allocate (e.g., -m 64)
    -p [PORT]Specify the port to use if networking is enabled (default: 3000)
    sglrenderer [-h] [-v] [-o] [-n] [-x] [-g MAJOR.MINOR] [-r WIDTHxHEIGHT] [-m SIZE] [-p PORT]