yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
8e6af6259
master
layout: user-guide
Uniformity Analysis
On certain hardware, accessing resources with a non-uniform index may lead to significant performance degradation. Developers can often benefit from a compiler warning for unintentional non-uniform resource access.
Starting from v2024.1.0, Slang provides uniformity analysis that can warn users if a non-dynamically-uniform value is being used unintentionally. This feature is not enabled by default but can be turned on with the -validate-uniformity command-line option when using slangc, or the CompilerOptionName::ValidateUniformity compiler option when using the API.
In addition to specifying the compiler option, the source code must be augmented with the dynamic_uniform modifier to mark function parameters, struct fields or local variables as expecting a dynamic uniform value.
For example, the following code will trigger a warning:
// Indicate that the `v` parameter needs to be dynamic uniform. float f ( dynamic_uniform float v) { return v + 1.0 ; } [ numthread ( 1 , 1 , 1 )] [ shader ( "compute" )] void main ( int tid : SV_DispatchThreadID) { f ( tid ); // warning: tid is not dynamically uniform. }
Currently, the analysis is being conservative for struct typed values, in that if any member of the struct is known to be non-uniform, the entire composite is
treated as non-uniform:
struct MyType { int a ; int b ; } void expectUniform ( dynamic_uniform int a){} void main ( int tid : SV_DispatchThreadID) { MyType t ; t . a = tid ; t . b = 0 ; // Generates a warning here despite t.b is non-uniform, because // t.a is non-uniform and that assignment makes `t` non-uniform. expectUniform ( t . b ); }
To allow the compiler to provide more accurate analysis, you can use mark struct fields as
dynamic_uniform:
struct MyType { int a ; dynamic_uniform int b; } void expectUniform ( dynamic_uniform int a){} void main ( int tid : SV_DispatchThreadID) { MyType t ; t . a = tid ; t . b = 0 ; // OK, because MyType::b is marked as dynamic_uniform. expectUniform ( t . b ); // Warning: trying to assign non-uniform value to dynamic_uniform location. t . b = tid ; }
Treat Values as Uniform
In some cases, the compiler might not be able to deduce a value to be non-uniform. If you are certain that a value can
be treated as dynamic uniform, you can call asDynamicUniform() function to force the compiler to treat the value as
dynamic uniform. For example:
void main ( int tid : SV_DispatchThreadID) { expectUniform ( asDynamicUniform ( tid )); // OK. }
Treat Function Return Values as Non-uniform
The uniformity analysis will automatically propagate uniformity to function return values. However, if you have
an intrinsic function that does not have a body, or you simply wish the return value of a function to be always
treated as non-uniform, you can mark the function with the [NonUniformReturn] attribute:
[ NonUniformReturn ] int f () { return 0 ; } void expectUniform ( dynamic_uniform int x) {} void main () { expectUniform ( f ()); // Warning. }
1--- 2layout : user-guide 3--- 4 5Uniformity Analysis 6=========== 7 8On certain hardware, accessing resources with a non-uniform index may lead to significant performance degradation. Developers can often benefit from a compiler warning for unintentional non-uniform resource access. 9 10Starting from v2024.1.0, Slang provides uniformity analysis that can warn users if a non-dynamically-uniform value is being used unintentionally. This feature is not enabled by default but can be turned on with the `-validate-uniformity` command-line option when using `slangc`, or the `CompilerOptionName::ValidateUniformity` compiler option when using the API. 11 12In addition to specifying the compiler option, the source code must be augmented with the `dynamic_uniform` modifier to mark function parameters, struct fields or local variables as expecting a dynamic uniform value. 13 14For example, the following code will trigger a warning: 15``` csharp 16// Indicate that the `v` parameter needs to be dynamic uniform. 17float f(dynamic_uniform float v) 18{ 19return v + 1.0; 20} 21 22[numthread(1,1,1)] 23[shader("compute")] 24void main(int tid : SV_DispatchThreadID) 25{ 26f(tid); // warning: tid is not dynamically uniform. 27} 28``` 29 30Currently, the analysis is being conservative for `struct` typed values, in that if any member of the `struct` is known to be non-uniform, the entire composite is 31treated as non-uniform: 32``` csharp 33struct MyType 34{ 35int a; 36int b; 37} 38 39void expectUniform(dynamic_uniform int a){} 40 41void main(int tid : SV_DispatchThreadID) 42{ 43MyType t; 44t.a = tid; 45t.b = 0; 46 47// Generates a warning here despite t.b is non-uniform, because 48// t.a is non-uniform and that assignment makes `t` non-uniform. 49expectUniform(t.b); 50} 51``` 52 53To allow the compiler to provide more accurate analysis, you can use mark struct fields as 54`dynamic_uniform`: 55 56``` csharp 57struct MyType 58{ 59int a; 60dynamic_uniform int b; 61} 62 63void expectUniform(dynamic_uniform int a){} 64 65void main(int tid : SV_DispatchThreadID) 66{ 67MyType t; 68t.a = tid; 69t.b = 0; 70 71// OK, because MyType::b is marked as dynamic_uniform. 72expectUniform(t.b); 73 74// Warning: trying to assign non-uniform value to dynamic_uniform location. 75t.b = tid; 76} 77``` 78 79## Treat Values as Uniform 80 81In some cases, the compiler might not be able to deduce a value to be non-uniform. If you are certain that a value can 82be treated as dynamic uniform, you can call `asDynamicUniform()` function to force the compiler to treat the value as 83dynamic uniform. For example: 84``` csharp 85void main(int tid: SV_DispatchThreadID) 86{ 87expectUniform(asDynamicUniform(tid)); // OK. 88} 89``` 90 91## Treat Function Return Values as Non-uniform 92 93The uniformity analysis will automatically propagate uniformity to function return values. However, if you have 94an intrinsic function that does not have a body, or you simply wish the return value of a function to be always 95treated as non-uniform, you can mark the function with the `[NonUniformReturn]` attribute: 96``` csharp 97[NonUniformReturn] 98int f() { return 0; } 99void expectUniform(dynamic_uniform int x) {} 100void main() 101{ 102expectUniform(f()); // Warning. 103} 104```