网页功能: 加入收藏 设为首页 网站搜索  
Direct3D 10系统(四)
发表日期:2007-03-28作者:[转贴] 出处:  

作者:David Blythe
本文版权归原作者所有,仅供个人学习使用,请勿转载,勿用于任何商业用途。
由于本人水平有限,难免出错,不清楚的地方请大家以原著为准。欢迎大家和我多多交流。
翻译:clayman
Blog:http://blog.csdn.net/soilwork
clayman_joe@yahoo.com.cn  

5 Core API and Runtime
         我们把API和运行时分为了两个独立,但是完整的部分:核心API/运行时以及着色语言/状态管理系统。我们将讲述新运行时中几个比较重要的部分,以及与当前系统相比的变化。
          核心API以及运行时作为硬件系统上的一个薄抽象层(thin abstraction layer),扮演了low-overhead的角色。可编程管线的转变和固定功能冗余功能的移除,戏剧性的简化了API和运行时。API为以下操作提供服务:分配以及修改资源;创建视图状态并把他们绑定到管线的不同部分;创建shader并且把他们绑定到管线;控制管线不可编程部分的状态;初始化渲染操作;通过检索统计(retrieving statistics)或资源内容,从管线中查询信息。

5.1 StateManagement
          我们要解决的主要问题之一,就是减少应用程序到硬件之间传输指令的端到端的消耗。我们把指令分为两类:分配或释放资源的类型,以及改变管线状态的类型。其中,我们特别关心后者,因为他们在应用程序中将频繁出现。我们使用了一个简单的模型,来把这些指令传递给管线。运行时将为应用程序的指令分配一块内存缓冲。每条通过运行时到驱动的API指令,都将转变为特定的硬件指令,并储存到这个缓冲里。当缓冲被填满或另一个操作需要同步渲染状态的时候(e.g 读取一个渲染目标的内容),整个缓冲就被提交给硬件。
         在过去10年的PC系统上,运行时模型几乎没变化。我们的目标是在不需要额外处理的情况下,把指令附加到缓冲中。在过去,这显然是不切实际的,因此,我们尽量了解其中的原因,并且寻找和修改设计方案,让我们的模型接近这个目标。
         我们发现在运行时和驱动两方面,都有一些原因,会带来额外的处理。
*API和硬件之间的不匹配
*延迟处理的风格(deferred processing style)
* 错误传输应用程序请求
         上面三个原因中,第三个是最容易解决的,只要在应用程序开发者,运行时,驱动,以及硬件提供者之间达成一致,就能极大的改善情况(e.g 不是10%而是数十倍的提高)。
          第二个问题涉及到传统的实现策略:当图元提交到管线时,分辨哪些状态改变是累积的。这样做的优点是可以成批的处理一组状态的改变,同时,相互独立的(非正交的non-orthogonal)状态实现可以一起处理,而不是每次处理相关改变中一个独立的状态。他还允许丢弃冗余状态。但是,这些功能都需要占用额外的CPU周期来记录改变,并且进行全局控制。非正交的灾难性例子之一,就是纹理绑定的改变,需要重新编译shader,以适应新的纹理格式。我们提倡尽可能减少对硬件状态实现的依赖性,把对冗余状态改变的处理,划分到运行时中一个可选的层来处理。
         第一个问题涉及到多种类型的不匹配。重编译shader时的正交不匹配??就是例子之一 (orthogonality mismatches as exemplified by the shader recompile example),当然还有很多种其他情况。原因之一与状态改变的粒度(granularity)有关。无论OpenGL还是以前的Direct3D本版,都把状态改变的粒度定义的非常精细(fine granularity),e.g,改变一个混合因子,或者改变一种采样模式。我们已经进行了许多尝试,努力把状态改变集中到一起,以提高效率,比如,使用OpenGL中的显示列表或者Direct3D 9中的状态块(state blocks)。虽然这些解决方案可以工作的很好,但是,我们选择了一种更简单的方法。丢弃固定管线的冗余功能已经大大减少了总的状态种类数量。通过分析,我们发现当前过细的粒度划分,并没有什么优点,因此,我们把分散的状态组织为了较大的,相关的,不可变的聚合体(immutable aggregates)成为状态对象(state objects)。这样可以建立一个清晰的模型,指明哪些状态应该是独立的,哪些不是,从而减少完全重新装配管线所需的API调用数量。我们发现使用了这些新API的程序,能提高匹配的准确性。
         Direct3D 10定义了5个状态对象:InputLayout (vertex buffer layout),Sampler,Rasterizer,DepthStencil,以及Blend。这样的划分,反映了状态逻辑上的关系,如果应用程序需要单独频繁的改变某个独立状态,那么可以进一步对此进行细分。当创建状态对象时,驱动将为此状态创建相应的硬件表示(e.g,一组寄存器值),当对象需要绑定到管线时,相应的命令就被复制到命令缓冲中。某些硬件实现可能会在硬件中保留(缓存)状态表示,从而减少把 API命令转换为硬件命令的代价。
         在第四节中,我们描述了更新管线常量时可能出现的问题。他实际上只是管道故障(hazards)中,比较普通的一种。当某个值即将被使用,但之前的值仍在使用时,同样可能导致一些故障。解决这个问题通常使用的方法就是,使用额外的储存空间来保存新值,同时,重定向引用,指向新的缓冲。
         另一种故障发生在从刚写入数据的资源中读取数据时。比如,把之前的渲染目标作为纹理来使用。当进行这样的交换时,要求渲染指令已经执行完毕,同时,所有数据已被写入渲染目标,这样才能从中拾取数据。与前面的描述的更新故障不同,read-after-write故障更难,或者根本不可能在API和运行时中解决。为了避免在这种情况下对管线造成延迟(stalling),应用程序在构建时,就应该尽量避免渲染操作需要立即读取之前渲染目标中的数据。
 
