• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*-------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2017 Google Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Utilities for Vulkan SPIR-V assembly tests
22  *//*--------------------------------------------------------------------*/
23 
24 #include "vktSpvAsmUtils.hpp"
25 
26 #include "deMemory.h"
27 #include "deSTLUtil.hpp"
28 #include "vkQueryUtil.hpp"
29 #include "vkRefUtil.hpp"
30 #include "vkPlatform.hpp"
31 
32 #include <limits>
33 
34 namespace vkt
35 {
36 namespace SpirVAssembly
37 {
38 
39 using namespace vk;
40 
is8BitStorageFeaturesSupported(const Context & context,Extension8BitStorageFeatures toCheck)41 bool is8BitStorageFeaturesSupported (const Context& context, Extension8BitStorageFeatures toCheck)
42 {
43 	VkPhysicalDevice8BitStorageFeaturesKHR extensionFeatures = context.get8BitStorageFeatures();
44 
45 	if ((toCheck & EXT8BITSTORAGEFEATURES_STORAGE_BUFFER) != 0 && extensionFeatures.storageBuffer8BitAccess == VK_FALSE)
46 		TCU_FAIL("storageBuffer8BitAccess has to be supported");
47 
48 	if ((toCheck & EXT8BITSTORAGEFEATURES_UNIFORM_STORAGE_BUFFER) != 0 && extensionFeatures.uniformAndStorageBuffer8BitAccess == VK_FALSE)
49 		return false;
50 
51 	if ((toCheck & EXT8BITSTORAGEFEATURES_PUSH_CONSTANT) != 0 && extensionFeatures.storagePushConstant8 == VK_FALSE)
52 		return false;
53 
54 	return true;
55 }
56 
57 #define IS_CORE_FEATURE_AVAILABLE(CHECKED, AVAILABLE, FEATURE)	\
58 	if ((CHECKED.FEATURE != DE_FALSE) && (AVAILABLE.FEATURE == DE_FALSE)) { *missingFeature = #FEATURE; return false; }
59 
isCoreFeaturesSupported(const Context & context,const vk::VkPhysicalDeviceFeatures & toCheck,const char ** missingFeature)60 bool isCoreFeaturesSupported (const Context&						context,
61 							  const vk::VkPhysicalDeviceFeatures&	toCheck,
62 							  const char**							missingFeature)
63 {
64 	const VkPhysicalDeviceFeatures&	availableFeatures	= context.getDeviceFeatures();
65 
66 	IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, robustBufferAccess);
67 	IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, fullDrawIndexUint32);
68 	IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, imageCubeArray);
69 	IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, independentBlend);
70 	IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, geometryShader);
71 	IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, tessellationShader);
72 	IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, sampleRateShading);
73 	IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, dualSrcBlend);
74 	IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, logicOp);
75 	IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, multiDrawIndirect);
76 	IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, drawIndirectFirstInstance);
77 	IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, depthClamp);
78 	IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, depthBiasClamp);
79 	IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, fillModeNonSolid);
80 	IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, depthBounds);
81 	IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, wideLines);
82 	IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, largePoints);
83 	IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, alphaToOne);
84 	IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, multiViewport);
85 	IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, samplerAnisotropy);
86 	IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, textureCompressionETC2);
87 	IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, textureCompressionASTC_LDR);
88 	IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, textureCompressionBC);
89 	IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, occlusionQueryPrecise);
90 	IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, pipelineStatisticsQuery);
91 	IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, vertexPipelineStoresAndAtomics);
92 	IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, fragmentStoresAndAtomics);
93 	IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, shaderTessellationAndGeometryPointSize);
94 	IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, shaderImageGatherExtended);
95 	IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, shaderStorageImageExtendedFormats);
96 	IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, shaderStorageImageMultisample);
97 	IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, shaderStorageImageReadWithoutFormat);
98 	IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, shaderStorageImageWriteWithoutFormat);
99 	IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, shaderUniformBufferArrayDynamicIndexing);
100 	IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, shaderSampledImageArrayDynamicIndexing);
101 	IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, shaderStorageBufferArrayDynamicIndexing);
102 	IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, shaderStorageImageArrayDynamicIndexing);
103 	IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, shaderClipDistance);
104 	IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, shaderCullDistance);
105 	IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, shaderFloat64);
106 	IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, shaderInt64);
107 	IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, shaderInt16);
108 	IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, shaderResourceResidency);
109 	IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, shaderResourceMinLod);
110 	IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, sparseBinding);
111 	IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, sparseResidencyBuffer);
112 	IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, sparseResidencyImage2D);
113 	IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, sparseResidencyImage3D);
114 	IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, sparseResidency2Samples);
115 	IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, sparseResidency4Samples);
116 	IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, sparseResidency8Samples);
117 	IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, sparseResidency16Samples);
118 	IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, sparseResidencyAliased);
119 	IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, variableMultisampleRate);
120 	IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, inheritedQueries);
121 
122 	return true;
123 }
124 
is16BitStorageFeaturesSupported(const Context & context,Extension16BitStorageFeatures toCheck)125 bool is16BitStorageFeaturesSupported (const Context& context, Extension16BitStorageFeatures toCheck)
126 {
127 	const VkPhysicalDevice16BitStorageFeatures& extensionFeatures = context.get16BitStorageFeatures();
128 
129 	if ((toCheck & EXT16BITSTORAGEFEATURES_UNIFORM_BUFFER_BLOCK) != 0 && extensionFeatures.storageBuffer16BitAccess == VK_FALSE)
130 		return false;
131 
132 	if ((toCheck & EXT16BITSTORAGEFEATURES_UNIFORM) != 0 && extensionFeatures.uniformAndStorageBuffer16BitAccess == VK_FALSE)
133 		return false;
134 
135 	if ((toCheck & EXT16BITSTORAGEFEATURES_PUSH_CONSTANT) != 0 && extensionFeatures.storagePushConstant16 == VK_FALSE)
136 		return false;
137 
138 	if ((toCheck & EXT16BITSTORAGEFEATURES_INPUT_OUTPUT) != 0 && extensionFeatures.storageInputOutput16 == VK_FALSE)
139 		return false;
140 
141 	return true;
142 }
143 
isVariablePointersFeaturesSupported(const Context & context,ExtensionVariablePointersFeatures toCheck)144 bool isVariablePointersFeaturesSupported (const Context& context, ExtensionVariablePointersFeatures toCheck)
145 {
146 	const VkPhysicalDeviceVariablePointerFeatures& extensionFeatures = context.getVariablePointerFeatures();
147 
148 	if ((toCheck & EXTVARIABLEPOINTERSFEATURES_VARIABLE_POINTERS_STORAGEBUFFER) != 0 && extensionFeatures.variablePointersStorageBuffer == VK_FALSE)
149 		return false;
150 
151 	if ((toCheck & EXTVARIABLEPOINTERSFEATURES_VARIABLE_POINTERS) != 0 && extensionFeatures.variablePointers == VK_FALSE)
152 		return false;
153 
154 	return true;
155 }
156 
isFloat16Int8FeaturesSupported(const Context & context,ExtensionFloat16Int8Features toCheck)157 bool isFloat16Int8FeaturesSupported (const Context& context, ExtensionFloat16Int8Features toCheck)
158 {
159 	const VkPhysicalDeviceFloat16Int8FeaturesKHR& extensionFeatures = context.getFloat16Int8Features();
160 
161 	if ((toCheck & EXTFLOAT16INT8FEATURES_FLOAT16) != 0 && extensionFeatures.shaderFloat16 == VK_FALSE)
162 		return false;
163 
164 	if ((toCheck & EXTFLOAT16INT8FEATURES_INT8) != 0 && extensionFeatures.shaderInt8 == VK_FALSE)
165 		return false;
166 
167 	return true;
168 }
169 
isFloatControlsFeaturesSupported(const Context & context,const ExtensionFloatControlsFeatures & toCheck)170 bool isFloatControlsFeaturesSupported (const Context& context, const ExtensionFloatControlsFeatures& toCheck)
171 {
172 	ExtensionFloatControlsFeatures refControls;
173 	deMemset(&refControls, 0, sizeof(ExtensionFloatControlsFeatures));
174 
175 	// compare with all flags set to false to verify if any float control features are actualy requested by the test
176 	if (deMemCmp(&toCheck, &refControls, sizeof(ExtensionFloatControlsFeatures)) == 0)
177 		return true;
178 
179 	// return false when float control features are requested and proper extension is not supported
180 	const std::vector<std::string>& deviceExtensions = context.getDeviceExtensions();
181 	if (!isDeviceExtensionSupported(context.getUsedApiVersion(), deviceExtensions, "VK_KHR_shader_float_controls"))
182 		return false;
183 
184 	// perform query to get supported float control properties
185 	{
186 		refControls.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES_KHR;
187 		refControls.pNext = DE_NULL;
188 
189 		VkPhysicalDeviceProperties2 deviceProperties;
190 		deviceProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
191 		deviceProperties.pNext = &refControls;
192 
193 		const VkPhysicalDevice			physicalDevice		= context.getPhysicalDevice();
194 		const vk::InstanceInterface&	instanceInterface	= context.getInstanceInterface();
195 
196 		instanceInterface.getPhysicalDeviceProperties2(physicalDevice, &deviceProperties);
197 	}
198 
199 	// check if flags needed by the test are not supported by the device
200 	bool requiredFeaturesNotSupported =
201 		(toCheck.shaderDenormFlushToZeroFloat16			&& !refControls.shaderDenormFlushToZeroFloat16) ||
202 		(toCheck.shaderDenormPreserveFloat16			&& !refControls.shaderDenormPreserveFloat16) ||
203 		(toCheck.shaderRoundingModeRTEFloat16			&& !refControls.shaderRoundingModeRTEFloat16) ||
204 		(toCheck.shaderRoundingModeRTZFloat16			&& !refControls.shaderRoundingModeRTZFloat16) ||
205 		(toCheck.shaderSignedZeroInfNanPreserveFloat16	&& !refControls.shaderSignedZeroInfNanPreserveFloat16) ||
206 		(toCheck.shaderDenormFlushToZeroFloat32			&& !refControls.shaderDenormFlushToZeroFloat32) ||
207 		(toCheck.shaderDenormPreserveFloat32			&& !refControls.shaderDenormPreserveFloat32) ||
208 		(toCheck.shaderRoundingModeRTEFloat32			&& !refControls.shaderRoundingModeRTEFloat32) ||
209 		(toCheck.shaderRoundingModeRTZFloat32			&& !refControls.shaderRoundingModeRTZFloat32) ||
210 		(toCheck.shaderSignedZeroInfNanPreserveFloat32	&& !refControls.shaderSignedZeroInfNanPreserveFloat32) ||
211 		(toCheck.shaderDenormFlushToZeroFloat64			&& !refControls.shaderDenormFlushToZeroFloat64) ||
212 		(toCheck.shaderDenormPreserveFloat64			&& !refControls.shaderDenormPreserveFloat64) ||
213 		(toCheck.shaderRoundingModeRTEFloat64			&& !refControls.shaderRoundingModeRTEFloat64) ||
214 		(toCheck.shaderRoundingModeRTZFloat64			&& !refControls.shaderRoundingModeRTZFloat64) ||
215 		(toCheck.shaderSignedZeroInfNanPreserveFloat64	&& !refControls.shaderSignedZeroInfNanPreserveFloat64);
216 
217 	// we checked if required features are not supported - we need to
218 	// negate the result to know if all required features are available
219 	return !requiredFeaturesNotSupported;
220 }
221 
getMinRequiredVulkanVersion(const SpirvVersion version)222 deUint32 getMinRequiredVulkanVersion (const SpirvVersion version)
223 {
224 	switch(version)
225 	{
226 	case SPIRV_VERSION_1_0:
227 		return VK_API_VERSION_1_0;
228 	case SPIRV_VERSION_1_1:
229 	case SPIRV_VERSION_1_2:
230 	case SPIRV_VERSION_1_3:
231 		return VK_API_VERSION_1_1;
232 	default:
233 		DE_ASSERT(0);
234 	}
235 	return 0u;
236 }
237 
getVulkanName(const deUint32 version)238 std::string	getVulkanName (const deUint32 version)
239 {
240 	return std::string(version == VK_API_VERSION_1_1 ? "1.1" : "1.0");
241 }
242 
243 // Generate and return 64-bit integers.
244 //
245 // Expected count to be at least 16.
getInt64s(de::Random & rnd,const deUint32 count)246 std::vector<deInt64> getInt64s (de::Random& rnd, const deUint32 count)
247 {
248 	std::vector<deInt64> data;
249 
250 	data.reserve(count);
251 
252 	// Make sure we have boundary numbers.
253 	data.push_back(deInt64(0x0000000000000000));  // 0
254 	data.push_back(deInt64(0x0000000000000001));  // 1
255 	data.push_back(deInt64(0x000000000000002a));  // 42
256 	data.push_back(deInt64(0x000000007fffffff));  // 2147483647
257 	data.push_back(deInt64(0x0000000080000000));  // 2147483648
258 	data.push_back(deInt64(0x00000000ffffffff));  // 4294967295
259 	data.push_back(deInt64(0x0000000100000000));  // 4294967296
260 	data.push_back(deInt64(0x7fffffffffffffff));  // 9223372036854775807
261 	data.push_back(deInt64(0x8000000000000000));  // -9223372036854775808
262 	data.push_back(deInt64(0x8000000000000001));  // -9223372036854775807
263 	data.push_back(deInt64(0xffffffff00000000));  // -4294967296
264 	data.push_back(deInt64(0xffffffff00000001));  // -4294967295
265 	data.push_back(deInt64(0xffffffff80000000));  // -2147483648
266 	data.push_back(deInt64(0xffffffff80000001));  // -2147483647
267 	data.push_back(deInt64(0xffffffffffffffd6));  // -42
268 	data.push_back(deInt64(0xffffffffffffffff));  // -1
269 
270 	DE_ASSERT(count >= data.size());
271 
272 	for (deUint32 numNdx = static_cast<deUint32>(data.size()); numNdx < count; ++numNdx)
273 		data.push_back(static_cast<deInt64>(rnd.getUint64()));
274 
275 	return data;
276 }
277 
278 // Generate and return 32-bit integers.
279 //
280 // Expected count to be at least 16.
getInt32s(de::Random & rnd,const deUint32 count)281 std::vector<deInt32> getInt32s (de::Random& rnd, const deUint32 count)
282 {
283 	std::vector<deInt32> data;
284 
285 	data.reserve(count);
286 
287 	// Make sure we have boundary numbers.
288 	data.push_back(deInt32(0x00000000));  // 0
289 	data.push_back(deInt32(0x00000001));  // 1
290 	data.push_back(deInt32(0x0000002a));  // 42
291 	data.push_back(deInt32(0x00007fff));  // 32767
292 	data.push_back(deInt32(0x00008000));  // 32768
293 	data.push_back(deInt32(0x0000ffff));  // 65535
294 	data.push_back(deInt32(0x00010000));  // 65536
295 	data.push_back(deInt32(0x7fffffff));  // 2147483647
296 	data.push_back(deInt32(0x80000000));  // -2147483648
297 	data.push_back(deInt32(0x80000001));  // -2147483647
298 	data.push_back(deInt32(0xffff0000));  // -65536
299 	data.push_back(deInt32(0xffff0001));  // -65535
300 	data.push_back(deInt32(0xffff8000));  // -32768
301 	data.push_back(deInt32(0xffff8001));  // -32767
302 	data.push_back(deInt32(0xffffffd6));  // -42
303 	data.push_back(deInt32(0xffffffff));  // -1
304 
305 	DE_ASSERT(count >= data.size());
306 
307 	for (deUint32 numNdx = static_cast<deUint32>(data.size()); numNdx < count; ++numNdx)
308 		data.push_back(static_cast<deInt32>(rnd.getUint32()));
309 
310 	return data;
311 }
312 
313 // Generate and return 16-bit integers.
314 //
315 // Expected count to be at least 8.
getInt16s(de::Random & rnd,const deUint32 count)316 std::vector<deInt16> getInt16s (de::Random& rnd, const deUint32 count)
317 {
318 	std::vector<deInt16> data;
319 
320 	data.reserve(count);
321 
322 	// Make sure we have boundary numbers.
323 	data.push_back(deInt16(0x0000));  // 0
324 	data.push_back(deInt16(0x0001));  // 1
325 	data.push_back(deInt16(0x002a));  // 42
326 	data.push_back(deInt16(0x7fff));  // 32767
327 	data.push_back(deInt16(0x8000));  // -32868
328 	data.push_back(deInt16(0x8001));  // -32767
329 	data.push_back(deInt16(0xffd6));  // -42
330 	data.push_back(deInt16(0xffff));  // -1
331 
332 	DE_ASSERT(count >= data.size());
333 
334 	for (deUint32 numNdx = static_cast<deUint32>(data.size()); numNdx < count; ++numNdx)
335 		data.push_back(static_cast<deInt16>(rnd.getUint16()));
336 
337 	return data;
338 }
339 
340 // Generate and return 8-bit integers.
341 //
342 // Expected count to be at least 8.
getInt8s(de::Random & rnd,const deUint32 count)343 std::vector<deInt8> getInt8s (de::Random& rnd, const deUint32 count)
344 {
345 	std::vector<deInt8> data;
346 
347 	data.reserve(count);
348 
349 	// Make sure we have boundary numbers.
350 	data.push_back(deInt8(0x00));  // 0
351 	data.push_back(deInt8(0x01));  // 1
352 	data.push_back(deInt8(0x2a));  // 42
353 	data.push_back(deInt8(0x7f));  // 127
354 	data.push_back(deInt8(0x80));  // -128
355 	data.push_back(deInt8(0x81));  // -127
356 	data.push_back(deInt8(0xd6));  // -42
357 	data.push_back(deInt8(0xff));  // -1
358 
359 	DE_ASSERT(count >= data.size());
360 
361 	for (deUint32 numNdx = static_cast<deUint32>(data.size()); numNdx < count; ++numNdx)
362 		data.push_back(static_cast<deInt8>(rnd.getUint8()));
363 
364 	return data;
365 }
366 
367 // IEEE-754 floating point numbers:
368 // +--------+------+----------+-------------+
369 // | binary | sign | exponent | significand |
370 // +--------+------+----------+-------------+
371 // | 64-bit |  1   |    11    |     52      |
372 // +--------+------+----------+-------------+
373 // | 32-bit |  1   |    8     |     23      |
374 // +--------+------+----------+-------------+
375 // | 16-bit |  1   |    5     |     10      |
376 // +--------+------+----------+-------------+
377 //
378 // 64-bit floats:
379 //
380 // (0x3FD2000000000000: 0.28125: with exact match in 16-bit normalized)
381 // (0x3F10060000000000: exact half way within two 16-bit normalized; round to zero: 0x0401)
382 // (0xBF10060000000000: exact half way within two 16-bit normalized; round to zero: 0x8402)
383 // (0x3F100C0000000000: not exact half way within two 16-bit normalized; round to zero: 0x0403)
384 // (0xBF100C0000000000: not exact half way within two 16-bit normalized; round to zero: 0x8404)
385 
386 // Generate and return 64-bit floats
387 //
388 // The first 24 number pairs are manually picked, while the rest are randomly generated.
389 // Expected count to be at least 24 (numPicks).
getFloat64s(de::Random & rnd,deUint32 count)390 std::vector<double> getFloat64s (de::Random& rnd, deUint32 count)
391 {
392 	std::vector<double> float64;
393 
394 	float64.reserve(count);
395 
396 	if (count >= 24)
397 	{
398 		// Zero
399 		float64.push_back(0.f);
400 		float64.push_back(-0.f);
401 		// Infinity
402 		float64.push_back(std::numeric_limits<double>::infinity());
403 		float64.push_back(-std::numeric_limits<double>::infinity());
404 		// SNaN
405 		float64.push_back(std::numeric_limits<double>::signaling_NaN());
406 		float64.push_back(-std::numeric_limits<double>::signaling_NaN());
407 		// QNaN
408 		float64.push_back(std::numeric_limits<double>::quiet_NaN());
409 		float64.push_back(-std::numeric_limits<double>::quiet_NaN());
410 
411 		// Denormalized 64-bit float matching 0 in 16-bit
412 		float64.push_back(ldexp((double)1.f, -1023));
413 		float64.push_back(-ldexp((double)1.f, -1023));
414 
415 		// Normalized 64-bit float matching 0 in 16-bit
416 		float64.push_back(ldexp((double)1.f, -100));
417 		float64.push_back(-ldexp((double)1.f, -100));
418 		// Normalized 64-bit float with exact denormalized match in 16-bit
419 		float64.push_back(bitwiseCast<double>(deUint64(0x3B0357C299A88EA8)));
420 		float64.push_back(bitwiseCast<double>(deUint64(0xBB0357C299A88EA8)));
421 
422 		// Normalized 64-bit float with exact normalized match in 16-bit
423 		float64.push_back(ldexp((double)1.f, -14));  // 2e-14: minimum 16-bit positive normalized
424 		float64.push_back(-ldexp((double)1.f, -14)); // 2e-14: maximum 16-bit negative normalized
425 		// Normalized 64-bit float falling above half way within two 16-bit normalized
426 		float64.push_back(bitwiseCast<double>(deUint64(0x3FD2000000000000)));
427 		float64.push_back(bitwiseCast<double>(deUint64(0xBFD2000000000000)));
428 		// Normalized 64-bit float falling exact half way within two 16-bit normalized
429 		float64.push_back(bitwiseCast<double>(deUint64(0x3F100C0000000000)));
430 		float64.push_back(bitwiseCast<double>(deUint64(0xBF100C0000000000)));
431 		// Some number
432 		float64.push_back((double)0.28125f);
433 		float64.push_back((double)-0.28125f);
434 		// Normalized 64-bit float matching infinity in 16-bit
435 		float64.push_back(ldexp((double)1.f, 100));
436 		float64.push_back(-ldexp((double)1.f, 100));
437 	}
438 
439 	const deUint32		numPicks	= static_cast<deUint32>(float64.size());
440 
441 	DE_ASSERT(count >= numPicks);
442 	count -= numPicks;
443 
444 	for (deUint32 numNdx = 0; numNdx < count; ++numNdx)
445 	{
446 		double randValue = rnd.getDouble();
447 		float64.push_back(randValue);
448 	}
449 
450 	return float64;
451 }
452 
453 // IEEE-754 floating point numbers:
454 // +--------+------+----------+-------------+
455 // | binary | sign | exponent | significand |
456 // +--------+------+----------+-------------+
457 // | 16-bit |  1   |    5     |     10      |
458 // +--------+------+----------+-------------+
459 // | 32-bit |  1   |    8     |     23      |
460 // +--------+------+----------+-------------+
461 //
462 // 16-bit floats:
463 //
464 // 0   000 00   00 0000 0001 (0x0001: 2e-24:         minimum positive denormalized)
465 // 0   000 00   11 1111 1111 (0x03ff: 2e-14 - 2e-24: maximum positive denormalized)
466 // 0   000 01   00 0000 0000 (0x0400: 2e-14:         minimum positive normalized)
467 //
468 // 32-bit floats:
469 //
470 // 0   011 1110 1   001 0000 0000 0000 0000 0000 (0x3e900000: 0.28125: with exact match in 16-bit normalized)
471 // 0   011 1000 1   000 0000 0011 0000 0000 0000 (0x38803000: exact half way within two 16-bit normalized; round to zero: 0x0401)
472 // 1   011 1000 1   000 0000 0011 0000 0000 0000 (0xb8803000: exact half way within two 16-bit normalized; round to zero: 0x8402)
473 // 0   011 1000 1   000 0000 1111 1111 0000 0000 (0x3880ff00: not exact half way within two 16-bit normalized; round to zero: 0x0403)
474 // 1   011 1000 1   000 0000 1111 1111 0000 0000 (0xb880ff00: not exact half way within two 16-bit normalized; round to zero: 0x8404)
475 
476 // Generate and return 32-bit floats
477 //
478 // The first 24 number pairs are manually picked, while the rest are randomly generated.
479 // Expected count to be at least 24 (numPicks).
getFloat32s(de::Random & rnd,deUint32 count)480 std::vector<float> getFloat32s (de::Random& rnd, deUint32 count)
481 {
482 	std::vector<float> float32;
483 
484 	float32.reserve(count);
485 
486 	// Zero
487 	float32.push_back(0.f);
488 	float32.push_back(-0.f);
489 	// Infinity
490 	float32.push_back(std::numeric_limits<float>::infinity());
491 	float32.push_back(-std::numeric_limits<float>::infinity());
492 	// SNaN
493 	float32.push_back(std::numeric_limits<float>::signaling_NaN());
494 	float32.push_back(-std::numeric_limits<float>::signaling_NaN());
495 	// QNaN
496 	float32.push_back(std::numeric_limits<float>::quiet_NaN());
497 	float32.push_back(-std::numeric_limits<float>::quiet_NaN());
498 
499 	// Denormalized 32-bit float matching 0 in 16-bit
500 	float32.push_back(deFloatLdExp(1.f, -127));
501 	float32.push_back(-deFloatLdExp(1.f, -127));
502 
503 	// Normalized 32-bit float matching 0 in 16-bit
504 	float32.push_back(deFloatLdExp(1.f, -100));
505 	float32.push_back(-deFloatLdExp(1.f, -100));
506 	// Normalized 32-bit float with exact denormalized match in 16-bit
507 	float32.push_back(deFloatLdExp(1.f, -24));  // 2e-24: minimum 16-bit positive denormalized
508 	float32.push_back(-deFloatLdExp(1.f, -24)); // 2e-24: maximum 16-bit negative denormalized
509 	// Normalized 32-bit float with exact normalized match in 16-bit
510 	float32.push_back(deFloatLdExp(1.f, -14));  // 2e-14: minimum 16-bit positive normalized
511 	float32.push_back(-deFloatLdExp(1.f, -14)); // 2e-14: maximum 16-bit negative normalized
512 	// Normalized 32-bit float falling above half way within two 16-bit normalized
513 	float32.push_back(bitwiseCast<float>(deUint32(0x3880ff00)));
514 	float32.push_back(bitwiseCast<float>(deUint32(0xb880ff00)));
515 	// Normalized 32-bit float falling exact half way within two 16-bit normalized
516 	float32.push_back(bitwiseCast<float>(deUint32(0x38803000)));
517 	float32.push_back(bitwiseCast<float>(deUint32(0xb8803000)));
518 	// Some number
519 	float32.push_back(0.28125f);
520 	float32.push_back(-0.28125f);
521 	// Normalized 32-bit float matching infinity in 16-bit
522 	float32.push_back(deFloatLdExp(1.f, 100));
523 	float32.push_back(-deFloatLdExp(1.f, 100));
524 
525 	const deUint32		numPicks	= static_cast<deUint32>(float32.size());
526 
527 	DE_ASSERT(count >= numPicks);
528 	count -= numPicks;
529 
530 	for (deUint32 numNdx = 0; numNdx < count; ++numNdx)
531 		float32.push_back(rnd.getFloat());
532 
533 	return float32;
534 }
535 
536 // IEEE-754 floating point numbers:
537 // +--------+------+----------+-------------+
538 // | binary | sign | exponent | significand |
539 // +--------+------+----------+-------------+
540 // | 16-bit |  1   |    5     |     10      |
541 // +--------+------+----------+-------------+
542 // | 32-bit |  1   |    8     |     23      |
543 // +--------+------+----------+-------------+
544 //
545 // 16-bit floats:
546 //
547 // 0   000 00   00 0000 0001 (0x0001: 2e-24:         minimum positive denormalized)
548 // 0   000 00   11 1111 1111 (0x03ff: 2e-14 - 2e-24: maximum positive denormalized)
549 // 0   000 01   00 0000 0000 (0x0400: 2e-14:         minimum positive normalized)
550 //
551 // 0   000 00   00 0000 0000 (0x0000: +0)
552 // 0   111 11   00 0000 0000 (0x7c00: +Inf)
553 // 0   000 00   11 1111 0000 (0x03f0: +Denorm)
554 // 0   000 01   00 0000 0001 (0x0401: +Norm)
555 // 0   111 11   00 0000 1111 (0x7c0f: +SNaN)
556 // 0   111 11   00 1111 0000 (0x7c0f: +QNaN)
557 
558 // Generate and return 16-bit floats and their corresponding 32-bit values.
559 //
560 // The first 14 number pairs are manually picked, while the rest are randomly generated.
561 // Expected count to be at least 14 (numPicks).
getFloat16s(de::Random & rnd,deUint32 count)562 std::vector<deFloat16> getFloat16s (de::Random& rnd, deUint32 count)
563 {
564 	std::vector<deFloat16> float16;
565 
566 	float16.reserve(count);
567 
568 	// Zero
569 	float16.push_back(deUint16(0x0000));
570 	float16.push_back(deUint16(0x8000));
571 	// Infinity
572 	float16.push_back(deUint16(0x7c00));
573 	float16.push_back(deUint16(0xfc00));
574 	// SNaN
575 	float16.push_back(deUint16(0x7c0f));
576 	float16.push_back(deUint16(0xfc0f));
577 	// QNaN
578 	float16.push_back(deUint16(0x7cf0));
579 	float16.push_back(deUint16(0xfcf0));
580 
581 	// Denormalized
582 	float16.push_back(deUint16(0x03f0));
583 	float16.push_back(deUint16(0x83f0));
584 	// Normalized
585 	float16.push_back(deUint16(0x0401));
586 	float16.push_back(deUint16(0x8401));
587 	// Some normal number
588 	float16.push_back(deUint16(0x14cb));
589 	float16.push_back(deUint16(0x94cb));
590 
591 	const deUint32		numPicks	= static_cast<deUint32>(float16.size());
592 
593 	DE_ASSERT(count >= numPicks);
594 	count -= numPicks;
595 
596 	for (deUint32 numIdx = 0; numIdx < count; ++numIdx)
597 		float16.push_back(rnd.getUint16());
598 
599 	return float16;
600 }
601 
602 } // SpirVAssembly
603 } // vkt
604