泡泡网显卡频道 PCPOP首页      /      显卡     /      评测    /    正文

完美DX10!ATI新王者HD2900XT权威评测

● 第三章 第二节 DX10的架构特性 以及带来的好处。

 

    DirectX之所以在广大的开发者中流行,是得益于它的简单易用和丰富的功能特性。然而,DirectX一直被一个主要的问题所困扰,那就是高CPU负载。

 

    在图形编程API出现之前,三维程序直接向图形硬件发送图形命令来完成绘制工作。虽然这样绘制效率相当高,但是程序中要应对各种不同硬件上的不同命令,这使得开发工作十分困难,且程序中很容易出错。当越来越多不同的图形硬件冒出来的时候,这就成了一件十分不能忍的事。

 

    于是便出现了像DirectX和OpenGL这样的图形API。它们在图形硬件和应用程序之间架起了一个中间层,这样,应用程序可以使用统一的图形编程代码,而对底层各种硬件的适应,则由图形API来完成。这就将游戏程序员们从与大量的图形硬件交换意见的恶梦中解救出来,使他们能够将精力集中在“制作伟大的游戏作品”上面^_^

 

    但是这样就完美了么?不是的。每次DirectX从应用程序那里接收到一条命令,它就需要先对这条命令进行分析和处理,再向图形硬件发送相对应的硬件命令。由于这个分析和处理的过程是在CPU上完成的,这就意味着每一条3D绘图命令都会带来CPU的负载。这种负载给3D图象带来两个负面影响:限制了画面中可以同时绘制的物体数量;限制了可以在一个场景中使用的独立的特效的数量。这就使得游戏画面中的细节数量受到了很大的限制。而使图像具有真实感的重要因素,偏偏是细节量。

 

    DirectX 10的一个主要目标就是最大地降低CPU负载。它主要通过三个途径来达到这个目的:第一,修改API核心,使得绘制物体和切换材质特效时的消耗降低;第二,引入新的机制,降低图形运算操作对CPU的依赖性,使更多的运算在GPU中完成;第三,使大量的物体可以通过调用单条DirectX绘制命令进行批量绘制。下面我们就来仔细的看一下这三种方式:

 

1.降低绘制消耗


    第一种方式的一个重要例子就是DirectX 10中对三维数据和绘制命令进行验证过程的修改。所谓三维数据和命令的验证,是指在DirectX绘制图形之前,对传给它的图形数据和绘制命令进行格式和数据完整性的检查,以保证它们被送到图形硬件时不会导致硬件出问题;这是很必要的一步操作,但是不幸的是它会带来很大的性能开销。

 

 
{imageTitle}

 

 

 

    从上表我们可以很容易的看出,在DirectX 9中,每次绘制一帧画面之前,都会对即将使用的相关数据进行一次验证。而DirectX 10中,仅当这些数据被创建后验证一次。这很明显是可以大大提高游戏进行中的效率的。

 

