找到驱动切换的代码,自然而然就要找实现的位置了,简单搜了下,原来是GLSL Shader字节码转换到HLSL字节码,正好和Klayge做了相反的工作。
时间上似乎也差不多,Klyage是2014年搞的
http://www.klayge.org/2014/03/25/announces-dxbc2glsl-a-hlsl-bytecode-to-glsl-compiler/
bgfx最老的一个文件.gitattributes显示是3年前,现在是2018年1月,3年前2015年1月或更早,双方谁都没提到过对面,看起来似乎是平行世界。
要么就是当年流行这种东西?不得而知。反正重要是来看看大概是什么位置实现的。
顺便bgfx这代码量也不小,虽然只能算是个图形API封装,达不到游戏引擎级别,但是看到一堆线程,信号啥的直接就想跪了,没这方面基础果然看不习惯。
再顺便,看bgfx这趋势和代码量,似乎有望成为下一个SDL,SFML,加个音频的话我真就用他了...
分析思路是这样的,首先看第1个例子cubes,因为第0个例子只是演示了imgui和自带的debug文本,没什么shader方面的参考价值。
cubes.cpp,128行找到
m_program = loadProgram("vs_cubes", "fs_cubes");
一路跟进,来到bgfx_utils.cpp,99行
static bgfx::ShaderHandle loadShader(bx::FileReaderI* _reader, const char* _name)
这个函数里面有关于DX还是OpenGL的switch分支判定。
但是继续跟却找不到什么头绪了。
接着从bgfx的src文件名看。
发现在renderer下面有shader.cpp,shader_dxbc.cpp等,在DX驱动模式下,
shader_dxbc.cpp的555行看到
int32_t readString(bx::ReaderSeekerI* _reader, int64_t _offset, char* _out, uint32_t _max, bx::Error* _err)
下断点,成功断下来,换到Opengl下无效,可以判断此处应为DX转换代码,顺便BC应该是Byte Code的意思。
之后在堆栈里向上找,找到一处多态调用bgfx.cpp,2405行
case CommandBuffer::CreateShader:
这个分支下面有一句
m_renderCtx->createShader(handle, mem);
就是这里做了多态处理。
继续跟可以发现,如果是OGL,就直接在renderer_gl.cpp中做
m_id = glCreateShader(m_type);
建立GL Shader
如果是DX,从字节码判定,然后在renderer_d3d11.cpp中
CreateVertexShader
CreatePixelShader
CreateComputeShader
之后可能要看看nbody是怎么实现的,话说回来, bgfx也算学习OpenGL Compute Shader的资料了,因为OpenGL这方面的资料实在太少,完全不能打。
DX好歹有个SDK例子和龙书,OpenGL就没看到什么太靠谱的例子。Geometry Shader的例子到是有,做GPU粒子的看过几个也实现了,CS的是真没见过。
顺便发现bgfx只有VS,PS,CS,顶点,像素和计算着色器3种,没有Geometry Shader的实现,不知道是什么原因没实现,但是总给我一种三缺一的不爽,虽然CS,GS很少用,大部分情况只要有VS,PS就够了。