# Writing Mesa Device Drivers

## Introduction

Several different classes of drivers can be identified:

- 100% Software Driver - a software driver that does not utilize accelerated graphics hardware. Such a driver will basically just write (and read) pixel values to the computer's frame buffer or a malloc'd color buffer. Examples include the X11/XMesa driver, the Windows driver and OSMesa.
- Hardware Rasterization Driver - for graphics hardware that implements accelerated point/line/triangle rasterization, but relies on core Mesa for vertex transformation. Examples include the DRI 3Dfx, Matrox, and Rage 128 drivers.
- Hardware Transformation and Rasterization Driver - for graphics hardware that implements accelerated rasterization and vertex transformation. Examples include the DRI Radeon and R200 drivers.

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.

## Getting Started

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.

## Programming API vs. Drivers

There are two aspects to a Mesa device driver:

- Public programming API - this is the interface which application programmers use. Examples are the GLX, WGL and OSMesa interfaces. If you're developing a device driver for a new operating system or window system you'll have to design and implement an OpenGL glue interface similar to these. This interface will, in turn, communicate with the internal driver code.
- Private/internal driver code - this is the code which (effectively) translates OpenGL API calls into rendering operations. The device driver must manage hardware resources, track OpenGL state and implement or dispatch the fundamental rendering operations such as point, line, triangle and image rendering.

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.

## Software Driver Overview

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).

### Rendering Contexts

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.

### Frame Buffers

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.

### Spans

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.

### Miscellaneous functions

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).

### Optimizations

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.

## Hardware Driver Overview

To do...

## OOP-Style Inheritance and Specialization

Even though Mesa and most device drivers are written in C, object oriented programming principles are used in several places.

### Rendering Contexts

Every Mesa device driver will need to define a device-specific rendering context structure.

## State Tracking