1 /*-------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2017 Google Inc.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 * \brief Utilities for Vulkan SPIR-V assembly tests
22 *//*--------------------------------------------------------------------*/
24 #include "vktSpvAsmUtils.hpp"
27 #include "deSTLUtil.hpp"
28 #include "vkQueryUtil.hpp"
29 #include "vkRefUtil.hpp"
30 #include "vkPlatform.hpp"
36 namespace SpirVAssembly
41 std::string VariableLocation::toString() const
43 return "set_" + de::toString(set) + "_binding_" + de::toString(binding);
46 std::string VariableLocation::toDescription() const
48 return "Set " + de::toString(set) + " and Binding " + de::toString(binding);
51 #define IS_CORE_FEATURE_AVAILABLE(CHECKED, AVAILABLE, FEATURE) \
52 if ((CHECKED.FEATURE != DE_FALSE) && (AVAILABLE.FEATURE == DE_FALSE)) { *missingFeature = #FEATURE; return false; }
54 bool isCoreFeaturesSupported (const Context& context,
55 const vk::VkPhysicalDeviceFeatures& toCheck,
56 const char** missingFeature)
58 const VkPhysicalDeviceFeatures& availableFeatures = context.getDeviceFeatures();
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)
119 #define IS_AVAIL(EXT_NAME, FEATURE) \
120 if (toCheck.FEATURE && !extensionFeatures.FEATURE) { *missingFeature = EXT_NAME #FEATURE; return false; }
122 bool isFloat16Int8FeaturesSupported(const Context& context, const vk::VkPhysicalDeviceShaderFloat16Int8Features& toCheck, const char **missingFeature)
124 const VkPhysicalDeviceShaderFloat16Int8Features& extensionFeatures = context.getShaderFloat16Int8Features();
126 IS_AVAIL("ShaderFloat16Int8.", shaderFloat16);
127 IS_AVAIL("ShaderFloat16Int8.", shaderInt8);
132 bool is8BitStorageFeaturesSupported(const Context& context, const vk::VkPhysicalDevice8BitStorageFeatures& toCheck, const char **missingFeature)
134 const VkPhysicalDevice8BitStorageFeatures& extensionFeatures = context.get8BitStorageFeatures();
136 IS_AVAIL("8BitStorage.", storageBuffer8BitAccess);
137 IS_AVAIL("8BitStorage.", uniformAndStorageBuffer8BitAccess);
138 IS_AVAIL("8BitStorage.", storagePushConstant8);
143 bool is16BitStorageFeaturesSupported(const Context& context, const vk::VkPhysicalDevice16BitStorageFeatures& toCheck, const char **missingFeature)
145 const VkPhysicalDevice16BitStorageFeatures& extensionFeatures = context.get16BitStorageFeatures();
147 IS_AVAIL("16BitStorage.", storageBuffer16BitAccess);
148 IS_AVAIL("16BitStorage.", uniformAndStorageBuffer16BitAccess);
149 IS_AVAIL("16BitStorage.", storagePushConstant16);
150 IS_AVAIL("16BitStorage.", storageInputOutput16);
155 bool isVariablePointersFeaturesSupported(const Context& context, const vk::VkPhysicalDeviceVariablePointersFeatures& toCheck, const char **missingFeature)
157 const VkPhysicalDeviceVariablePointersFeatures& extensionFeatures = context.getVariablePointersFeatures();
159 IS_AVAIL("VariablePointers.", variablePointersStorageBuffer);
160 IS_AVAIL("VariablePointers.", variablePointers);
165 bool isVulkanMemoryModelFeaturesSupported(const Context& context, const vk::VkPhysicalDeviceVulkanMemoryModelFeatures& toCheck, const char **missingFeature)
167 const VkPhysicalDeviceVulkanMemoryModelFeatures& extensionFeatures = context.getVulkanMemoryModelFeatures();
169 IS_AVAIL("VulkanMemoryModel.", vulkanMemoryModel);
170 IS_AVAIL("VulkanMemoryModel.", vulkanMemoryModelDeviceScope);
171 IS_AVAIL("VulkanMemoryModel.", vulkanMemoryModelAvailabilityVisibilityChains);
176 #ifndef CTS_USES_VULKANSC
177 bool isIntegerDotProductFeaturesSupported(const Context& context, const vk::VkPhysicalDeviceShaderIntegerDotProductFeaturesKHR& toCheck, const char **missingFeature)
179 const VkPhysicalDeviceShaderIntegerDotProductFeaturesKHR& extensionFeatures = context.getShaderIntegerDotProductFeatures();
181 IS_AVAIL("ShaderIntegerDotProduct.", shaderIntegerDotProduct);
185 #endif // CTS_USES_VULKANSC
189 bool isFloatControlsFeaturesSupported (const Context& context, const vk::VkPhysicalDeviceFloatControlsProperties& toCheck, const char **missingFeature)
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)
209 *missingFeature = "Float controls properties";
211 // return false when float control features are requested and proper extension is not supported
212 if (!context.isDeviceFunctionalitySupported("VK_KHR_shader_float_controls"))
215 // perform query to get supported float control properties
216 vk::VkPhysicalDeviceFloatControlsProperties refControls;
218 refControls.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES;
219 refControls.pNext = DE_NULL;
221 VkPhysicalDeviceProperties2 deviceProperties;
222 deviceProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
223 deviceProperties.pNext = &refControls;
225 const VkPhysicalDevice physicalDevice = context.getPhysicalDevice();
226 const vk::InstanceInterface& instanceInterface = context.getInstanceInterface();
228 instanceInterface.getPhysicalDeviceProperties2(physicalDevice, &deviceProperties);
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;
236 bool requiredDenormBehaviorNotSupported =
237 ((toCheck.denormBehaviorIndependence == fcIndAll) && (refControls.denormBehaviorIndependence != fcIndAll)) ||
238 ((toCheck.denormBehaviorIndependence == fcInd32) && (refControls.denormBehaviorIndependence == fcIndNone));
240 bool requiredRoundingModeNotSupported =
241 ((toCheck.roundingModeIndependence == fcIndAll) && (refControls.roundingModeIndependence != fcIndAll)) ||
242 ((toCheck.roundingModeIndependence == fcInd32) && (refControls.roundingModeIndependence == fcIndNone));
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);
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;
269 bool isVulkanFeaturesSupported(const Context& context, const VulkanFeatures& requested, const char **missingFeature)
271 if (!isCoreFeaturesSupported(context, requested.coreFeatures, missingFeature))
274 if (!is8BitStorageFeaturesSupported(context, requested.ext8BitStorage, missingFeature))
277 if (!is16BitStorageFeaturesSupported(context, requested.ext16BitStorage, missingFeature))
280 if (!isVariablePointersFeaturesSupported(context, requested.extVariablePointers, missingFeature))
283 if (!isFloat16Int8FeaturesSupported(context, requested.extFloat16Int8, missingFeature))
286 if (!isVulkanMemoryModelFeaturesSupported(context, requested.extVulkanMemoryModel, missingFeature))
289 if (!isFloatControlsFeaturesSupported(context, requested.floatControlsProperties, missingFeature))
292 #ifndef CTS_USES_VULKANSC
293 if (!isIntegerDotProductFeaturesSupported(context, requested.extIntegerDotProduct, missingFeature))
295 #endif // CTS_USES_VULKANSC
300 deUint32 getMinRequiredVulkanVersion (const SpirvVersion version)
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
325 std::string getVulkanName (const deUint32 version)
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
336 // Generate and return 64-bit integers.
338 // Expected count to be at least 16.
339 std::vector<deInt64> getInt64s (de::Random& rnd, const deUint32 count)
341 std::vector<deInt64> data;
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
363 DE_ASSERT(count >= data.size());
365 for (deUint32 numNdx = static_cast<deUint32>(data.size()); numNdx < count; ++numNdx)
366 data.push_back(static_cast<deInt64>(rnd.getUint64()));
371 // Generate and return 32-bit integers.
373 // Expected count to be at least 16.
374 std::vector<deInt32> getInt32s (de::Random& rnd, const deUint32 count)
376 std::vector<deInt32> data;
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
398 DE_ASSERT(count >= data.size());
400 for (deUint32 numNdx = static_cast<deUint32>(data.size()); numNdx < count; ++numNdx)
401 data.push_back(static_cast<deInt32>(rnd.getUint32()));
406 // Generate and return 16-bit integers.
408 // Expected count to be at least 8.
409 std::vector<deInt16> getInt16s (de::Random& rnd, const deUint32 count)
411 std::vector<deInt16> data;
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
425 DE_ASSERT(count >= data.size());
427 for (deUint32 numNdx = static_cast<deUint32>(data.size()); numNdx < count; ++numNdx)
428 data.push_back(static_cast<deInt16>(rnd.getUint16()));
433 // Generate and return 8-bit integers.
435 // Expected count to be at least 8.
436 std::vector<deInt8> getInt8s (de::Random& rnd, const deUint32 count)
438 std::vector<deInt8> data;
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
452 DE_ASSERT(count >= data.size());
454 for (deUint32 numNdx = static_cast<deUint32>(data.size()); numNdx < count; ++numNdx)
455 data.push_back(static_cast<deInt8>(rnd.getUint8()));
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 // +--------+------+----------+-------------+
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)
479 // Generate and return 64-bit floats
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)
485 std::vector<double> float64;
487 float64.reserve(count);
492 float64.push_back(0.f);
493 float64.push_back(-0.f);
495 float64.push_back(std::numeric_limits<double>::infinity());
496 float64.push_back(-std::numeric_limits<double>::infinity());
498 float64.push_back(std::numeric_limits<double>::signaling_NaN());
499 float64.push_back(-std::numeric_limits<double>::signaling_NaN());
501 float64.push_back(std::numeric_limits<double>::quiet_NaN());
502 float64.push_back(-std::numeric_limits<double>::quiet_NaN());
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));
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)));
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)));
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));
532 const deUint32 numPicks = static_cast<deUint32>(float64.size());
534 DE_ASSERT(count >= numPicks);
537 for (deUint32 numNdx = 0; numNdx < count; ++numNdx)
539 double randValue = rnd.getDouble();
540 float64.push_back(randValue);
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 // +--------+------+----------+-------------+
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)
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)
569 // Generate and return 32-bit floats
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)
575 std::vector<float> float32;
577 float32.reserve(count);
580 float32.push_back(0.f);
581 float32.push_back(-0.f);
583 float32.push_back(std::numeric_limits<float>::infinity());
584 float32.push_back(-std::numeric_limits<float>::infinity());
586 float32.push_back(std::numeric_limits<float>::signaling_NaN());
587 float32.push_back(-std::numeric_limits<float>::signaling_NaN());
589 float32.push_back(std::numeric_limits<float>::quiet_NaN());
590 float32.push_back(-std::numeric_limits<float>::quiet_NaN());
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));
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)));
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));
618 const deUint32 numPicks = static_cast<deUint32>(float32.size());
620 DE_ASSERT(count >= numPicks);
623 for (deUint32 numNdx = 0; numNdx < count; ++numNdx)
624 float32.push_back(rnd.getFloat());
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 // +--------+------+----------+-------------+
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)
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)
651 // Generate and return 16-bit floats and their corresponding 32-bit values.
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)
657 std::vector<deFloat16> float16;
659 float16.reserve(count);
662 float16.push_back(deUint16(0x0000));
663 float16.push_back(deUint16(0x8000));
665 float16.push_back(deUint16(0x7c00));
666 float16.push_back(deUint16(0xfc00));
668 float16.push_back(deUint16(0x7c0f));
669 float16.push_back(deUint16(0xfc0f));
671 float16.push_back(deUint16(0x7cf0));
672 float16.push_back(deUint16(0xfcf0));
675 float16.push_back(deUint16(0x03f0));
676 float16.push_back(deUint16(0x83f0));
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));
684 const deUint32 numPicks = static_cast<deUint32>(float16.size());
686 DE_ASSERT(count >= numPicks);
689 for (deUint32 numIdx = 0; numIdx < count; ++numIdx)
690 float16.push_back(rnd.getUint16());
695 std::string getOpCapabilityShader()
697 return "OpCapability Shader\n";
700 std::string getUnusedEntryPoint()
702 return "OpEntryPoint Vertex %unused_func \"unused_func\"\n";
705 std::string getUnusedDecorations(const VariableLocation& location)
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";
714 std::string getUnusedTypesAndConstants()
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";
724 std::string getUnusedBuffer()
726 return "%unused_buffer = OpVariable %unused_ptr_Uniform_UnusedBufferType Uniform\n";
729 std::string getUnusedFunctionBody()
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"