contant buffer中的packoffset
“在DirectX10中不使用Effect框架处理Shader与程序间的数据传递”中,有些cbuffer中的变量定义后带有packoffset(c#)。这里简单介绍一下这个packoffset。
通过使用packoffset 可以指定变量存储在constant buffer中的特定位置。
在hlsl中,默认是按float4来对齐数据的。例如两个float2,实际上就是一个float4,四字对齐。一个寄存器就表示一个float4,如c0,float4中的元素可以通过c0.x,c0.xyz这样的方法来使用。
具体来看"HLSLWithoutFX10 Sample"中的例子,在C++文件中有如下结构定义,这个结构用于给constant buffer填充数据:
{
D3DXMATRIX mWorldViewProj;
//mWorldViewProj will probably be global to all shaders in a project.
//It's a good idea not to move it around between shaders.
D3DXVECTOR4 vSomeVectorThatMayBeNeededByASpecificShader;
float fSomeFloatThatMayBeNeededByASpecificShader;
float fTime;
//fTime may also be global to all shaders in a project.
float fSomeFloatThatMayBeNeededByASpecificShader2;
float fSomeFloatThatMayBeNeededByASpecificShader3;
};
在HLSL中:
{
row_major float4x4 mWorldViewProj : packoffset(c0);
// World * View * Projection transformation
float fTime : packoffset(c5.y);
// Time parameter. This keeps increasing
// Notice, that this parameter is placed in c5.y.
// If it were packed by the default packing rules,
// it would be placed in c4.x
};
对比一下加上注释就很明白了。
在cb0中,第一个mWorldViewProj:packoffset(c0)表示将会在这个cbuffer中的c0位置开始存储mWorldViewProj,共使用c0,c1,c2,c3。
第二个fTime在默认情况下应该是存放于c4.x中,但是这里写的是c5.y?
看VS_CONSTANT_BUFFER:
D3DXMATRIX mWorldViewProj
D3DXVECTOR4 vSomeVectorThatMayBeNeededByASpecificShader
float fSomeFloatThatMayBeNeededByASpecificShader
float fTime
发现在fTime前有一个D3DXVECTOR4与float。关键就在这里,D3DXVECTOR4占据了c4,float占据了c5.x,所以fTime就是c5.y了。
另可以参考DirectX sdk中的“Packing Rules for Constant Variables”。