Shader的功能参数性能

Hei*_*bug 6 opengl directx shader glsl hlsl

我试图了解如何在着色器语言中实现传递参数.

我已经阅读了几篇文章和文档,但我仍然有些疑惑.特别是我试图理解C++函数调用的差异,特别强调性能.

HSLS,Cg和之间略有差异,GLSL但我想下划线的实现非常相似.

到目前为止我所理解的:

  • 除非另有说明,否则函数参数总是按值传递(即使矩阵也是如此?)
  • 在这种情况下,通过价值传递与其具有不同的含义C++.不支持递归,因此不使用堆栈,并且大多数函数都是内联的,并且参数直接放入寄存器中.
  • 函数通常由default(HLSL)内联,或者至少内联关键字始终受编译器(Cg)的尊重

上面的考虑是对的吗?

现在2具体问题:

1)传递矩阵作为函数参数

inline float4 DoSomething(in Mat4x4 mat, in float3 vec)
{
  ...
} 
Run Code Online (Sandbox Code Playgroud)

考虑到上面的功能,C++这将是令人讨厌的,并且肯定会更好地使用引用:const Mat4x4&.

着色器怎么样?这是一个糟糕的方法吗?我读过,例如,inout限定符可用于通过引用传递矩阵,但实际上它暗示了被调用函数修改的矩阵.

2)数量(和参数类型)是否有任何含义?例如,更好地使用具有有限参数集的函数?或者避免传递矩阵?是inout修改在这里提高性能的有效方法是什么?如果是这样,任何人都知道典型的编译器如何实现它?

3)是否有任何区别HLSLGLSL说明吗?有人有这方面的提示吗?

Ret*_*adi 6

根据规范,始终复制值。对于in参数,在调用时复制out参数,在返回时复制inout参数,在调用和返回时复制参数。

用规范的语言(GLSL 4.50,第6.1.1节“函数调用约定”):

所有参数在调用时均按从左到右的顺序进行一次评估。输入参数的求值结果将被复制到形式参数中。评估out参数会产生一个l值,该l值用于在函数返回时复制出一个值。评估inout参数会同时产生一个值和一个l值;该值在调用时被复制到形式参数中,而左值用于在函数返回时复制出一个值。

一个实现当然可以自由地优化它想要的任何东西,只要结果与记录的行为相同即可。但是我不认为您可以期望它以任何指定的方式工作。

例如,inout通过引用传递所有参数将不会被保存。假设您有以下代码:

vec4 Foo(inout mat4 mat1, inout mat4 mat2) {
    mat1 = mat4(0.0);
    mat2 = mat4(1.0);
    return mat1 * vec4(1.0);
}

mat4 myMat;
vec4 res = Foo(myMat, myMat);
Run Code Online (Sandbox Code Playgroud)

正确的结果是包含所有0.0成分的向量。如果参数是按引用传递,mat1而且mat2里面Foo()会别名相同的矩阵。这意味着to的赋值mat2也会更改的值mat1,并且结果是一个包含所有1.0分量的向量。哪有错

这当然是一个非常人为的示例,但是优化必须是选择性的,以便在所有情况下都能正常工作。