Skip to content
Rigby-FoundationPublic

About

OpenGL 2.1 for the sic OS

Topics

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

8 Commits

Folders and files

Repository files navigation

zgl — OpenGL for sic

The host GPU from user space, in two layers. Optional, like zwm: make install drops the libraries and headers into the sysroot and the test programs into its rootfs/ overlay.

lib/virgl.c, include/virgl.h    libvirgl: /dev/gpu0 and the virgl command stream
lib/r300/, include/r300_hw.h    the same stream run on an R300 IGP (/dev/radeongpu)
lib/gl/                         libzgl: OpenGL 2.1 on top of it
include/GL/gl.h                 the API; GL/sic_gl.h the context ABI for SDL
tools/virgltri.c                a triangle through libvirgl alone
tools/zgltest.c                 libzgl: immediate mode, a lit cube, GLSL + VBO + texture

How it works

sic's virtio-gpu driver speaks virgl when the host offers it (QEMU with virglrenderer: -device virtio-vga-gl -display sdl,gl=on). /dev/gpu0 gives a process a rendering context, resources (textures and buffers, with guest memory behind them when asked, mmap'able), transfers both ways, and command submission (include/abi/gpu.h in sic). The host runs the commands on its own GL; there is no GPU code in the kernel beyond that.

libvirgl wraps the ioctls and encodes the command stream: create and bind objects (shaders as TGSI text, blend/rasterizer/depth-stencil state, vertex elements, sampler views and states, surfaces), set the framebuffer, viewport, constants and vertex/index buffers, draw, clear, copy, and the inline writes for small uploads. virgltri uses it directly.

libzgl is OpenGL 2.1 on that: the object model (buffers, textures with mipmaps, shaders, programs, uniforms, vertex attributes), the state (blend, depth, stencil, cull, scissor, alpha test, polygon offset), and the fixed-function pipeline OpenGL 1.x programs use — matrix stacks, lights and materials, immediate mode, client arrays, texture environments — expressed as generated GLSL programs so the host needs one path only. GLSL 1.20 is compiled to TGSI by lib/gl/glsl.c: the types, constructors and swizzles, control flow (constant-bound loops unrolled, the rest real loops), user functions (inlined), the built-in functions, gl_* state and varyings, textures. Quads, quad strips, polygons and line loops become index lists.

The frame is an offscreen colour + depth resource; sic_gl_swap() reads it back (top row first, 0x00RRGGBB) into wherever sic_gl_set_target() pointed — SDL's zwm driver points it at the window's shared buffer, so a swap is one readback and a damage message. When zwm composites on the GPU nothing is read back: sic_gl_flush() copies the frame into a host buffer (sic_gl_buffer()) that the server samples in place. zwm itself renders with zgl into a buffer the display scans out (sic_gl_scanout(), sic_gl_present()); GL/zgl_ext.h has what a compositor needs on top: another program's buffer as a texture, fast uploads of 0x00RRGGBB.

Not there: display lists, evaluators, feedback/selection, accumulation, multisampling, 1D/3D textures, framebuffer objects, glCopyTex*. GL_RENDERER names the host GPU (zgl on virgl (Apple M4)). Big-endian guests (the PowerPC port) are out: the command stream and vertex data are little-endian and virglrenderer assumes as much.

On a Radeon IGP

On R300-class IGPs without hardware vertex processing (Radeon Xpress 200M/1100/1150, RS400/RS480; sic's /dev/radeongpu), libvirgl runs the command stream itself instead of sending it to a host: lib/r300 is a small virglrenderer for the chip. Vertex shaders run on the CPU (a TGSI interpreter), then clipping and the viewport; fragment shaders are compiled to R300 fragment programs (64 ALU, 32 TEX, 4 indirections, no branches: IF/ELSE become selects, loops must unroll). Textures are B8G8R8A8, non-power-of-two ones without mipmaps or repeat. ZGL_R300=0 falls back to software GL.

On a phone's Adreno

lib/adreno (libadreno, inside libvirgl) runs an Adreno 6xx through sic's /dev/adrenogpu: buffers, PM4 streams, fences and the 2D engine, which zwm composes the screen with. For 3D, ir3/ builds Mesa's own shader compiler for the chip, ir3, with NIR and Gallium's TGSI front end (TGSI is what lib/gl/glsl.c emits): libir3.a, and ir3c, which compiles a TGSI shader into A6xx instructions and prints their disassembly. The sources are a pinned Mesa release (fetched once, its SHA-256 checked); the files Mesa generates come from its Python generators (python3 with mako and pyyaml), except the assembler's flex/bison output in ir3/gen/. make ir3 builds and installs it (not part of make).

make ir3                                  # build/mesa-<ver>, libir3.a, ir3c -> the sysroot
make -C ir3 HOST=1                        # ir3c for this machine, to compare
ir3c shader.tgsi out.bin

Building

make            # build/<arch>/libvirgl.a libzgl.a virgltri zgltest
make install    # -> $SYSROOT/usr/{include,lib}, rootfs/bin

Needs the sysroot (sic's abi/gpu.h, libc, libzwm for the tools). Programs include <GL/gl.h> and link libzgl.a libvirgl.a; SDL programs get it through SDL_GL_* (see zde). zgltest prints what it rendered as ASCII and ok, so it works over a serial console.

The host side is virglrenderer inside QEMU. Homebrew's QEMU is built without it; on macOS build QEMU with --enable-virglrenderer --enable-opengl --enable-sdl against Homebrew's virglrenderer, mesa (for EGL) and a static libepoxy with EGL enabled. The SDL display needs a core-profile context (QEMU asks for a legacy one; patch ui/sdl2.c to request 4.1 core and ui/shader/* to #version 150). For a Retina screen the same file gets SDL_WINDOW_ALLOW_HIGHDPI, reports the drawable's pixels (not the window's points) in the resize event, and leaves the window alone once the guest runs at that size (ui/sdl2-gl.c blits to the drawable): the guest then runs at the panel's real resolution in a window of the same apparent size, shown 1:1 instead of scaled up by macOS. The same build with --target-list=x86_64-softmmu,aarch64-softmmu serves the aarch64 port: -device virtio-gpu-gl-pci -display sdl,gl=on on -M virt (zgl is the same code, little-endian either way).

License

Copyright (C) 2026 Rigby Foundation. The libraries (lib/, include/) are LGPL-2.1-or-later (LICENSE.LGPL) so any program can link them; the tools and the build are GPL-2.0-only (LICENSE). include/virgl_protocol.h, virgl_hw.h and p_defines.h are virglrenderer's (MIT).

About

OpenGL 2.1 for the sic OS

Topics

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages