c# – 快速多窗口渲染

我已经搜索和测试C#天的不同类型的渲染库了好几个星期了.到目前为止,我还没有找到一个在多窗口渲染设置下工作得很好的图书馆.要求是能够在12个监视器设置(财务图表)上运行该程序,而不需要在快速计算机上进行延迟.每个窗口每秒需要更新多次.在执行此操作时,CPU需要执行大量密集和时间关键的任务,因此某些负担必须转移到GPU.那就是硬件渲染步骤,换句话说就是DirectX或OpenGL.

我已经尝试过GDI与Windows窗体,并认为它的方式太慢我的需要.我已经通过OpenTK(在Windows窗体控件上)尝试了OpenGL,这似乎非常快速(我仍然有一些测试可以运行),但是很难很好地工作(很难找到/编译好的文本渲染库).最近我通过SharpDX尝试使用Windows窗体DirectX9,DirectX10和Direct2D.我为每个窗口尝试了一个单独的设备,单个设备/多个交换链接近.所有这些都导致在多个窗口上的性能非常差.例如,如果我将目标FPS设置为20,并在不同的显示器上打开4个全屏窗口,则整个操作系统开始滞后非常严重.渲染只是将屏幕清除为黑色,不会渲染图元.这个测试的CPU使用率约为0%,GPU使用率约为10%,我不明白这里的瓶颈是什么?我的开发电脑是非常快的,i7 2700k,AMD HD7900,16GB RAM,所以测试应该肯定运行在这一个.

相比之下,我在C / Win32 API一个设备/多个交换链上进行了一些DirectX9测试,我可以在四个监视器工作空间(3D茶壶上旋转)上打开100个窗口,并且仍然具有完美负责的操作系统(fps为当然在渲染窗口下降到五点左右,这是我预计运行100个同时渲染的).

有没有人知道在C#上进行多窗口渲染的任何好方法,或者我被迫在C中重写我的程序以获得该性能(主要的痛苦)?我想在我去C路线之前给OpenGL另一个镜头.我会在这里报告任何发现.

测试方法参考:

对于C#DirectX单设备多次交换测试,我使用这个很好的答案的方法:
Display Different images per monitor directX 10

Direct3D10版本:

我创建了这样的d3d10device和DXGIFactory:

D3DDev = new SharpDX.Direct3D10.Device(SharpDX.Direct3D10.DriverType.Hardware,
            SharpDX.Direct3D10.DeviceCreationFlags.None);
DXGIFac = new SharpDX.DXGI.Factory();

然后这样初始化渲染窗口:

var scd = new SwapChainDescription();
scd.BufferCount = 1;
scd.ModeDescription = new ModeDescription(control.Width, control.Height,
      new Rational(60, 1), Format.R8G8B8A8_UNorm);
scd.IsWindowed = true;
scd.OutputHandle = control.Handle;
scd.SampleDescription = new SampleDescription(1, 0);
scd.SwapEffect = SwapEffect.Discard;
scd.Usage = Usage.RenderTargetOutput;

SC = new SwapChain(Parent.DXGIFac, Parent.D3DDev, scd);

var backBuffer = Texture2D.FromSwapChain<Texture2D>(SC, 0);
_rt = new RenderTargetView(Parent.D3DDev, backBuffer);

每个渲染迭代执行的绘图命令简单:

Parent.D3DDev.ClearRenderTargetView(_rt, new Color4(0, 0, 0, 0));
SC.Present(0, SharpDX.DXGI.PresentFlags.None);

DirectX9版本非常相似:

设备初始化:

PresentParameters par = new PresentParameters();
par.PresentationInterval = PresentInterval.Immediate;
par.Windowed = true;
par.SwapEffect = SharpDX.Direct3D9.SwapEffect.Discard;
par.PresentationInterval = PresentInterval.Immediate;
par.AutoDepthStencilFormat = SharpDX.Direct3D9.Format.D16;
par.EnableAutoDepthStencil = true;
par.BackBufferFormat = SharpDX.Direct3D9.Format.X8R8G8B8;

// firsthandle is the handle of first rendering window
D3DDev = new SharpDX.Direct3D9.Device(new Direct3D(), 0, DeviceType.Hardware, firsthandle,
    CreateFlags.SoftwareVertexProcessing, par);

渲染窗口初始化:

if (parent.D3DDev.SwapChainCount == 0)
{
    SC = parent.D3DDev.GetSwapChain(0);
}
else
{
    PresentParameters pp = new PresentParameters();
    pp.Windowed = true;
    pp.SwapEffect = SharpDX.Direct3D9.SwapEffect.Discard;
    pp.BackBufferFormat = SharpDX.Direct3D9.Format.X8R8G8B8;
    pp.EnableAutoDepthStencil = true;
    pp.AutoDepthStencilFormat = SharpDX.Direct3D9.Format.D16;
    pp.PresentationInterval = PresentInterval.Immediate;

    SC = new SharpDX.Direct3D9.SwapChain(parent.D3DDev, pp);
}

绘图循环代码

SharpDX.Direct3D9.Surface bb = SC.GetBackBuffer(0);
Parent.D3DDev.SetRenderTarget(0, bb);

Parent.D3DDev.Clear(ClearFlags.Target, Color.Black, 1f, 0);
SC.Present(Present.None, new SharpDX.Rectangle(), new SharpDX.Rectangle(), HWND);
bb.Dispose();

C DirectX9 / Win32 API测试与多个交换和一个设备代码在这里:

[C++] DirectX9 Multi-window test – Pastebin.com

这是Kevin Harris的很好的示例代码的修改版本.

编辑:

为了说清楚,在进行多窗口渲染时,我的主要问题不是低帧,这是所有操作系统功能的一般延迟(窗口动画,拖放和滚动等)​​.

说到DirectX只是在这里,但我记得我们有同样的问题一次(5个显卡和一个单一的PC 9屏幕).

很多时候全屏开关似乎想要在显示器上启用垂直同步,并且由于Present无法进行线程化,所以垂直同步的屏幕越多,您将拥有更高的下降(因为您将等待0到16毫秒)现在电话.

我们遇到的解决方案是将窗口创建为最大化并移除边框,但并不理想,而是从10 fps将矩形重新绘制到标准速度(60).

如果你想要代码示例让我知道我会准备一个.

也只是为了测试我有一个去创建30个窗口在我的引擎使用c#/ slimdx / dx11,渲染一个球体与基本的阴影,仍然超过40 fps.

翻译自:https://stackoverflow.com/questions/13213648/fast-multi-window-rendering

转载注明原文:c# – 快速多窗口渲染