Windows 98 3D Graphics Rendering Pipeline Explained

This article explores how Microsoft Windows 98 processed 3D graphics rendering pipeline calls, detailing the transition of commands from the software application layer to the physical graphics hardware. It covers the roles of the Direct3D and OpenGL APIs, the division between CPU-bound software emulation and hardware acceleration, and the architecture of the Windows 9x driver model that facilitated high-performance gaming and multimedia execution.

The Application and API Layer

When a 3D application or game ran on Windows 98, it initiated the rendering pipeline by calling a 3D Application Programming Interface (API), predominantly Microsoft Direct3D (part of DirectX 6.0 through 7.0a during the Windows 98 lifecycle) or Silicon Graphics' OpenGL.

The application defined the 3D scene using geometric primitives, typically triangles. It submitted vertex data—consisting of spatial coordinates (\(X, Y, Z\)), color values, surface normals, and texture coordinates (\(U, V\))—along with render state changes, such as enabling bilinear filtering, alpha blending, or specular highlights.

The Role of DirectX: HAL vs. HEL

Under Direct3D, rendering calls entered the runtime layer, which determined how the commands should be executed:

  1. Hardware Abstraction Layer (HAL): If the installed graphics card natively supported a requested feature, the runtime routed the call through the Direct3D HAL. The HAL acted as a thin, low-overhead interface directly exposing the hardware's accelerated capabilities.
  2. Hardware Emulation Layer (HEL): If the graphics card lacked hardware support for a feature (such as specular highlights or specific texture formats), the HEL stepped in. The HEL performed the calculations entirely on the host CPU using optimized software routines, trading frame rate for visual compatibility.

Transform and Lighting (T&L)

During the early Windows 98 era, the "Transform and Lighting" stage of the pipeline was predominantly executed on the host CPU.

  • Geometry Transformation: The CPU converted 3D object coordinates into world coordinates, camera space, and finally 2D screen coordinates using matrix mathematics.
  • Clipping: Vertices located outside the camera's viewing frustum were clipped to avoid unnecessary processing.
  • Lighting Calculations: Vertex colors were modified based on defined light sources within the scene.

With the release of DirectX 7 in 1999 and the advent of GPUs like the NVIDIA GeForce 256, hardware-accelerated T&L was introduced, offloading these compute-heavy vector operations from the CPU to the graphics processing unit via the Direct3D 7 pipeline.

Command Translation and Driver Execution

Once primitives were transformed and lit, the application called batch rendering functions such as DrawPrimitive. Direct3D converted these high-level requests into standardized command tokens.

These tokens passed into the graphics display driver. In Windows 98, display drivers typically operated as a 16-bit/32-bit hybrid:

  • User-Mode Display Driver: Processed API tokens and compiled them into vendor-specific machine instructions.
  • Mini-Driver / Virtual Device Driver (VxD): Windows 98 relied heavily on monolithic VxDs running in Ring 0 (kernel space), alongside the newer Windows Driver Model (WDM). Because Windows 98 had relaxed memory protection compared to Windows NT, 3D drivers could write directly to physical memory and hardware registers with minimal operating system overhead.

Data Transfer via AGP and PCI

Commands and assets were dispatched across the system bus:

  • Command Buffers: The driver populated command rings in system RAM or dedicated video memory (VRAM).
  • Textures and Vertices: Using the Accelerated Graphics Port (AGP 1x/2x, and later 4x), Windows 98 utilized Direct Memory Access (DMA) and AGP Texturing (DirectX DIME—Direct Memory Execute). This allowed the graphics chip to read texture data directly from system RAM without first copying it over the slower system bus into local VRAM.

Rasterization and Frame Buffer Output

The graphics hardware fetched the compiled instructions and executed the final stages of the pipeline:

  1. Triangle Setup: Calculating edge equations for the rasterizer.
  2. Rasterization: Converting vectors into individual fragments (potential pixels).
  3. Texture Mapping and Filtering: Sampling textures and applying bilinear or trilinear interpolation.
  4. Depth (Z) Buffering: Discarding occluded pixels to maintain proper scene depth.
  5. Pixel Blending: Combining colors, fog effects, and alpha transparency before writing the final pixel values to the back buffer in VRAM.

Once the frame was fully drawn, the application issued a flip or swap call via DirectDraw (the 2D surface manager underpinning Direct3D). The graphics card exchanged the front and back buffer pointers, presenting the finished 3D scene to the CRT or LCD monitor during the vertical blanking interval.