HLSL bytecode to GLSL编译器的第一步

1623 篇文章 22 订阅
1277 篇文章 12 订阅
转载请注明出处为KlayGE游戏引擎,本文的永久链接为http://www.klayge.org/?p=1821

从KlayGE 4.0开始,不但有为了下一版本开发的短期任务,还有一些中长期研发的任务。其中之一就是HLSL bytecode to GLSL编译器。现在KlayGE里的shader主要由HLSL写成,通过#ifdef的土办法兼容Cg。对D3D11来说可以直接使用,但对于OpenGL和OpenGL ES 2就得大费周折了。那种情况下,shader需要经过Cg编译器编译成传统的GLSL,在经过我自己的token级别的编译器转换成现代的GLSL,然后才能使用。

为什么不直接用Cg?看看Cg runtime在ATI卡上的表现吧。

为什么不用传统的GLSL?NV的驱动有一套attribute和index之间的绑定规则,比如gl_Position一定是0,gl_Normal一定是6(或者某个数,但是个常量),而且无法通过API来获取预定义attribute的index。这套规则在ATI卡上是不可用的。现代的GLSL没有预定义的attribute和varing(除了position),所以都可以给定attribute名来获取index,兼容性好得多。

所以,这里更好的解决方案是把不通过Cg编译器,就把HLSL编译成GLSL。目前有一些能做到这件事情的库,比如AMD的hlsl2glsl(已经停止开发),unity的hlsl2glsl fork(从AMD的发展而来),以及mojoshader。他们的问题在于,只支持到了SM3,对KlayGE来说连最低要求都没达到。只能自己做一个编译器。

如果需要把HLSL直接编译成GLSL,就需要做HLSL的解析等事,既麻烦又不能保证效率。所以我选择了把HLSL编译产生的bytecode解析出来,生成GLSL。因为HLSL->bytecode可以直接用现成的编译器,省了很多麻烦。(即便是linux上,也可以用wine来执行d3dx的HLSL编译)

方案明确后,步骤也就能很快定义出来:

  1. D3D11 bytecode反汇编
  2. VS/PS to GLSL
  3. GS/HS/DS to GLSL

在参考了mesa的d3d1x for linux之后,目前已经实现了第一步,反汇编器。下面一段VS:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
void DeferredRenderingVS (float4 pos  : POSITION ,
#ifdef NOPERSPECTIVE_SUPPORT
    out noperspective float2 oTc  : TEXCOORD0 ,
#else
    out float3 oTc  : TEXCOORD0 ,
#endif
    out float3 oViewDir  : TEXCOORD1 ,
    out float4 oPos  : SV_Position )
{
    oPos  = mul (pos , light_volume_mvp ) ;
    oViewDir  = mul (pos , light_volume_mv ). xyz ;
    oTc. xy  = oPos. xy  / oPos. w  *  0.5f ;
    oTc. y  *= KLAYGE_FLIPPING ;
    oTc. xy  +=  0.5f ;
#ifndef NOPERSPECTIVE_SUPPORT
    oTc. z  = oPos. w ;
    oTc. xy  *= oTc. z ;
#endif
}

经过fxc编译成vs_5_0后,可以用我的disasm反汇编出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
vs_5_0
dcl_global_flags refactoringAllowed
dcl_constant_buffer cb0 [ 12 ] .xyzw , immediateIndexed
dcl_input v0 .xyzw
dcl_output o0 .xy
dcl_output o1 .xyz
dcl_output_siv o2 .xyzw , position
dcl_temps  2
dp4 r0 .x , v0 .xyzw , cb0 [ 8 ] .xyzw
dp4 r0 .y , v0 .xyzw , cb0 [ 9 ] .xyzw
dp4 r0 .w , v0 .xyzw , cb0 [ 11 ] .xyzw
div r1 .xy , r0 .xyxx , r0 .wwww
mov o2 .xyw , r0 .xyxw
mad o0 .xy , r1 .xyxx , l ( 0.5 ,  - 0.5 ,  0 ,  0 ) , l ( 0.5 ,  0.5 ,  0 ,  0 )
dp4 o1 .x , v0 .xyzw , cb0 [ 4 ] .xyzw
dp4 o1 .y , v0 .xyzw , cb0 [ 5 ] .xyzw
dp4 o1 .z , v0 .xyzw , cb0 [ 6 ] .xyzw
dp4 o2 .z , v0 .xyzw , cb0 [ 10 ] .xyzw
ret

与fxc的反汇编结果完全一致。ps_5_0的测试也可以通过。

HLSL bytecode to GLSL编译器的第一步算是迈出了,接下去我会开始尝试一些GLSL VS/PS的生成工作。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值