2.降低CPU依赖性

 

    在降低CPU依赖性方面,DirectX 10 引入的三个重要机制就是:纹理阵列(texture arrays)、绘制断言(predicated draw)和数据流输出(stream out)。不要被这三个晦涩的名词吓倒,实际上它们是三个不难理解的机制。

 

    首先我们来看纹理阵列。传统的DirectX在多张纹理中进行切换的操作是一个很消耗CPU的操作,因为每切换一次,都要调用一次DirectX的API函数。而每绘制一个使用新纹理的物体,就要进行一次这样的切换操作;有时为了实现特殊的材质特效,绘制一个物体时可能就要切换好几次纹理,开销很大。

 

    所以,以前游戏美工们经常索性将大量的小纹理拼合到一张大的纹理中,通过给不同的三维物体分配这张大纹理的不同局部以期减少纹理切换,提高游戏运行效率。然而,想想也知道,这件事做起来会非常麻烦,而且DirectX 9中对纹理的尺寸的限制是4048×4048像素,也就是说,如果要容下更多的小纹理块,可能就得开辟很多张这样的大纹理。

 

    DirectX 10引入的新的纹理阵列机构,将允许在一个由显卡维护的阵列中容纳512张单独的纹理,而且,在shader程序中可以使用一条新的指令来获取这个阵列中的任意一张纹理。而这种shader指令是运行在GPU中的;这样,就把原来要消耗很多CPU时间的纹理切换工作轻松地转给了GPU。由于纹理一般是直接放在显存中的,所以这件事由同显存一起放在显卡上的GPU来完成真是天经地义,大快人心^_^。现在,在应用程序的层面,只要一开始设置好纹理阵列中的纹理,然后每次绘制一个物体时为它指定一个纹理的索引号,并同物体三维数据一起传递到shader中,就可以放心的让GPU来给物体选纹理了。

 

    然后说说绘制断言。在一般的三维场景里,很多物体都是完全被别的物体挡在后面的。这时候如果要显卡绘制这些物体就是白费力气。尽管高级的GPU可以通过硬件算法将场景画面中被挡住的像素(注意是像素)预先剔除,但是仍然会有一些处理消耗。例如,一个完全被挡住的复杂的角色模型,它的身上可能有几千个顶点,需要做复杂的骨骼皮肤动画处理、顶点光照运算等等——然而,GPU是在处理完这些顶点之后,并要把这个角色模型一个像素一个像素地画到画面中时,才开始判断每个像素是否需要画——当所有的像素都被剔除了时,之前做的顶点处理也就全白费了-_- || 于是,游戏开发者们想出了一个方法来解决这个问题,这就是绘制断言。

 

    简言之就是用一个可以代表某个复杂物体的简单物体来判断这个物体是否被全部挡住了——例如用一个可以罩住刚才那个角色的大盒子,当绘制这个盒子时,如果所有的像素都被P掉了,也就说明这个盒子肯定完全看不见,更甭说里边的角色了,也就不用做什么骨骼皮肤运算啦之类的操作了。一个盒子顶多有八个顶点,这学过初中几何的人都知道,相比处理几千个顶点,开销小得多。但是,以前这步中有些部分也是要在CPU中完成的。现在,在DirectX 10中,已经彻彻低低的交由GPU来做了^_^。真是很周到啊。

 

    最后来看看数据流输出。这是一个DirectX 10中的非常重要的特性,它允许GPU上的Vertex shader或Geometry shader向显存中添加数据!您也许觉得这感觉没什么,然而在以往的vertex shader中是比较独特的。以前的DirectX中,vertex shader只能读取显存中已有的顶点数据;而DirectX 10中引入的新的Geometry shader,不但能读取显存中的顶点数据、几何(点、线段、三角形)数据,还可以生成新的几何数据放回显存。鉴于其重要性,这一机制我们将在第四节:几何Shader以及Stream Out中单独介绍。

 

3.批量绘制

 

    在DirectX 9中,对渲染状态的管理一直是一个十分消耗CPU时间的操作。所谓渲染状态,是指显卡进行一次绘制操作时所需要设置的各种数据和参数。例如,要绘制一个人物角色,就需要先设置他的几何模型数据的数据格式、纹理过滤模式、半透明混合模式等等——每设置一项,都要调用一次DirectX API,占用大量CPU时间,极大的约束了渲染的性能。

 

    为了使这些操作能够批量的进行,DirectX 10中引入了两个新的结构——状态对象(state object)和常量缓冲(constant buffers)。


    状态对象就是将以前的零散状态按照功能归结为几个整体,这样,当要设置一系列相关状态时,无需为每一个状态来调用一次DirectX API,只需要调用一次将这些状态统统设置到显卡中去。

 

    而常量缓冲是另一个十分有意义的机制。在绘制模型前的准备工作中,渲染状态的设置只是一小部分。还是拿绘制人物角色来说,能照亮这个人的光源的颜色、位置、类型、范围等等,都要提前设给显卡;为了通过骨骼来带动他的皮肤做出姿势,还要设置骨骼的位置信息等等——总之是很多东西;而这些东西主要都是通过GPU中的常量寄存器(constant registers)来传递给它的。每个常量寄存器可以存储一个4维的浮点型向量(即四个浮点数)。常量寄存器是游戏程序向GPU输入游戏场景中数据的重要途径。在DirectX 9中,这种常量寄存器的数量是十分有限的,这在下文中的对比图表中我们也可以看到;而且每次更新一个寄存器,都需要调用一次DirectX API函数。而DirectX 10中,使用了常量缓冲(constant buffer)这种结构;在每个constant buffer中都可以容纳4096个常量,而且只需调用一次API就可以更新一大批常量。

 

{imageTitle}


 采用constant buffer绘制的大量克隆物体。

