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