Coding - Input Lag
Posted: Sat Sep 17, 2005 10:01 pm
Possible another very interesting article by Chaos/Farbrausch talking about input lags and DirectX problems... here we go...
One of the most annoying problems in DirectX is input lag. If your CPU is faster than the GPU, the driver queues all drawing commands and asks the application to send yet another frame. Some drivers are so hard optimised for perfect benchmark results that they buffer more than one frame. This has two problems: first the graphics may lag many frames behind the user input, making the programm unusable. Second, if your application has synchronised sound, the graphics will be behind the audio, and you can't compensate since you don't know how much.
Several solutions have been presented. The simplest is locking the backbuffer, but that kills concurrency. The fastest is using DX9 Queries, but that won't work everywhere. The most usable is locking two textures alternativly, which allows for concurrency but does not allow the driver to buffer more than one frame.
My variant of this is using two surfaces and ColorFill(). And that looks like this:
Initialisation code
Note that you should check every return code, especially for Present().
One of the most annoying problems in DirectX is input lag. If your CPU is faster than the GPU, the driver queues all drawing commands and asks the application to send yet another frame. Some drivers are so hard optimised for perfect benchmark results that they buffer more than one frame. This has two problems: first the graphics may lag many frames behind the user input, making the programm unusable. Second, if your application has synchronised sound, the graphics will be behind the audio, and you can't compensate since you don't know how much.
Several solutions have been presented. The simplest is locking the backbuffer, but that kills concurrency. The fastest is using DX9 Queries, but that won't work everywhere. The most usable is locking two textures alternativly, which allows for concurrency but does not allow the driver to buffer more than one frame.
My variant of this is using two surfaces and ColorFill(). And that looks like this:
Initialisation code
Code: Select all
/****************************************************************************/
static IDirect3DSurface9 *DXBlockSurface[2];
static IDirect3DDevice9 *DXDev;
/****************************************************************************/
void init()
{
DXDev->CreateOffscreenPlainSurface(16,16,D3DFMT_A8R8G8B8,
D3DPOOL_DEFAULT,&DXBlockSurface[0],0);
DXDev->CreateOffscreenPlainSurface(16,16,D3DFMT_A8R8G8B8,
D3DPOOL_DEFAULT,&DXBlockSurface[1],0);
}
/****************************************************************************/
And your flip() might look like this:
/****************************************************************************/
void flip()
{
static sInt dblock;
D3DLOCKED_RECT lr;
volatile sInt dummy;
DXDev->ColorFill(DXBlockSurface[dblock],0,0xff002050);
dblock = 1-dblock;
if(!FAILED((DXBlockSurface[dblock]->LockRect(&lr,0,D3DLOCK_READONLY))))
{
dummy = *(sInt *)lr.pBits;
DXBlockSurface[dblock]->UnlockRect();
}
DXDev->Present(0,0,0,0);
}
/****************************************************************************/