转载请注明出处为KlayGE游戏引擎,本文的永久链接为http://www.klayge.org/?p=3304

个顶点。这样的数据对GPU来说是很头疼的。所以引擎往往需要在Buffer上做一些工作来改善渲染的性能。

由于在目前常见的架构上,CPU和GPU不能同时读写一块内存,CPU在写入数据的时候GPU只能读取另一个地方来渲染。所以一定需要某个机制,来避免这样的冲突。

:Discard

最古老的一个做法就是,自己维护一块内存,每一次需要画东西的时候先放在那块内存中。每一帧用一次discard的方式对GPU buffer做一次map,把数据拷贝进去。这么做很简单,所有复杂的同步都交给驱动去完成。

倍的内存空间,加上自己维护的那块内存,就需要3倍空间。同时,由于空间的申请和释放并不快,每一帧都这么做对性能来说有一定影响。

:No overwrite + Discard

自从图形API支持no overwrite了之后,就出现了一个新方法。不需要自己维护一块内存,而是在每次画东西的时候直接用no overwrite的方式map GPU buffer,把数据放进去。同时,记录下buffer是用了多少。如果已经满了,就用discard来map,抛弃旧有空间。

No overwrite避免CPU/GPU冲突的方式是由程序自己保证,CPU新的填充数据不覆盖到GPU需要用的数据,所以CPU和GPU总是在读写同一块内存的不同区域。这么做并不需要申请新空间,map的性能远高于discard。但是这么做仍会有不少时候会遇到空间满了需要discard。其实很多数据已经被GPU用完,完全可以复用而不必总discard。

更高效的方法:transient

重新考虑一下这个情景,可以发现如果是个CPU程序,需要反复申请和释放很多小块的内存,那么大家都会想到用memory pool。那么为何不把memory pool的思路用到这里来呢?GDC 2012上Don't Throw it all Away: Efficient Buffer Management中的Transient buffer正是如此。不久以前KlayGE的团队成员林胜华实现了ppt中所说的transient buffer,目前UI和文字都已经转成了用这种buffer管理方式。

Transient和思路和memory pool一样,都是基于free list管理一块空间。区别在于,CPU的memory pool,free list就保存在那块空间里,每个item包含了下一个未分配区域的指针。对于GPU buffer来说,平常需要让GPU用来渲染,所以不能处于map状态。所以free list是在CPU端单独维护,而每个item包含的是未分配区域在GPU buffer中的偏移量。通过这样的间接转换,就能在CPU端管理GPU buffer中的空闲非空闲区域了。接口方面,transient buffer和memory pool也非常相似,主要都是Alloc和Dealloc。在Alloc的时候,需要通过no overwrite来map内部的GPU buffer,把数据拷贝进去。因为有free list标记所有空闲区域,所以这时候是可以非常安全地使用no overwrite,而不用担心数据覆盖问题。

帧之后才真正被GPU使用。所以在transient buffer内部还需要维护一个列表,保存每一帧被Dealloc的数据,在3帧之后才真正把它标记成空闲区域。

那么,还剩一个问题是,满了怎么办。一个做法是discard,再把整个区域当作空闲区域。另一个做法是申请一个更大的GPU buffer,把旧的数据拷贝过去,并加长free list。第一种做法如果遇到一次Alloc就需要大于整个buffer空间的情况,还是需要退化到第二种做法。所以目前KlayGE里只实现了第二种。

不支持no overwrite的平台

对于OpenGL 3.0之前而且不支持GL_ARB_map_buffer_range,或者OpenGL ES 3.0之前而且不支持GL_EXT_map_buffer_range的平台,是没有no overwrite的能力的。对于这样的平台,原文没涉及。在KlayGE中,遇到这种情况会在CPU端维护一个和GPU buffer一样大的vector,并在渲染之前通过discard的方式拷贝给真正的GPU buffer。这保证了对上层程序来说,不必考虑no overwrite的支持度。这也是KlayGE的实现对原文的一个扩展。

未来

在目前的D3D11上,也就只能做到这个程度了。如果未来需要进一步加速,在OpenGL上可以考虑用GL_ARB_buffer_storage提供的GL_MAP_PERSISTENT_BIT,做到CPU和GPU同时使用一块Buffer的目的。D3D12改善了这点,也能同时使用,解除了目前的读写冲突。

另一方面,对于particle system那样非常规则地申请和释放内存的情况,原文中还提供了一个叫做Discard-Free Temporary Buffers的方法,来自于StarCraft 2。比transient buffer更适合这种使用模式。在以后我们也会做一些尝试。

 
 



来自 <http://www.klayge.org/2015/05/25/%E9%AB%98%E6%95%88gpu-buffer%E7%AE%A1%E7%90%86%E4%B9%8Btransient-buffer/>

