为什么不使用GDI重复填充数组中RGB数据的窗口?

use*_*783 16 directx winapi gdi directdraw

这是这个问题的后续行动.我正在编写一个简单的游戏,我正在寻找在Win32窗口中(反复)显示RGB数据数组的最快方法,没有闪烁或其他工件.

在上一个问题的答案中建议采用几种不同的方法,但没有达成共识,哪种方法最快.所以,我把测试程序汇总在一起.代码只是在屏幕上反复显示帧缓冲,尽可能快.

这些是我获得的结果,对于在32位视频模式下运行的32位数据 - 他们可能会让一些人感到惊讶:

- Direct3D (1):             500 fps
- Direct3D (2):             650 fps
- DirectDraw (3):          1100 fps
- DirectDraw (4):           800 fps
- GDI (SetDIBitsToDevice): 2000 fps
Run Code Online (Sandbox Code Playgroud)

鉴于这些数字:

  • 为什么许多人坚持认为GDI对于此操作来说太慢了?
  • 有没有理由比SetDIBitsToDevice更喜欢DirectDraw或Direct3D?

以下是每个Direct*代码路径调用的简短摘要.如果有人知道使用DirectDraw/Direct3D的更有效方法,请发表评论.

1. CreateTexture(D3DUSAGE_DYNAMIC, D3DPOOL_DEFAULT);
       LockRect(); memcpy(); UnlockRect(); DrawPrimitive()

2. CreateTexture(0, D3DPOOL_SYSTEMMEM); CreateTexture(0, D3DPOOL_DEFAULT);
       LockRect(); memcpy(); UnlockRect(); UpdateTexture(); DrawPrimitive()

3. CreateSurface(); SetSurfaceDesc(lpSurface = &frameBuffer[0]);
       memcpy(); primarySurface->Blt();

4. CreateSurface();
       Lock(); memcpy(); Unlock(); primarySurface->Blt();
Run Code Online (Sandbox Code Playgroud)

Jer*_*fin 7

这里有几点要记住.首先,许多"常识"是基于一些不再适用的事实.

在AGP时代,当CPU直接与GPU通信时,它总是使用基本PCI协议,它以"1x"速率发生(总是并且不可避免地).AGX 2x/4x/8x 在GPU 直接进入内存控制器时应用.换句话说,取决于你看,这是高达8倍的速度有GPU从内存中加载的纹理,因为它是为CPU相同的数据直接发送到GPU.当然,CPU也比支持的PCI总线具有更多的内存带宽.

然而,当事情切换到PCI-E时,完全改变了.虽然根据路径可能存在带宽差异,但没有一般规则内存 - > GPU将比CPU-> GPU更快.(大多数情况下)安全的一个概括是,如果你有一个专用的显卡,那么GPU对显卡内存的带宽几乎总是比主板上的主内存带宽.

在你的情况下,这并不重要 - 你所谈论的是无论如何将数据从CPU空间移动到GPU空间.使用DirectX(或OpenGL)时的主要速度差异发生在GPU上保留所有(或大部分)计算时,并且完全避免使用CPU(或主存储器).他们没有(现在AGP是历史)在内存 - >显示带宽方面提供了任何实质性的改进.