HLSL中struct里面的变量在内存中的放置方式

 《Intro to d3d10》里面关于hlslstructure packing有这样一段描述

struct Light

{

    Light()

    {

        ZeroMemory(this, sizeof(Light));

    }

    D3DXVECTOR3 pos;

    float pad1;       // not used

    D3DXVECTOR3 dir;

    float pad2;       // not used

    D3DXCOLOR ambient;

    D3DXCOLOR diffuse;

    D3DXCOLOR specular;

    D3DXVECTOR3 att;

    float spotPow;

    float range;

};

The issue with the pad” variables is to make the C++ structure match the HLSL structure. In the HLSL, structure padding occurs so that elements are packed into 4D vectors, with the restriction that a single element cannot be split across two 4D vectors. Consider the following example:

struct S

{

    float3 pos;

    float3 dir;

};

If we have to pack the data into 4D vectors, you might think it is done like this:

vector 1: (pos.x, pos.y, pos.z, dir.x)

vector 2: (dir.y, dir.z, empty, empty)

However, this splits the element dir across two 4D vectors, which is not allowed — an element is not allowed to straddle a 4D vector boundary. Therefore, it has to be packed like this:

vector 1: (pos.x, pos.y, pos.z, empty)

vector 2: (dir.x, dir.y, dir.z, empty)

Thus, the pad” variables in our C++ structure are able to correspond to those empty slots in the padded HLSL structure (since C++ does not follow the same packing rules as HLSL).

    个人感觉with the restriction that a single element cannot be split across two 4D vectors这段的描述是不对的,至少是有歧义。经过几次测试,加之请教了一个大牛,基本确定的是:HLSL的结构体struct其实并不管你是一个变量还是几个变量,它就是按照一次放满一个float4的内存长度,多少变量都往一个float4里面塞,塞满了再接着塞下一个float4

    所以就要小心面对float3float2这样的变量,因为前面有变量的关系已经不能再塞到一个float4里面了,那么就要小心。要放几个填充变量,使得float2float3能够在新的一个float4里面重新开始放置。比如下面的例子:

struct S

{

 float3 pos;

 float3 normal;

}

    应该写为

struct S

{

 float3 pos;

float pad1;

 float3 normal;

float pad2;

}

    一个师兄介绍最好采用下面的方式:

struct S

{

 Float4 pos;

 Float4 normal;

}

    当然如果不想packing也可以,比如下面:

vector a: (pos.x, pos.y, pos.z, dir.x)

vector b: (dir.y, dir.z, empty, empty)存放的话,在hlsl你得float3 aa=a.xyz;float3 bb=float3(a.w,b.x,b.y)

 

    另外如果不想packing。根据大牛的介绍:hlsl编译的时候开了优化选项和不开packing也不一样,就是可以让hlslpacking,比如在d3d9里面得用Id3DXEffect::setRawValue传递进去,这个偶自己就没有测试过,很少使用Effect框架。

原文链接: https://www.cnblogs.com/bester/archive/2011/09/02/3255795.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

    HLSL中struct里面的变量在内存中的放置方式

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/31602

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月8日 上午8:54
下一篇 2023年2月8日 上午8:55

相关推荐