yum-mirror/slang

Making it easier to work with shaders

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

Darren WihandiAdd full support for SPV_NV_shader_subgroup_partitioned (#7103)0476b57fa

master
4.1 KiB127 linesraw
1//TEST_CATEGORY(wave, compute)
2//TEST:COMPARE_COMPUTE_EX(filecheck-buffer=CHECK):-vk -compute -shaderobj -emit-spirv-directly
3//TEST:COMPARE_COMPUTE_EX(filecheck-buffer=CHECK):-vk -compute -shaderobj -emit-spirv-via-glsl
4//TEST:COMPARE_COMPUTE_EX(filecheck-buffer=CHECK):-cuda -compute  -shaderobj -xslang -DCUDA
5
6//TEST:COMPARE_COMPUTE_EX(filecheck-buffer=CHECK):-vk -compute -shaderobj -emit-spirv-directly -xslang -DUSE_GLSL_SYNTAX -allow-glsl
7
8//TEST_INPUT:ubuffer(data=[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], stride=4):out,name outputBuffer
9RWStructuredBuffer<uint> outputBuffer;
10
11#if defined(USE_GLSL_SYNTAX)
12#define __partitionedMin subgroupPartitionedMinNV
13#define __partitionedMax subgroupPartitionedMaxNV
14#else
15#define __partitionedMin WaveMultiMin
16#define __partitionedMax WaveMultiMax
17#endif
18
19
20static uint gMinResult = 0;
21static uint gMaxResult = 0;
22static uint gMinMaxValue = 0;
23
24__generic<T : __BuiltinArithmeticType>
25bool test1MinMax(uint4 mask)
26{
27    let minResult = T(gMinResult);
28    let maxResult = T(gMaxResult);
29    let minMaxValue = T(gMinMaxValue);
30
31    return true
32        & all(__partitionedMin(minMaxValue, mask) == minResult)
33        & all(__partitionedMax(minMaxValue, mask) == maxResult)
34        ;
35}
36
37__generic<T : __BuiltinArithmeticType, let N : int>
38bool testVMinMax(uint4 mask) {
39    typealias GVec = vector<T, N>;
40
41    let minResult = GVec(T(gMinResult));
42    let maxResult = GVec(T(gMaxResult));
43    let minMaxValue = GVec(T(gMinMaxValue));
44
45    return true
46        & all(__partitionedMin(minMaxValue, mask) == minResult)
47        & all(__partitionedMax(minMaxValue, mask) == maxResult)
48        ;
49}
50
51bool testMinMax(uint4 mask)
52{
53    return true
54        & test1MinMax<int>(mask)
55        & testVMinMax<int, 2>(mask)
56        & testVMinMax<int, 3>(mask)
57        & testVMinMax<int, 4>(mask)
58        & test1MinMax<uint>(mask)
59        & testVMinMax<uint, 2>(mask)
60        & testVMinMax<uint, 3>(mask)
61        & testVMinMax<uint, 4>(mask)
62        & test1MinMax<float>(mask)
63        & testVMinMax<float, 2>(mask)
64        & testVMinMax<float, 3>(mask)
65        & testVMinMax<float, 4>(mask)
66        & test1MinMax<double>(mask)
67        & testVMinMax<double, 2>(mask)
68        & testVMinMax<double, 3>(mask)
69        & testVMinMax<double, 4>(mask)
70
71#if !defined(CUDA)
72        & test1MinMax<int8_t>(mask)
73        & testVMinMax<int8_t, 2>(mask)
74        & testVMinMax<int8_t, 3>(mask)
75        & testVMinMax<int8_t, 4>(mask)
76        & test1MinMax<int16_t>(mask)
77        & testVMinMax<int16_t, 2>(mask)
78        & testVMinMax<int16_t, 3>(mask)
79        & testVMinMax<int16_t, 4>(mask)
80        & test1MinMax<int64_t>(mask)
81        & testVMinMax<int64_t, 2>(mask)
82        & testVMinMax<int64_t, 3>(mask)
83        & testVMinMax<int64_t, 4>(mask)
84        & test1MinMax<uint8_t>(mask)
85        & testVMinMax<uint8_t, 2>(mask)
86        & testVMinMax<uint8_t, 3>(mask)
87        & testVMinMax<uint8_t, 4>(mask)
88        & test1MinMax<uint16_t>(mask)
89        & testVMinMax<uint16_t, 2>(mask)
90        & testVMinMax<uint16_t, 3>(mask)
91        & testVMinMax<uint16_t, 4>(mask)
92        & test1MinMax<uint64_t>(mask)
93        & testVMinMax<uint64_t, 2>(mask)
94        & testVMinMax<uint64_t, 3>(mask)
95        & testVMinMax<uint64_t, 4>(mask)
96        & test1MinMax<half>(mask)
97        & testVMinMax<half, 2>(mask)
98        & testVMinMax<half, 3>(mask)
99        & testVMinMax<half, 4>(mask)
100#endif
101        ;
102}
103
104[numthreads(32, 1, 1)]
105[shader("compute")]
106void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID)
107{
108    uint index = dispatchThreadID.x;
109
110    // Split into two groups, first group has 15 invocations/lanes and second group has 17.
111    let isSecondGroup = index >= 15;
112    uint4 mask = isSecondGroup ? uint4(0xFFFF8000, 0, 0, 0) : uint4(0x0007FFF, 0, 0, 0);
113
114    // Set min value on one invocation on each partition/mask.
115    let isMinInvocation = (index == 0) || (index == 15);
116
117    gMinResult = isSecondGroup ? uint(2) : uint(0);
118    gMaxResult = isSecondGroup ? uint(3) : uint(1);
119    gMinMaxValue = isMinInvocation ? gMinResult : gMaxResult;
120
121    bool result = true
122            && testMinMax(mask)
123            ;
124
125    // CHECK-COUNT-32: 1
126    outputBuffer[index] = uint(result);
127}