Several different classes of drivers can be identified:
Each class of driver builds on the functionality of the preceeding one. For example, a hardware rasterization driver may need to fall back to software rasterization when a particular OpenGL state combination is set but not supported by the hardware (perhaps smooth, stippled, textured triangles).
Likewise, a hardware transformation driver might need to fall back to software-based transformation when a particular, seldom-used lighting mode is enabled.
The best way to get started writing a new driver is to find an existing driver similar to what you plan to implement, and then study it.
It's not feasible for this document to explain every detail of writing a driver. The minute details can be gleaned by looking at existing drivers. This document focuses on the high-level concepts and will perhaps expand on the details in the future.
For examples of 100% software drivers, the OSMesa and XMesa (fake/stand-alone GLX) drivers are the best examples.
For examples of hardware drivers, the DRI Radeon and R200 drivers are good examples.
There are two aspects to a Mesa device driver:
The remainder of this document will focus on the later part. Furthermore, we'll use the GLX interface for examples.
In the case of the DRI drivers, the public GLX interface is contained in the libGL.so library. libGL.so, in turn, dynamically loads one of the DRI drivers (such as radeon_dri.so). Both libGL.so and the driver modules talk to the X window system via the DRI extension. Furthermore, the driver modules interface to the graphics hardware with the help of a kernel module and the conventional 2D X server driver.
A software driver is primarily concerned with writing pixel values to the system's color buffer (and reading them back). The color buffers might be window canvases (typically the front color buffer) and/or off-screen image buffers (typically the back color buffer). The depth, stencil and accumulation buffers will be implemented within core Mesa.
The software driver must also be concerned with allocation and deallocation of rendering contexts, frame buffers and pixel formats (visuals).
The glue interface will always have a function for creating new rendering contexts (such as glXCreateContext). The device driver must have a function which allocates and initializes a device-specific rendering context.
The frame buffer can either be a screen region defined by a window or the entire screen.
In either case, the device driver must implement functions for allocating, initializing and managing frame buffers.
The fundamental rendering operation is to write (and read) spans of pixels to the front / back color buffers. A span is a horizontal array of pixel colors with an array of mask flags. The span begins at a particular (x,y) screen coordinate, extends for N pixels, describes N RGBA colors (or color indexes) and has an array of N boolean flags indicating which pixels to write and skip.
Additionally, a software driver will typically have functions for binding rendering contexts to frame buffers (via glXMakeCurrent), swapping color buffers (via glXSwapBuffers), synchronization (via glFlush/glFinish) and queries (via glGetString).
A software driver might implement optimized routines for drawing lines and triangles for common cases (such as smooth shading with depth-testing). Then, the span functions can be bypassed for a little extra speed. The OSMesa and XMesa drivers have examples of this.
To do...
Even though Mesa and most device drivers are written in C, object oriented programming principles are used in several places.
Every Mesa device driver will need to define a device-specific rendering context structure.