关于BeginScene和EndScene函数
发布:siney | 发布时间: 2009-02-06昨天闲来没事,特地跟踪了下Farcry2引擎的渲染流程,无意间发现Farcry2每帧竟然会多次调用BeginScene和EndScene函数,我以前的认识是每帧开始的时候BeginScene,Present之前EndScene,一般为了gpu和cpu的并行性,会在EndScene和Present函数之间插入一些计算代码(比如物理计算等),让cpu不至于等待gpu绘图。
很多人可能会认为在SetRenderTarget之后要BeginScene,使用完RenderTarget后要EndScene,网络上有很多例子也是这样写的,但这是完全错误的,渲染RenderTarget不需要Begin和End,否则会导致D3D_ERROR,如下:
Direct3D9: (ERROR) :BeginScene, already in scene. BeginScene failed.
就是说不允许连续两次的BeginScene调用,所以一般就是一帧调用一次Begin和End函数,而Farcry2非常奇怪,它存在如下函数调用顺序:
GetBackBuffer ->BackBuffer
SetRenderTarget
BeginScene
Some Draw Call
EndScene
BeginScene
Some Draw Call
EndScene
……
SetRenderTarget( BackBuffer )
BeginScene
Some Draw Call
EndScene
BeginScene
Some Draw Call
EndScene
……
Present
有时候甚至会出现一对空的
BeginScene
EndScene
中间什么也没干,我很好奇这些函数到底有什么特别的用法,我在DXSDK文档和google都搜索了,没有找到关于此的描述,不明白其中的原因,我猜想是不是这样可以提高cpu和gpu之间的并行率,但我以自己引擎来测试,把一些渲染代码放在一起Begin/End,没有发现有效率的提升,如果有那位看到此博客的朋友知道原因,希望不吝赐教。
- 相关文章:
- 1.cywater2000
- 你只要render,就需要begin-end,当你把渲染逻辑分成多个小块的时候,就可能要用多个bengin-end。你把begin-end当成类似lock-unlock的话就好理解了。
为什么要多个短小的,而不是一个长范围的呢?比如
BeginScene
...
EndScene
Present
DX文档里说的很清楚:
“ To enable maximal parallelism between the CPU and the graphics accelerator, it is advantageous to call IDirect3DDevice9::EndScene as far ahead of calling present as possible.”siney 于 2009-02-07 10:55:10 回复目前我也是这样认为的,这也是dxsdk文档里唯一一段对此的描述,我在文章中也写了,一般会在EndScene和Present之间插入一些计算代码,来保证EndScene之后不会立刻等待gpu绘图,而且还是无法解释Farcry2 会什么存在空的
Begin/End调用这个问题。cywater2000 于 2009-02-07 12:39:56 回复Begin/End这2个函数是必须调用的,但中间的Draw却是根据逻辑决定的。所以有空的很正常。 - 2009-02-07 00:38:58 回复该留言
- 3.xoyojank
- http://blog.csdn.net/xoyojank
- 要是用了ID3DXRenderToSurface就会这样的
- 2009-02-09 13:12:27 回复该留言
- 4.xingzhe2001
- 这是由于如果begin和end之间渲染命令太多,导致d3d的runtime的command buffer满了,会引起核心模式和用户模式的切换,可能是影响性能吧。
- 2009-07-24 11:19:05 回复该留言
- 5.xingzhe2001
- 参考这片文章http://www.cnblogs.com/effulgent/archive/2009/02/10/1387438.html
begin和end之间渲染命令太多导致后画的资源在显存中不能常驻,导致不必要的内存传输。 - 2009-07-24 11:49:41 回复该留言
发表评论
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。






