yum-mirror/slang

Making it easier to work with shaders

git clone https://git.yummers.dev/yum-mirror/slang

Gangzheng TongFix user-guide typos (#6789)8e6af6259

master
3.1 KiB104 linesraw

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{
19    return v + 1.0;
20}
21
22[numthread(1,1,1)]
23[shader("compute")]
24void main(int tid : SV_DispatchThreadID)
25{
26    f(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{
35    int a;
36    int b;
37}
38
39void expectUniform(dynamic_uniform int a){}
40
41void main(int tid : SV_DispatchThreadID)
42{
43    MyType t;
44    t.a = tid;
45    t.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.
49    expectUniform(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{
59    int a;
60    dynamic_uniform int b;
61}
62
63void expectUniform(dynamic_uniform int a){}
64
65void main(int tid : SV_DispatchThreadID)
66{
67    MyType t;
68    t.a = tid;
69    t.b = 0;
70
71    // OK, because MyType::b is marked as dynamic_uniform.
72    expectUniform(t.b);
73
74    // Warning: trying to assign non-uniform value to dynamic_uniform location.
75    t.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{
87    expectUniform(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{
102    expectUniform(f()); // Warning.
103}
104```