多年前我写过编译期字符串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来校验下载的文件和已经存在磁盘上的 ...
One step closer
继拥抱C++11,一步一步来第一篇和第二篇之后,develop分支又经过了一次改进。现在,编译KlayGE所需要的编译器提升到了vc11、g++4.6和clang 3.4。相比上一次的vc10和g++4.3这样刚开始支持C++11的编译器来说,11和4.6基本支持了所有的C++11特性。所以代码里面可以比较自由地使用C++11,而代码更简单。
全部支持的特性
目前vc11、g++ 4.6和clang 3.4都支持的C++11特性如下,远多于vc10、g++ 4.3和clang 3.0这个组合。
语言核心部分
Static assertions (N1720)
Multi-declarator auto (N1737)
Right angle brackets (N1757)
auto-typed variables (N1984)
Extern templates (N1987)
Rvalue references (N2 ...
在上一篇拥抱C++11,一步一步来里,我制订了一个一步步使用C++11的路线图。KlayGE 4.7去掉了早于vc10、g++ 4.3和clang 3.0的编译器支持,但由于时间关系,还没来得及把它们都支持的C++11特性改为默认开启,仍然用了wrapper层。现在,KlayGE 4.8的开发已经开始,也有足够的时间真正地来执行C++11的计划。目前已经在develop分支里做实现了一部分。
全都支持的特性
整理一下vc10、g++ 4.3和clang 3.0都支持的C++11特性,可以得到一个列表:
语言核心部分
Static assertions (N1720)
Right angle brackets (N1757)
Extern templates (N1987)
auto-typed variables (N1984)
Rvalue references (N2118)
Declared type of an exp ...
在KlayGE 4.7发布之前,4.8其实已经完成了大部分的计划。今天新版本的开发也已经开始,这里公布一些我对KlayGE 4.8的计划,更开发组成员和用户参考。和以前一样,欢迎有兴趣、有时间加入KlayGE 4.8开发阵营的朋友们继续参加。
最近几个版本都是在注重新增一些渲染功能。KlayGE 4.8除了继续保持之外,还会把现有的功能做一些重构和优化,使其更方便使用。同时,移动平台的支持还将继续发展。
时间线
这里列出几个重要的时间点,以供进度参考。
2015年11月30日,feature complete:所有功能都已经完成,没完成的推迟到下一个版本。
2015年12月15日,code complete:完成所有代码,除非特殊情况,否则不能在改变接口。
2015年12 ...
[zh]
又到了KlayGE的发布周期。今天,KlayGE 4.7正式发布了!在这个版本的开发中,有一些功能是由团队成员完成的,同时也有很多朋友提供了宝贵的建议和bug报告,在此表示感谢。由于开发设备的限制,难免有一些测试不足的情况,尽请见谅。KlayGE 4.7的主要更新如下:
引擎方面的改进
MacOSX成为完整的开发平台。上一个版本还需要在Windows上编译shader。这个版本可以独立在MacOSX上进行开发。(由钱康来完成)
Transient Buffer。高效的GPU buffer管理,用来加速UI和文字渲染。(由林胜华完成)
硬件检测。支持引擎内的硬件检测能力,检测主板、内存的型号和频率等信息。(由裴博翔完成)
自动测试框架。引入一个单元测试的框架 ...
这几年Intel和AMD都推出了集成GPU的消费级CPU,并强调它们的内存是共享的架构,也就是UMA(Unified Memory Architeture)。最近AMD和NVIDIA的独立显卡也加入战团,开始逐步支持UMA。最新的D3D12直接内置了UMA的支持,开发者可以让自己的程序充分利用上UMA所带来的优势。那么UMA能带来什么好处?它的限制在哪里?
各种平台的状况
自从PC上第一块GPU,NVIDIA Geforce 256问世以来,GPU一直都是自带一块显存的。当年的AGP总线是非对称的设计,数据传到GPU要远快于从GPU读回。CPU和GPU的访存是完全分开的。后来的PCIE总线让两端传输的速度相等了,并提供了一些相互访问的能力。在驱动里,system memory的区域可以映射成可以被GPU访问的,反过来 ...
在游戏引擎里,每一帧都可能有UI和文字的渲染。这些东西的特点是,琐碎,随机,但每一部分的数据量很小。比如UI由很多矩形块组成,每个只有4个顶点。这样的数据对GPU来说是很头疼的。所以引擎往往需要在Buffer上做一些工作来改善渲染的性能。
由于在目前常见的架构上,CPU和GPU不能同时读写一块内存,CPU在写入数据的时候GPU只能读取另一个地方来渲染。所以一定需要某个机制,来避免这样的冲突。
常见方法1:Discard
最古老的一个做法就是,自己维护一块内存,每一次需要画东西的时候先放在那块内存中。每一帧用一次discard的方式对GPU buffer做一次map,把数据拷贝进去。这么做很简单,所有复杂的同步都交给驱动去完成。
在内部,di ...
自从去年GDC释出了一些消息以来,D3D12 SDK终于在上个月底随着VS2015RC公开了。除了API的更新,D3D12还包含了一个称为11on12的库,让移植前所未有的快捷。目前KlayGE的D3D12插件正在开发中,本系列文章将会把一些方法和经验总结出来。简单起见,后续的代码省略了错误检查等细节。同时,阅读本系列的前提是对D3D11有基本的了解。
D3D移植的过去
纵观D3D的历史,几乎每个版本都是从新开发,和旧版本没有接口上的继承关系。也就是说,和一般COM组件的概念不同,不能从新版本的接口QueryInterface出老版本的接口。结果就是,每次需要移植到新的D3D版本,都会需要拷贝代码、修改代码,甚至重写。在整个渲染部分都换到新API之前,系统完全无法工 ...
Singleton是一个非常常用的设计模式。几乎所有稍大的程序都会用到它。所以构建一个线程安全,并且高效的singleton很重要。既然要讨论这个主题,我们就先来定义一下我们的需求:
Lazy initialization。只有在第一次使用的时候才需要初始化出一个singleton对象。这使得程序不需要考虑过多顺序耦合的情况。同时也避免了启动时初始化太多不知道什么时候才会用到的东西。
线程安全。多个线程有可能同时调用singleton。如果只需要单线程,那实在没什么需要讨论的。
高效。因为singleton会被反复调用,如果效率低的话浪费太大了。
通用。适合现有的各种平台,以及未来可能出现的平台。
有了这些需求,我们就可以开始讨论如何构造这么一 ...