为什么不使用GDI用来自数组的RGB数据重复填充窗口? [英] Why not use GDI to repeatedly fill a window with RGB data from an array?

查看:151
本文介绍了为什么不使用GDI用来自数组的RGB数据重复填充窗口?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是对

This is a follow-up to this question. I'm currently writing a simple game and am looking for the fastest way to (repeatedly) display an array of RGB data in a Win32 window, without flickering or other artifacts.

在上一个问题的答案中建议了几种不同的方法,但是尚未就哪种方法最快达成共识.因此,我整理了一个测试程序.该代码只是尽可能快地在屏幕上重复显示帧缓冲区.

Several different approaches were recommended in the answers to the previous question, but there was no consensus on which would be the fastest. So, I threw together a test program. The code simply displays a framebuffer on the screen repeatedly, as fast as possible.

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

These are the results I obtained, for 32-bit data running in a 32-bit video mode - they may surprise some people:

- Direct3D (1):             500 fps
- Direct3D (2):             650 fps
- DirectDraw (3):          1100 fps
- DirectDraw (4):           800 fps
- GDI (SetDIBitsToDevice): 2000 fps

给出以下数字:

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

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

Here is a brief summary of the calls made by each of the Direct* codepaths. If anyone knows a more efficient way to use DirectDraw/Direct3D, please comment.

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();

推荐答案

在这里有几件事要牢记.首先,很多常识"是基于不再实际适用的一些事实.

There are a couple of things to keep in mind here. First of all, a lot of "common knowledge" is based on some facts that no longer really apply.

在AGP时代,当CPU直接与GPU通讯时,它始终使用基本的PCI协议,该协议以"1x"的速率发生(总是且不可避免).当GPU直接进入内存控制器时,仅适用于AGX 2x/4x/8x .换句话说,根据您看的时间,让GPU从内存中加载纹理的速度是CPU将相同数据直接发送到GPU的速度的八倍.当然,CPU还比支持的PCI总线具有更多的内存带宽.

In the days of AGP, when the CPU talked directly to the GPU, it always used the base PCI protocol, which happened at the "1x" rate (always and inevitably). AGX 2x/4x/8x only applied when the GPU was taking to the memory controller directly. In other words, depending on when you looked, it was up to 8 times as fast to have the GPU load a texture from memory as it was for the CPU to send the same data directly to the GPU. Of course, the CPU also had a great deal more bandwidth to memory than the PCI bus supported.

但是,当事情切换到PCI-E时,情况就完全改变了.尽管带宽因路径而异,但没有一般性的规则可以确定内存-> GPU的速度将快于CPU-> GPU.最安全的一种概括是如果如果您有专用的图形卡,那么图形卡上的内存几乎总是比主板上的主内存具有更多的带宽.

When things switched to PCI-E, however, that changed completely. While there can be differences in bandwidth depending on path, there's no general rule that memory->GPU will be faster than CPU->GPU. The one generalization that's (mostly) safe is that if you have a dedicated graphics card, then the GPU will almost always have more bandwidth to the memory on the graphics card than it does to main memory on the motherboard.

在您的情况下,这无关紧要-您正在谈论的是将数据从CPU空间转移到GPU空间.使用DirectX(或OpenGL)的主要速度差异发生在将所有(或大部分)计算 保留在GPU上并且完全避免使用CPU(或主内存)的情况下.他们没有(现在AGP已经成为历史)在内存->显示带宽方面没有任何实质性的改善.

In your case, that doesn't matter much though -- you're talking about moving data from CPU space to GPU space regardless. The main speed difference with using DirectX (or OpenGL) happens when you keep all (or most) of the computation on the GPU, and avoid using the CPU (or main memory) at all. They don't (now that AGP is history) provide any substantial improvement in memory->display bandwidth.

这篇关于为什么不使用GDI用来自数组的RGB数据重复填充窗口?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