• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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