Skip to content
据我上一次写D3D11 feature一晃已经4年了。相信这么多年来大部分开发者不再像当年那样无知了。现在Win10和D3D12已经发布,图形驱动模型也有不少发展。现在在Win10里的图形栈经过了较大规模的重构。虽然在上层很难察觉,但底层已经很不一样。 老的兼容方式 当年D3D9刚出来的时候,大部分显卡和驱动还是D3D8的。当时的兼容方式是,让D3D9的runtime跑在D3D8的驱动上。D3D9和D3D10之间出现了个短暂的断层,互相不兼容。不久之后D3D10.1又可以通过feature level的方式在老显卡上跑。这个东西叫做10level9,意思是10的runtime在9的硬件上。后来出了11,也一直是用这样的方式。 总的来说,老的兼容方式就是,硬件厂商提供一个或多个驱动,runti ...
上一篇把完成了一个最基本的D3D12程序,画一个三角形。同时我也说了,没有回头路。本篇将开始从11on12转向纯D3D12。 上一篇我们的假设假设是最基本的系统,关掉所有post process、UI、文字,就渲染一个三角形。这样的系统至少需要一个vertex buffer、一个rtv、一个vs、一个ps、一次clear、一次draw call。进一步的发展需要一个稍微复杂的系统,有文字和UI。也就是还需要一个index buffer、一个cbv、一个srv、一个sampler。Index buffer和vertex buffer的构建没区别,所以就是cbv、srv和sampler的事情。 在此之前,需要先介绍两个D3D12的概念,heap和root signature。因为CBV/SRV/UAV/Sampler都需要依赖于这两个。 Heap Heap是D3D12新 ...
从八月初开始正式做D3D12插件以来,经过5个星期、每天平均一小时的开发,终于达成了第一阶段的目标:在渲染层接口不变的情况下,用纯D3D12渲染所有例子。 其实还不是所有特性都实现了。在例子中,遇到这种情况会退回到另一条code path。原先这些code path是为了在较弱的硬件上也能达到同样的效果,同样也可以用于开发新插件的中间产品。还没实现的特性有: Stream output(退回到render to texture) Compute shader(退回到用pixel shader实现) UAVs No overwrite(退回到discard) Query(总是返回0) Indirect draw Depth stencil和压缩纹理的mipmap生成(退回到在CPU上生成) 下一个阶段会进一步实现这些特性,做 ...
上一篇把资源转成了用12的设备建立,下一步有点犯难了。 让我们做一个假设。要让一个最基本的系统能渲染起来,换句话说,关掉所有post process、UI、文字,就渲染一个三角形。至少需要一个vertex buffer、一个rtv、一个vs、一个ps、一次clear、一次draw call。Vertex buffer的问题已经解决;vs和ps本身和11的一样;clear和11的几乎一样,只要改成调用graphics command list上的函数即可;draw call也是。好了,那么问题就集中在 如何使用rtv; 如何组装起来渲染 但无论如何,这都是不归路。我们只能向前走,再也没法像前面那样,用11on12来让两者交互使用。 RTV D3D12里的RTV是放在一个heap里的,使用的时候把heap里的一个hand ...
上一篇我们讲了如何建立D3D12的设备,并在其之上建立出11on12的设备。接下去就要开始一步一步转移到纯D3D12下了。 第一个应该转的是相对独立的资源,包括buffer和texture。建立D3D12的资源,之后用前文说的CreateWrappedResource转成D3D11的资源,继续交给D3D11on12渲染就可以了。这样仍然可以往前走一小步,保证引擎还能工作。 Buffer Buffer包括vertex buffer、index buffer和constant buffer。 D3D12_HEAP_PROPERTIES heap_prop; heap_prop.Type = D3D12_HEAP_TYPE_UPLOAD; heap_prop.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; heap_prop.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; heap_prop.CreationNode ...
昨天晚上,sourceforge的宕机时间刚恢复,我就打算把新的develop和master分支推上去。笔记本上的本地git库是一个改动中的,和github等上的历史结构有些不同了。结果我不小心用了强制push,于是现在github、bitbucket、sourceforge、codeplex上的git库全都被更改了。 7月8号以来pull或者fetch过develop或者master分支的用户,会受到影响。需要用Reset develop/master to this的功能reset到“KlayGE: Rendering: Fix the black screen in WinRT. (ticket #295)”这个commit,SHA-1是1217bcff860130d6d187925cdf342fb0ea11ab96。如果在原有分支上有个修改的,需要同时cherry pick到新的分支上来。 对这个push事故,我深表歉意。给大家制造麻 ...
KlayGE里很早就支持屏幕空间实时非平面反射,并在后来扩展到了全方向的反射。虽然比传统的反射能少渲染一遍场景,速度有明显提高,但由于计算完全在像素级,开销仍然比较大。本篇将探讨一下如何加速反射的渲染,主要思路来自于SIGGRAPH 2014 Advances in Real-Time Rendering in Games里的Reflection System in Thief。 原始效果 拿Ocean例子来统计速度。在NVIDIA Geforece GTX 960上,没有反射的时候249FPS,有反射的时候就剩下159FPS了。也就是说,反射占了2.27ms左右。 加速1:半分辨率 既然是PS的瓶颈,那么最直接的优化方法就是降低分辨率。 原先的反射是在special shading里面计算的,必须是全分辨率。在新的改进里,render ...
继上一篇提到了把编译器要求升到了vc11/g++ 4.6/clang 3.4之后,develop分支又做出了一些改进。终于,我们完成了现阶段的C++11化改进。 constexpr vc14开始支持constexpr,所以可以用它来实现编译期字符串hash。以后还会进一步增加constexpr的使用,改善执行性能。在KFL里定义了一个宏KLAYGE_CONSTEXPR,在支持的时候是constexpr,否则定义为空。 emplace,move map里插入元素,原先的做法是insert(make_pair(key, value))。这么做代码比较长,在C++11里有了emplace,可以用emplace(key, value)来代替原来的写法。而且STL的实现里一般用了move semantic把key和value直接移入map,不用拷贝。如果原先已经有构造好了的pair,那么用insert和 ...
多年前我写过编译期字符串Hash和再探编译期字符串Hash两篇博文,分别证明了C++98下无法实现编译期的字符串hash,以及如何在C++11下用constexpr实现。过了这么多年,原有的实现在Clang上出现了严重的编译性能下降,需要一些修改才能顺利编译。而vc14也开始支持constexpr了,经过实验,发现问题仍很严重。所以这里不得不再次试着改进编译期字符串hash的方法。 旧方法回顾 上次的实现用了constexpr配合模板嵌套,实现了一个初步的编译期计算字符串hash的方法。 constexpr size_t _Hash(const char (&str)[1]) { return *str + 0x9e3779b9; } template <size_t N> constexpr size_t _Hash(const char (&str)[N]) { ...
在前几个版本开发的过程中,每次都有一些对工程系统的改进,但也积累了一些问题。在KlayGE 4.8的开发刚刚开始之时,我打算尽量把之前发现的问题解决掉,让以后的开发和使用更为顺利。 改进依赖文件的管理 在上一个版本中,KlayGE的代码库迁移到了git,同时也把第三方库和资源文件等放到独立于代码库的地方,在CMake里下载。但是,原先只是通过文件名来检测是否已经下载过。只要文件存在就不动它。这对一般只下载发行版的用户来说没有问题,但对开发者来说有有点麻烦了。一有新版本的依赖文件,就需要手动删除旧的,并再次执行CMake生成。钱康来就曾在开发4.7的过程中遇到过这个问题。他提议应该用个MD5来校验下载的文件和已经存在磁盘上的 ...