Skip to content

Instantly share code, notes, and snippets.

Last active November 14, 2023 13:34
Show Gist options
  • Star 59 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save Keenuts/199184f9a6d7a68d9a62cf0011147c0b to your computer and use it in GitHub Desktop.
Save Keenuts/199184f9a6d7a68d9a62cf0011147c0b to your computer and use it in GitHub Desktop.
GSoC 2017 | Virgl Windows Driver

GSOC 2017 | Virgl Windows Driver

Project links

The project is split into several parts:

  • The kernel driver, with simple 3D command forwarding and 3D resource allocation
  • The userland driver, in fact the OpenGL backend
  • The reference, explaining virtio-gpu commands
(another repo:

For the one interested, here is en entry about this project:

OpenGL ICD: Quick overview

OpenGL ICD (Installable Client Driver) is a fancy name for an OpenGL implementation. This one is pretty simple, and is only here as a POC.

OpenGL* : OpenGL entry points, GlBegin, GLEnd, etc...
State* : This is the state-tracker. We only deal with high level structures
Virgl* : VirtIO related parts. This part focus on the actual commands we want to send to the driver
DriverAPI* : This is the part focused on driver communication. How can we communicate with the kernel, or test-suite if in debug.

Simple example:

On a context creation, I call wglCreateContext. Go straight to the wrapper(opengl.cpp). Then state-tracker. Check if context exists, what do I need to create it, and send VIRGL_CREATE_CONTEXT commands. Also need to create and attach some resources. Once commands are ready, time to send something to the kernel. For this, we need to use D3DKMT_Escape function.

In the kernel, we check the command, and can submit it through the Virtio queues, and hope for the best.

What's done

Kernel driver

For now, we can submit 3D command buffers on the host. To comminicate with the kernel, we must use the Escape function. Commands are composed of a head, and a payload.

Head (UINT32) Payload




This command is used when the ICD wants to send a command to the host. No checks are done, and the command is directly sent to the host through the CtrlQueue

struct {
  UINT32[] cmd; //the command


These commands are used to create buffers on system's memory. Using these buffer, you can use the backing attachment command. The only way to update buffer content is to send a UM allocated buffer and use OPENGL_ICD_UPDATE command.

struct {
  UINT32 size; //size of the buffer to create
  UINT64 handle; //OUT parameter: the handle
struct {
  UINT64 handle; //the handle previously grabbed from OPENGL_ICD_CMD_ALLOCATE
  UINT32 size; //size of the data
  VOID *data; //UM data pointer
struct {
  UINT64 handle; //the handle previously grabbed from OPENGL_ICD_CMD_ALLOCATE


Driver interface and VirtIO commands

This ICD support the most important VirGL and virtio-gpu commands.

  • Virtio-gpu commands
    • createContext
    • deleteContext
    • createResource2D
    • createResource3D
    • attachResource
    • detachResource
    • unrefResource
  • VirGL commands
    • createSubContext
    • setCurrentSubContext
    • deleteSubContext
    • Clear
    • setViewportState
    • createObject
    • bindObject
    • bindShader
    • setViewportState
    • setScissorState
    • setPolygonStipple
    • setFramebufferState
    • setConstantBuffer
    • inlineWrite
    • drawVBO


This very basic state-tracker let you create a context, setup basic OpenGL features (viewport, scissor, stipple..). You can then create a VBO, and hopefuly, display some vertices.

What needs to be done

  • Extend the commands supported by the ICD
  • Add a proper state-tracker on top of this API
  • Add security / thread-safety !
  • Be able to get feedback from VirGL commands
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment