xref: /aosp_15_r20/external/deqp/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsScanHelpers.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2019 The Khronos Group Inc.
6  * Copyright (c) 2019 Google Inc.
7  * Copyright (c) 2017 Codeplay Software Ltd.
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  */ /*!
22  * \file
23  * \brief Subgroups Tests
24  */ /*--------------------------------------------------------------------*/
25 
26 #include "vktSubgroupsScanHelpers.hpp"
27 #include "vktSubgroupsTestsUtils.hpp"
28 
29 #include <string>
30 #include <vector>
31 
32 using namespace tcu;
33 using namespace std;
34 using namespace vk;
35 using namespace vkt;
36 
getScanOpName(string prefix,string suffix,Operator op,ScanType scanType)37 string getScanOpName(string prefix, string suffix, Operator op, ScanType scanType)
38 {
39     string n;
40     switch (scanType)
41     {
42     case SCAN_REDUCE:
43         n = "";
44         break;
45     case SCAN_INCLUSIVE:
46         n = "Inclusive";
47         break;
48     case SCAN_EXCLUSIVE:
49         n = "Exclusive";
50         break;
51     }
52     switch (op)
53     {
54     case OPERATOR_ADD:
55         n += "Add";
56         break;
57     case OPERATOR_MUL:
58         n += "Mul";
59         break;
60     case OPERATOR_MIN:
61         n += "Min";
62         break;
63     case OPERATOR_MAX:
64         n += "Max";
65         break;
66     case OPERATOR_AND:
67         n += "And";
68         break;
69     case OPERATOR_OR:
70         n += "Or";
71         break;
72     case OPERATOR_XOR:
73         n += "Xor";
74         break;
75     }
76     return prefix + n + suffix;
77 }
78 
getOpOperation(Operator op,VkFormat format,string lhs,string rhs)79 string getOpOperation(Operator op, VkFormat format, string lhs, string rhs)
80 {
81     switch (op)
82     {
83     default:
84         DE_FATAL("Unsupported op type");
85         return "";
86     case OPERATOR_ADD:
87         return lhs + " + " + rhs;
88     case OPERATOR_MUL:
89         return lhs + " * " + rhs;
90     case OPERATOR_MIN:
91         switch (format)
92         {
93         default:
94             return "min(" + lhs + ", " + rhs + ")";
95         case VK_FORMAT_R16_SFLOAT:
96         case VK_FORMAT_R32_SFLOAT:
97         case VK_FORMAT_R64_SFLOAT:
98             return "(isnan(" + lhs + ") ? " + rhs + " : (isnan(" + rhs + ") ? " + lhs + " : min(" + lhs + ", " + rhs +
99                    ")))";
100         case VK_FORMAT_R16G16_SFLOAT:
101         case VK_FORMAT_R16G16B16_SFLOAT:
102         case VK_FORMAT_R16G16B16A16_SFLOAT:
103         case VK_FORMAT_R32G32_SFLOAT:
104         case VK_FORMAT_R32G32B32_SFLOAT:
105         case VK_FORMAT_R32G32B32A32_SFLOAT:
106         case VK_FORMAT_R64G64_SFLOAT:
107         case VK_FORMAT_R64G64B64_SFLOAT:
108         case VK_FORMAT_R64G64B64A64_SFLOAT:
109             return "mix(mix(min(" + lhs + ", " + rhs + "), " + lhs + ", isnan(" + rhs + ")), " + rhs + ", isnan(" +
110                    lhs + "))";
111         }
112     case OPERATOR_MAX:
113         switch (format)
114         {
115         default:
116             return "max(" + lhs + ", " + rhs + ")";
117         case VK_FORMAT_R16_SFLOAT:
118         case VK_FORMAT_R32_SFLOAT:
119         case VK_FORMAT_R64_SFLOAT:
120             return "(isnan(" + lhs + ") ? " + rhs + " : (isnan(" + rhs + ") ? " + lhs + " : max(" + lhs + ", " + rhs +
121                    ")))";
122         case VK_FORMAT_R16G16_SFLOAT:
123         case VK_FORMAT_R16G16B16_SFLOAT:
124         case VK_FORMAT_R16G16B16A16_SFLOAT:
125         case VK_FORMAT_R32G32_SFLOAT:
126         case VK_FORMAT_R32G32B32_SFLOAT:
127         case VK_FORMAT_R32G32B32A32_SFLOAT:
128         case VK_FORMAT_R64G64_SFLOAT:
129         case VK_FORMAT_R64G64B64_SFLOAT:
130         case VK_FORMAT_R64G64B64A64_SFLOAT:
131             return "mix(mix(max(" + lhs + ", " + rhs + "), " + lhs + ", isnan(" + rhs + ")), " + rhs + ", isnan(" +
132                    lhs + "))";
133         }
134     case OPERATOR_AND:
135         switch (format)
136         {
137         default:
138             return lhs + " & " + rhs;
139         case VK_FORMAT_R8_USCALED:
140             return lhs + " && " + rhs;
141         case VK_FORMAT_R8G8_USCALED:
142             return "bvec2(" + lhs + ".x && " + rhs + ".x, " + lhs + ".y && " + rhs + ".y)";
143         case VK_FORMAT_R8G8B8_USCALED:
144             return "bvec3(" + lhs + ".x && " + rhs + ".x, " + lhs + ".y && " + rhs + ".y, " + lhs + ".z && " + rhs +
145                    ".z)";
146         case VK_FORMAT_R8G8B8A8_USCALED:
147             return "bvec4(" + lhs + ".x && " + rhs + ".x, " + lhs + ".y && " + rhs + ".y, " + lhs + ".z && " + rhs +
148                    ".z, " + lhs + ".w && " + rhs + ".w)";
149         }
150     case OPERATOR_OR:
151         switch (format)
152         {
153         default:
154             return lhs + " | " + rhs;
155         case VK_FORMAT_R8_USCALED:
156             return lhs + " || " + rhs;
157         case VK_FORMAT_R8G8_USCALED:
158             return "bvec2(" + lhs + ".x || " + rhs + ".x, " + lhs + ".y || " + rhs + ".y)";
159         case VK_FORMAT_R8G8B8_USCALED:
160             return "bvec3(" + lhs + ".x || " + rhs + ".x, " + lhs + ".y || " + rhs + ".y, " + lhs + ".z || " + rhs +
161                    ".z)";
162         case VK_FORMAT_R8G8B8A8_USCALED:
163             return "bvec4(" + lhs + ".x || " + rhs + ".x, " + lhs + ".y || " + rhs + ".y, " + lhs + ".z || " + rhs +
164                    ".z, " + lhs + ".w || " + rhs + ".w)";
165         }
166     case OPERATOR_XOR:
167         switch (format)
168         {
169         default:
170             return lhs + " ^ " + rhs;
171         case VK_FORMAT_R8_USCALED:
172             return lhs + " ^^ " + rhs;
173         case VK_FORMAT_R8G8_USCALED:
174             return "bvec2(" + lhs + ".x ^^ " + rhs + ".x, " + lhs + ".y ^^ " + rhs + ".y)";
175         case VK_FORMAT_R8G8B8_USCALED:
176             return "bvec3(" + lhs + ".x ^^ " + rhs + ".x, " + lhs + ".y ^^ " + rhs + ".y, " + lhs + ".z ^^ " + rhs +
177                    ".z)";
178         case VK_FORMAT_R8G8B8A8_USCALED:
179             return "bvec4(" + lhs + ".x ^^ " + rhs + ".x, " + lhs + ".y ^^ " + rhs + ".y, " + lhs + ".z ^^ " + rhs +
180                    ".z, " + lhs + ".w ^^ " + rhs + ".w)";
181         }
182     }
183 }
184 
getIdentity(Operator op,VkFormat format)185 string getIdentity(Operator op, VkFormat format)
186 {
187     const bool isFloat    = subgroups::isFormatFloat(format);
188     const bool isInt      = subgroups::isFormatSigned(format);
189     const bool isUnsigned = subgroups::isFormatUnsigned(format);
190 
191     switch (op)
192     {
193     default:
194         DE_FATAL("Unsupported op type");
195         return "";
196     case OPERATOR_ADD:
197         return subgroups::getFormatNameForGLSL(format) + "(0)";
198     case OPERATOR_MUL:
199         return subgroups::getFormatNameForGLSL(format) + "(1)";
200     case OPERATOR_MIN:
201         if (isFloat)
202         {
203             return subgroups::getFormatNameForGLSL(format) + "(intBitsToFloat(0x7f800000))";
204         }
205         else if (isInt)
206         {
207             switch (format)
208             {
209             default:
210                 return subgroups::getFormatNameForGLSL(format) + "(0x7fffffff)";
211             case VK_FORMAT_R8_SINT:
212             case VK_FORMAT_R8G8_SINT:
213             case VK_FORMAT_R8G8B8_SINT:
214             case VK_FORMAT_R8G8B8A8_SINT:
215             case VK_FORMAT_R8_UINT:
216             case VK_FORMAT_R8G8_UINT:
217             case VK_FORMAT_R8G8B8_UINT:
218             case VK_FORMAT_R8G8B8A8_UINT:
219                 return subgroups::getFormatNameForGLSL(format) + "(0x7f)";
220             case VK_FORMAT_R16_SINT:
221             case VK_FORMAT_R16G16_SINT:
222             case VK_FORMAT_R16G16B16_SINT:
223             case VK_FORMAT_R16G16B16A16_SINT:
224             case VK_FORMAT_R16_UINT:
225             case VK_FORMAT_R16G16_UINT:
226             case VK_FORMAT_R16G16B16_UINT:
227             case VK_FORMAT_R16G16B16A16_UINT:
228                 return subgroups::getFormatNameForGLSL(format) + "(0x7fff)";
229             case VK_FORMAT_R64_SINT:
230             case VK_FORMAT_R64G64_SINT:
231             case VK_FORMAT_R64G64B64_SINT:
232             case VK_FORMAT_R64G64B64A64_SINT:
233             case VK_FORMAT_R64_UINT:
234             case VK_FORMAT_R64G64_UINT:
235             case VK_FORMAT_R64G64B64_UINT:
236             case VK_FORMAT_R64G64B64A64_UINT:
237                 return subgroups::getFormatNameForGLSL(format) + "(0x7fffffffffffffffUL)";
238             }
239         }
240         else if (isUnsigned)
241         {
242             return subgroups::getFormatNameForGLSL(format) + "(-1)";
243         }
244         else
245         {
246             DE_FATAL("Unhandled case");
247             return "";
248         }
249     case OPERATOR_MAX:
250         if (isFloat)
251         {
252             return subgroups::getFormatNameForGLSL(format) + "(intBitsToFloat(0xff800000))";
253         }
254         else if (isInt)
255         {
256             switch (format)
257             {
258             default:
259                 return subgroups::getFormatNameForGLSL(format) + "(0x80000000)";
260             case VK_FORMAT_R8_SINT:
261             case VK_FORMAT_R8G8_SINT:
262             case VK_FORMAT_R8G8B8_SINT:
263             case VK_FORMAT_R8G8B8A8_SINT:
264             case VK_FORMAT_R8_UINT:
265             case VK_FORMAT_R8G8_UINT:
266             case VK_FORMAT_R8G8B8_UINT:
267             case VK_FORMAT_R8G8B8A8_UINT:
268                 return subgroups::getFormatNameForGLSL(format) + "(0x80)";
269             case VK_FORMAT_R16_SINT:
270             case VK_FORMAT_R16G16_SINT:
271             case VK_FORMAT_R16G16B16_SINT:
272             case VK_FORMAT_R16G16B16A16_SINT:
273             case VK_FORMAT_R16_UINT:
274             case VK_FORMAT_R16G16_UINT:
275             case VK_FORMAT_R16G16B16_UINT:
276             case VK_FORMAT_R16G16B16A16_UINT:
277                 return subgroups::getFormatNameForGLSL(format) + "(0x8000)";
278             case VK_FORMAT_R64_SINT:
279             case VK_FORMAT_R64G64_SINT:
280             case VK_FORMAT_R64G64B64_SINT:
281             case VK_FORMAT_R64G64B64A64_SINT:
282             case VK_FORMAT_R64_UINT:
283             case VK_FORMAT_R64G64_UINT:
284             case VK_FORMAT_R64G64B64_UINT:
285             case VK_FORMAT_R64G64B64A64_UINT:
286                 return subgroups::getFormatNameForGLSL(format) + "(0x8000000000000000UL)";
287             }
288         }
289         else if (isUnsigned)
290         {
291             return subgroups::getFormatNameForGLSL(format) + "(0)";
292         }
293         else
294         {
295             DE_FATAL("Unhandled case");
296             return "";
297         }
298     case OPERATOR_AND:
299         return subgroups::getFormatNameForGLSL(format) + "(~0)";
300     case OPERATOR_OR:
301         return subgroups::getFormatNameForGLSL(format) + "(0)";
302     case OPERATOR_XOR:
303         return subgroups::getFormatNameForGLSL(format) + "(0)";
304     }
305 }
306 
getCompare(Operator op,VkFormat format,string lhs,string rhs)307 string getCompare(Operator op, VkFormat format, string lhs, string rhs)
308 {
309     const string formatName = subgroups::getFormatNameForGLSL(format);
310     const bool isMinMax     = (op == OPERATOR_MIN || op == OPERATOR_MAX);
311 
312     switch (format)
313     {
314     default:
315         return "all(equal(" + lhs + ", " + rhs + "))";
316     case VK_FORMAT_R8_USCALED:
317     case VK_FORMAT_R8_UINT:
318     case VK_FORMAT_R8_SINT:
319     case VK_FORMAT_R16_UINT:
320     case VK_FORMAT_R16_SINT:
321     case VK_FORMAT_R32_UINT:
322     case VK_FORMAT_R32_SINT:
323     case VK_FORMAT_R64_UINT:
324     case VK_FORMAT_R64_SINT:
325         return "(" + lhs + " == " + rhs + ")";
326     case VK_FORMAT_R16_SFLOAT:
327         if (isMinMax)
328             return "(" + lhs + " == " + rhs + ")";
329         else
330             return "(abs(" + lhs + " - " + rhs + ") < " + formatName + "(gl_SubgroupSize==128 ? 0.2: 0.1))";
331     case VK_FORMAT_R32_SFLOAT:
332     case VK_FORMAT_R64_SFLOAT:
333         if (isMinMax)
334             return "(" + lhs + " == " + rhs + ")";
335         else
336             return "(abs(" + lhs + " - " + rhs + ") < (gl_SubgroupSize==128 ? 0.00002:0.00001))";
337     case VK_FORMAT_R16G16_SFLOAT:
338     case VK_FORMAT_R16G16B16_SFLOAT:
339     case VK_FORMAT_R16G16B16A16_SFLOAT:
340         if (isMinMax)
341             return "all(equal(" + lhs + ", " + rhs + "))";
342         else
343             return "all(lessThan(abs(" + lhs + " - " + rhs + "), " + formatName + "(gl_SubgroupSize==128 ? 0.2: 0.1)))";
344     case VK_FORMAT_R32G32_SFLOAT:
345     case VK_FORMAT_R32G32B32_SFLOAT:
346     case VK_FORMAT_R32G32B32A32_SFLOAT:
347     case VK_FORMAT_R64G64_SFLOAT:
348     case VK_FORMAT_R64G64B64_SFLOAT:
349     case VK_FORMAT_R64G64B64A64_SFLOAT:
350         if (isMinMax)
351             return "all(equal(" + lhs + ", " + rhs + "))";
352         else
353             return "all(lessThan(abs(" + lhs + " - " + rhs + "), " + formatName +
354                    "(gl_SubgroupSize==128 ? 0.00002: 0.00001)))";
355     }
356 }
357