Accessing Surface Memory Directly
You can directly access the surface memory by using the IDirect3DSurface9::LockRect method. When you call this method, the pRect parameter is a pointer to a RECT structure that describes the rectangle on the surface to access directly. To request that the entire surface be locked, set pRect to NULL. Also, you can specify a RECT that covers only a portion of the surface. Providing that no two rectangles overlap, two threads or processes can simultaneously lock multiple rectangles in a surface. Note that a multisample back buffer cannot be locked.
The IDirect3DSurface9::LockRect method fills a D3DLOCKED_RECT structure with all the information to properly access the surface memory. The structure includes information about the pitch and has a pointer to the locked bits. When you finish accessing the surface memory, call the IDirect3DSurface9::UnlockRect method to unlock it.
While you have a surface locked, you can directly manipulate the contents. The following list describes some tips for avoiding common problems with directly rendering surface memory.
- Never assume a constant display pitch. Always examine the pitch information returned by the IDirect3DSurface9::LockRect method. This pitch can vary for a number of reasons, including the location of the surface memory, the display card type, or even the version of the Direct3D driver. For more information, see Width vs. Pitch.
- Make certain you copy to unlocked surfaces. Direct3D copy methods will fail if called on a locked surface.
- Limit your application's activity while a surface is locked.
- Always copy data aligned to display memory. Windows 98 uses a page fault handler, Vflatd.386, to implement a virtual flat-frame buffer for display cards with bank-switched memory. The handler allows these display devices to present a linear frame buffer to Direct3D. Copying data unaligned to display memory can cause the system to suspend operations if the copy spans memory banks.
- A surface may not be locked if it belongs to a resource assigned to the D3DPOOL_DEFAULT memory pool unless it is a dynamic texture or a surface created using IDirect3DDevice9::CreateOffscreenPlainSurface. Back buffer surfaces, which may be accessed using the IDirect3DDevice9::GetBackBuffer and IDirect3DSwapChain9::GetBackBuffer methods, may be locked only if the swap chain was created with the Flags member of D3DPRESENT_PARAMETERS to include D3DPRESENTFLAG_LOCKABLE_BACKBUFFER.