Width vs. Pitch

A version of this page is also available for

Windows Embedded CE 6.0 R3


Although the terms width and pitch are discussed casually, they have very important (and distinctly different) meanings. As a result, you should understand the meanings for each, and how to interpret the values that DirectDraw uses to describe them.

DirectDraw uses the DDSURFACEDESC structure to carry information describing a surface. Among other things, this structure is defined to contain information about a surface's dimensions, as well as how those dimensions are represented in memory.

The structure uses the dwHeight and dwWidth members to describe the logical dimensions of the surface. Both of these members are measured in pixels. Therefore, the dwHeight and dwWidth values for a 640×480 surface are the same whether it is an 8-bit palettized surface or a 24-bit RGB surface.

The DDSURFACEDESC structure contains information about how a surface is represented in memory through the lPitch and lXPitch members. The value in the lPitch member describes the surface's memory pitch (also called stride) in the vertical direction, while the lXPitch member describes the surface's memory pitch in the horizontal direction.

Pitch is the distance, in bytes, between two memory addresses that represent the beginning of one bitmap line and the beginning of the next bitmap line. Because pitch is measured in bytes rather than pixels, a 640×480×8 surface will have a very different pitch value than a surface with the same dimensions but a different pixel format.

Additionally, the pitch value sometimes reflects bytes that DirectDraw has reserved as a cache, so it is not safe to assume that pitch is simply the width multiplied by the number of bytes per pixel.

Rather, you could visualize the difference between width and pitch as shown in the following illustration.


In this figure, the front buffer and back buffer are both 640×480×8, and the cache is 384×480×8.

Pitch values are useful when you are directly accessing surface memory. For example, after calling the IDirectDrawSurface::Lock method, the lpSurface member of the associated DDSURFACEDESC structure contains the address of the top-left pixel of the locked area of the surface, and the lPitch member is the surface pitch.

You access pixels horizontally by adding the lXPitch value to, or subtracting it from, the current surface pointer, and you move up or down by adding the lPitch value to, or subtracting it from, the current surface pointer.

When accessing surfaces directly, take care to stay within the memory allocated for the dimensions of the surface and stay out of any memory reserved for cache.

Additionally, when you lock only a portion of a surface, you must stay within the rectangle you specify when locking the surface. Failing to follow these guidelines will have unpredictable results.

When rendering directly into surface memory, always use the pitch returned by the Lock method (or the IDirectDrawSurface::GetDC method).

Do not assume a pitch based solely on the display mode. If your application works on some display adapters but looks garbled on others, this may be the cause of your problem.

The lXPitch member has been added to support rotated surfaces. With a 640x480x16 surface, typical values for lPitch and lXPitch are 1280 bytes and 2 bytes, respectively. If this surface is rotated by 90 degrees counterclockwise, lPitch and lXPitch will become -2 bytes and 1280 bytes, respectively (note that the lPitch and lXPitch can be negative).

For more information, see Accessing Surface Memory Directly.