Skip to content

Instantly share code, notes, and snippets.

@Keenuts
Last active July 17, 2024 08:19
Show Gist options
  • 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

https://github.com/Keenuts/virtio-gpu-win-icd
https://github.com/Keenuts/virtio-gpu-documentation
https://gitlab.com/spice/virtio-gpu-wddm/virtio-gpu-wddm-dod
(another repo: https://github.com/Keenuts/virtio-gpu-win/)

For the one interested, here is en entry about this project:
http://studiopixl.com/blog/index.php/posts/3d-acceleration-using-virtio

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

HEAD

4 Values are supported OPENGL_ICD_CMD_ALLOCATE (2), OPENGL_ICD_UPDATE (3), OPENGL_ICD_FREE (4), OPENGL_ICD_TRANSFER (1)

OPENGL_ICD_TRANSFER

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

  • OPENGL_ICD_TRANSFER
struct {
  UINT32 head; //OPENGL_ICD_TRANSFER
  UINT32[] cmd; //the command
}

OPENGL_ICD_CMD_ALLOCATE, OPENGL_ICD_UPDATE, OPENGL_ICD_FREE

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.

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

OpenGL ICD

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

State-tracker

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