在HLSL中使用一个包含所有相关数据或几个较小缓冲区的大缓冲区更好

时间:2017-03-05 23:33:09

标签: directx shader directx-11 hlsl

如果在使用HLSL或其他高级着色器语言将数据发送到GPU时具有单独的缓冲区,我对代码设计和性能方面感兴趣。

这是特定着色器需要有大量可变数据的地方,这些数据在运行时会发生变化,因此需要缓冲区传递信息。

我举了一个非常基本的例子:

cbuffer SomeLargeBuffer : register(cb0)
{
    float3 data;
    float someData;
    float4 largeArray[2500];
    float moreData;
    ...
    ...
    ... 
    ...
    ...
}

或拥有

cbuffer SamllerBuffer: register(cb0)
{
    float3 data;
    float someRelatedData;

}

cbuffer SecondSmallerBuffer : register(cb1)
{

    float4 largeArray[2500];
    float moreData;

}

cbuffer ThirdBuffer: register(cb2)
{
    ...
    ...
    ...
}

1 个答案:

答案 0 :(得分:5)

就效率而言,documentation on shader constants in HLSL给出了以下建议:

  

有效使用常量缓冲区的最佳方法是组织着色器   变量根据其更新频率变为常量缓冲区。   这允许应用程序最小化所需的带宽   更新着色器常量。例如,着色器可能会声明两个   持续缓冲并根据它们组织每个数据   更新频率:需要在每个对象上更新的数据   基础(如世界矩阵)被分组为一个常量缓冲区   可以为每个对象更新。这与数据分开   表征场景,因此可能更新更少   经常(当场景改变时)。

因此,如果您以不同的速率更新数据,最好将在同一频率下更新的所有数据分组到相同的常量缓冲区中。通常,数据要么更新a)每一帧,b)零星地或c)从不(一次启动时)。减少总常量缓冲区的数量也有助于提高性能,因为它会减少绑定调用的次数和所需的资源跟踪。

在代码设计方面,很难说,虽然它通常很适合更新频率模式。

相关问题