修复Windows 7上的DirectX 7延迟?

时间:2013-05-21 10:48:12

标签: windows-7 nvidia latency directx

我们有一个针对DirextX 7 SDK编程的软件(即代码使用LPDIRECTDRAWSURFACE7等)并全屏运行。主要任务是以可靠的方式在屏幕上放置一些内容以响应外部触发器。这在Windows XP上表现得非常好:通常软件会等待一些触发器,当触发时,会创建一个新帧,将其放入后备缓冲区,然后告诉DX翻转缓冲区。结果是触发器和屏幕上有效显示帧之间的近似延迟,取决于视频卡和驱动程序,对于60Hz屏幕,3帧或50毫秒。这是在各种系统上测试的,都运行NVidia卡。在某些具有较高端卡的系统上,我们甚至可以获得2帧。

在Windows 7上运行相同的软件时(根本没有安装其他软件)但是,我们不能低于5帧。在管道中的某个地方,操作系统或驱动程序或两者都需要2个额外的帧,这几乎是应用程序无法接受的。我们尝试禁用航空/桌面组合/不同的驱动程序版本/不同的视频卡,但无济于事。

  • 这是从哪里来的?这是在某处记录的吗?
  • 有一种简单的方法可以修复吗?我知道DirectX 7已经过时了,但升级到再次编译更新的版本可能需要大量的工作,所以另一种类型的修复会很好。也许某些可以在代码中设置的标志?

编辑这里有一些似乎相关的代码:

创建前/后表面:

ddraw7->SetCooperativeLevel( GetSafeHwnd(),
  DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN | DDSCL_ALLOWMODEX | DDSCL_MULTITHREADED )

DDSURFACEDESC2 desc;
ZeroMemory( &desc, sizeof(desc) );
desc.dwSize = sizeof( desc );
desc.dwFlags =  DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP |
                      DDSCAPS_COMPLEX | DDSCAPS_3DDEVICE |
                      DDSCAPS_VIDEOMEMORY | DDSCAPS_LOCALVIDMEM;
desc.dwBackBufferCount = 1;
ddraw7->CreateSurface( &desc, &primsurf, 0 )

DDSCAPS2 surfcaps;
ZeroMemory( &surfcaps,sizeof( surfcaps ) );
surfcaps.dwCaps = DDSCAPS_BACKBUFFER;
primsurf->GetAttachedSurface( &surfcaps, &backsurf );

创建用于在绘制帧之前渲染帧的表面:

DDSURFACEDESC2 desc;
ZeroMemory( &desc, sizeof(desc) );
desc.dwSize = sizeof(desc);
desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS ;
desc.dwWidth = w;
desc.dwHeight = h;
desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY;
desc.ddpfPixelFormat.dwSize = sizeof( DDPIXELFORMAT );
desc.ddpfPixelFormat.dwFlags = DDPF_PALETTEINDEXED8;

LPDIRECTDRAWSURFACE7 surf;
HRESULT r=ddraw7->CreateSurface( &desc, &surf, 0 )

渲染循环,在OnIdle

//clear surface
DDBLTFX bltfx;
ZeroMemory( &bltfx, sizeof(bltfx) );
bltfx.dwSize = sizeof( bltfx );
bltfx.dwFillColor = RGBtoPixel( r, g, b );
backsurf->Blt( rect, 0, 0, DDBLT_COLORFILL | DDBLT_WAIT, &bltfx )

//blit some prerendered surface onto it, x/y/rect etc are calculated properly)
backsurf->BltFast( x, y, sourceSurf, s&sourceRect, DDBLTFAST_WAIT );

primsurf->Flip( 0, DDFLIP_WAIT )

primsurf->Blt(&drect,backsurf,&srect,DDBLT_WAIT,0);

1 个答案:

答案 0 :(得分:3)

我认为Windows XP的东西是红色的鲱鱼。直接运行DirectX 7的Windows的最新版本是Windows 2000.Windows XP只是在DX9中模拟DX7,与Windows 7一样。

我猜测你的应用程序使用了调色板纹理,当DX模拟该功能时(因为它在DX7之后被删除),它会使用索引颜色生成纹理。您可以尝试使用GPUView对应用进行概要分析,看看将纹理推送到GPU是否存在延迟。例如,也许Win7驱动程序首先压缩它?