函数在调用时执行计算工作;
函数以以下方式被调用:
表达式调用; (有返回值)
函数语句; (无返回值)
入口点函数;
函数有两类:
内置函数;
用户自定义函数;
函数声明通过以下方式创建用户自定义函数:
An optional set of attributes.
The name of the function.
The formal parameter list: an ordered sequence of zero or more formal parameter declarations, which may have attributes applied, separated by commas, and surrounded by parentheses.
An optional return type, which may have attributes applied.
The function body. This is the set of statements to be executed when the function is called.
代码示例:
// Declare the add_two function.
// It has two formal parameters, i and b.
// It has a return type of i32.
// It has a body with a return statement.
fn add_two(i: i32, b: f32) -> i32 {
return i + 2; // A formal parameter is available for use in the body.
}
// A compute shader entry point function, 'main'.
// It has no specified return type.
// It invokes the add_two function, and captures
// the resulting value in the named value 'six'.
@compute @workgroup_size(1)
fn main() {
let six: i32 = add_two(4, 5.0);
}
函数的限制:
顶点着色器必须返回内建位置输出值;
入口点函数不要被其它地方调用;
如果函数有返回值,值的类型必须是可构造的;
函数参数必须是以下类型:
a constructible type
a pointer type
a texture type
a sampler type
每个函数调用实参的计算结果必须是对应函数形参的类型
用户自定义函数指针参数必须是以下地址空间:
function;
private;
内建函数指针参数地址空间必须是以下类型:
function;
private;
workgroup;
storage;
有效或者无效的函数指针类型
fn bar(p : ptr<function, f32>) {
}
fn baz(p : ptr<private, i32>) {
}
fn bar2(p : ptr<function, f32>) {
let a = &*&*(p);
bar(p); // Valid
bar(a); // Valid
}
struct S {
x : i32
}
var usable_priv : i32;
var unusable_priv : array<i32, 4>;
fn foo() {
var usable_func : f32;
var unusable_func : S;
let a_priv = &usable_priv;
let b_priv = a_priv;
let c_priv = &*&usable_priv;
let d_priv = &(unusable_priv.x);
let e_priv = d_priv;
let a_func = &usable_func;
let b_func = &unusable_func;
let c_func = &(*b_func)[0];
let d_func = c_func;
let e_func = &*a_func;
baz(&usable_priv); // Valid, address-of a variable.
baz(a_priv); // Valid, effectively address-of a variable.
baz(b_priv); // Valid, effectively address-of a variable.
baz(c_priv); // Valid, effectively address-of a variable.
baz(d_priv); // Invalid, memory view has changed.
baz(e_priv); // Invalid, memory view has changed.
bar(&usable_func); // Valid, address-of a variable.
bar(c_func); // Invalid, memory view has changed.
bar(d_func); // Invalid, memory view has changed.
bar(e_func); // Valid, effectively address-of a variable.
}