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