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
toString() const41 std::string VariableLocation::toString() const
42 {
43 return "set_" + de::toString(set) + "_binding_" + de::toString(binding);
44 }
45
toDescription() const46 std::string VariableLocation::toDescription() const
47 {
48 return "Set " + de::toString(set) + " and Binding " + de::toString(binding);
49 }
50
is8BitStorageFeaturesSupported(const Context & context,Extension8BitStorageFeatures toCheck)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 return false;
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
isCoreFeaturesSupported(const Context & context,const vk::VkPhysicalDeviceFeatures & toCheck,const char ** missingFeature)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
is16BitStorageFeaturesSupported(const Context & context,Extension16BitStorageFeatures toCheck)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
isVariablePointersFeaturesSupported(const Context & context,ExtensionVariablePointersFeatures toCheck)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
isFloat16Int8FeaturesSupported(const Context & context,ExtensionFloat16Int8Features toCheck)167 bool isFloat16Int8FeaturesSupported (const Context& context, ExtensionFloat16Int8Features toCheck)
168 {
169 const VkPhysicalDeviceShaderFloat16Int8Features& 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
isVulkanMemoryModelFeaturesSupported(const Context & context,ExtensionVulkanMemoryModelFeatures toCheck)180 bool isVulkanMemoryModelFeaturesSupported (const Context& context, ExtensionVulkanMemoryModelFeatures toCheck)
181 {
182 const VkPhysicalDeviceVulkanMemoryModelFeaturesKHR& extensionFeatures = context.getVulkanMemoryModelFeatures();
183
184 if ((toCheck & EXTVULKANMEMORYMODELFEATURES_ENABLE) != 0 && extensionFeatures.vulkanMemoryModel == VK_FALSE)
185 return false;
186
187 if ((toCheck & EXTVULKANMEMORYMODELFEATURES_DEVICESCOPE) != 0 && extensionFeatures.vulkanMemoryModelDeviceScope == VK_FALSE)
188 return false;
189
190 if ((toCheck & EXTVULKANMEMORYMODELFEATURES_AVAILABILITYVISIBILITYCHAINS) != 0 && extensionFeatures.vulkanMemoryModelAvailabilityVisibilityChains == VK_FALSE)
191 return false;
192
193 return true;
194 }
195
isFloatControlsFeaturesSupported(const Context & context,const ExtensionFloatControlsFeatures & toCheck)196 bool isFloatControlsFeaturesSupported (const Context& context, const ExtensionFloatControlsFeatures& toCheck)
197 {
198 // if all flags are set to false then no float control features are actualy requested by the test
199 if ((toCheck.shaderSignedZeroInfNanPreserveFloat16 ||
200 toCheck.shaderSignedZeroInfNanPreserveFloat32 ||
201 toCheck.shaderSignedZeroInfNanPreserveFloat64 ||
202 toCheck.shaderDenormPreserveFloat16 ||
203 toCheck.shaderDenormPreserveFloat32 ||
204 toCheck.shaderDenormPreserveFloat64 ||
205 toCheck.shaderDenormFlushToZeroFloat16 ||
206 toCheck.shaderDenormFlushToZeroFloat32 ||
207 toCheck.shaderDenormFlushToZeroFloat64 ||
208 toCheck.shaderRoundingModeRTEFloat16 ||
209 toCheck.shaderRoundingModeRTEFloat32 ||
210 toCheck.shaderRoundingModeRTEFloat64 ||
211 toCheck.shaderRoundingModeRTZFloat16 ||
212 toCheck.shaderRoundingModeRTZFloat32 ||
213 toCheck.shaderRoundingModeRTZFloat64) == false)
214 return true;
215
216 // return false when float control features are requested and proper extension is not supported
217 if (!context.isDeviceFunctionalitySupported("VK_KHR_shader_float_controls"))
218 return false;
219
220 // perform query to get supported float control properties
221 ExtensionFloatControlsFeatures refControls;
222 {
223 refControls.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES_KHR;
224 refControls.pNext = DE_NULL;
225
226 VkPhysicalDeviceProperties2 deviceProperties;
227 deviceProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
228 deviceProperties.pNext = &refControls;
229
230 const VkPhysicalDevice physicalDevice = context.getPhysicalDevice();
231 const vk::InstanceInterface& instanceInterface = context.getInstanceInterface();
232
233 instanceInterface.getPhysicalDeviceProperties2(physicalDevice, &deviceProperties);
234 }
235
236 using FCIndependence = VkShaderFloatControlsIndependence;
237 FCIndependence fcInd32 = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_32_BIT_ONLY_KHR;
238 FCIndependence fcIndAll = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_ALL_KHR;
239 FCIndependence fcIndNone = VK_SHADER_FLOAT_CONTROLS_INDEPENDENCE_NONE_KHR;
240
241 bool requiredDenormBehaviorNotSupported =
242 ((toCheck.denormBehaviorIndependence == fcIndAll) && (refControls.denormBehaviorIndependence != fcIndAll)) ||
243 ((toCheck.denormBehaviorIndependence == fcInd32) && (refControls.denormBehaviorIndependence == fcIndNone));
244
245 bool requiredRoundingModeNotSupported =
246 ((toCheck.roundingModeIndependence == fcIndAll) && (refControls.roundingModeIndependence != fcIndAll)) ||
247 ((toCheck.roundingModeIndependence == fcInd32) && (refControls.roundingModeIndependence == fcIndNone));
248
249 // check if flags needed by the test are not supported by the device
250 bool requiredFeaturesNotSupported =
251 requiredDenormBehaviorNotSupported ||
252 requiredRoundingModeNotSupported ||
253 (toCheck.shaderDenormFlushToZeroFloat16 && !refControls.shaderDenormFlushToZeroFloat16) ||
254 (toCheck.shaderDenormPreserveFloat16 && !refControls.shaderDenormPreserveFloat16) ||
255 (toCheck.shaderRoundingModeRTEFloat16 && !refControls.shaderRoundingModeRTEFloat16) ||
256 (toCheck.shaderRoundingModeRTZFloat16 && !refControls.shaderRoundingModeRTZFloat16) ||
257 (toCheck.shaderSignedZeroInfNanPreserveFloat16 && !refControls.shaderSignedZeroInfNanPreserveFloat16) ||
258 (toCheck.shaderDenormFlushToZeroFloat32 && !refControls.shaderDenormFlushToZeroFloat32) ||
259 (toCheck.shaderDenormPreserveFloat32 && !refControls.shaderDenormPreserveFloat32) ||
260 (toCheck.shaderRoundingModeRTEFloat32 && !refControls.shaderRoundingModeRTEFloat32) ||
261 (toCheck.shaderRoundingModeRTZFloat32 && !refControls.shaderRoundingModeRTZFloat32) ||
262 (toCheck.shaderSignedZeroInfNanPreserveFloat32 && !refControls.shaderSignedZeroInfNanPreserveFloat32) ||
263 (toCheck.shaderDenormFlushToZeroFloat64 && !refControls.shaderDenormFlushToZeroFloat64) ||
264 (toCheck.shaderDenormPreserveFloat64 && !refControls.shaderDenormPreserveFloat64) ||
265 (toCheck.shaderRoundingModeRTEFloat64 && !refControls.shaderRoundingModeRTEFloat64) ||
266 (toCheck.shaderRoundingModeRTZFloat64 && !refControls.shaderRoundingModeRTZFloat64) ||
267 (toCheck.shaderSignedZeroInfNanPreserveFloat64 && !refControls.shaderSignedZeroInfNanPreserveFloat64);
268
269 // we checked if required features are not supported - we need to
270 // negate the result to know if all required features are available
271 return !requiredFeaturesNotSupported;
272 }
273
getMinRequiredVulkanVersion(const SpirvVersion version)274 deUint32 getMinRequiredVulkanVersion (const SpirvVersion version)
275 {
276 switch(version)
277 {
278 case SPIRV_VERSION_1_0:
279 return VK_API_VERSION_1_0;
280 case SPIRV_VERSION_1_1:
281 case SPIRV_VERSION_1_2:
282 case SPIRV_VERSION_1_3:
283 case SPIRV_VERSION_1_4:
284 return VK_API_VERSION_1_1;
285 case SPIRV_VERSION_1_5:
286 return VK_API_VERSION_1_2;
287 default:
288 DE_ASSERT(0);
289 }
290 return 0u;
291 }
292
getVulkanName(const deUint32 version)293 std::string getVulkanName (const deUint32 version)
294 {
295 return std::string(version == VK_API_VERSION_1_1 ? "1.1" : "1.0");
296 }
297
298 // Generate and return 64-bit integers.
299 //
300 // Expected count to be at least 16.
getInt64s(de::Random & rnd,const deUint32 count)301 std::vector<deInt64> getInt64s (de::Random& rnd, const deUint32 count)
302 {
303 std::vector<deInt64> data;
304
305 data.reserve(count);
306
307 // Make sure we have boundary numbers.
308 data.push_back(deInt64(0x0000000000000000)); // 0
309 data.push_back(deInt64(0x0000000000000001)); // 1
310 data.push_back(deInt64(0x000000000000002a)); // 42
311 data.push_back(deInt64(0x000000007fffffff)); // 2147483647
312 data.push_back(deInt64(0x0000000080000000)); // 2147483648
313 data.push_back(deInt64(0x00000000ffffffff)); // 4294967295
314 data.push_back(deInt64(0x0000000100000000)); // 4294967296
315 data.push_back(deInt64(0x7fffffffffffffff)); // 9223372036854775807
316 data.push_back(deInt64(0x8000000000000000)); // -9223372036854775808
317 data.push_back(deInt64(0x8000000000000001)); // -9223372036854775807
318 data.push_back(deInt64(0xffffffff00000000)); // -4294967296
319 data.push_back(deInt64(0xffffffff00000001)); // -4294967295
320 data.push_back(deInt64(0xffffffff80000000)); // -2147483648
321 data.push_back(deInt64(0xffffffff80000001)); // -2147483647
322 data.push_back(deInt64(0xffffffffffffffd6)); // -42
323 data.push_back(deInt64(0xffffffffffffffff)); // -1
324
325 DE_ASSERT(count >= data.size());
326
327 for (deUint32 numNdx = static_cast<deUint32>(data.size()); numNdx < count; ++numNdx)
328 data.push_back(static_cast<deInt64>(rnd.getUint64()));
329
330 return data;
331 }
332
333 // Generate and return 32-bit integers.
334 //
335 // Expected count to be at least 16.
getInt32s(de::Random & rnd,const deUint32 count)336 std::vector<deInt32> getInt32s (de::Random& rnd, const deUint32 count)
337 {
338 std::vector<deInt32> data;
339
340 data.reserve(count);
341
342 // Make sure we have boundary numbers.
343 data.push_back(deInt32(0x00000000)); // 0
344 data.push_back(deInt32(0x00000001)); // 1
345 data.push_back(deInt32(0x0000002a)); // 42
346 data.push_back(deInt32(0x00007fff)); // 32767
347 data.push_back(deInt32(0x00008000)); // 32768
348 data.push_back(deInt32(0x0000ffff)); // 65535
349 data.push_back(deInt32(0x00010000)); // 65536
350 data.push_back(deInt32(0x7fffffff)); // 2147483647
351 data.push_back(deInt32(0x80000000)); // -2147483648
352 data.push_back(deInt32(0x80000001)); // -2147483647
353 data.push_back(deInt32(0xffff0000)); // -65536
354 data.push_back(deInt32(0xffff0001)); // -65535
355 data.push_back(deInt32(0xffff8000)); // -32768
356 data.push_back(deInt32(0xffff8001)); // -32767
357 data.push_back(deInt32(0xffffffd6)); // -42
358 data.push_back(deInt32(0xffffffff)); // -1
359
360 DE_ASSERT(count >= data.size());
361
362 for (deUint32 numNdx = static_cast<deUint32>(data.size()); numNdx < count; ++numNdx)
363 data.push_back(static_cast<deInt32>(rnd.getUint32()));
364
365 return data;
366 }
367
368 // Generate and return 16-bit integers.
369 //
370 // Expected count to be at least 8.
getInt16s(de::Random & rnd,const deUint32 count)371 std::vector<deInt16> getInt16s (de::Random& rnd, const deUint32 count)
372 {
373 std::vector<deInt16> data;
374
375 data.reserve(count);
376
377 // Make sure we have boundary numbers.
378 data.push_back(deInt16(0x0000)); // 0
379 data.push_back(deInt16(0x0001)); // 1
380 data.push_back(deInt16(0x002a)); // 42
381 data.push_back(deInt16(0x7fff)); // 32767
382 data.push_back(deInt16(0x8000)); // -32868
383 data.push_back(deInt16(0x8001)); // -32767
384 data.push_back(deInt16(0xffd6)); // -42
385 data.push_back(deInt16(0xffff)); // -1
386
387 DE_ASSERT(count >= data.size());
388
389 for (deUint32 numNdx = static_cast<deUint32>(data.size()); numNdx < count; ++numNdx)
390 data.push_back(static_cast<deInt16>(rnd.getUint16()));
391
392 return data;
393 }
394
395 // Generate and return 8-bit integers.
396 //
397 // Expected count to be at least 8.
getInt8s(de::Random & rnd,const deUint32 count)398 std::vector<deInt8> getInt8s (de::Random& rnd, const deUint32 count)
399 {
400 std::vector<deInt8> data;
401
402 data.reserve(count);
403
404 // Make sure we have boundary numbers.
405 data.push_back(deInt8(0x00)); // 0
406 data.push_back(deInt8(0x01)); // 1
407 data.push_back(deInt8(0x2a)); // 42
408 data.push_back(deInt8(0x7f)); // 127
409 data.push_back(deInt8(0x80)); // -128
410 data.push_back(deInt8(0x81)); // -127
411 data.push_back(deInt8(0xd6)); // -42
412 data.push_back(deInt8(0xff)); // -1
413
414 DE_ASSERT(count >= data.size());
415
416 for (deUint32 numNdx = static_cast<deUint32>(data.size()); numNdx < count; ++numNdx)
417 data.push_back(static_cast<deInt8>(rnd.getUint8()));
418
419 return data;
420 }
421
422 // IEEE-754 floating point numbers:
423 // +--------+------+----------+-------------+
424 // | binary | sign | exponent | significand |
425 // +--------+------+----------+-------------+
426 // | 64-bit | 1 | 11 | 52 |
427 // +--------+------+----------+-------------+
428 // | 32-bit | 1 | 8 | 23 |
429 // +--------+------+----------+-------------+
430 // | 16-bit | 1 | 5 | 10 |
431 // +--------+------+----------+-------------+
432 //
433 // 64-bit floats:
434 //
435 // (0x3FD2000000000000: 0.28125: with exact match in 16-bit normalized)
436 // (0x3F10060000000000: exact half way within two 16-bit normalized; round to zero: 0x0401)
437 // (0xBF10060000000000: exact half way within two 16-bit normalized; round to zero: 0x8402)
438 // (0x3F100C0000000000: not exact half way within two 16-bit normalized; round to zero: 0x0403)
439 // (0xBF100C0000000000: not exact half way within two 16-bit normalized; round to zero: 0x8404)
440
441 // Generate and return 64-bit floats
442 //
443 // The first 24 number pairs are manually picked, while the rest are randomly generated.
444 // Expected count to be at least 24 (numPicks).
getFloat64s(de::Random & rnd,deUint32 count)445 std::vector<double> getFloat64s (de::Random& rnd, deUint32 count)
446 {
447 std::vector<double> float64;
448
449 float64.reserve(count);
450
451 if (count >= 24)
452 {
453 // Zero
454 float64.push_back(0.f);
455 float64.push_back(-0.f);
456 // Infinity
457 float64.push_back(std::numeric_limits<double>::infinity());
458 float64.push_back(-std::numeric_limits<double>::infinity());
459 // SNaN
460 float64.push_back(std::numeric_limits<double>::signaling_NaN());
461 float64.push_back(-std::numeric_limits<double>::signaling_NaN());
462 // QNaN
463 float64.push_back(std::numeric_limits<double>::quiet_NaN());
464 float64.push_back(-std::numeric_limits<double>::quiet_NaN());
465
466 // Denormalized 64-bit float matching 0 in 16-bit
467 float64.push_back(ldexp((double)1.f, -1023));
468 float64.push_back(-ldexp((double)1.f, -1023));
469
470 // Normalized 64-bit float matching 0 in 16-bit
471 float64.push_back(ldexp((double)1.f, -100));
472 float64.push_back(-ldexp((double)1.f, -100));
473 // Normalized 64-bit float with exact denormalized match in 16-bit
474 float64.push_back(bitwiseCast<double>(deUint64(0x3B0357C299A88EA8)));
475 float64.push_back(bitwiseCast<double>(deUint64(0xBB0357C299A88EA8)));
476
477 // Normalized 64-bit float with exact normalized match in 16-bit
478 float64.push_back(ldexp((double)1.f, -14)); // 2e-14: minimum 16-bit positive normalized
479 float64.push_back(-ldexp((double)1.f, -14)); // 2e-14: maximum 16-bit negative normalized
480 // Normalized 64-bit float falling above half way within two 16-bit normalized
481 float64.push_back(bitwiseCast<double>(deUint64(0x3FD2000000000000)));
482 float64.push_back(bitwiseCast<double>(deUint64(0xBFD2000000000000)));
483 // Normalized 64-bit float falling exact half way within two 16-bit normalized
484 float64.push_back(bitwiseCast<double>(deUint64(0x3F100C0000000000)));
485 float64.push_back(bitwiseCast<double>(deUint64(0xBF100C0000000000)));
486 // Some number
487 float64.push_back((double)0.28125f);
488 float64.push_back((double)-0.28125f);
489 // Normalized 64-bit float matching infinity in 16-bit
490 float64.push_back(ldexp((double)1.f, 100));
491 float64.push_back(-ldexp((double)1.f, 100));
492 }
493
494 const deUint32 numPicks = static_cast<deUint32>(float64.size());
495
496 DE_ASSERT(count >= numPicks);
497 count -= numPicks;
498
499 for (deUint32 numNdx = 0; numNdx < count; ++numNdx)
500 {
501 double randValue = rnd.getDouble();
502 float64.push_back(randValue);
503 }
504
505 return float64;
506 }
507
508 // IEEE-754 floating point numbers:
509 // +--------+------+----------+-------------+
510 // | binary | sign | exponent | significand |
511 // +--------+------+----------+-------------+
512 // | 16-bit | 1 | 5 | 10 |
513 // +--------+------+----------+-------------+
514 // | 32-bit | 1 | 8 | 23 |
515 // +--------+------+----------+-------------+
516 //
517 // 16-bit floats:
518 //
519 // 0 000 00 00 0000 0001 (0x0001: 2e-24: minimum positive denormalized)
520 // 0 000 00 11 1111 1111 (0x03ff: 2e-14 - 2e-24: maximum positive denormalized)
521 // 0 000 01 00 0000 0000 (0x0400: 2e-14: minimum positive normalized)
522 //
523 // 32-bit floats:
524 //
525 // 0 011 1110 1 001 0000 0000 0000 0000 0000 (0x3e900000: 0.28125: with exact match in 16-bit normalized)
526 // 0 011 1000 1 000 0000 0011 0000 0000 0000 (0x38803000: exact half way within two 16-bit normalized; round to zero: 0x0401)
527 // 1 011 1000 1 000 0000 0011 0000 0000 0000 (0xb8803000: exact half way within two 16-bit normalized; round to zero: 0x8402)
528 // 0 011 1000 1 000 0000 1111 1111 0000 0000 (0x3880ff00: not exact half way within two 16-bit normalized; round to zero: 0x0403)
529 // 1 011 1000 1 000 0000 1111 1111 0000 0000 (0xb880ff00: not exact half way within two 16-bit normalized; round to zero: 0x8404)
530
531 // Generate and return 32-bit floats
532 //
533 // The first 24 number pairs are manually picked, while the rest are randomly generated.
534 // Expected count to be at least 24 (numPicks).
getFloat32s(de::Random & rnd,deUint32 count)535 std::vector<float> getFloat32s (de::Random& rnd, deUint32 count)
536 {
537 std::vector<float> float32;
538
539 float32.reserve(count);
540
541 // Zero
542 float32.push_back(0.f);
543 float32.push_back(-0.f);
544 // Infinity
545 float32.push_back(std::numeric_limits<float>::infinity());
546 float32.push_back(-std::numeric_limits<float>::infinity());
547 // SNaN
548 float32.push_back(std::numeric_limits<float>::signaling_NaN());
549 float32.push_back(-std::numeric_limits<float>::signaling_NaN());
550 // QNaN
551 float32.push_back(std::numeric_limits<float>::quiet_NaN());
552 float32.push_back(-std::numeric_limits<float>::quiet_NaN());
553
554 // Denormalized 32-bit float matching 0 in 16-bit
555 float32.push_back(deFloatLdExp(1.f, -127));
556 float32.push_back(-deFloatLdExp(1.f, -127));
557
558 // Normalized 32-bit float matching 0 in 16-bit
559 float32.push_back(deFloatLdExp(1.f, -100));
560 float32.push_back(-deFloatLdExp(1.f, -100));
561 // Normalized 32-bit float with exact denormalized match in 16-bit
562 float32.push_back(deFloatLdExp(1.f, -24)); // 2e-24: minimum 16-bit positive denormalized
563 float32.push_back(-deFloatLdExp(1.f, -24)); // 2e-24: maximum 16-bit negative denormalized
564 // Normalized 32-bit float with exact normalized match in 16-bit
565 float32.push_back(deFloatLdExp(1.f, -14)); // 2e-14: minimum 16-bit positive normalized
566 float32.push_back(-deFloatLdExp(1.f, -14)); // 2e-14: maximum 16-bit negative normalized
567 // Normalized 32-bit float falling above half way within two 16-bit normalized
568 float32.push_back(bitwiseCast<float>(deUint32(0x3880ff00)));
569 float32.push_back(bitwiseCast<float>(deUint32(0xb880ff00)));
570 // Normalized 32-bit float falling exact half way within two 16-bit normalized
571 float32.push_back(bitwiseCast<float>(deUint32(0x38803000)));
572 float32.push_back(bitwiseCast<float>(deUint32(0xb8803000)));
573 // Some number
574 float32.push_back(0.28125f);
575 float32.push_back(-0.28125f);
576 // Normalized 32-bit float matching infinity in 16-bit
577 float32.push_back(deFloatLdExp(1.f, 100));
578 float32.push_back(-deFloatLdExp(1.f, 100));
579
580 const deUint32 numPicks = static_cast<deUint32>(float32.size());
581
582 DE_ASSERT(count >= numPicks);
583 count -= numPicks;
584
585 for (deUint32 numNdx = 0; numNdx < count; ++numNdx)
586 float32.push_back(rnd.getFloat());
587
588 return float32;
589 }
590
591 // IEEE-754 floating point numbers:
592 // +--------+------+----------+-------------+
593 // | binary | sign | exponent | significand |
594 // +--------+------+----------+-------------+
595 // | 16-bit | 1 | 5 | 10 |
596 // +--------+------+----------+-------------+
597 // | 32-bit | 1 | 8 | 23 |
598 // +--------+------+----------+-------------+
599 //
600 // 16-bit floats:
601 //
602 // 0 000 00 00 0000 0001 (0x0001: 2e-24: minimum positive denormalized)
603 // 0 000 00 11 1111 1111 (0x03ff: 2e-14 - 2e-24: maximum positive denormalized)
604 // 0 000 01 00 0000 0000 (0x0400: 2e-14: minimum positive normalized)
605 //
606 // 0 000 00 00 0000 0000 (0x0000: +0)
607 // 0 111 11 00 0000 0000 (0x7c00: +Inf)
608 // 0 000 00 11 1111 0000 (0x03f0: +Denorm)
609 // 0 000 01 00 0000 0001 (0x0401: +Norm)
610 // 0 111 11 00 0000 1111 (0x7c0f: +SNaN)
611 // 0 111 11 00 1111 0000 (0x7c0f: +QNaN)
612
613 // Generate and return 16-bit floats and their corresponding 32-bit values.
614 //
615 // The first 14 number pairs are manually picked, while the rest are randomly generated.
616 // Expected count to be at least 14 (numPicks).
getFloat16s(de::Random & rnd,deUint32 count)617 std::vector<deFloat16> getFloat16s (de::Random& rnd, deUint32 count)
618 {
619 std::vector<deFloat16> float16;
620
621 float16.reserve(count);
622
623 // Zero
624 float16.push_back(deUint16(0x0000));
625 float16.push_back(deUint16(0x8000));
626 // Infinity
627 float16.push_back(deUint16(0x7c00));
628 float16.push_back(deUint16(0xfc00));
629 // SNaN
630 float16.push_back(deUint16(0x7c0f));
631 float16.push_back(deUint16(0xfc0f));
632 // QNaN
633 float16.push_back(deUint16(0x7cf0));
634 float16.push_back(deUint16(0xfcf0));
635
636 // Denormalized
637 float16.push_back(deUint16(0x03f0));
638 float16.push_back(deUint16(0x83f0));
639 // Normalized
640 float16.push_back(deUint16(0x0401));
641 float16.push_back(deUint16(0x8401));
642 // Some normal number
643 float16.push_back(deUint16(0x14cb));
644 float16.push_back(deUint16(0x94cb));
645
646 const deUint32 numPicks = static_cast<deUint32>(float16.size());
647
648 DE_ASSERT(count >= numPicks);
649 count -= numPicks;
650
651 for (deUint32 numIdx = 0; numIdx < count; ++numIdx)
652 float16.push_back(rnd.getUint16());
653
654 return float16;
655 }
656
getOpCapabilityShader()657 std::string getOpCapabilityShader()
658 {
659 return "OpCapability Shader\n";
660 }
661
getUnusedEntryPoint()662 std::string getUnusedEntryPoint()
663 {
664 return "OpEntryPoint Vertex %unused_func \"unused_func\"\n";
665 }
666
getUnusedDecorations(const VariableLocation & location)667 std::string getUnusedDecorations(const VariableLocation& location)
668 {
669 return "OpMemberDecorate %UnusedBufferType 0 Offset 0\n"
670 "OpMemberDecorate %UnusedBufferType 1 Offset 4\n"
671 "OpDecorate %UnusedBufferType BufferBlock\n"
672 "OpDecorate %unused_buffer DescriptorSet " + de::toString(location.set) + "\n"
673 "OpDecorate %unused_buffer Binding " + de::toString(location.binding) + "\n";
674 }
675
getUnusedTypesAndConstants()676 std::string getUnusedTypesAndConstants()
677 {
678 return "%c_f32_101 = OpConstant %f32 101\n"
679 "%c_i32_201 = OpConstant %i32 201\n"
680 "%UnusedBufferType = OpTypeStruct %f32 %i32\n"
681 "%unused_ptr_Uniform_UnusedBufferType = OpTypePointer Uniform %UnusedBufferType\n"
682 "%unused_ptr_Uniform_float = OpTypePointer Uniform %f32\n"
683 "%unused_ptr_Uniform_int = OpTypePointer Uniform %i32\n";
684 }
685
getUnusedBuffer()686 std::string getUnusedBuffer()
687 {
688 return "%unused_buffer = OpVariable %unused_ptr_Uniform_UnusedBufferType Uniform\n";
689 }
690
getUnusedFunctionBody()691 std::string getUnusedFunctionBody()
692 {
693 return "%unused_func = OpFunction %void None %voidf\n"
694 "%unused_func_label = OpLabel\n"
695 "%unused_out_float_ptr = OpAccessChain %unused_ptr_Uniform_float %unused_buffer %c_i32_0\n"
696 "OpStore %unused_out_float_ptr %c_f32_101\n"
697 "%unused_out_int_ptr = OpAccessChain %unused_ptr_Uniform_int %unused_buffer %c_i32_1\n"
698 "OpStore %unused_out_int_ptr %c_i32_201\n"
699 "OpReturn\n"
700 "OpFunctionEnd\n";
701 }
702
703 } // SpirVAssembly
704 } // vkt
705