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"
33 namespace SpirVAssembly
41 VkPhysicalDeviceFeatures filterDefaultDeviceFeatures (const VkPhysicalDeviceFeatures& deviceFeatures)
43 VkPhysicalDeviceFeatures enabledDeviceFeatures = deviceFeatures;
45 // Disable robustness by default, as it has an impact on performance on some HW.
46 enabledDeviceFeatures.robustBufferAccess = false;
48 return enabledDeviceFeatures;
51 VkPhysicalDevice8BitStorageFeaturesKHR querySupported8BitStorageFeatures (const deUint32 apiVersion, const InstanceInterface& vki, VkPhysicalDevice device, const std::vector<std::string>& instanceExtensions)
53 VkPhysicalDevice8BitStorageFeaturesKHR extensionFeatures =
55 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR, // VkStructureType sType;
56 DE_NULL, // void* pNext;
57 false, // VkBool32 storageBuffer8BitAccess;
58 false, // VkBool32 uniformAndStorageBuffer8BitAccess;
59 false, // VkBool32 storagePushConstant8;
61 VkPhysicalDeviceFeatures2 features;
63 deMemset(&features, 0, sizeof(features));
64 features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
65 features.pNext = &extensionFeatures;
67 // Call the getter only if supported. Otherwise above "zero" defaults are used
68 if(isInstanceExtensionSupported(apiVersion, instanceExtensions, "VK_KHR_get_physical_device_properties2"))
70 vki.getPhysicalDeviceFeatures2(device, &features);
73 return extensionFeatures;
76 VkPhysicalDevice16BitStorageFeatures querySupported16BitStorageFeatures (const deUint32 apiVersion, const InstanceInterface& vki, VkPhysicalDevice device, const std::vector<std::string>& instanceExtensions)
78 VkPhysicalDevice16BitStorageFeatures extensionFeatures =
80 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES_KHR, // sType
82 false, // storageUniformBufferBlock16
83 false, // storageUniform16
84 false, // storagePushConstant16
85 false, // storageInputOutput16
87 VkPhysicalDeviceFeatures2 features;
89 deMemset(&features, 0, sizeof(features));
90 features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
91 features.pNext = &extensionFeatures;
93 // Call the getter only if supported. Otherwise above "zero" defaults are used
94 if(isInstanceExtensionSupported(apiVersion, instanceExtensions, "VK_KHR_get_physical_device_properties2"))
96 vki.getPhysicalDeviceFeatures2(device, &features);
99 return extensionFeatures;
102 VkPhysicalDeviceVariablePointerFeatures querySupportedVariablePointersFeatures (const deUint32 apiVersion, const InstanceInterface& vki, VkPhysicalDevice device, const std::vector<std::string>& instanceExtensions)
104 VkPhysicalDeviceVariablePointerFeatures extensionFeatures =
106 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES_KHR, // sType
108 false, // variablePointersStorageBuffer
109 false, // variablePointers
112 VkPhysicalDeviceFeatures2 features;
113 deMemset(&features, 0, sizeof(features));
114 features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
115 features.pNext = &extensionFeatures;
117 // Call the getter only if supported. Otherwise above "zero" defaults are used
118 if(isInstanceExtensionSupported(apiVersion, instanceExtensions, "VK_KHR_get_physical_device_properties2"))
120 vki.getPhysicalDeviceFeatures2(device, &features);
123 return extensionFeatures;
128 bool is8BitStorageFeaturesSupported (const deUint32 apiVersion, const InstanceInterface& vki, VkPhysicalDevice device, const std::vector<std::string>& instanceExtensions, Extension8BitStorageFeatures toCheck)
130 VkPhysicalDevice8BitStorageFeaturesKHR extensionFeatures = querySupported8BitStorageFeatures(apiVersion, vki, device, instanceExtensions);
132 if ((toCheck & EXT8BITSTORAGEFEATURES_STORAGE_BUFFER) != 0 && extensionFeatures.storageBuffer8BitAccess == VK_FALSE)
133 TCU_FAIL("storageBuffer8BitAccess has to be supported");
135 if ((toCheck & EXT8BITSTORAGEFEATURES_UNIFORM_STORAGE_BUFFER) != 0 && extensionFeatures.uniformAndStorageBuffer8BitAccess == VK_FALSE)
138 if ((toCheck & EXT8BITSTORAGEFEATURES_PUSH_CONSTANT) != 0 && extensionFeatures.storagePushConstant8 == VK_FALSE)
144 bool is16BitStorageFeaturesSupported (const Context& context, Extension16BitStorageFeatures toCheck)
146 const VkPhysicalDevice16BitStorageFeatures& extensionFeatures = context.get16BitStorageFeatures();
148 if ((toCheck & EXT16BITSTORAGEFEATURES_UNIFORM_BUFFER_BLOCK) != 0 && extensionFeatures.storageBuffer16BitAccess == VK_FALSE)
151 if ((toCheck & EXT16BITSTORAGEFEATURES_UNIFORM) != 0 && extensionFeatures.uniformAndStorageBuffer16BitAccess == VK_FALSE)
154 if ((toCheck & EXT16BITSTORAGEFEATURES_PUSH_CONSTANT) != 0 && extensionFeatures.storagePushConstant16 == VK_FALSE)
157 if ((toCheck & EXT16BITSTORAGEFEATURES_INPUT_OUTPUT) != 0 && extensionFeatures.storageInputOutput16 == VK_FALSE)
163 bool isVariablePointersFeaturesSupported (const Context& context, ExtensionVariablePointersFeatures toCheck)
165 const VkPhysicalDeviceVariablePointerFeatures& extensionFeatures = context.getVariablePointerFeatures();
167 if ((toCheck & EXTVARIABLEPOINTERSFEATURES_VARIABLE_POINTERS_STORAGEBUFFER) != 0 && extensionFeatures.variablePointersStorageBuffer == VK_FALSE)
170 if ((toCheck & EXTVARIABLEPOINTERSFEATURES_VARIABLE_POINTERS) != 0 && extensionFeatures.variablePointers == VK_FALSE)
176 Move<VkDevice> createDeviceWithExtensions (Context& context,
177 const deUint32 queueFamilyIndex,
178 const std::vector<std::string>& supportedExtensions,
179 const std::vector<std::string>& requiredExtensions)
181 const InstanceInterface& vki = context.getInstanceInterface();
182 const VkPhysicalDevice physicalDevice = context.getPhysicalDevice();
183 std::vector<const char*> extensions;
184 void* pExtension = DE_NULL;
185 const VkPhysicalDeviceFeatures deviceFeatures = getPhysicalDeviceFeatures(vki, physicalDevice);
186 VkPhysicalDevice16BitStorageFeatures ext16BitStorageFeatures;
187 VkPhysicalDeviceVariablePointerFeatures extVariablePointerFeatures;
189 for (deUint32 extNdx = 0; extNdx < requiredExtensions.size(); ++extNdx)
191 const std::string& ext = requiredExtensions[extNdx];
193 // Check that all required extensions are supported first.
194 if (!isDeviceExtensionSupported(context.getUsedApiVersion(), supportedExtensions, ext))
196 TCU_THROW(NotSupportedError, (std::string("Device extension not supported: ") + ext).c_str());
199 // Currently don't support enabling multiple extensions at the same time.
200 if (ext == "VK_KHR_16bit_storage")
202 // For the 16bit storage extension, we have four features to test. Requesting all features supported.
203 // Note that we don't throw NotImplemented errors here if a specific feature is not supported;
204 // that should be done when actually trying to use that specific feature.
205 ext16BitStorageFeatures = querySupported16BitStorageFeatures(context.getUsedApiVersion(), vki, physicalDevice, context.getInstanceExtensions());
206 pExtension = &ext16BitStorageFeatures;
208 else if (ext == "VK_KHR_variable_pointers")
210 // For the VariablePointers extension, we have two features to test. Requesting all features supported.
211 extVariablePointerFeatures = querySupportedVariablePointersFeatures(context.getUsedApiVersion(), vki, physicalDevice, context.getInstanceExtensions());
212 pExtension = &extVariablePointerFeatures;
215 if (!isCoreDeviceExtension(context.getUsedApiVersion(), ext))
216 extensions.push_back(ext.c_str());
219 const float queuePriorities[] = { 1.0f };
220 const VkDeviceQueueCreateInfo queueInfos[] =
223 VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
225 (VkDeviceQueueCreateFlags)0,
227 DE_LENGTH_OF_ARRAY(queuePriorities),
231 const VkPhysicalDeviceFeatures features = filterDefaultDeviceFeatures(deviceFeatures);
232 const VkDeviceCreateInfo deviceParams =
234 VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
236 (VkDeviceCreateFlags)0,
237 DE_LENGTH_OF_ARRAY(queueInfos),
241 (deUint32)extensions.size(),
242 extensions.empty() ? DE_NULL : &extensions[0],
246 return vk::createDevice(context.getPlatformInterface(), context.getInstance(), vki, physicalDevice, &deviceParams);
249 Allocator* createAllocator (const InstanceInterface& instanceInterface, const VkPhysicalDevice physicalDevice, const DeviceInterface& deviceInterface, const VkDevice device)
251 const VkPhysicalDeviceMemoryProperties memoryProperties = getPhysicalDeviceMemoryProperties(instanceInterface, physicalDevice);
253 // \todo [2015-07-24 jarkko] support allocator selection/configuration from command line (or compile time)
254 return new SimpleAllocator(deviceInterface, device, memoryProperties);
257 deUint32 getMinRequiredVulkanVersion (const SpirvVersion version)
261 case SPIRV_VERSION_1_0:
262 return VK_API_VERSION_1_0;
263 case SPIRV_VERSION_1_1:
264 case SPIRV_VERSION_1_2:
265 case SPIRV_VERSION_1_3:
266 return VK_API_VERSION_1_1;
273 std::string getVulkanName (const deUint32 version)
275 return std::string(version == VK_API_VERSION_1_1 ? "1.1" : "1.0");