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: n = ""; break;
43 case SCAN_INCLUSIVE: n = "Inclusive"; break;
44 case SCAN_EXCLUSIVE: n = "Exclusive"; break;
45 }
46 switch (op)
47 {
48 case OPERATOR_ADD: n += "Add"; break;
49 case OPERATOR_MUL: n += "Mul"; break;
50 case OPERATOR_MIN: n += "Min"; break;
51 case OPERATOR_MAX: n += "Max"; break;
52 case OPERATOR_AND: n += "And"; break;
53 case OPERATOR_OR: n += "Or"; break;
54 case OPERATOR_XOR: n += "Xor"; break;
55 }
56 return prefix + n + suffix;
57 }
58
getOpOperation(Operator op,VkFormat format,string lhs,string rhs)59 string getOpOperation (Operator op, VkFormat format, string lhs, string rhs)
60 {
61 switch (op)
62 {
63 default:
64 DE_FATAL("Unsupported op type");
65 return "";
66 case OPERATOR_ADD:
67 return lhs + " + " + rhs;
68 case OPERATOR_MUL:
69 return lhs + " * " + rhs;
70 case OPERATOR_MIN:
71 switch (format)
72 {
73 default:
74 return "min(" + lhs + ", " + rhs + ")";
75 case VK_FORMAT_R16_SFLOAT:
76 case VK_FORMAT_R32_SFLOAT:
77 case VK_FORMAT_R64_SFLOAT:
78 return "(isnan(" + lhs + ") ? " + rhs + " : (isnan(" + rhs + ") ? " + lhs + " : min(" + lhs + ", " + rhs + ")))";
79 case VK_FORMAT_R16G16_SFLOAT:
80 case VK_FORMAT_R16G16B16_SFLOAT:
81 case VK_FORMAT_R16G16B16A16_SFLOAT:
82 case VK_FORMAT_R32G32_SFLOAT:
83 case VK_FORMAT_R32G32B32_SFLOAT:
84 case VK_FORMAT_R32G32B32A32_SFLOAT:
85 case VK_FORMAT_R64G64_SFLOAT:
86 case VK_FORMAT_R64G64B64_SFLOAT:
87 case VK_FORMAT_R64G64B64A64_SFLOAT:
88 return "mix(mix(min(" + lhs + ", " + rhs + "), " + lhs + ", isnan(" + rhs + ")), " + rhs + ", isnan(" + lhs + "))";
89 }
90 case OPERATOR_MAX:
91 switch (format)
92 {
93 default:
94 return "max(" + 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 + " : max(" + lhs + ", " + rhs + ")))";
99 case VK_FORMAT_R16G16_SFLOAT:
100 case VK_FORMAT_R16G16B16_SFLOAT:
101 case VK_FORMAT_R16G16B16A16_SFLOAT:
102 case VK_FORMAT_R32G32_SFLOAT:
103 case VK_FORMAT_R32G32B32_SFLOAT:
104 case VK_FORMAT_R32G32B32A32_SFLOAT:
105 case VK_FORMAT_R64G64_SFLOAT:
106 case VK_FORMAT_R64G64B64_SFLOAT:
107 case VK_FORMAT_R64G64B64A64_SFLOAT:
108 return "mix(mix(max(" + lhs + ", " + rhs + "), " + lhs + ", isnan(" + rhs + ")), " + rhs + ", isnan(" + lhs + "))";
109 }
110 case OPERATOR_AND:
111 switch (format)
112 {
113 default:
114 return lhs + " & " + rhs;
115 case VK_FORMAT_R8_USCALED:
116 return lhs + " && " + rhs;
117 case VK_FORMAT_R8G8_USCALED:
118 return "bvec2(" + lhs + ".x && " + rhs + ".x, " + lhs + ".y && " + rhs + ".y)";
119 case VK_FORMAT_R8G8B8_USCALED:
120 return "bvec3(" + lhs + ".x && " + rhs + ".x, " + lhs + ".y && " + rhs + ".y, " + lhs + ".z && " + rhs + ".z)";
121 case VK_FORMAT_R8G8B8A8_USCALED:
122 return "bvec4(" + lhs + ".x && " + rhs + ".x, " + lhs + ".y && " + rhs + ".y, " + lhs + ".z && " + rhs + ".z, " + lhs + ".w && " + rhs + ".w)";
123 }
124 case OPERATOR_OR:
125 switch (format)
126 {
127 default:
128 return lhs + " | " + rhs;
129 case VK_FORMAT_R8_USCALED:
130 return lhs + " || " + rhs;
131 case VK_FORMAT_R8G8_USCALED:
132 return "bvec2(" + lhs + ".x || " + rhs + ".x, " + lhs + ".y || " + rhs + ".y)";
133 case VK_FORMAT_R8G8B8_USCALED:
134 return "bvec3(" + lhs + ".x || " + rhs + ".x, " + lhs + ".y || " + rhs + ".y, " + lhs + ".z || " + rhs + ".z)";
135 case VK_FORMAT_R8G8B8A8_USCALED:
136 return "bvec4(" + lhs + ".x || " + rhs + ".x, " + lhs + ".y || " + rhs + ".y, " + lhs + ".z || " + rhs + ".z, " + lhs + ".w || " + rhs + ".w)";
137 }
138 case OPERATOR_XOR:
139 switch (format)
140 {
141 default:
142 return lhs + " ^ " + rhs;
143 case VK_FORMAT_R8_USCALED:
144 return lhs + " ^^ " + rhs;
145 case VK_FORMAT_R8G8_USCALED:
146 return "bvec2(" + lhs + ".x ^^ " + rhs + ".x, " + lhs + ".y ^^ " + rhs + ".y)";
147 case VK_FORMAT_R8G8B8_USCALED:
148 return "bvec3(" + lhs + ".x ^^ " + rhs + ".x, " + lhs + ".y ^^ " + rhs + ".y, " + lhs + ".z ^^ " + rhs + ".z)";
149 case VK_FORMAT_R8G8B8A8_USCALED:
150 return "bvec4(" + lhs + ".x ^^ " + rhs + ".x, " + lhs + ".y ^^ " + rhs + ".y, " + lhs + ".z ^^ " + rhs + ".z, " + lhs + ".w ^^ " + rhs + ".w)";
151 }
152 }
153 }
154
getIdentity(Operator op,VkFormat format)155 string getIdentity (Operator op, VkFormat format)
156 {
157 const bool isFloat = subgroups::isFormatFloat(format);
158 const bool isInt = subgroups::isFormatSigned(format);
159 const bool isUnsigned = subgroups::isFormatUnsigned(format);
160
161 switch (op)
162 {
163 default:
164 DE_FATAL("Unsupported op type");
165 return "";
166 case OPERATOR_ADD:
167 return subgroups::getFormatNameForGLSL(format) + "(0)";
168 case OPERATOR_MUL:
169 return subgroups::getFormatNameForGLSL(format) + "(1)";
170 case OPERATOR_MIN:
171 if (isFloat)
172 {
173 return subgroups::getFormatNameForGLSL(format) + "(intBitsToFloat(0x7f800000))";
174 }
175 else if (isInt)
176 {
177 switch (format)
178 {
179 default:
180 return subgroups::getFormatNameForGLSL(format) + "(0x7fffffff)";
181 case VK_FORMAT_R8_SINT:
182 case VK_FORMAT_R8G8_SINT:
183 case VK_FORMAT_R8G8B8_SINT:
184 case VK_FORMAT_R8G8B8A8_SINT:
185 case VK_FORMAT_R8_UINT:
186 case VK_FORMAT_R8G8_UINT:
187 case VK_FORMAT_R8G8B8_UINT:
188 case VK_FORMAT_R8G8B8A8_UINT:
189 return subgroups::getFormatNameForGLSL(format) + "(0x7f)";
190 case VK_FORMAT_R16_SINT:
191 case VK_FORMAT_R16G16_SINT:
192 case VK_FORMAT_R16G16B16_SINT:
193 case VK_FORMAT_R16G16B16A16_SINT:
194 case VK_FORMAT_R16_UINT:
195 case VK_FORMAT_R16G16_UINT:
196 case VK_FORMAT_R16G16B16_UINT:
197 case VK_FORMAT_R16G16B16A16_UINT:
198 return subgroups::getFormatNameForGLSL(format) + "(0x7fff)";
199 case VK_FORMAT_R64_SINT:
200 case VK_FORMAT_R64G64_SINT:
201 case VK_FORMAT_R64G64B64_SINT:
202 case VK_FORMAT_R64G64B64A64_SINT:
203 case VK_FORMAT_R64_UINT:
204 case VK_FORMAT_R64G64_UINT:
205 case VK_FORMAT_R64G64B64_UINT:
206 case VK_FORMAT_R64G64B64A64_UINT:
207 return subgroups::getFormatNameForGLSL(format) + "(0x7fffffffffffffffUL)";
208 }
209 }
210 else if (isUnsigned)
211 {
212 return subgroups::getFormatNameForGLSL(format) + "(-1)";
213 }
214 else
215 {
216 DE_FATAL("Unhandled case");
217 return "";
218 }
219 case OPERATOR_MAX:
220 if (isFloat)
221 {
222 return subgroups::getFormatNameForGLSL(format) + "(intBitsToFloat(0xff800000))";
223 }
224 else if (isInt)
225 {
226 switch (format)
227 {
228 default:
229 return subgroups::getFormatNameForGLSL(format) + "(0x80000000)";
230 case VK_FORMAT_R8_SINT:
231 case VK_FORMAT_R8G8_SINT:
232 case VK_FORMAT_R8G8B8_SINT:
233 case VK_FORMAT_R8G8B8A8_SINT:
234 case VK_FORMAT_R8_UINT:
235 case VK_FORMAT_R8G8_UINT:
236 case VK_FORMAT_R8G8B8_UINT:
237 case VK_FORMAT_R8G8B8A8_UINT:
238 return subgroups::getFormatNameForGLSL(format) + "(0x80)";
239 case VK_FORMAT_R16_SINT:
240 case VK_FORMAT_R16G16_SINT:
241 case VK_FORMAT_R16G16B16_SINT:
242 case VK_FORMAT_R16G16B16A16_SINT:
243 case VK_FORMAT_R16_UINT:
244 case VK_FORMAT_R16G16_UINT:
245 case VK_FORMAT_R16G16B16_UINT:
246 case VK_FORMAT_R16G16B16A16_UINT:
247 return subgroups::getFormatNameForGLSL(format) + "(0x8000)";
248 case VK_FORMAT_R64_SINT:
249 case VK_FORMAT_R64G64_SINT:
250 case VK_FORMAT_R64G64B64_SINT:
251 case VK_FORMAT_R64G64B64A64_SINT:
252 case VK_FORMAT_R64_UINT:
253 case VK_FORMAT_R64G64_UINT:
254 case VK_FORMAT_R64G64B64_UINT:
255 case VK_FORMAT_R64G64B64A64_UINT:
256 return subgroups::getFormatNameForGLSL(format) + "(0x8000000000000000UL)";
257 }
258 }
259 else if (isUnsigned)
260 {
261 return subgroups::getFormatNameForGLSL(format) + "(0)";
262 }
263 else
264 {
265 DE_FATAL("Unhandled case");
266 return "";
267 }
268 case OPERATOR_AND:
269 return subgroups::getFormatNameForGLSL(format) + "(~0)";
270 case OPERATOR_OR:
271 return subgroups::getFormatNameForGLSL(format) + "(0)";
272 case OPERATOR_XOR:
273 return subgroups::getFormatNameForGLSL(format) + "(0)";
274 }
275 }
276
getCompare(Operator op,VkFormat format,string lhs,string rhs)277 string getCompare (Operator op, VkFormat format, string lhs, string rhs)
278 {
279 const string formatName = subgroups::getFormatNameForGLSL(format);
280 const bool isMinMax = (op == OPERATOR_MIN || op == OPERATOR_MAX);
281
282 switch (format)
283 {
284 default:
285 return "all(equal(" + lhs + ", " + rhs + "))";
286 case VK_FORMAT_R8_USCALED:
287 case VK_FORMAT_R8_UINT:
288 case VK_FORMAT_R8_SINT:
289 case VK_FORMAT_R16_UINT:
290 case VK_FORMAT_R16_SINT:
291 case VK_FORMAT_R32_UINT:
292 case VK_FORMAT_R32_SINT:
293 case VK_FORMAT_R64_UINT:
294 case VK_FORMAT_R64_SINT:
295 return "(" + lhs + " == " + rhs + ")";
296 case VK_FORMAT_R16_SFLOAT:
297 if (isMinMax)
298 return "(" + lhs + " == " + rhs + ")";
299 else
300 return "(abs(" + lhs + " - " + rhs + ") < " + formatName + "(gl_SubgroupSize==128 ? 0.2: 0.1))";
301 case VK_FORMAT_R32_SFLOAT:
302 case VK_FORMAT_R64_SFLOAT:
303 if (isMinMax)
304 return "(" + lhs + " == " + rhs + ")";
305 else
306 return "(abs(" + lhs + " - " + rhs + ") < (gl_SubgroupSize==128 ? 0.00002:0.00001))";
307 case VK_FORMAT_R16G16_SFLOAT:
308 case VK_FORMAT_R16G16B16_SFLOAT:
309 case VK_FORMAT_R16G16B16A16_SFLOAT:
310 if (isMinMax)
311 return "all(equal(" + lhs + ", " + rhs + "))";
312 else
313 return "all(lessThan(abs(" + lhs + " - " + rhs + "), " + formatName + "(gl_SubgroupSize==128 ? 0.2: 0.1)))";
314 case VK_FORMAT_R32G32_SFLOAT:
315 case VK_FORMAT_R32G32B32_SFLOAT:
316 case VK_FORMAT_R32G32B32A32_SFLOAT:
317 case VK_FORMAT_R64G64_SFLOAT:
318 case VK_FORMAT_R64G64B64_SFLOAT:
319 case VK_FORMAT_R64G64B64A64_SFLOAT:
320 if (isMinMax)
321 return "all(equal(" + lhs + ", " + rhs + "))";
322 else
323 return "all(lessThan(abs(" + lhs + " - " + rhs + "), " + formatName + "(gl_SubgroupSize==128 ? 0.00002: 0.00001)))";
324 }
325 }
326