好久没更新了。。上自己博客看了下这篇2个月前的草稿都还没写完。。的确是要荒废了快。。囧
最近上班没什么事情,所以便考虑着把自己老土的d9图形山寨引擎移植到d10上(其实可以直接移植到d11的)。。我就慢半拍吧。。首先d10,11和d9的一大区别就是本来d9众多的setState被去除,而使用改进的state object,这些包括了Input-Layout State, Rasterizer State,Depth-Stencil State, Blend State, Sampler State。可以看到本来的多次set函数被大量简化了,而这些state object都是依靠对应的DESC(描述),来直接创建出来,用户在使用的时候只需要向驱动层传递一个句柄(也就是新的set函数)既可以对许多个状态进行改变,例如Rasterizer State的DESC:
typedef struct D3D10_RASTERIZER_DESC {
D3D10_FILL_MODE FillMode;
D3D10_CULL_MODE CullMode;
BOOL FrontCounterClockwise;
INT DepthBias;
FLOAT DepthBiasClamp;
FLOAT SlopeScaledDepthBias;
BOOL DepthClipEnable;
BOOL ScissorEnable;
BOOL MultisampleEnable;
BOOL AntialiasedLineEnable;
} D3D10_RASTERIZER_DESC;
可以看到一次set可以一次给驱动发送以前d9曾经需要很多条command的工作,可想而知其带来的性能提升。
但这也带来了新的问题,由于这些state object的创建是比较耗时的,所以便不可能像以前d9一样没帧都去set,而且由于DESC里有多个配置项,也无法简单的去cache。看到这里,我想看过Christer和clayman大人那两篇关于渲染排序文章的同学应该能想到对应的思路。那就是做一个sortkey,对于Rasterizer State来说,FillMode这些枚举,bool都是能直接做入sortkey的(节省比较次数),剩下的譬如int或者float则直接比较,也就是重载operator==和!=
譬如
bool operator==(const D3D10RasterState& rhs)
{
if(SortKey == rhs.SortKey && DESC.DepthBias == rhs.DESC. DepthBias &&
fabs(DESC. DepthBiasClamp – rhs.DESC. DepthBiasClamp) < 0.000001f && etc..)
return true;
return false;
}
UE3中这块大概也是这样的,不过他没有弄sortkey什么,他是很简单直接重载了==和!=的用memcmp比较State的DESC就完了..简单易用吧。。