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 VkPhysicalDeviceFragmentShadingRateFeaturesKHR* fragmentShadingRateFeatures = nullptr;
39 VkPhysicalDeviceShadingRateImageFeaturesNV* shadingRateImageFeatures = nullptr;
40 VkPhysicalDeviceFragmentDensityMapFeaturesEXT* fragmentDensityMapFeatures = nullptr;
41 VkPhysicalDevicePageableDeviceLocalMemoryFeaturesEXT* pageableDeviceLocalMemoryFeatures = nullptr;
42
43 m_coreFeatures2 = initVulkanStructure();
44 m_vulkan11Features = initVulkanStructure();
45 m_vulkan12Features = initVulkanStructure();
46 m_vulkan13Features = initVulkanStructure();
47
48 if (isInstanceExtensionSupported(apiVersion, instanceExtensions, "VK_KHR_get_physical_device_properties2"))
49 {
50 const std::vector<VkExtensionProperties> deviceExtensionProperties = enumerateDeviceExtensionProperties(vki, physicalDevice, DE_NULL);
51 void** nextPtr = &m_coreFeatures2.pNext;
52 std::vector<FeatureStructWrapperBase*> featuresToFillFromBlob;
53 bool vk13Supported = (apiVersion >= VK_API_VERSION_1_3);
54 bool vk12Supported = (apiVersion >= VK_API_VERSION_1_2);
55
56 // since vk12 we have blob structures combining features of couple previously
57 // available feature structures, that now in vk12+ must be removed from chain
58 if (vk12Supported)
59 {
60 addToChainVulkanStructure(&nextPtr, m_vulkan11Features);
61 addToChainVulkanStructure(&nextPtr, m_vulkan12Features);
62
63 if (vk13Supported)
64 addToChainVulkanStructure(&nextPtr, m_vulkan13Features);
65 }
66
67 // iterate over data for all feature that are defined in specification
68 for (const auto& featureStructCreationData : featureStructCreationArray)
69 {
70 const char* featureName = featureStructCreationData.name;
71
72 // check if this feature is available on current device
73 if (de::contains(deviceExtensions.begin(), deviceExtensions.end(), featureName) &&
74 verifyFeatureAddCriteria(featureStructCreationData, deviceExtensionProperties))
75 {
76 FeatureStructWrapperBase* p = (*featureStructCreationData.creatorFunction)();
77 if (p == DE_NULL)
78 continue;
79
80 // if feature struct is part of VkPhysicalDeviceVulkan1{1,2,3}Features
81 // we dont add it to the chain but store and fill later from blob data
82 bool featureFilledFromBlob = false;
83 if (vk12Supported)
84 {
85 deUint32 blobApiVersion = getBlobFeaturesVersion(p->getFeatureDesc().sType);
86 if (blobApiVersion)
87 featureFilledFromBlob = (apiVersion >= blobApiVersion);
88 }
89
90 if (featureFilledFromBlob)
91 featuresToFillFromBlob.push_back(p);
92 else
93 {
94 VkStructureType structType = p->getFeatureDesc().sType;
95 void* rawStructPtr = p->getFeatureTypeRaw();
96
97 if (structType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT)
98 robustness2Features = reinterpret_cast<VkPhysicalDeviceRobustness2FeaturesEXT*>(rawStructPtr);
99 else if (structType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_ROBUSTNESS_FEATURES_EXT)
100 imageRobustnessFeatures = reinterpret_cast<VkPhysicalDeviceImageRobustnessFeaturesEXT*>(rawStructPtr);
101 else if (structType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_FEATURES_KHR)
102 fragmentShadingRateFeatures = reinterpret_cast<VkPhysicalDeviceFragmentShadingRateFeaturesKHR*>(rawStructPtr);
103 else if (structType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADING_RATE_IMAGE_FEATURES_NV)
104 shadingRateImageFeatures = reinterpret_cast<VkPhysicalDeviceShadingRateImageFeaturesNV*>(rawStructPtr);
105 else if (structType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_FEATURES_EXT)
106 fragmentDensityMapFeatures = reinterpret_cast<VkPhysicalDeviceFragmentDensityMapFeaturesEXT*>(rawStructPtr);
107 else if (structType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PAGEABLE_DEVICE_LOCAL_MEMORY_FEATURES_EXT)
108 pageableDeviceLocalMemoryFeatures = reinterpret_cast<VkPhysicalDevicePageableDeviceLocalMemoryFeaturesEXT*>(rawStructPtr);
109
110 // add to chain
111 *nextPtr = rawStructPtr;
112 nextPtr = p->getFeatureTypeNext();
113 }
114 m_features.push_back(p);
115 }
116 }
117
118 vki.getPhysicalDeviceFeatures2(physicalDevice, &m_coreFeatures2);
119
120 // fill data from VkPhysicalDeviceVulkan1{1,2,3}Features
121 if (vk12Supported)
122 {
123 AllFeaturesBlobs allBlobs =
124 {
125 m_vulkan11Features,
126 m_vulkan12Features,
127 m_vulkan13Features,
128 // add blobs from future vulkan versions here
129 };
130
131 for (auto feature : featuresToFillFromBlob)
132 feature->initializeFeatureFromBlob(allBlobs);
133 }
134 }
135 else
136 m_coreFeatures2.features = getPhysicalDeviceFeatures(vki, physicalDevice);
137
138 // 'enableAllFeatures' is used to create a complete list of supported features.
139 if (!enableAllFeatures)
140 {
141 // Disable robustness by default, as it has an impact on performance on some HW.
142 if (robustness2Features)
143 {
144 robustness2Features->robustBufferAccess2 = false;
145 robustness2Features->robustImageAccess2 = false;
146 robustness2Features->nullDescriptor = false;
147 }
148 if (imageRobustnessFeatures)
149 {
150 imageRobustnessFeatures->robustImageAccess = false;
151 }
152 m_vulkan13Features.robustImageAccess = false;
153 m_coreFeatures2.features.robustBufferAccess = false;
154
155 // Disable VK_EXT_fragment_density_map and VK_NV_shading_rate_image features
156 // that must: not be enabled if KHR fragment shading rate features are enabled.
157 if (fragmentShadingRateFeatures &&
158 (fragmentShadingRateFeatures->pipelineFragmentShadingRate ||
159 fragmentShadingRateFeatures->primitiveFragmentShadingRate ||
160 fragmentShadingRateFeatures->attachmentFragmentShadingRate))
161 {
162 if (shadingRateImageFeatures)
163 shadingRateImageFeatures->shadingRateImage = false;
164 if (fragmentDensityMapFeatures)
165 fragmentDensityMapFeatures->fragmentDensityMap = false;
166 }
167
168 // Disable pageableDeviceLocalMemory by default since it may modify the behavior
169 // of device-local, and even host-local, memory allocations for all tests.
170 // pageableDeviceLocalMemory will use targetted testing on a custom device.
171 if (pageableDeviceLocalMemoryFeatures)
172 pageableDeviceLocalMemoryFeatures->pageableDeviceLocalMemory = false;
173 }
174 }
175
verifyFeatureAddCriteria(const FeatureStructCreationData & item,const std::vector<VkExtensionProperties> & properties)176 bool DeviceFeatures::verifyFeatureAddCriteria (const FeatureStructCreationData& item, const std::vector<VkExtensionProperties>& properties)
177 {
178 if (deStringEqual(item.name, VK_KHR_VULKAN_MEMORY_MODEL_EXTENSION_NAME))
179 {
180 for (const auto& property : properties)
181 {
182 if (deStringEqual(property.extensionName, item.name))
183 return (property.specVersion == item.specVersion);
184 }
185 }
186
187 return true;
188 }
189
contains(const std::string & feature,bool throwIfNotExists) const190 bool DeviceFeatures::contains (const std::string& feature, bool throwIfNotExists) const
191 {
192 for (const auto f : m_features)
193 {
194 if (deStringEqual(f->getFeatureDesc().name, feature.c_str()))
195 return true;
196 }
197
198 if (throwIfNotExists)
199 TCU_THROW(NotSupportedError, "Feature " + feature + " is not supported");
200
201 return false;
202 }
203
isDeviceFeatureInitialized(VkStructureType sType) const204 bool DeviceFeatures::isDeviceFeatureInitialized (VkStructureType sType) const
205 {
206 for (const auto f : m_features)
207 {
208 if (f->getFeatureDesc().sType == sType)
209 return true;
210 }
211 return false;
212 }
213
~DeviceFeatures(void)214 DeviceFeatures::~DeviceFeatures (void)
215 {
216 for (auto p : m_features)
217 delete p;
218
219 m_features.clear();
220 }
221
222 } // vk
223
224