1 /*------------------------------------------------------------------------- 2 * Vulkan CTS 3 * ---------- 4 * 5 * Copyright (c) 2019 The Khronos Group 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 #include "deSTLUtil.hpp" 21 #include "deString.h" 22 #include "vkQueryUtil.hpp" 23 #include "vkDeviceFeatures.inl" 24 #include "vkDeviceFeatures.hpp" 25 26 namespace vk 27 { 28 DeviceFeatures(const InstanceInterface & vki,const deUint32 apiVersion,const VkPhysicalDevice physicalDevice,const std::vector<std::string> & instanceExtensions,const std::vector<std::string> & deviceExtensions,const deBool enableAllFeatures)29 DeviceFeatures::DeviceFeatures(const InstanceInterface &vki, 30 const deUint32 apiVersion, 31 const VkPhysicalDevice physicalDevice, 32 const std::vector<std::string> &instanceExtensions, 33 const std::vector<std::string> &deviceExtensions, 34 const deBool enableAllFeatures) 35 { 36 VkPhysicalDeviceRobustness2FeaturesEXT *robustness2Features = nullptr; 37 VkPhysicalDeviceImageRobustnessFeaturesEXT *imageRobustnessFeatures = nullptr; 38 #ifndef CTS_USES_VULKANSC 39 VkPhysicalDeviceFragmentShadingRateFeaturesKHR *fragmentShadingRateFeatures = nullptr; 40 VkPhysicalDeviceShadingRateImageFeaturesNV *shadingRateImageFeatures = nullptr; 41 VkPhysicalDeviceFragmentDensityMapFeaturesEXT *fragmentDensityMapFeatures = nullptr; 42 VkPhysicalDevicePageableDeviceLocalMemoryFeaturesEXT *pageableDeviceLocalMemoryFeatures = nullptr; 43 VkPhysicalDeviceMutableDescriptorTypeFeaturesEXT *mutableDescriptorTypeFeatures = nullptr; 44 #endif // CTS_USES_VULKANSC 45 46 m_coreFeatures2 = initVulkanStructure(); 47 m_vulkan11Features = initVulkanStructure(); 48 m_vulkan12Features = initVulkanStructure(); 49 #ifndef CTS_USES_VULKANSC 50 m_vulkan13Features = initVulkanStructure(); 51 #endif // CTS_USES_VULKANSC 52 #ifdef CTS_USES_VULKANSC 53 m_vulkanSC10Features = initVulkanStructure(); 54 #endif // CTS_USES_VULKANSC 55 56 if (isInstanceExtensionSupported(apiVersion, instanceExtensions, "VK_KHR_get_physical_device_properties2")) 57 { 58 const std::vector<VkExtensionProperties> deviceExtensionProperties = enumerateDeviceExtensionProperties(vki, physicalDevice, DE_NULL); 59 void **nextPtr = &m_coreFeatures2.pNext; 60 std::vector<FeatureStructWrapperBase *> featuresToFillFromBlob; 61 #ifndef CTS_USES_VULKANSC 62 bool vk13Supported = (apiVersion >= VK_MAKE_API_VERSION(0, 1, 3, 0)); 63 #endif // CTS_USES_VULKANSC 64 bool vk12Supported = (apiVersion >= VK_MAKE_API_VERSION(0, 1, 2, 0)); 65 #ifdef CTS_USES_VULKANSC 66 bool vksc10Supported = (apiVersion >= VK_MAKE_API_VERSION(1, 1, 0, 0)); 67 #endif // CTS_USES_VULKANSC 68 69 // since vk12 we have blob structures combining features of couple previously 70 // available feature structures, that now in vk12+ must be removed from chain 71 if (vk12Supported) 72 { 73 addToChainVulkanStructure(&nextPtr, m_vulkan11Features); 74 addToChainVulkanStructure(&nextPtr, m_vulkan12Features); 75 76 #ifndef CTS_USES_VULKANSC 77 if (vk13Supported) 78 addToChainVulkanStructure(&nextPtr, m_vulkan13Features); 79 #endif // CTS_USES_VULKANSC 80 } 81 #ifdef CTS_USES_VULKANSC 82 if (vksc10Supported) 83 { 84 addToChainVulkanStructure(&nextPtr, m_vulkanSC10Features); 85 } 86 #endif // CTS_USES_VULKANSC 87 88 std::vector<std::string> allDeviceExtensions = deviceExtensions; 89 #ifdef CTS_USES_VULKANSC 90 // VulkanSC: add missing core extensions to the list 91 std::vector<const char *> coreExtensions; 92 getCoreDeviceExtensions(apiVersion, coreExtensions); 93 for (const auto &coreExt : coreExtensions) 94 if (!de::contains(allDeviceExtensions.begin(), allDeviceExtensions.end(), std::string(coreExt))) 95 allDeviceExtensions.push_back(coreExt); 96 #endif // CTS_USES_VULKANSC 97 98 // iterate over data for all feature that are defined in specification 99 for (const auto &featureStructCreationData : featureStructCreationArray) 100 { 101 const char *featureName = featureStructCreationData.name; 102 103 // check if this feature is available on current device 104 if (de::contains(allDeviceExtensions.begin(), allDeviceExtensions.end(), featureName) && 105 verifyFeatureAddCriteria(featureStructCreationData, deviceExtensionProperties)) 106 { 107 FeatureStructWrapperBase *p = (*featureStructCreationData.creatorFunction)(); 108 if (p == DE_NULL) 109 continue; 110 111 // if feature struct is part of VkPhysicalDeviceVulkan1{1,2,3}Features 112 // we dont add it to the chain but store and fill later from blob data 113 bool featureFilledFromBlob = false; 114 if (vk12Supported) 115 { 116 deUint32 blobApiVersion = getBlobFeaturesVersion(p->getFeatureDesc().sType); 117 if (blobApiVersion) 118 featureFilledFromBlob = (apiVersion >= blobApiVersion); 119 } 120 121 if (featureFilledFromBlob) 122 featuresToFillFromBlob.push_back(p); 123 else 124 { 125 VkStructureType structType = p->getFeatureDesc().sType; 126 void *rawStructPtr = p->getFeatureTypeRaw(); 127 128 if (structType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT) 129 robustness2Features = reinterpret_cast<VkPhysicalDeviceRobustness2FeaturesEXT *>(rawStructPtr); 130 else if (structType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_ROBUSTNESS_FEATURES_EXT) 131 imageRobustnessFeatures = reinterpret_cast<VkPhysicalDeviceImageRobustnessFeaturesEXT *>(rawStructPtr); 132 #ifndef CTS_USES_VULKANSC 133 else if (structType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_FEATURES_KHR) 134 fragmentShadingRateFeatures = reinterpret_cast<VkPhysicalDeviceFragmentShadingRateFeaturesKHR *>(rawStructPtr); 135 else if (structType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADING_RATE_IMAGE_FEATURES_NV) 136 shadingRateImageFeatures = reinterpret_cast<VkPhysicalDeviceShadingRateImageFeaturesNV *>(rawStructPtr); 137 else if (structType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_FEATURES_EXT) 138 fragmentDensityMapFeatures = reinterpret_cast<VkPhysicalDeviceFragmentDensityMapFeaturesEXT *>(rawStructPtr); 139 else if (structType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PAGEABLE_DEVICE_LOCAL_MEMORY_FEATURES_EXT) 140 pageableDeviceLocalMemoryFeatures = reinterpret_cast<VkPhysicalDevicePageableDeviceLocalMemoryFeaturesEXT *>(rawStructPtr); 141 else if (structType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MUTABLE_DESCRIPTOR_TYPE_FEATURES_EXT) 142 mutableDescriptorTypeFeatures = reinterpret_cast<VkPhysicalDeviceMutableDescriptorTypeFeaturesEXT *>(rawStructPtr); 143 #endif // CTS_USES_VULKANSC 144 // add to chain 145 *nextPtr = rawStructPtr; 146 nextPtr = p->getFeatureTypeNext(); 147 } 148 m_features.push_back(p); 149 } 150 else 151 { 152 #ifndef CTS_USES_VULKANSC 153 // Some non-standard promotions may need feature structs filled in anyway. 154 if (!strcmp(featureName, "VK_EXT_extended_dynamic_state") && vk13Supported) 155 { 156 FeatureStructWrapperBase *p = (*featureStructCreationData.creatorFunction)(); 157 if (p == DE_NULL) 158 continue; 159 160 auto f = reinterpret_cast<VkPhysicalDeviceExtendedDynamicStateFeaturesEXT *>(p->getFeatureTypeRaw()); 161 f->extendedDynamicState = true; 162 m_features.push_back(p); 163 } 164 if (!strcmp(featureName, "VK_EXT_extended_dynamic_state2") && vk13Supported) 165 { 166 FeatureStructWrapperBase *p = (*featureStructCreationData.creatorFunction)(); 167 if (p == DE_NULL) 168 continue; 169 170 auto f = reinterpret_cast<VkPhysicalDeviceExtendedDynamicState2FeaturesEXT *>(p->getFeatureTypeRaw()); 171 f->extendedDynamicState2 = true; 172 m_features.push_back(p); 173 } 174 #endif // CTS_USES_VULKANSC 175 } 176 } 177 178 vki.getPhysicalDeviceFeatures2(physicalDevice, &m_coreFeatures2); 179 180 // fill data from VkPhysicalDeviceVulkan1{1,2,3}Features 181 if (vk12Supported) 182 { 183 AllFeaturesBlobs allBlobs = 184 { 185 m_vulkan11Features, 186 m_vulkan12Features, 187 #ifndef CTS_USES_VULKANSC 188 m_vulkan13Features, 189 #endif // CTS_USES_VULKANSC 190 // add blobs from future vulkan versions here 191 }; 192 193 for (auto feature : featuresToFillFromBlob) 194 feature->initializeFeatureFromBlob(allBlobs); 195 } 196 } 197 else 198 m_coreFeatures2.features = getPhysicalDeviceFeatures(vki, physicalDevice); 199 200 // 'enableAllFeatures' is used to create a complete list of supported features. 201 if (!enableAllFeatures) 202 { 203 // Disable robustness by default, as it has an impact on performance on some HW. 204 if (robustness2Features) 205 { 206 robustness2Features->robustBufferAccess2 = false; 207 robustness2Features->robustImageAccess2 = false; 208 robustness2Features->nullDescriptor = false; 209 } 210 if (imageRobustnessFeatures) 211 { 212 imageRobustnessFeatures->robustImageAccess = false; 213 } 214 m_coreFeatures2.features.robustBufferAccess = false; 215 216 #ifndef CTS_USES_VULKANSC 217 // Disable VK_EXT_fragment_density_map and VK_NV_shading_rate_image features 218 // that must: not be enabled if KHR fragment shading rate features are enabled. 219 if (fragmentShadingRateFeatures && 220 (fragmentShadingRateFeatures->pipelineFragmentShadingRate || 221 fragmentShadingRateFeatures->primitiveFragmentShadingRate || 222 fragmentShadingRateFeatures->attachmentFragmentShadingRate)) 223 { 224 if (shadingRateImageFeatures) 225 shadingRateImageFeatures->shadingRateImage = false; 226 if (fragmentDensityMapFeatures) 227 fragmentDensityMapFeatures->fragmentDensityMap = false; 228 } 229 230 // Disable pageableDeviceLocalMemory by default since it may modify the behavior 231 // of device-local, and even host-local, memory allocations for all tests. 232 // pageableDeviceLocalMemory will use targetted testing on a custom device. 233 if (pageableDeviceLocalMemoryFeatures) 234 pageableDeviceLocalMemoryFeatures->pageableDeviceLocalMemory = false; 235 236 // Disable mutableDescriptorTypeFeatures by default because it can 237 // impact performance on some hardware. 238 if (mutableDescriptorTypeFeatures) 239 mutableDescriptorTypeFeatures->mutableDescriptorType = false; 240 #endif // CTS_USES_VULKANSC 241 } 242 } 243 verifyFeatureAddCriteria(const FeatureStructCreationData & item,const std::vector<VkExtensionProperties> & properties)244 bool DeviceFeatures::verifyFeatureAddCriteria(const FeatureStructCreationData &item, const std::vector<VkExtensionProperties> &properties) 245 { 246 #ifndef CTS_USES_VULKANSC 247 if (deStringEqual(item.name, VK_KHR_VULKAN_MEMORY_MODEL_EXTENSION_NAME)) 248 { 249 for (const auto &property : properties) 250 { 251 if (deStringEqual(property.extensionName, item.name)) 252 return (property.specVersion == item.specVersion); 253 } 254 } 255 #else // CTS_USES_VULKANSC 256 DE_UNREF(item); 257 DE_UNREF(properties); 258 #endif // CTS_USES_VULKANSC 259 260 return true; 261 } 262 contains(const std::string & feature,bool throwIfNotExists) const263 bool DeviceFeatures::contains(const std::string &feature, bool throwIfNotExists) const 264 { 265 for (const auto f : m_features) 266 { 267 if (deStringEqual(f->getFeatureDesc().name, feature.c_str())) 268 return true; 269 } 270 271 if (throwIfNotExists) 272 TCU_THROW(NotSupportedError, "Feature " + feature + " is not supported"); 273 274 return false; 275 } 276 isDeviceFeatureInitialized(VkStructureType sType) const277 bool DeviceFeatures::isDeviceFeatureInitialized(VkStructureType sType) const 278 { 279 for (const auto f : m_features) 280 { 281 if (f->getFeatureDesc().sType == sType) 282 return true; 283 } 284 return false; 285 } 286 ~DeviceFeatures(void)287 DeviceFeatures::~DeviceFeatures(void) 288 { 289 for (auto p : m_features) 290 delete p; 291 292 m_features.clear(); 293 } 294 295 } // vk 296