diff --git a/Makefile.am b/Makefile.am
index 5c2d4e085889984c931f8bbef8c305e2d8316ca0..b901ff6eac58fe41190248fba55fbe202b4c468b 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -231,6 +231,8 @@ vkd3d_shader_tests = \
 	tests/hlsl/vector-indexing-uniform.shader_test \
 	tests/hlsl/vector-indexing.shader_test \
 	tests/hlsl/vertex-shader-ops.shader_test \
+	tests/hlsl/wave-ops-float.shader_test \
+	tests/hlsl/wave-ops-uint.shader_test \
 	tests/hlsl/writemask-assignop-0.shader_test \
 	tests/hlsl/writemask-assignop-1.shader_test \
 	tests/hlsl/writemask-assignop-2.shader_test \
diff --git a/tests/hlsl/wave-ops-float.shader_test b/tests/hlsl/wave-ops-float.shader_test
new file mode 100644
index 0000000000000000000000000000000000000000..b858948436973faffff86db17b9b2ef47f1adcb3
--- /dev/null
+++ b/tests/hlsl/wave-ops-float.shader_test
@@ -0,0 +1,459 @@
+[require]
+shader model >= 6.0
+
+[uav 0]
+format r32g32b32a32 float
+size (buffer, 4)
+
+3.5 1.0 4.0 2.5
+3.5 1.0 4.0 2.5
+3.5 1.5 4.0 2.5
+3.5 1.0 4.5 2.5
+
+[uav 1]
+format r32g32b32a32 uint
+size (buffer, 8)
+
+0 0 0 0
+0 0 0 0
+0 0 0 0
+0 0 0 0
+0 0 0 0
+0 0 0 0
+0 0 0 0
+0 0 0 0
+
+[compute shader]
+RWBuffer<float4> u0;
+RWBuffer<uint4> u1;
+
+    [numthreads(4, 1, 1)]
+void main(uint id : SV_GroupIndex)
+{
+    bool4 b = WaveActiveAllEqual(u0[id]);
+    u1[id] = uint4(b.x, b.y, b.z, b.w);
+}
+
+[test]
+todo dispatch 4 1 1
+probe uav 1 (0) rgbaui (1, 0, 0, 1)
+probe uav 1 (1) rgbaui (1, 0, 0, 1)
+probe uav 1 (2) rgbaui (1, 0, 0, 1)
+probe uav 1 (3) rgbaui (1, 0, 0, 1)
+
+
+[compute shader]
+RWBuffer<float4> u0;
+RWBuffer<uint4> u1;
+
+    [numthreads(4, 1, 1)]
+void main(uint id : SV_GroupIndex)
+{
+    bool any = u0[id].y == 1.5f;
+    bool all = u0[id].x == 3.5f;
+    bool none = u0[id].z == 3.0f;
+    u1[id] = uint4(WaveActiveAnyTrue(any), WaveActiveAnyTrue(all), WaveActiveAnyTrue(none), 0);
+    u1[4 + id] = uint4(WaveActiveAllTrue(any), WaveActiveAllTrue(all), WaveActiveAllTrue(none), 0);
+}
+
+[test]
+todo dispatch 4 1 1
+probe uav 1 (0) rgbaui (1, 1, 0, 0)
+probe uav 1 (1) rgbaui (1, 1, 0, 0)
+probe uav 1 (2) rgbaui (1, 1, 0, 0)
+probe uav 1 (3) rgbaui (1, 1, 0, 0)
+probe uav 1 (4) rgbaui (0, 1, 0, 0)
+probe uav 1 (5) rgbaui (0, 1, 0, 0)
+probe uav 1 (6) rgbaui (0, 1, 0, 0)
+probe uav 1 (7) rgbaui (0, 1, 0, 0)
+
+
+[compute shader]
+RWBuffer<float4> u0;
+RWBuffer<uint4> u1;
+
+    [numthreads(4, 1, 1)]
+void main(uint id : SV_GroupIndex)
+{
+    bool b = u0[id].y < 1.5;
+    u1[id] = WaveActiveBallot(b);
+}
+
+[test]
+todo dispatch 4 1 1
+probe uav 1 (0) rgbaui (0xb, 0, 0, 0)
+
+
+[uav 1]
+format r32g32b32a32 float
+size (buffer, 8)
+
+0 0 0 0
+0 0 0 0
+0 0 0 0
+0 0 0 0
+0 0 0 0
+0 0 0 0
+0 0 0 0
+0 0 0 0
+
+[compute shader]
+RWBuffer<float4> u0;
+RWBuffer<float4> u1;
+
+    [numthreads(4, 1, 1)]
+void main(uint id : SV_GroupIndex)
+{
+    float4 f = u0[id] + u0[id ^ 1];
+    u1[id] = WaveReadLaneFirst(f);
+    u1[4 + id] = WaveReadLaneAt(f, 3);
+}
+
+[test]
+todo dispatch 4 1 1
+probe uav 1 (0) rgba (7.0, 2.0, 8.0, 5.0)
+probe uav 1 (1) rgba (7.0, 2.0, 8.0, 5.0)
+probe uav 1 (2) rgba (7.0, 2.0, 8.0, 5.0)
+probe uav 1 (3) rgba (7.0, 2.0, 8.0, 5.0)
+probe uav 1 (4) rgba (7.0, 2.5, 8.5, 5.0)
+probe uav 1 (5) rgba (7.0, 2.5, 8.5, 5.0)
+probe uav 1 (6) rgba (7.0, 2.5, 8.5, 5.0)
+probe uav 1 (7) rgba (7.0, 2.5, 8.5, 5.0)
+
+
+[compute shader]
+RWBuffer<float4> u0;
+RWBuffer<float4> u1;
+
+    [numthreads(4, 1, 1)]
+void main(uint id : SV_GroupIndex)
+{
+    u1[id] = WaveActiveSum(u0[id]);
+}
+
+[test]
+todo dispatch 4 1 1
+probe uav 1 (0) rgba (14.0, 4.5, 16.5, 10.0)
+probe uav 1 (1) rgba (14.0, 4.5, 16.5, 10.0)
+probe uav 1 (2) rgba (14.0, 4.5, 16.5, 10.0)
+probe uav 1 (3) rgba (14.0, 4.5, 16.5, 10.0)
+
+
+[compute shader]
+RWBuffer<float4> u0;
+RWBuffer<float4> u1;
+
+    [numthreads(4, 1, 1)]
+void main(uint id : SV_GroupIndex)
+{
+    u1[id] = WaveActiveProduct(u0[id]);
+}
+
+[test]
+todo dispatch 4 1 1
+probe uav 1 (0) rgba (150.0625, 1.5, 288.0, 39.0625)
+probe uav 1 (1) rgba (150.0625, 1.5, 288.0, 39.0625)
+probe uav 1 (2) rgba (150.0625, 1.5, 288.0, 39.0625)
+probe uav 1 (3) rgba (150.0625, 1.5, 288.0, 39.0625)
+
+
+[compute shader]
+RWBuffer<float4> u0;
+RWBuffer<float4> u1;
+
+    [numthreads(4, 1, 1)]
+void main(uint id : SV_GroupIndex)
+{
+    u1[id] = WaveActiveMin(u0[id]);
+}
+
+[test]
+todo dispatch 4 1 1
+probe uav 1 (0) rgba (3.5, 1.0, 4.0, 2.5)
+probe uav 1 (1) rgba (3.5, 1.0, 4.0, 2.5)
+probe uav 1 (2) rgba (3.5, 1.0, 4.0, 2.5)
+probe uav 1 (3) rgba (3.5, 1.0, 4.0, 2.5)
+
+
+[compute shader]
+RWBuffer<float4> u0;
+RWBuffer<float4> u1;
+
+    [numthreads(4, 1, 1)]
+void main(uint id : SV_GroupIndex)
+{
+    u1[id] = WaveActiveMax(u0[id]);
+}
+
+[test]
+todo dispatch 4 1 1
+probe uav 1 (0) rgba (3.5, 1.5, 4.5, 2.5)
+probe uav 1 (1) rgba (3.5, 1.5, 4.5, 2.5)
+probe uav 1 (2) rgba (3.5, 1.5, 4.5, 2.5)
+probe uav 1 (3) rgba (3.5, 1.5, 4.5, 2.5)
+
+
+[compute shader]
+RWBuffer<float4> u0;
+RWBuffer<float4> u1;
+
+    [numthreads(4, 1, 1)]
+void main(uint id : SV_GroupIndex)
+{
+    u1[id] = WavePrefixSum(u0[id]);
+}
+
+[test]
+todo dispatch 4 1 1
+probe uav 1 (0) rgba (0.0, 0.0, 0.0, 0.0)
+probe uav 1 (1) rgba (3.5, 1.0, 4.0, 2.5)
+probe uav 1 (2) rgba (7.0, 2.0, 8.0, 5.0)
+probe uav 1 (3) rgba (10.5, 3.5, 12.0, 7.5)
+
+
+[compute shader]
+RWBuffer<float4> u0;
+RWBuffer<float4> u1;
+
+    [numthreads(4, 1, 1)]
+void main(uint id : SV_GroupIndex)
+{
+    u1[id] = WavePrefixProduct(u0[id]);
+}
+
+[test]
+todo dispatch 4 1 1
+probe uav 1 (0) rgba (1.0, 1.0, 1.0, 1.0)
+probe uav 1 (1) rgba (3.5, 1.0, 4.0, 2.5)
+probe uav 1 (2) rgba (12.25, 1.0, 16.0, 6.25)
+probe uav 1 (3) rgba (42.875, 1.5, 64.0, 15.625)
+
+
+[uav 0]
+format r32g32b32a32 float
+size (buffer, 4)
+
+0.25 0.50 0.75 1.00
+0.50 0.25 1.00 0.75
+0.75 1.00 0.50 0.25
+1.00 0.75 0.25 0.50
+
+[compute shader]
+RWBuffer<float4> u0;
+RWBuffer<float4> u1;
+
+    [numthreads(4, 1, 1)]
+void main(uint id : SV_GroupIndex)
+{
+    uint i = WaveGetLaneIndex() % 4;
+    float4 f = u0[i];
+    u1[i] = QuadReadAcrossX(f);
+}
+
+[test]
+todo dispatch 4 1 1
+probe uav 1 (0) rgba (0.5, 0.25, 1.0, 0.75)
+probe uav 1 (1) rgba (0.25, 0.5, 0.75, 1.0)
+probe uav 1 (2) rgba (1.0, 0.75, 0.25, 0.5)
+probe uav 1 (3) rgba (0.75, 1.0, 0.5, 0.25)
+
+
+[compute shader]
+RWBuffer<float4> u0;
+RWBuffer<float4> u1;
+
+    [numthreads(4, 1, 1)]
+void main(uint id : SV_GroupIndex)
+{
+    uint i = WaveGetLaneIndex() % 4;
+    float4 f = u0[i];
+    // Constant lane id.
+    u1[i] = QuadReadLaneAt(f, 2);
+}
+
+[test]
+todo dispatch 4 1 1
+probe uav 1 (0) rgba (0.75, 1.0, 0.5, 0.25)
+probe uav 1 (1) rgba (0.75, 1.0, 0.5, 0.25)
+probe uav 1 (2) rgba (0.75, 1.0, 0.5, 0.25)
+probe uav 1 (3) rgba (0.75, 1.0, 0.5, 0.25)
+
+
+[pixel shader]
+RWBuffer<float4> u0;
+RWBuffer<float4> u1;
+
+float4 main(float4 pos : SV_Position) : SV_Target
+{
+    uint i = WaveGetLaneIndex() % 4;
+    float4 f = u0[i];
+    u1[i] = QuadReadAcrossX(f);
+    return f;
+}
+
+[test]
+todo draw quad
+probe rtv 0 (0, 0) rgba (0.25, 0.5, 0.75, 1.0)
+probe rtv 0 (1, 0) rgba (0.5, 0.25, 1.0, 0.75)
+probe rtv 0 (0, 1) rgba (0.75, 1.0, 0.5, 0.25)
+probe rtv 0 (1, 1) rgba (1.0, 0.75, 0.25, 0.5)
+probe uav 1 (0) rgba (0.5, 0.25, 1.0, 0.75)
+probe uav 1 (1) rgba (0.25, 0.5, 0.75, 1.0)
+probe uav 1 (2) rgba (1.0, 0.75, 0.25, 0.5)
+probe uav 1 (3) rgba (0.75, 1.0, 0.5, 0.25)
+
+
+[pixel shader]
+RWBuffer<float4> u0;
+RWBuffer<float4> u1;
+
+float4 main(float4 pos : SV_Position) : SV_Target
+{
+    uint i = WaveGetLaneIndex() % 4;
+    float4 f = u0[i];
+    u1[i] = QuadReadAcrossY(f);
+    return f;
+}
+
+[test]
+todo draw quad
+probe uav 1 (0) rgba (0.75, 1.0, 0.5, 0.25)
+probe uav 1 (1) rgba (1.0, 0.75, 0.25, 0.5)
+probe uav 1 (2) rgba (0.25, 0.5, 0.75, 1.0)
+probe uav 1 (3) rgba (0.5, 0.25, 1.0, 0.75)
+
+
+[pixel shader]
+RWBuffer<float4> u0;
+RWBuffer<float4> u1;
+
+float4 main(float4 pos : SV_Position) : SV_Target
+{
+    uint i = WaveGetLaneIndex() % 4;
+    float4 f = u0[i];
+    u1[i] = QuadReadAcrossDiagonal(f);
+    return f;
+}
+
+[test]
+todo draw quad
+probe uav 1 (0) rgba (1.0, 0.75, 0.25, 0.5)
+probe uav 1 (1) rgba (0.75, 1.0, 0.5, 0.25)
+probe uav 1 (2) rgba (0.5, 0.25, 1.0, 0.75)
+probe uav 1 (3) rgba (0.25, 0.5, 0.75, 1.0)
+
+
+% Values in helper lanes are undefined for all wave ops except the quad ops.
+[pixel shader]
+RWBuffer<float4> u0;
+RWBuffer<float4> u1;
+
+float4 main(float4 pos : SV_Position) : SV_Target
+{
+    uint i = WaveGetLaneIndex() % 4;
+    if (i >= 2)
+        discard;
+    float4 f = u0[i];
+    u1[i] = QuadReadAcrossDiagonal(f);
+    return float4(1.0, 0.0, 0.0, 1.0);
+}
+
+[test]
+todo draw quad
+probe rtv 0 (0, 0) rgba (1.0, 0.0, 0.0, 1.0)
+probe rtv 0 (1, 0) rgba (1.0, 0.0, 0.0, 1.0)
+probe rtv 0 (0, 1) rgba (0.75, 1.0, 0.5, 0.25)
+probe rtv 0 (1, 1) rgba (1.0, 0.75, 0.25, 0.5)
+probe uav 1 (0) rgba (1.0, 0.75, 0.25, 0.5)
+probe uav 1 (1) rgba (0.75, 1.0, 0.5, 0.25)
+probe uav 1 (2) rgba (0.5, 0.25, 1.0, 0.75)
+probe uav 1 (3) rgba (0.25, 0.5, 0.75, 1.0)
+
+
+[pixel shader]
+RWBuffer<float4> u0;
+RWBuffer<float4> u1;
+
+float4 main(float4 pos : SV_Position) : SV_Target
+{
+    uint i = WaveGetLaneIndex() % 4;
+    float4 f = u0[i];
+    // Constant lane id.
+    u1[i] = QuadReadLaneAt(f, 1);
+    return f;
+}
+
+[test]
+todo draw quad
+probe uav 1 (0) rgba (0.5, 0.25, 1.0, 0.75)
+probe uav 1 (1) rgba (0.5, 0.25, 1.0, 0.75)
+probe uav 1 (2) rgba (0.5, 0.25, 1.0, 0.75)
+probe uav 1 (3) rgba (0.5, 0.25, 1.0, 0.75)
+
+
+[pixel shader]
+uniform uint id;
+
+RWBuffer<float4> u0;
+RWBuffer<float4> u1;
+
+float4 main(float4 pos : SV_Position) : SV_Target
+{
+    uint i = WaveGetLaneIndex() % 4;
+    float4 f = u0[i];
+    // Uniform lane id.
+    u1[i] = QuadReadLaneAt(f, id);
+    return f;
+}
+
+[test]
+uniform 0 uint 0
+todo draw quad
+probe uav 1 (0) rgba (0.25, 0.5, 0.75, 1.0)
+probe uav 1 (1) rgba (0.25, 0.5, 0.75, 1.0)
+probe uav 1 (2) rgba (0.25, 0.5, 0.75, 1.0)
+probe uav 1 (3) rgba (0.25, 0.5, 0.75, 1.0)
+uniform 0 uint 1
+todo draw quad
+probe uav 1 (0) rgba (0.5, 0.25, 1.0, 0.75)
+probe uav 1 (1) rgba (0.5, 0.25, 1.0, 0.75)
+probe uav 1 (2) rgba (0.5, 0.25, 1.0, 0.75)
+probe uav 1 (3) rgba (0.5, 0.25, 1.0, 0.75)
+uniform 0 uint 2
+todo draw quad
+probe uav 1 (0) rgba (0.75, 1.0, 0.5, 0.25)
+probe uav 1 (1) rgba (0.75, 1.0, 0.5, 0.25)
+probe uav 1 (2) rgba (0.75, 1.0, 0.5, 0.25)
+probe uav 1 (3) rgba (0.75, 1.0, 0.5, 0.25)
+uniform 0 uint 3
+todo draw quad
+probe uav 1 (0) rgba (1.0, 0.75, 0.25, 0.5)
+probe uav 1 (1) rgba (1.0, 0.75, 0.25, 0.5)
+probe uav 1 (2) rgba (1.0, 0.75, 0.25, 0.5)
+probe uav 1 (3) rgba (1.0, 0.75, 0.25, 0.5)
+
+
+[pixel shader]
+RWBuffer<float4> u0;
+RWBuffer<float4> u1;
+
+float4 main(float4 pos : SV_Position) : SV_Target
+{
+    uint i = WaveGetLaneIndex() % 4;
+    if (!i)
+        discard;
+    float4 f = u0[i];
+    // Lane 1 is the first active.
+    u1[i] = WaveReadLaneFirst(f);
+    return float4(1.0, 0.0, 0.0, 1.0);
+}
+
+[test]
+todo draw quad
+probe rtv 0 (0, 0) rgba (0.25, 0.5, 0.75, 1.0)
+probe rtv 0 (1, 0) rgba (1.0, 0.0, 0.0, 1.0)
+probe rtv 0 (0, 1) rgba (1.0, 0.0, 0.0, 1.0)
+probe rtv 0 (1, 1) rgba (1.0, 0.0, 0.0, 1.0)
+probe uav 1 (1) rgba (0.5, 0.25, 1.0, 0.75)
+probe uav 1 (2) rgba (0.5, 0.25, 1.0, 0.75)
+probe uav 1 (3) rgba (0.5, 0.25, 1.0, 0.75)
diff --git a/tests/hlsl/wave-ops-int.shader_test b/tests/hlsl/wave-ops-int.shader_test
new file mode 100644
index 0000000000000000000000000000000000000000..e3a44621f417d85666213fb40190c489d55f78bf
--- /dev/null
+++ b/tests/hlsl/wave-ops-int.shader_test
@@ -0,0 +1,55 @@
+[require]
+shader model >= 6.0
+
+[uav 0]
+format r32g32b32a32 sint
+size (buffer, 4)
+
+-3 1 -4 2
+ 3 1 -4 2
+ 0 5 -3 2
+-1 1 -1 2
+
+[uav 1]
+format r32g32b32a32 sint
+size (buffer, 4)
+
+0 0 0 0
+0 0 0 0
+0 0 0 0
+0 0 0 0
+
+[compute shader]
+RWBuffer<int4> u0;
+RWBuffer<int4> u1;
+
+    [numthreads(4, 1, 1)]
+void main(uint id : SV_GroupIndex)
+{
+    u1[id] = WaveActiveMin(u0[id]);
+}
+
+[test]
+todo dispatch 4 1 1
+probe uav 1 (0) rgbai (-3, 1, -4, 2)
+probe uav 1 (1) rgbai (-3, 1, -4, 2)
+probe uav 1 (2) rgbai (-3, 1, -4, 2)
+probe uav 1 (3) rgbai (-3, 1, -4, 2)
+
+
+[compute shader]
+RWBuffer<int4> u0;
+RWBuffer<int4> u1;
+
+    [numthreads(4, 1, 1)]
+void main(uint id : SV_GroupIndex)
+{
+    u1[id] = WaveActiveMax(u0[id]);
+}
+
+[test]
+todo dispatch 4 1 1
+probe uav 1 (0) rgbai (3, 5, -1, 2)
+probe uav 1 (1) rgbai (3, 5, -1, 2)
+probe uav 1 (2) rgbai (3, 5, -1, 2)
+probe uav 1 (3) rgbai (3, 5, -1, 2)
diff --git a/tests/hlsl/wave-ops-uint.shader_test b/tests/hlsl/wave-ops-uint.shader_test
new file mode 100644
index 0000000000000000000000000000000000000000..c04b3951aa26cc919b2540ae33f07f1857e34984
--- /dev/null
+++ b/tests/hlsl/wave-ops-uint.shader_test
@@ -0,0 +1,304 @@
+[require]
+shader model >= 6.0
+
+[uav 0]
+format r32 uint
+size (buffer, 4)
+
+8 15 8 10
+
+[uav 1]
+format r32 uint
+size (buffer, 8)
+
+0 0 0 0 0 0 0 0
+
+[compute shader]
+RWBuffer<uint> u1 : register(u1);
+
+    [numthreads(4, 1, 1)]
+void main(uint id : SV_GroupIndex)
+{
+    u1[id] = WaveIsFirstLane();
+}
+
+[test]
+todo dispatch 4 1 1
+probe uav 1 (0) rui (1)
+probe uav 1 (1) rui (0)
+probe uav 1 (2) rui (0)
+probe uav 1 (3) rui (0)
+
+
+[compute shader]
+RWBuffer<uint> u1 : register(u1);
+
+    [numthreads(4, 1, 1)]
+void main(uint id : SV_GroupIndex)
+{
+    if (!id)
+    {
+        u1[0] = 0;
+        return;
+    }
+    u1[id] = WaveIsFirstLane();
+}
+
+[test]
+todo dispatch 4 1 1
+probe uav 1 (0) rui (0)
+probe uav 1 (1) rui (1)
+probe uav 1 (2) rui (0)
+probe uav 1 (3) rui (0)
+
+
+[compute shader]
+RWBuffer<uint> u1 : register(u1);
+
+    [numthreads(4, 1, 1)]
+void main(uint id : SV_GroupIndex)
+{
+    u1[id] = WaveGetLaneIndex();
+}
+
+[test]
+todo dispatch 4 1 1
+probe uav 1 (0) rui (0)
+probe uav 1 (1) rui (1)
+probe uav 1 (2) rui (2)
+probe uav 1 (3) rui (3)
+
+
+[compute shader]
+RWBuffer<uint> u1 : register(u1);
+
+    [numthreads(4, 1, 1)]
+void main(uint id : SV_GroupIndex)
+{
+    // Between 4 and 128, and includes inactive and/or helper lanes.
+    uint count = WaveGetLaneCount();
+    u1[id] = count >= 4 && count <= 128;
+}
+
+[test]
+todo dispatch 4 1 1
+probe uav 1 (0) rui (1)
+probe uav 1 (1) rui (1)
+probe uav 1 (2) rui (1)
+probe uav 1 (3) rui (1)
+
+
+[compute shader]
+RWBuffer<uint> u0;
+RWBuffer<uint> u1;
+
+    [numthreads(4, 1, 1)]
+void main(uint id : SV_GroupIndex)
+{
+    uint i = (id & 1) ? -u0[id] : u0[id];
+    u1[id] = WaveActiveMin(i);
+}
+
+[test]
+todo dispatch 4 1 1
+probe uav 1 (0) rui (8)
+probe uav 1 (1) rui (8)
+probe uav 1 (2) rui (8)
+probe uav 1 (3) rui (8)
+
+
+[compute shader]
+RWBuffer<uint> u0;
+RWBuffer<uint> u1;
+
+    [numthreads(4, 1, 1)]
+void main(uint id : SV_GroupIndex)
+{
+    bool b = u0[id] == 8;
+    u1[id] = WaveActiveBallot(b).x;
+}
+
+[test]
+todo dispatch 4 1 1
+probe uav 1 (0) rui (5)
+probe uav 1 (1) rui (5)
+probe uav 1 (2) rui (5)
+probe uav 1 (3) rui (5)
+
+
+[compute shader]
+RWBuffer<uint> u0;
+RWBuffer<uint> u1;
+
+    [numthreads(4, 1, 1)]
+void main(uint id : SV_GroupIndex)
+{
+    uint i = u0[id] + u0[id ^ 1];
+    u1[id] = WaveReadLaneFirst(i);
+}
+
+[test]
+todo dispatch 4 1 1
+probe uav 1 (0) rui (23)
+probe uav 1 (1) rui (23)
+probe uav 1 (2) rui (23)
+probe uav 1 (3) rui (23)
+
+
+[compute shader]
+RWBuffer<uint> u0;
+RWBuffer<uint> u1;
+
+    [numthreads(4, 1, 1)]
+void main(uint id : SV_GroupIndex)
+{
+    uint i = u0[id] + u0[id ^ 1];
+    u1[id] = WaveReadLaneAt(i, 3);
+}
+
+[test]
+todo dispatch 4 1 1
+probe uav 1 (0) rui (18)
+probe uav 1 (1) rui (18)
+probe uav 1 (2) rui (18)
+probe uav 1 (3) rui (18)
+
+
+[compute shader]
+RWBuffer<uint> u0;
+RWBuffer<uint> u1;
+
+    [numthreads(4, 1, 1)]
+void main(uint id : SV_GroupIndex)
+{
+    bool b = u0[id] == 8;
+    u1[id] = WaveActiveCountBits(b);
+}
+
+[test]
+todo dispatch 4 1 1
+probe uav 1 (0) rui (2)
+probe uav 1 (1) rui (2)
+probe uav 1 (2) rui (2)
+probe uav 1 (3) rui (2)
+
+
+[compute shader]
+RWBuffer<uint> u0;
+RWBuffer<uint> u1;
+
+    [numthreads(4, 1, 1)]
+void main(uint id : SV_GroupIndex)
+{
+    bool b = u0[id] == 8;
+    u1[id] = WavePrefixCountBits(b);
+}
+
+[test]
+todo dispatch 4 1 1
+probe uav 1 (0) rui (0)
+probe uav 1 (1) rui (1)
+probe uav 1 (2) rui (1)
+probe uav 1 (3) rui (2)
+
+
+[compute shader]
+RWBuffer<uint> u0;
+RWBuffer<uint> u1;
+
+    [numthreads(4, 1, 1)]
+void main(uint id : SV_GroupIndex)
+{
+    u1[id] = WaveActiveSum(u0[id]);
+}
+
+[test]
+todo dispatch 4 1 1
+probe uav 1 (0) rui (41)
+probe uav 1 (1) rui (41)
+probe uav 1 (2) rui (41)
+probe uav 1 (3) rui (41)
+
+
+[compute shader]
+RWBuffer<uint> u0;
+RWBuffer<uint> u1;
+
+    [numthreads(4, 1, 1)]
+void main(uint id : SV_GroupIndex)
+{
+    u1[id] = WaveActiveBitAnd(u0[id]);
+}
+
+[test]
+todo dispatch 4 1 1
+probe uav 1 (0) rui (8)
+probe uav 1 (1) rui (8)
+probe uav 1 (2) rui (8)
+probe uav 1 (3) rui (8)
+
+
+[compute shader]
+RWBuffer<uint> u0;
+RWBuffer<uint> u1;
+
+    [numthreads(4, 1, 1)]
+void main(uint id : SV_GroupIndex)
+{
+    u1[id] = WaveActiveBitOr(u0[id]);
+}
+
+[test]
+todo dispatch 4 1 1
+probe uav 1 (0) rui (15)
+probe uav 1 (1) rui (15)
+probe uav 1 (2) rui (15)
+probe uav 1 (3) rui (15)
+
+
+[compute shader]
+RWBuffer<uint> u0;
+RWBuffer<uint> u1;
+
+    [numthreads(4, 1, 1)]
+void main(uint id : SV_GroupIndex)
+{
+    u1[id] = WaveActiveBitXor(u0[id]);
+}
+
+[test]
+todo dispatch 4 1 1
+probe uav 1 (0) rui (5)
+probe uav 1 (1) rui (5)
+probe uav 1 (2) rui (5)
+probe uav 1 (3) rui (5)
+
+
+[compute shader]
+uniform uint2 u;
+
+RWBuffer<uint> u0;
+RWBuffer<uint> u1;
+
+    [numthreads(4, 1, 1)]
+void main(uint id : SV_GroupIndex)
+{
+    uint table[] = {u.x, u.y};
+    uint i;
+
+    // Value depends on control flow.
+    if (id & 1)
+        i = table[id / 2u];
+    else
+        i = u0[id / 2u];
+
+    u1[id] = WaveActiveSum(i);
+}
+
+[test]
+uniform 0 uint4 1 5 0 0
+todo dispatch 4 1 1
+probe uav 1 (0) rui (29)
+probe uav 1 (1) rui (29)
+probe uav 1 (2) rui (29)
+probe uav 1 (3) rui (29)