输入
类似的项目,比如hlsl2glsl fork和mojoshader,都只支持到了SM3。对于SM4+的shader,只能自己做一个编译器。DXBC2GLSL的输入是SM5的字节码(也兼容SM4),经过解析,得到输入变量、输出变量、资源声明和shader指令等。
由于调用的是d3dcompiler.dll,shader转换的工作变成平台相关了。如果需要在Linux上做这件事情,就得用Wine来执行d3dcompiler。
输出
DXBC2GLSL包含了一个库和两个工具。用户可以在自己的程序中使用DXBC2GLSL的库进行转换,也可以调用工具进行离线转换。输出的GLSL可以是OpenGL 2.0-4.4的VS/PS/GS。HS/DS/CS,以及OpenGL ES的版本也在开发中。
和Cg的对比
原先在KlayGE中的流水线是,带有#ifdef的HLSL经过一次token转换,得到Cg源代码。经过Cg编译器转换成GLSL。在经过一次token转换,得到“现代”的GLSL。通过这样多次转换,消除了Cg编译器产生的代码对硬件的依赖。这个过程相当繁复,带来的结果是虽然稳定性有所保证,但转换速度下降了。同时由于Cg和HLSL的区别,要保证源代码兼容,很多高级的HLSL功能也都被禁止了。
使用DXBC2GLSL之后,HLSL可以完全兼容。只需要一次转换就能得到最终的GLSL。
这里比较一下KlayGE中使用DXBC2GLSL和Cg流水线的区别。编译速度和Shader性能两项,测试的是DeferredRendering例子。
DXBC2GLSL流水线 | Cg流水线 | |
---|---|---|
Shader Model | SM5 | SM3和一部分SM4 |
转换方式 | 一次转换 | 三次转换 |
编译速度 | 5秒 | 9秒 |
Shader性能 | 95FPS | 80FPS |
Vertex Shader | 完全支持 | 不支持gl_VertexID、gl_InstanceID… |
Pixel Shader | 完全支持 | 不支持gl_PrimitiveID、gl_SampleID… |
Geometry Shader | 完全支持 | 不支持gl_PrimitiveIDIn、gl_Layer… |
Hull Shader | 开发中 | 不支持 |
Domain Shader | 开发中 | 不支持 |
Compute Shader | 开发中 | 不支持 |
Uint系列指令 | 支持 | 不支持 |
Atomic系列指令 | 支持 | 不支持 |
Texture array | 支持(但尚未在KlayGE中使用) | 不支持 |
未来
目前的DXBC2GLSL只是打下了一个基础,以后还需要更多的测试、重构和优化。另外,这套框架在理论上甚至可以做到把compute shader转成OpenCL。