图片来源:Microsoft DirectX 10 SDK


    举一个具体些的例子来对比一下:在以前,如果程序中想在场景里画很多的树木和杂草,可以采用一个类似于“克隆”的方法:先做好一棵或几棵树、草的三维模型,然后在画一帧画面时,不停的在不同的位置、方向,用不同的大小为参数,调用DirectX API的绘制函数来画这些模型,就可以画出很多草木来;但是每画一棵,都要设置一大堆参数后调用一次API;这是很耗CPU时间的,所以在以前的游戏中很难有大规模且细节丰富的森林场景。

 

    而在DirectX 10中,我们可以先把树、草的几个模型设给显卡,然后将所有要画的树木的位置、方向和大小一次性的写入到constant buffer中,然后告诉DirectX——画!显卡就一下把所有的树木和草都一起绘制出来了^_^ 这样,像Far cry 2 那样的游戏,才能营造出十分逼真的森林效果。

 

{imageTitle}
 
 DX9和DX10的处理器负载情况对比

 

总结

 

    总之,DirectX 10降生到这个世上,就是为了带走由于CPU负载过大而给游戏图形效果带来的苦难。通过提前数据验证、纹理阵列、绘制断言、数据流输出、状态对象、常量缓冲等机制,帮助游戏的效果和效率上升到一个新的高度。

{imageTitle}

0人已赞
第1页:完美DX10!ATI新王者HD2900XT权威评测第2页:完美DX10!ATI HD2000系列评测提纲第3页:2007显卡年!AMD/NVIDIA决战图形市场第4页:奋起直追!全新Radeon HD 2000产品线解析第5页:功能化发展!Radeon HD2000系列亮点逐个看第6页:第二章:统一渲染架构解析第7页:第二章/第二节:革命!R600的统一渲染架构第8页:4第9页:第三章:DirectX发展回顾以及DirectX10详细介绍第10页:第二节 DX10的架构特性 以及带来的好处第11页:第三章/第三节:ATI 3Dc功能回顾第12页:3第13页:3第14页:3第15页:3第16页:集众家之长,R600架构总览第17页:R600架构分块介绍第18页:Setup Engine(装配引擎)第19页:Ultra-Threaded Dispatch Processor(超线程分配处理器)第20页:Stream Processing Units(流处理器)第21页:R600的超标量SIMD架构第22页:4第23页:5第24页:ATI片内缓存相关技术第25页:Memory Control(显存控制器)第26页:第六章 R600的神工鬼斧——Tessellation技术第27页:第六章\\第二节 传统的虚拟3D技术回顾第28页:第二小节 凹凸贴图 Bump mapping第29页:第六章\\第二节\\第三小节 法线贴图(normal mapping)第30页:视差贴图技术parallax occlusion mapping第31页:位移贴图(displacement mapping)第32页:Ati的独门秘籍 Trumform 第33页:Tessellation技术第34页:神奇的小数点——细分网格算法中小数位的意义第35页:Tessellation效率的源泉——控制“笼子”第36页:Tessellation技术的流程第37页:Tessellation技术的应用和前景第38页:1第39页:AA发展第40页:CFAA第41页:123第42页:ATI显卡产品形象代言人——Ruby四度出击第43页:X800 & X850 Ruby第44页:DX9C的最高境界 X1800 Ruby第45页:R600 DX10 Ruby高清晰截图赏析第46页:R600 DX10 Ruby引擎和技术解析第47页:23第48页:R600 DX10 Ruby所用图形引擎揭秘第49页:1第50页:2第51页:第九章\\第二节第52页:庞大的运算资源,R600单卡就能物理加速第53页:3第54页:第四章:AMD高清视频功能解析第55页:22第56页:第三节 硬件视频加速第57页:第四节 UVD 引擎解码流程第58页:第五节 UVD测试第59页:第一节 电脑音频的数码之路第60页:第二节 HDMI数字音频技术背景第61页:第三节 各种显卡HDMI接口方案第62页:第四节 R600系列方案第63页:第五节:实战R600音频播放第64页:第六节 HD 2900XT怎么用?第65页:显卡介绍第66页:123123第67页:显卡介绍第68页:123第69页:显卡介绍第70页:3第71页:123123第72页:测试系统配置和设置第73页:阿苏大发送颠覆第74页:113123第75页:4第76页:05第77页:06第78页:游戏第79页:游戏第80页:123第81页:6第82页:6第83页:交火第84页:功耗测试第85页:1第86页:第二节 客观,公正,专业,全面,泡泡网为您带来最权威的DX10测试第87页:第三节 Call of Juarez游戏DX10测试 第88页:第四节 DirectX SDK测试(微软官方2007年四月版)第89页:第四小节:Draw Predicated第90页:第七小节:MotionBlur10第91页:第十小节:Skining 10第92页:第十四章 总结 另觅蓝海!AMD让ATI看得更远第93页:123

关注我们

泡泡网

手机扫码关注