(转)KlayGE游戏引擎 :高效的GBUFFER管理方式的更多相关文章

  1. [ZZ] KlayGE 游戏引擎 之 Order Independent Transparency(OIT)

    转载请注明出处为KlayGE游戏引擎,本文的永久链接为http://www.klayge.org/?p=2233 http://dogasshole.iteye.com/blog/1429665 ht ...

  2. 最先进的开源游戏引擎KlayGE 4.3发布

    转载请注明出处为KlayGE游戏引擎,本文的永久链接为http://www.klayge.org/?p=2536 经过KlayGE团队半年来的努力,今天KlayGE 4.3正式发布了!在这个版本的开发 ...

  3. 最先进的开源游戏引擎KlayGE 4.4发布

    转载请注明出处为KlayGE游戏引擎,本文的永久链接为http://www.klayge.org/?p=2785 随着半年一个新版本的周期,今天KlayGE 4.4正式发布了!在这个版本的开发中,多名 ...

  4. 转:高层游戏引擎——基于OGRE所实现的高层游戏引擎框架

    高层游戏引擎——基于OGRE所实现的高层游戏引擎框架 这是意念自己的毕业论文,在一个具体的实践之中,意念主要负责的是物件和GUI之外的其他游戏系统.意念才学疏陋,望众位前辈不吝赐教.由于代码质量不高. ...

  5. 开源免费的HTML5游戏引擎

    青瓷引擎的成长 青瓷引擎自2015年4月项目启动开始,7月首次亮相2015年ChinaJoy,便得到业界的极大关注,随后开启限量测试,收到数百个开发者团队的试用申请及反馈,期间经历了18个内测版本,完 ...

  6. GJM : 各大开发游戏引擎

    感谢您的阅读.喜欢的.有用的就请大哥大嫂们高抬贵手"推荐一下"吧!你的精神支持是博主强大的写作动力以及转载收藏动力.欢迎转载! 版权声明:本文原创发表于 [请点击连接前往] ,未经 ...

  7. 转载:[转]如何学好3D游戏引擎编程

      [转]如何学好3D游戏引擎编程 Albert 本帖被 gamengines 从 游戏引擎(Game Engine) 此文为转载,但是值得一看. 此篇文章献给那些为了游戏编程不怕困难的热血青年,它的 ...

  8. 20个免费的 JavaScript 游戏引擎分享给开发者

    这篇文章收集了20个免费的 JavaScript 游戏引擎分享给开发者.这些游戏引擎能够帮助游戏开发人员更快速高效的开发出各种好玩的游戏. 使用 HTML5.CSS3 和 Javascript 可以帮 ...

  9. 开源免费的HTML5游戏引擎——青瓷引擎(QICI Engine) 1.0正式版发布了!

    青瓷引擎的成长 青瓷引擎自2015年4月项目启动开始,7月首次亮相2015年ChinaJoy,便得到业界的极大关注,随后开启限量测试,收到数百个开发者团队的试用申请及反馈,期间经历了18个内测版本,完 ...

随机推荐

  1. Linux高性能server编程——定时器

    版权声明:本文为博主原创文章.未经博主允许不得转载. https://blog.csdn.net/walkerkalr/article/details/36869913  定时器 服务器程序通常管 ...

  2. 动态数组第k小,Poj(1442)

    题目链接:http://poj.org/problem?id=1442 本来想复制一下,然后直接sort,结果T了. 在网上看了一下,有用两个队列做的,想了半天,没看懂什么意思.后来模拟一边,总算是懂 ...

  3. php中的脚本加速扩展opcache

    今儿在azure里装php5.5.4,发现原先php5.4.php5.3中的zend guard laoder以及php5.2中的Zend Optimizer均不能再用,一直很喜欢用的eacceler ...

  4. 递归遍历目录拷贝cdh下的lib到一个目录

    destpath='/home/hadoop/soft/hadoop-2.0.0-cdh4.5.0/cdhlib/'jarpath='/home/hadoop/soft/hadoop-2.0.0-cd ...

  5. jQuery 二级联动

    jQuery 二级联动 ----请选择省份---- 北京 上海 江苏 ----请选择城市---- 东城 西城 崇文 宣武 朝阳  黄浦 卢湾 徐汇 长宁 静安 南京  镇江 苏州 南通 扬州 & ...

  6. JavaEE 面试题总结

    一. JDBC 4 1. Java中访问数据库的步骤 4 2. Statement,PreparedStatement,CallableStatement的功能.特点. 4 3. 如何利用JDBC的A ...

  7. 面试-Spring理解

    转自http://hui.sohu.com/infonews/article/6331404387079946240 spring呢,是pivotal公司维护的一系列开源工具的总称,最为人所知的是sp ...

  8. iOS网络图片缓存详解

    在开发移动应用的时候比如Android,IOS,因为手机流量.网速.内存等这些因素,当我们的移动应用是针对互联网,并要频繁访问网络的话,对网络优化这块就显得尤为重要了. 比如某个应用要经常显示网络图片 ...

  9. 使用Git操作码云

    一.安装并配置 .安装git 下载地址: 官方网站:https://git-for-windows.github.io/ 国内镜像:https://pan.baidu.com/s/1kU5OCOB#l ...

  10. github上更新fork项目

    转载:https://blog.csdn.net/qq1332479771/article/details/56087333 ps:需要用GitHub所指定的chrome或者firefox浏览器,其它 ...