Directx 在HLSL中使用一个大缓冲区和所有相关数据,还是使用几个较小的缓冲区更好

Directx 在HLSL中使用一个大缓冲区和所有相关数据,还是使用几个较小的缓冲区更好,directx,shader,directx-11,hlsl,Directx,Shader,Directx 11,Hlsl,我对代码设计和性能方面都感兴趣,如果在HLSL或其他高级着色器语言中向GPU发送数据时使用单独的缓冲区更好 这就是特定着色器需要有大量可变数据的地方,这些数据在运行时会发生变化,因此需要通过缓冲区传递信息 我举一个非常基本的例子: cbuffer SomeLargeBuffer : register(cb0) { float3 data; float someData; float4 largeArray[2500]; float moreData; ..

我对代码设计和性能方面都感兴趣,如果在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)
{
    ...
    ...
    ...
}

在效率方面,委员会提出以下建议:

有效使用常量缓冲区的最佳方法是组织着色器 根据变量的更新频率将变量放入常量缓冲区。 这使得应用程序能够最小化所需的带宽 更新着色器常量。例如,着色器可能声明两个 常量缓冲区,并根据其属性组织每个缓冲区中的数据 更新频率:每个对象上需要更新的数据 基(类似于世界矩阵)被分组到一个常数缓冲区中,该缓冲区 可以为每个对象更新。这是独立于 描述场景的特征,因此更新的可能性要小得多 经常(当场景改变时)

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


就代码设计而言,很难说,尽管通常它自然符合更新模式的频率。

最初的Direct3D 10恒定缓冲区设计是,每次更改任何部分时,都会更新整个CB,因此,最好按更新频率对其进行组织,以避免反复上传相同的数据。使用Windows 8或更高版本上的DirectX 11.1以及支持的可选功能,您可以更高效地对效果系统进行部分常量缓冲区更新,从而更好地处理更大的“全局样式”CBs。