Windows 7 修复Windows 7上的DirectX 7延迟?

Windows 7 修复Windows 7上的DirectX 7延迟?,windows-7,nvidia,latency,directx,Windows 7,Nvidia,Latency,Directx,我们有一个针对DirExtx7SDK编程的软件(即代码使用LPDIRECTDRAWSURFACE7等),并在全屏上运行。主要任务是以可靠的方式在屏幕上显示一些东西,以响应外部触发器。这在Windows XP上表现得非常好:基本上,软件会等待某个触发器,当触发时,会创建一个新帧,将其放入backbuffer,然后告诉DX翻转缓冲区。结果是触发和帧在屏幕上有效显示之间的近似延迟,取决于视频卡和驱动程序,对于60Hz屏幕,为3帧或50毫秒。这是在各种系统上测试的,所有系统都运行NVidia卡。在一些具

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

但是,当在Windows7上运行相同的软件时(没有安装任何其他软件),我们不能获得低于5帧的帧数。这意味着在管道中的某个地方,操作系统或驱动程序或两者都会吃掉2个额外的帧,这对于应用程序来说几乎是不可接受的。我们尝试禁用aero/桌面合成/不同的驱动程序版本/不同的视频卡,但没有成功

  • 这是从哪里来的?这有文件记录吗
  • 有没有一个简单的方法来修复?我知道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);

我认为windowsxp是一个骗人的东西。上一个直接运行DirectX 7的Windows版本是Windows 2000。Windows XP只是在DX9中模拟DX7,与Windows 7的做法相同


我大胆猜测,您的应用程序使用了调色板纹理,当DX模拟该功能时(在DX7之后删除),它将使用索引颜色生成纹理。您可以尝试使用评测应用程序,以查看将纹理推送到GPU时是否有延迟。例如,可能是Win7驱动程序先对其进行压缩?

是否愿意解释为什么这被否决?例如,如果它不属于这里,至少说明原因。在stackoverflow上询问它,因为这是一个编码问题。是的,我不确定,这可能只是一些配置问题-无论如何,投票决定关闭移动到SOIt可能是一个驱动程序问题-较新的图形卡/驱动程序使用DX9/10模拟DX7,这可能导致延迟。@请参阅编辑。。我花了将近一个小时的时间才提取出来,这本身就是一个坚实的迹象,表明我们可能更好地从scrathwe中重写东西,因为我们没有使用苍白的纹理,或任何其他特殊的DX功能:所有内容都被逐像素直接写入表面内存。但是谢谢你提到GPUView,我不知道,但它看起来非常有趣。@stijn你有运行任何着色器吗?没有;没有代码atm,但假设渲染循环只是在曲面中设置一些像素,将曲面拼接到backbuffer曲面上并调用Flip()