• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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