5.2 Validation and Error Handing
          部分API设计的原则是避免发生错误,或者避免对某些使用频率较低,但代价很大的操作进行错误检查,比如对创建对象进行检查,而不是对使用对象检查。虽然我们对性能的需求,不允许通过API对已部署的程序进行过多错误检查。这里,我们的错误检测和报告策略是把错误分为两类,致命和非致命的。在任何版本的运行时中,都会对致命错误进行检测和报告。非致命错误的检测则是通过一个单独的监听层来完成,它对运行时来说是透明的。这个验证层最初是在程序的开发时使用,当部署程序的时候,开发者通常会屏蔽它。为了检测错误,它通常还会寻找和报告API的不理想(non-ideal)使用类型。可以对这个验证层进行控制,指定他对哪些错误进行探测和报告。
         错误分化的方法确实有一点点模糊(ambiguity):哪些错误总是会被检测,哪些没有被检测出的错误将有怎样的行为?未定义的错误行为稍后可能会转变为一种unintended but relied upon (defacto)  behavior。再者,如果运行时没有检测出某个特定的错误,那么驱动将忽略性能代价,尽力避免出现灾难性的硬件错误。我们将努力鉴别出这种错误,并且在运行时中对他们进行检测。另外,在渲染时,我们不会进行任何错误检查,e.g,错误检测将被延迟,直到一个Draw命令完成。致命错误保护扩了深度缓冲和渲染目标尺寸不匹配,同时把一个资源绑定到读取和写入操作上,等等,不致命的错误则包括:不匹配的shader类型联接(签名),以及数据格式声明不匹配。
         在当前着色编成模型发展的阶段,捕获着色程序运行期间的错误代价是很大的。因此,我们定义了完善的行为,比如,当数组越界时返回0,来获得一致的行为。从长远来看,硬件将会支持异常机制。

~~~~~~~~~~~~~~~~~~~~无聊的分割线~~~~~~~~~~~~~~~~~~~~~
还有一部分就完了
似乎看的人不是太多
大概是我更新的太慢了吧
最近很郁闷,虽然找了份工作却又不太满意,唉~~~

我来说两句】 【加入收藏】 【返加顶部】 【打印本页】 【关闭窗口
中搜索 Direct3D 10系统(四)
本类热点文章
  DDraw和D3D立即模式编程手册
  矩阵求逆的快速算法
  本地化支持:OGRE+CEGUI中文输入:OGRE方..
  Direct3D中实现图元的鼠标拾取
  3D场景中的圆形天空顶
  OpenGL显卡编程
  一种高效的基于大规模地形场景的OCCLUS..
  一个完善的读取3DS文件例子
  如何制作一个可控制的人体骨骼模型
  Direct3D 入门之我见
  Slope(斜坡) 法线生成算法,在地形渲染..
  在Direct3D中渲染文字
最新分类信息我要发布 
最新招聘信息

关于我们 / 合作推广 / 给我留言 / 版权举报 / 意见建议 / 广告投放  
Copyright ©2003-2024 Lihuasoft.net webmaster(at)lihuasoft.net
网站编程QQ群   京ICP备05001064号 页面生成时间:0.01014