3182a79c5bc8ca7e46a8851a34f7f2ce25ab8610
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / spirv_assembly / vktSpvAsmUtils.cpp
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
41 std::string VariableLocation::toString() const
42 {
43         return "set_" + de::toString(set) + "_binding_" + de::toString(binding);
44 }
45
46 std::string VariableLocation::toDescription() const
47 {
48         return "Set " + de::toString(set) + " and Binding " + de::toString(binding);
49 }
50
51 bool is8BitStorageFeaturesSupported (const Context& context, Extension8BitStorageFeatures toCheck)
52 {
53         VkPhysicalDevice8BitStorageFeaturesKHR extensionFeatures = context.get8BitStorageFeatures();
54
55         if ((toCheck & EXT8BITSTORAGEFEATURES_STORAGE_BUFFER) != 0 && extensionFeatures.storageBuffer8BitAccess == VK_FALSE)
56                 TCU_FAIL("storageBuffer8BitAccess has to be supported");
57
58         if ((toCheck & EXT8BITSTORAGEFEATURES_UNIFORM_STORAGE_BUFFER) != 0 && extensionFeatures.uniformAndStorageBuffer8BitAccess == VK_FALSE)
59                 return false;
60
61         if ((toCheck & EXT8BITSTORAGEFEATURES_PUSH_CONSTANT) != 0 && extensionFeatures.storagePushConstant8 == VK_FALSE)
62                 return false;
63
64         return true;
65 }
66
67 #define IS_CORE_FEATURE_AVAILABLE(CHECKED, AVAILABLE, FEATURE)  \
68         if ((CHECKED.FEATURE != DE_FALSE) && (AVAILABLE.FEATURE == DE_FALSE)) { *missingFeature = #FEATURE; return false; }
69
70 bool isCoreFeaturesSupported (const Context&                                            context,
71                                                           const vk::VkPhysicalDeviceFeatures&   toCheck,
72                                                           const char**                                                  missingFeature)
73 {
74         const VkPhysicalDeviceFeatures& availableFeatures       = context.getDeviceFeatures();
75
76         IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, robustBufferAccess);
77         IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, fullDrawIndexUint32);
78         IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, imageCubeArray);
79         IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, independentBlend);
80         IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, geometryShader);
81         IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, tessellationShader);
82         IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, sampleRateShading);
83         IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, dualSrcBlend);
84         IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, logicOp);
85         IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, multiDrawIndirect);
86         IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, drawIndirectFirstInstance);
87         IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, depthClamp);
88         IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, depthBiasClamp);
89         IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, fillModeNonSolid);
90         IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, depthBounds);
91         IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, wideLines);
92         IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, largePoints);
93         IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, alphaToOne);
94         IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, multiViewport);
95         IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, samplerAnisotropy);
96         IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, textureCompressionETC2);
97         IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, textureCompressionASTC_LDR);
98         IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, textureCompressionBC);
99         IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, occlusionQueryPrecise);
100         IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, pipelineStatisticsQuery);
101         IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, vertexPipelineStoresAndAtomics);
102         IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, fragmentStoresAndAtomics);
103         IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, shaderTessellationAndGeometryPointSize);
104         IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, shaderImageGatherExtended);
105         IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, shaderStorageImageExtendedFormats);
106         IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, shaderStorageImageMultisample);
107         IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, shaderStorageImageReadWithoutFormat);
108         IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, shaderStorageImageWriteWithoutFormat);
109         IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, shaderUniformBufferArrayDynamicIndexing);
110         IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, shaderSampledImageArrayDynamicIndexing);
111         IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, shaderStorageBufferArrayDynamicIndexing);
112         IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, shaderStorageImageArrayDynamicIndexing);
113         IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, shaderClipDistance);
114         IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, shaderCullDistance);
115         IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, shaderFloat64);
116         IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, shaderInt64);
117         IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, shaderInt16);
118         IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, shaderResourceResidency);
119         IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, shaderResourceMinLod);
120         IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, sparseBinding);
121         IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, sparseResidencyBuffer);
122         IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, sparseResidencyImage2D);
123         IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, sparseResidencyImage3D);
124         IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, sparseResidency2Samples);
125         IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, sparseResidency4Samples);
126         IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, sparseResidency8Samples);
127         IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, sparseResidency16Samples);
128         IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, sparseResidencyAliased);
129         IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, variableMultisampleRate);
130         IS_CORE_FEATURE_AVAILABLE(toCheck, availableFeatures, inheritedQueries);
131
132         return true;
133 }
134
135 bool is16BitStorageFeaturesSupported (const Context& context, Extension16BitStorageFeatures toCheck)
136 {
137         const VkPhysicalDevice16BitStorageFeatures& extensionFeatures = context.get16BitStorageFeatures();
138
139         if ((toCheck & EXT16BITSTORAGEFEATURES_UNIFORM_BUFFER_BLOCK) != 0 && extensionFeatures.storageBuffer16BitAccess == VK_FALSE)
140                 return false;
141
142         if ((toCheck & EXT16BITSTORAGEFEATURES_UNIFORM) != 0 && extensionFeatures.uniformAndStorageBuffer16BitAccess == VK_FALSE)
143                 return false;
144
145         if ((toCheck & EXT16BITSTORAGEFEATURES_PUSH_CONSTANT) != 0 && extensionFeatures.storagePushConstant16 == VK_FALSE)
146                 return false;
147
148         if ((toCheck & EXT16BITSTORAGEFEATURES_INPUT_OUTPUT) != 0 && extensionFeatures.storageInputOutput16 == VK_FALSE)
149                 return false;
150
151         return true;
152 }
153
154 bool isVariablePointersFeaturesSupported (const Context& context, ExtensionVariablePointersFeatures toCheck)
155 {
156         const VkPhysicalDeviceVariablePointersFeatures& extensionFeatures = context.getVariablePointersFeatures();
157
158         if ((toCheck & EXTVARIABLEPOINTERSFEATURES_VARIABLE_POINTERS_STORAGEBUFFER) != 0 && extensionFeatures.variablePointersStorageBuffer == VK_FALSE)
159                 return false;
160
161         if ((toCheck & EXTVARIABLEPOINTERSFEATURES_VARIABLE_POINTERS) != 0 && extensionFeatures.variablePointers == VK_FALSE)
162                 return false;
163
164         return true;
165 }
166
167 bool isFloat16Int8FeaturesSupported (const Context& context, ExtensionFloat16Int8Features toCheck)
168 {
169         const VkPhysicalDeviceFloat16Int8FeaturesKHR& extensionFeatures = context.getShaderFloat16Int8Features();
170
171         if ((toCheck & EXTFLOAT16INT8FEATURES_FLOAT16) != 0 && extensionFeatures.shaderFloat16 == VK_FALSE)
172                 return false;
173
174         if ((toCheck & EXTFLOAT16INT8FEATURES_INT8) != 0 && extensionFeatures.shaderInt8 == VK_FALSE)
175                 return false;
176
177         return true;
178 }
179
180 bool isFloatControlsFeaturesSupported (const Context& context, const ExtensionFloatControlsFeatures& toCheck)
181 {
182         // if all flags are set to false then no float control features are actualy requested by the test
183         if ((toCheck.shaderSignedZeroInfNanPreserveFloat16 ||
184                  toCheck.shaderSignedZeroInfNanPreserveFloat32 ||
185                  toCheck.shaderSignedZeroInfNanPreserveFloat64 ||
186                  toCheck.shaderDenormPreserveFloat16 ||
187                  toCheck.shaderDenormPreserveFloat32 ||
188                  toCheck.shaderDenormPreserveFloat64 ||
189                  toCheck.shaderDenormFlushToZeroFloat16 ||
190                  toCheck.shaderDenormFlushToZeroFloat32 ||
191                  toCheck.shaderDenormFlushToZeroFloat64 ||
192                  toCheck.shaderRoundingModeRTEFloat16 ||
193                  toCheck.shaderRoundingModeRTEFloat32 ||
194                  toCheck.shaderRoundingModeRTEFloat64 ||
195                  toCheck.shaderRoundingModeRTZFloat16 ||
196                  toCheck.shaderRoundingModeRTZFloat32 ||
197                  toCheck.shaderRoundingModeRTZFloat64) == false)
198                 return true;
199
200         // return false when float control features are requested and proper extension is not supported
201         if (!context.isDeviceFunctionalitySupported("VK_KHR_shader_float_controls"))
202                 return false;
203
204         // perform query to get supported float control properties
205         ExtensionFloatControlsFeatures refControls;
206         {
207                 refControls.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES_KHR;
208                 refControls.pNext = DE_NULL;
209
210                 VkPhysicalDeviceProperties2 deviceProperties;
211                 deviceProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
212                 deviceProperties.pNext = &refControls;
213
214                 const VkPhysicalDevice                  physicalDevice          = context.getPhysicalDevice();
215                 const vk::InstanceInterface&    instanceInterface       = context.getInstanceInterface();
216
217                 instanceInterface.getPhysicalDeviceProperties2(physicalDevice, &deviceProperties);
218         }
219
220         using FCIndependence = VkShaderFloatControlsIndependenceKHR;
221         FCIndependence fcInd32          = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_32_BIT_ONLY_KHR;
222         FCIndependence fcIndAll         = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL_KHR;
223         FCIndependence fcIndNone        = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE_KHR;
224
225         bool requiredDenormBehaviorNotSupported =
226                 ((toCheck.denormBehaviorIndependence == fcIndAll) && (refControls.denormBehaviorIndependence != fcIndAll)) ||
227                 ((toCheck.denormBehaviorIndependence == fcInd32)  && (refControls.denormBehaviorIndependence == fcIndNone));
228
229         bool requiredRoundingModeNotSupported =
230                 ((toCheck.roundingModeIndependence == fcIndAll) && (refControls.roundingModeIndependence != fcIndAll)) ||
231                 ((toCheck.roundingModeIndependence == fcInd32)  && (refControls.roundingModeIndependence == fcIndNone));
232
233         // check if flags needed by the test are not supported by the device
234         bool requiredFeaturesNotSupported =
235                 requiredDenormBehaviorNotSupported ||
236                 requiredRoundingModeNotSupported ||
237                 (toCheck.shaderDenormFlushToZeroFloat16                 && !refControls.shaderDenormFlushToZeroFloat16) ||
238                 (toCheck.shaderDenormPreserveFloat16                    && !refControls.shaderDenormPreserveFloat16) ||
239                 (toCheck.shaderRoundingModeRTEFloat16                   && !refControls.shaderRoundingModeRTEFloat16) ||
240                 (toCheck.shaderRoundingModeRTZFloat16                   && !refControls.shaderRoundingModeRTZFloat16) ||
241                 (toCheck.shaderSignedZeroInfNanPreserveFloat16  && !refControls.shaderSignedZeroInfNanPreserveFloat16) ||
242                 (toCheck.shaderDenormFlushToZeroFloat32                 && !refControls.shaderDenormFlushToZeroFloat32) ||
243                 (toCheck.shaderDenormPreserveFloat32                    && !refControls.shaderDenormPreserveFloat32) ||
244                 (toCheck.shaderRoundingModeRTEFloat32                   && !refControls.shaderRoundingModeRTEFloat32) ||
245                 (toCheck.shaderRoundingModeRTZFloat32                   && !refControls.shaderRoundingModeRTZFloat32) ||
246                 (toCheck.shaderSignedZeroInfNanPreserveFloat32  && !refControls.shaderSignedZeroInfNanPreserveFloat32) ||
247                 (toCheck.shaderDenormFlushToZeroFloat64                 && !refControls.shaderDenormFlushToZeroFloat64) ||
248                 (toCheck.shaderDenormPreserveFloat64                    && !refControls.shaderDenormPreserveFloat64) ||
249                 (toCheck.shaderRoundingModeRTEFloat64                   && !refControls.shaderRoundingModeRTEFloat64) ||
250                 (toCheck.shaderRoundingModeRTZFloat64                   && !refControls.shaderRoundingModeRTZFloat64) ||
251                 (toCheck.shaderSignedZeroInfNanPreserveFloat64  && !refControls.shaderSignedZeroInfNanPreserveFloat64);
252
253         // we checked if required features are not supported - we need to
254         // negate the result to know if all required features are available
255         return !requiredFeaturesNotSupported;
256 }
257
258 deUint32 getMinRequiredVulkanVersion (const SpirvVersion version)
259 {
260         switch(version)
261         {
262         case SPIRV_VERSION_1_0:
263                 return VK_API_VERSION_1_0;
264         case SPIRV_VERSION_1_1:
265         case SPIRV_VERSION_1_2:
266         case SPIRV_VERSION_1_3:
267         case SPIRV_VERSION_1_4:
268                 return VK_API_VERSION_1_1;
269         default:
270                 DE_ASSERT(0);
271         }
272         return 0u;
273 }
274
275 std::string     getVulkanName (const deUint32 version)
276 {
277         return std::string(version == VK_API_VERSION_1_1 ? "1.1" : "1.0");
278 }
279
280 // Generate and return 64-bit integers.
281 //
282 // Expected count to be at least 16.
283 std::vector<deInt64> getInt64s (de::Random& rnd, const deUint32 count)
284 {
285         std::vector<deInt64> data;
286
287         data.reserve(count);
288
289         // Make sure we have boundary numbers.
290         data.push_back(deInt64(0x0000000000000000));  // 0
291         data.push_back(deInt64(0x0000000000000001));  // 1
292         data.push_back(deInt64(0x000000000000002a));  // 42
293         data.push_back(deInt64(0x000000007fffffff));  // 2147483647
294         data.push_back(deInt64(0x0000000080000000));  // 2147483648
295         data.push_back(deInt64(0x00000000ffffffff));  // 4294967295
296         data.push_back(deInt64(0x0000000100000000));  // 4294967296
297         data.push_back(deInt64(0x7fffffffffffffff));  // 9223372036854775807
298         data.push_back(deInt64(0x8000000000000000));  // -9223372036854775808
299         data.push_back(deInt64(0x8000000000000001));  // -9223372036854775807
300         data.push_back(deInt64(0xffffffff00000000));  // -4294967296
301         data.push_back(deInt64(0xffffffff00000001));  // -4294967295
302         data.push_back(deInt64(0xffffffff80000000));  // -2147483648
303         data.push_back(deInt64(0xffffffff80000001));  // -2147483647
304         data.push_back(deInt64(0xffffffffffffffd6));  // -42
305         data.push_back(deInt64(0xffffffffffffffff));  // -1
306
307         DE_ASSERT(count >= data.size());
308
309         for (deUint32 numNdx = static_cast<deUint32>(data.size()); numNdx < count; ++numNdx)
310                 data.push_back(static_cast<deInt64>(rnd.getUint64()));
311
312         return data;
313 }
314
315 // Generate and return 32-bit integers.
316 //
317 // Expected count to be at least 16.
318 std::vector<deInt32> getInt32s (de::Random& rnd, const deUint32 count)
319 {
320         std::vector<deInt32> data;
321
322         data.reserve(count);
323
324         // Make sure we have boundary numbers.
325         data.push_back(deInt32(0x00000000));  // 0
326         data.push_back(deInt32(0x00000001));  // 1
327         data.push_back(deInt32(0x0000002a));  // 42
328         data.push_back(deInt32(0x00007fff));  // 32767
329         data.push_back(deInt32(0x00008000));  // 32768
330         data.push_back(deInt32(0x0000ffff));  // 65535
331         data.push_back(deInt32(0x00010000));  // 65536
332         data.push_back(deInt32(0x7fffffff));  // 2147483647
333         data.push_back(deInt32(0x80000000));  // -2147483648
334         data.push_back(deInt32(0x80000001));  // -2147483647
335         data.push_back(deInt32(0xffff0000));  // -65536
336         data.push_back(deInt32(0xffff0001));  // -65535
337         data.push_back(deInt32(0xffff8000));  // -32768
338         data.push_back(deInt32(0xffff8001));  // -32767
339         data.push_back(deInt32(0xffffffd6));  // -42
340         data.push_back(deInt32(0xffffffff));  // -1
341
342         DE_ASSERT(count >= data.size());
343
344         for (deUint32 numNdx = static_cast<deUint32>(data.size()); numNdx < count; ++numNdx)
345                 data.push_back(static_cast<deInt32>(rnd.getUint32()));
346
347         return data;
348 }
349
350 // Generate and return 16-bit integers.
351 //
352 // Expected count to be at least 8.
353 std::vector<deInt16> getInt16s (de::Random& rnd, const deUint32 count)
354 {
355         std::vector<deInt16> data;
356
357         data.reserve(count);
358
359         // Make sure we have boundary numbers.
360         data.push_back(deInt16(0x0000));  // 0
361         data.push_back(deInt16(0x0001));  // 1
362         data.push_back(deInt16(0x002a));  // 42
363         data.push_back(deInt16(0x7fff));  // 32767
364         data.push_back(deInt16(0x8000));  // -32868
365         data.push_back(deInt16(0x8001));  // -32767
366         data.push_back(deInt16(0xffd6));  // -42
367         data.push_back(deInt16(0xffff));  // -1
368
369         DE_ASSERT(count >= data.size());
370
371         for (deUint32 numNdx = static_cast<deUint32>(data.size()); numNdx < count; ++numNdx)
372                 data.push_back(static_cast<deInt16>(rnd.getUint16()));
373
374         return data;
375 }
376
377 // Generate and return 8-bit integers.
378 //
379 // Expected count to be at least 8.
380 std::vector<deInt8> getInt8s (de::Random& rnd, const deUint32 count)
381 {
382         std::vector<deInt8> data;
383
384         data.reserve(count);
385
386         // Make sure we have boundary numbers.
387         data.push_back(deInt8(0x00));  // 0
388         data.push_back(deInt8(0x01));  // 1
389         data.push_back(deInt8(0x2a));  // 42
390         data.push_back(deInt8(0x7f));  // 127
391         data.push_back(deInt8(0x80));  // -128
392         data.push_back(deInt8(0x81));  // -127
393         data.push_back(deInt8(0xd6));  // -42
394         data.push_back(deInt8(0xff));  // -1
395
396         DE_ASSERT(count >= data.size());
397
398         for (deUint32 numNdx = static_cast<deUint32>(data.size()); numNdx < count; ++numNdx)
399                 data.push_back(static_cast<deInt8>(rnd.getUint8()));
400
401         return data;
402 }
403
404 // IEEE-754 floating point numbers:
405 // +--------+------+----------+-------------+
406 // | binary | sign | exponent | significand |
407 // +--------+------+----------+-------------+
408 // | 64-bit |  1   |    11    |     52      |
409 // +--------+------+----------+-------------+
410 // | 32-bit |  1   |    8     |     23      |
411 // +--------+------+----------+-------------+
412 // | 16-bit |  1   |    5     |     10      |
413 // +--------+------+----------+-------------+
414 //
415 // 64-bit floats:
416 //
417 // (0x3FD2000000000000: 0.28125: with exact match in 16-bit normalized)
418 // (0x3F10060000000000: exact half way within two 16-bit normalized; round to zero: 0x0401)
419 // (0xBF10060000000000: exact half way within two 16-bit normalized; round to zero: 0x8402)
420 // (0x3F100C0000000000: not exact half way within two 16-bit normalized; round to zero: 0x0403)
421 // (0xBF100C0000000000: not exact half way within two 16-bit normalized; round to zero: 0x8404)
422
423 // Generate and return 64-bit floats
424 //
425 // The first 24 number pairs are manually picked, while the rest are randomly generated.
426 // Expected count to be at least 24 (numPicks).
427 std::vector<double> getFloat64s (de::Random& rnd, deUint32 count)
428 {
429         std::vector<double> float64;
430
431         float64.reserve(count);
432
433         if (count >= 24)
434         {
435                 // Zero
436                 float64.push_back(0.f);
437                 float64.push_back(-0.f);
438                 // Infinity
439                 float64.push_back(std::numeric_limits<double>::infinity());
440                 float64.push_back(-std::numeric_limits<double>::infinity());
441                 // SNaN
442                 float64.push_back(std::numeric_limits<double>::signaling_NaN());
443                 float64.push_back(-std::numeric_limits<double>::signaling_NaN());
444                 // QNaN
445                 float64.push_back(std::numeric_limits<double>::quiet_NaN());
446                 float64.push_back(-std::numeric_limits<double>::quiet_NaN());
447
448                 // Denormalized 64-bit float matching 0 in 16-bit
449                 float64.push_back(ldexp((double)1.f, -1023));
450                 float64.push_back(-ldexp((double)1.f, -1023));
451
452                 // Normalized 64-bit float matching 0 in 16-bit
453                 float64.push_back(ldexp((double)1.f, -100));
454                 float64.push_back(-ldexp((double)1.f, -100));
455                 // Normalized 64-bit float with exact denormalized match in 16-bit
456                 float64.push_back(bitwiseCast<double>(deUint64(0x3B0357C299A88EA8)));
457                 float64.push_back(bitwiseCast<double>(deUint64(0xBB0357C299A88EA8)));
458
459                 // Normalized 64-bit float with exact normalized match in 16-bit
460                 float64.push_back(ldexp((double)1.f, -14));  // 2e-14: minimum 16-bit positive normalized
461                 float64.push_back(-ldexp((double)1.f, -14)); // 2e-14: maximum 16-bit negative normalized
462                 // Normalized 64-bit float falling above half way within two 16-bit normalized
463                 float64.push_back(bitwiseCast<double>(deUint64(0x3FD2000000000000)));
464                 float64.push_back(bitwiseCast<double>(deUint64(0xBFD2000000000000)));
465                 // Normalized 64-bit float falling exact half way within two 16-bit normalized
466                 float64.push_back(bitwiseCast<double>(deUint64(0x3F100C0000000000)));
467                 float64.push_back(bitwiseCast<double>(deUint64(0xBF100C0000000000)));
468                 // Some number
469                 float64.push_back((double)0.28125f);
470                 float64.push_back((double)-0.28125f);
471                 // Normalized 64-bit float matching infinity in 16-bit
472                 float64.push_back(ldexp((double)1.f, 100));
473                 float64.push_back(-ldexp((double)1.f, 100));
474         }
475
476         const deUint32          numPicks        = static_cast<deUint32>(float64.size());
477
478         DE_ASSERT(count >= numPicks);
479         count -= numPicks;
480
481         for (deUint32 numNdx = 0; numNdx < count; ++numNdx)
482         {
483                 double randValue = rnd.getDouble();
484                 float64.push_back(randValue);
485         }
486
487         return float64;
488 }
489
490 // IEEE-754 floating point numbers:
491 // +--------+------+----------+-------------+
492 // | binary | sign | exponent | significand |
493 // +--------+------+----------+-------------+
494 // | 16-bit |  1   |    5     |     10      |
495 // +--------+------+----------+-------------+
496 // | 32-bit |  1   |    8     |     23      |
497 // +--------+------+----------+-------------+
498 //
499 // 16-bit floats:
500 //
501 // 0   000 00   00 0000 0001 (0x0001: 2e-24:         minimum positive denormalized)
502 // 0   000 00   11 1111 1111 (0x03ff: 2e-14 - 2e-24: maximum positive denormalized)
503 // 0   000 01   00 0000 0000 (0x0400: 2e-14:         minimum positive normalized)
504 //
505 // 32-bit floats:
506 //
507 // 0   011 1110 1   001 0000 0000 0000 0000 0000 (0x3e900000: 0.28125: with exact match in 16-bit normalized)
508 // 0   011 1000 1   000 0000 0011 0000 0000 0000 (0x38803000: exact half way within two 16-bit normalized; round to zero: 0x0401)
509 // 1   011 1000 1   000 0000 0011 0000 0000 0000 (0xb8803000: exact half way within two 16-bit normalized; round to zero: 0x8402)
510 // 0   011 1000 1   000 0000 1111 1111 0000 0000 (0x3880ff00: not exact half way within two 16-bit normalized; round to zero: 0x0403)
511 // 1   011 1000 1   000 0000 1111 1111 0000 0000 (0xb880ff00: not exact half way within two 16-bit normalized; round to zero: 0x8404)
512
513 // Generate and return 32-bit floats
514 //
515 // The first 24 number pairs are manually picked, while the rest are randomly generated.
516 // Expected count to be at least 24 (numPicks).
517 std::vector<float> getFloat32s (de::Random& rnd, deUint32 count)
518 {
519         std::vector<float> float32;
520
521         float32.reserve(count);
522
523         // Zero
524         float32.push_back(0.f);
525         float32.push_back(-0.f);
526         // Infinity
527         float32.push_back(std::numeric_limits<float>::infinity());
528         float32.push_back(-std::numeric_limits<float>::infinity());
529         // SNaN
530         float32.push_back(std::numeric_limits<float>::signaling_NaN());
531         float32.push_back(-std::numeric_limits<float>::signaling_NaN());
532         // QNaN
533         float32.push_back(std::numeric_limits<float>::quiet_NaN());
534         float32.push_back(-std::numeric_limits<float>::quiet_NaN());
535
536         // Denormalized 32-bit float matching 0 in 16-bit
537         float32.push_back(deFloatLdExp(1.f, -127));
538         float32.push_back(-deFloatLdExp(1.f, -127));
539
540         // Normalized 32-bit float matching 0 in 16-bit
541         float32.push_back(deFloatLdExp(1.f, -100));
542         float32.push_back(-deFloatLdExp(1.f, -100));
543         // Normalized 32-bit float with exact denormalized match in 16-bit
544         float32.push_back(deFloatLdExp(1.f, -24));  // 2e-24: minimum 16-bit positive denormalized
545         float32.push_back(-deFloatLdExp(1.f, -24)); // 2e-24: maximum 16-bit negative denormalized
546         // Normalized 32-bit float with exact normalized match in 16-bit
547         float32.push_back(deFloatLdExp(1.f, -14));  // 2e-14: minimum 16-bit positive normalized
548         float32.push_back(-deFloatLdExp(1.f, -14)); // 2e-14: maximum 16-bit negative normalized
549         // Normalized 32-bit float falling above half way within two 16-bit normalized
550         float32.push_back(bitwiseCast<float>(deUint32(0x3880ff00)));
551         float32.push_back(bitwiseCast<float>(deUint32(0xb880ff00)));
552         // Normalized 32-bit float falling exact half way within two 16-bit normalized
553         float32.push_back(bitwiseCast<float>(deUint32(0x38803000)));
554         float32.push_back(bitwiseCast<float>(deUint32(0xb8803000)));
555         // Some number
556         float32.push_back(0.28125f);
557         float32.push_back(-0.28125f);
558         // Normalized 32-bit float matching infinity in 16-bit
559         float32.push_back(deFloatLdExp(1.f, 100));
560         float32.push_back(-deFloatLdExp(1.f, 100));
561
562         const deUint32          numPicks        = static_cast<deUint32>(float32.size());
563
564         DE_ASSERT(count >= numPicks);
565         count -= numPicks;
566
567         for (deUint32 numNdx = 0; numNdx < count; ++numNdx)
568                 float32.push_back(rnd.getFloat());
569
570         return float32;
571 }
572
573 // IEEE-754 floating point numbers:
574 // +--------+------+----------+-------------+
575 // | binary | sign | exponent | significand |
576 // +--------+------+----------+-------------+
577 // | 16-bit |  1   |    5     |     10      |
578 // +--------+------+----------+-------------+
579 // | 32-bit |  1   |    8     |     23      |
580 // +--------+------+----------+-------------+
581 //
582 // 16-bit floats:
583 //
584 // 0   000 00   00 0000 0001 (0x0001: 2e-24:         minimum positive denormalized)
585 // 0   000 00   11 1111 1111 (0x03ff: 2e-14 - 2e-24: maximum positive denormalized)
586 // 0   000 01   00 0000 0000 (0x0400: 2e-14:         minimum positive normalized)
587 //
588 // 0   000 00   00 0000 0000 (0x0000: +0)
589 // 0   111 11   00 0000 0000 (0x7c00: +Inf)
590 // 0   000 00   11 1111 0000 (0x03f0: +Denorm)
591 // 0   000 01   00 0000 0001 (0x0401: +Norm)
592 // 0   111 11   00 0000 1111 (0x7c0f: +SNaN)
593 // 0   111 11   00 1111 0000 (0x7c0f: +QNaN)
594
595 // Generate and return 16-bit floats and their corresponding 32-bit values.
596 //
597 // The first 14 number pairs are manually picked, while the rest are randomly generated.
598 // Expected count to be at least 14 (numPicks).
599 std::vector<deFloat16> getFloat16s (de::Random& rnd, deUint32 count)
600 {
601         std::vector<deFloat16> float16;
602
603         float16.reserve(count);
604
605         // Zero
606         float16.push_back(deUint16(0x0000));
607         float16.push_back(deUint16(0x8000));
608         // Infinity
609         float16.push_back(deUint16(0x7c00));
610         float16.push_back(deUint16(0xfc00));
611         // SNaN
612         float16.push_back(deUint16(0x7c0f));
613         float16.push_back(deUint16(0xfc0f));
614         // QNaN
615         float16.push_back(deUint16(0x7cf0));
616         float16.push_back(deUint16(0xfcf0));
617
618         // Denormalized
619         float16.push_back(deUint16(0x03f0));
620         float16.push_back(deUint16(0x83f0));
621         // Normalized
622         float16.push_back(deUint16(0x0401));
623         float16.push_back(deUint16(0x8401));
624         // Some normal number
625         float16.push_back(deUint16(0x14cb));
626         float16.push_back(deUint16(0x94cb));
627
628         const deUint32          numPicks        = static_cast<deUint32>(float16.size());
629
630         DE_ASSERT(count >= numPicks);
631         count -= numPicks;
632
633         for (deUint32 numIdx = 0; numIdx < count; ++numIdx)
634                 float16.push_back(rnd.getUint16());
635
636         return float16;
637 }
638
639 std::string getOpCapabilityShader()
640 {
641         return  "OpCapability Shader\n";
642 }
643
644 std::string getUnusedEntryPoint()
645 {
646         return  "OpEntryPoint Vertex %unused_func \"unused_func\"\n";
647 }
648
649 std::string getUnusedDecorations(const VariableLocation& location)
650 {
651         return  "OpMemberDecorate %UnusedBufferType 0 Offset 0\n"
652             "OpMemberDecorate %UnusedBufferType 1 Offset 4\n"
653             "OpDecorate %UnusedBufferType BufferBlock\n"
654             "OpDecorate %unused_buffer DescriptorSet " + de::toString(location.set) + "\n"
655             "OpDecorate %unused_buffer Binding " + de::toString(location.binding) + "\n";
656 }
657
658 std::string getUnusedTypesAndConstants()
659 {
660         return  "%c_f32_101 = OpConstant %f32 101\n"
661                         "%c_i32_201 = OpConstant %i32 201\n"
662                         "%UnusedBufferType = OpTypeStruct %f32 %i32\n"
663                         "%unused_ptr_Uniform_UnusedBufferType = OpTypePointer Uniform %UnusedBufferType\n"
664                         "%unused_ptr_Uniform_float = OpTypePointer Uniform %f32\n"
665                         "%unused_ptr_Uniform_int = OpTypePointer Uniform %i32\n";
666 }
667
668 std::string getUnusedBuffer()
669 {
670         return  "%unused_buffer = OpVariable %unused_ptr_Uniform_UnusedBufferType Uniform\n";
671 }
672
673 std::string getUnusedFunctionBody()
674 {
675         return  "%unused_func = OpFunction %void None %voidf\n"
676                         "%unused_func_label = OpLabel\n"
677                         "%unused_out_float_ptr = OpAccessChain %unused_ptr_Uniform_float %unused_buffer %c_i32_0\n"
678             "OpStore %unused_out_float_ptr %c_f32_101\n"
679                         "%unused_out_int_ptr = OpAccessChain %unused_ptr_Uniform_int %unused_buffer %c_i32_1\n"
680             "OpStore %unused_out_int_ptr %c_i32_201\n"
681             "OpReturn\n"
682             "OpFunctionEnd\n";
683 }
684
685 } // SpirVAssembly
686 } // vkt