-
Notifications
You must be signed in to change notification settings - Fork 329
Description
When generating the ParameterRequiredToBeUniform
and ParameterRequiredToBeUniformForReturnValue
tags for function parameters that are pointers, the analysis needs to distinguish between requiring the pointer to be uniform vs requiring the contents of the pointer to be uniform.
Example WGSL:
@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
fn bar(p : ptr<function, i32>) {
if (*p == 0) {
workgroupBarrier();
}
}
fn foo() {
var v = non_uniform;
bar(&v);
}
The analysis for bar will tag the parameter p
as ParameterRequiredToBeUniform
. When analyzing the callsite of bar
, it sees that the pointer value of the argument &v
is uniform (using the latest spec changes in #3586), and so no uniformity violation is detected. In this case, unlike the pointer argument to workgroupUniformLoad
, the requirement is on the contents of the pointer argument.
A similar example can be constructed for ParameterRequiredToBeUniformForReturnValue
:
@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
fn bar(p : ptr<function, i32>) -> i32 {
return *p;
}
fn foo() {
var v = non_uniform;
let ret = bar(&v);
if (ret == 0) {
workgroupBarrier();
}
}
This also applies to the relationship between different parameters: if pointer parameter a
is required to be uniform for the contents of pointer parameter b
to be considered uniform at function exit, we need to know whether this requirement is on the value of the pointer or its contents. Example:
@group(0) @binding(0) var<storage, read_write> non_uniform : i32;
fn bar(p : ptr<function, i32>, ret : ptr<function, i32>) {
*ret = *p;
}
fn foo() {
var v = non_uniform;
var ret : i32;
let ret = bar(&v, &ret);
if (ret == 0) {
workgroupBarrier();
}
}
CC @alan-baker