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