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 31 namespace vkt 32 { 33 namespace SpirVAssembly 34 { 35 36 using namespace vk; 37 38 namespace 39 { 40 41 VkPhysicalDeviceFeatures filterDefaultDeviceFeatures (const VkPhysicalDeviceFeatures& deviceFeatures) 42 { 43 VkPhysicalDeviceFeatures enabledDeviceFeatures = deviceFeatures; 44 45 // Disable robustness by default, as it has an impact on performance on some HW. 46 enabledDeviceFeatures.robustBufferAccess = false; 47 48 return enabledDeviceFeatures; 49 } 50 51 VkPhysicalDevice16BitStorageFeaturesKHR querySupported16BitStorageFeatures (const InstanceInterface& vki, VkPhysicalDevice device, const std::vector<std::string>& instanceExtensions) 52 { 53 VkPhysicalDevice16BitStorageFeaturesKHR extensionFeatures = 54 { 55 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES_KHR, // sType 56 DE_NULL, // pNext 57 false, // storageUniformBufferBlock16 58 false, // storageUniform16 59 false, // storagePushConstant16 60 false, // storageInputOutput16 61 }; 62 VkPhysicalDeviceFeatures2KHR features; 63 64 deMemset(&features, 0, sizeof(features)); 65 features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR; 66 features.pNext = &extensionFeatures; 67 68 // Call the getter only if supported. Otherwise above "zero" defaults are used 69 if (de::contains(instanceExtensions.begin(), instanceExtensions.end(), "VK_KHR_get_physical_device_properties2")) 70 { 71 vki.getPhysicalDeviceFeatures2KHR(device, &features); 72 } 73 74 return extensionFeatures; 75 } 76 77 VkPhysicalDeviceVariablePointerFeaturesKHR querySupportedVariablePointersFeatures (const InstanceInterface& vki, VkPhysicalDevice device, const std::vector<std::string>& instanceExtensions) 78 { 79 VkPhysicalDeviceVariablePointerFeaturesKHR extensionFeatures = 80 { 81 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES_KHR, // sType 82 DE_NULL, // pNext 83 false, // variablePointersStorageBuffer 84 false, // variablePointers 85 }; 86 87 VkPhysicalDeviceFeatures2KHR features; 88 deMemset(&features, 0, sizeof(features)); 89 features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR; 90 features.pNext = &extensionFeatures; 91 92 // Call the getter only if supported. Otherwise above "zero" defaults are used 93 if (de::contains(instanceExtensions.begin(), instanceExtensions.end(), "VK_KHR_get_physical_device_properties2")) 94 { 95 vki.getPhysicalDeviceFeatures2KHR(device, &features); 96 } 97 98 return extensionFeatures; 99 } 100 101 } // anonymous 102 103 bool is16BitStorageFeaturesSupported (const InstanceInterface& vki, VkPhysicalDevice device, const std::vector<std::string>& instanceExtensions, Extension16BitStorageFeatures toCheck) 104 { 105 VkPhysicalDevice16BitStorageFeaturesKHR extensionFeatures = querySupported16BitStorageFeatures(vki, device, instanceExtensions); 106 107 if ((toCheck & EXT16BITSTORAGEFEATURES_UNIFORM_BUFFER_BLOCK) != 0 && extensionFeatures.storageBuffer16BitAccess == VK_FALSE) 108 return false; 109 110 if ((toCheck & EXT16BITSTORAGEFEATURES_UNIFORM) != 0 && extensionFeatures.uniformAndStorageBuffer16BitAccess == VK_FALSE) 111 return false; 112 113 if ((toCheck & EXT16BITSTORAGEFEATURES_PUSH_CONSTANT) != 0 && extensionFeatures.storagePushConstant16 == VK_FALSE) 114 return false; 115 116 if ((toCheck & EXT16BITSTORAGEFEATURES_INPUT_OUTPUT) != 0 && extensionFeatures.storageInputOutput16 == VK_FALSE) 117 return false; 118 119 return true; 120 } 121 122 bool isVariablePointersFeaturesSupported (const InstanceInterface& vki, VkPhysicalDevice device, const std::vector<std::string>& instanceExtensions, ExtensionVariablePointersFeatures toCheck) 123 { 124 VkPhysicalDeviceVariablePointerFeaturesKHR extensionFeatures = querySupportedVariablePointersFeatures(vki, device, instanceExtensions); 125 126 if ((toCheck & EXTVARIABLEPOINTERSFEATURES_VARIABLE_POINTERS_STORAGEBUFFER) != 0 && extensionFeatures.variablePointersStorageBuffer == VK_FALSE) 127 return false; 128 129 if ((toCheck & EXTVARIABLEPOINTERSFEATURES_VARIABLE_POINTERS) != 0 && extensionFeatures.variablePointers == VK_FALSE) 130 return false; 131 132 return true; 133 } 134 135 Move<VkDevice> createDeviceWithExtensions (Context& context, 136 const deUint32 queueFamilyIndex, 137 const std::vector<std::string>& supportedExtensions, 138 const std::vector<std::string>& requiredExtensions) 139 { 140 const InstanceInterface& vki = context.getInstanceInterface(); 141 const VkPhysicalDevice physicalDevice = context.getPhysicalDevice(); 142 std::vector<const char*> extensions (requiredExtensions.size()); 143 void* pExtension = DE_NULL; 144 const VkPhysicalDeviceFeatures deviceFeatures = getPhysicalDeviceFeatures(vki, physicalDevice); 145 VkPhysicalDevice16BitStorageFeaturesKHR ext16BitStorageFeatures; 146 VkPhysicalDeviceVariablePointerFeaturesKHR extVariablePointerFeatures; 147 148 for (deUint32 extNdx = 0; extNdx < requiredExtensions.size(); ++extNdx) 149 { 150 const std::string& ext = requiredExtensions[extNdx]; 151 152 // Check that all required extensions are supported first. 153 if (!de::contains(supportedExtensions.begin(), supportedExtensions.end(), ext)) 154 { 155 TCU_THROW(NotSupportedError, (std::string("Device extension not supported: ") + ext).c_str()); 156 } 157 158 // Currently don't support enabling multiple extensions at the same time. 159 if (ext == "VK_KHR_16bit_storage") 160 { 161 // For the 16bit storage extension, we have four features to test. Requesting all features supported. 162 // Note that we don't throw NotImplemented errors here if a specific feature is not supported; 163 // that should be done when actually trying to use that specific feature. 164 ext16BitStorageFeatures = querySupported16BitStorageFeatures(vki, physicalDevice, context.getInstanceExtensions()); 165 pExtension = &ext16BitStorageFeatures; 166 } 167 else if (ext == "VK_KHR_variable_pointers") 168 { 169 // For the VariablePointers extension, we have two features to test. Requesting all features supported. 170 extVariablePointerFeatures = querySupportedVariablePointersFeatures(vki, physicalDevice, context.getInstanceExtensions()); 171 pExtension = &extVariablePointerFeatures; 172 } 173 174 extensions[extNdx] = ext.c_str(); 175 } 176 177 const float queuePriorities[] = { 1.0f }; 178 const VkDeviceQueueCreateInfo queueInfos[] = 179 { 180 { 181 VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, 182 DE_NULL, 183 (VkDeviceQueueCreateFlags)0, 184 queueFamilyIndex, 185 DE_LENGTH_OF_ARRAY(queuePriorities), 186 &queuePriorities[0] 187 } 188 }; 189 const VkPhysicalDeviceFeatures features = filterDefaultDeviceFeatures(deviceFeatures); 190 const VkDeviceCreateInfo deviceParams = 191 { 192 VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, 193 pExtension, 194 (VkDeviceCreateFlags)0, 195 DE_LENGTH_OF_ARRAY(queueInfos), 196 &queueInfos[0], 197 0u, 198 DE_NULL, 199 (deUint32)extensions.size(), 200 extensions.empty() ? DE_NULL : &extensions[0], 201 &features 202 }; 203 204 return vk::createDevice(vki, physicalDevice, &deviceParams); 205 } 206 207 Allocator* createAllocator (const InstanceInterface& instanceInterface, const VkPhysicalDevice physicalDevice, const DeviceInterface& deviceInterface, const VkDevice device) 208 { 209 const VkPhysicalDeviceMemoryProperties memoryProperties = getPhysicalDeviceMemoryProperties(instanceInterface, physicalDevice); 210 211 // \todo [2015-07-24 jarkko] support allocator selection/configuration from command line (or compile time) 212 return new SimpleAllocator(deviceInterface, device, memoryProperties); 213 } 214 215 } // SpirVAssembly 216 } // vkt 217