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