xref: /aosp_15_r20/external/deqp/external/vulkancts/framework/vulkan/vkDeviceFeatures.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
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 uint32_t apiVersion,const VkPhysicalDevice physicalDevice,const std::vector<std::string> & instanceExtensions,const std::vector<std::string> & deviceExtensions,const bool enableAllFeatures)29 DeviceFeatures::DeviceFeatures(const InstanceInterface &vki, const uint32_t apiVersion,
30                                const VkPhysicalDevice physicalDevice,
31                                const std::vector<std::string> &instanceExtensions,
32                                const std::vector<std::string> &deviceExtensions, const bool enableAllFeatures)
33 {
34     VkPhysicalDeviceRobustness2FeaturesEXT *robustness2Features         = nullptr;
35     VkPhysicalDeviceImageRobustnessFeaturesEXT *imageRobustnessFeatures = nullptr;
36 #ifndef CTS_USES_VULKANSC
37     VkPhysicalDeviceFragmentShadingRateFeaturesKHR *fragmentShadingRateFeatures             = nullptr;
38     VkPhysicalDeviceShadingRateImageFeaturesNV *shadingRateImageFeaturesNV                  = nullptr;
39     VkPhysicalDeviceFragmentDensityMapFeaturesEXT *fragmentDensityMapFeatures               = nullptr;
40     VkPhysicalDevicePageableDeviceLocalMemoryFeaturesEXT *pageableDeviceLocalMemoryFeatures = nullptr;
41     VkPhysicalDeviceMutableDescriptorTypeFeaturesEXT *mutableDescriptorTypeFeatures         = nullptr;
42     VkPhysicalDeviceLegacyDitheringFeaturesEXT *legacyDitheringFeatures                     = nullptr;
43 #endif // CTS_USES_VULKANSC
44 
45     m_coreFeatures2    = initVulkanStructure();
46     m_vulkan11Features = initVulkanStructure();
47     m_vulkan12Features = initVulkanStructure();
48 #ifndef CTS_USES_VULKANSC
49     m_vulkan13Features = initVulkanStructure();
50 #endif // CTS_USES_VULKANSC
51 #ifdef CTS_USES_VULKANSC
52     m_vulkanSC10Features = initVulkanStructure();
53 #endif // CTS_USES_VULKANSC
54 
55     if (isInstanceExtensionSupported(apiVersion, instanceExtensions, "VK_KHR_get_physical_device_properties2"))
56     {
57         const std::vector<VkExtensionProperties> deviceExtensionProperties =
58             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                  std::string(featureName) == "core_feature") &&
106                 verifyFeatureAddCriteria(featureStructCreationData, deviceExtensionProperties))
107             {
108                 FeatureStructWrapperBase *p = (*featureStructCreationData.creatorFunction)();
109                 if (p == DE_NULL)
110                     continue;
111 
112 #ifdef CTS_USES_VULKANSC
113                 // m_vulkanSC10Features was already added above
114                 if (p->getFeatureDesc().sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_SC_1_0_FEATURES)
115                     continue;
116 #endif // CTS_USES_VULKANSC
117 
118                 // if feature struct is part of VkPhysicalDeviceVulkan1{1,2,3}Features
119                 // we dont add it to the chain but store and fill later from blob data
120                 bool featureFilledFromBlob = false;
121                 if (vk12Supported)
122                 {
123                     uint32_t blobApiVersion = getBlobFeaturesVersion(p->getFeatureDesc().sType);
124                     if (blobApiVersion)
125                         featureFilledFromBlob = (apiVersion >= blobApiVersion);
126                 }
127 
128                 if (featureFilledFromBlob)
129                     featuresToFillFromBlob.push_back(p);
130                 else
131                 {
132                     VkStructureType structType = p->getFeatureDesc().sType;
133                     void *rawStructPtr         = p->getFeatureTypeRaw();
134 
135                     if (structType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT)
136                         robustness2Features = reinterpret_cast<VkPhysicalDeviceRobustness2FeaturesEXT *>(rawStructPtr);
137                     else if (structType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_ROBUSTNESS_FEATURES_EXT)
138                         imageRobustnessFeatures =
139                             reinterpret_cast<VkPhysicalDeviceImageRobustnessFeaturesEXT *>(rawStructPtr);
140 #ifndef CTS_USES_VULKANSC
141                     else if (structType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADING_RATE_FEATURES_KHR)
142                         fragmentShadingRateFeatures =
143                             reinterpret_cast<VkPhysicalDeviceFragmentShadingRateFeaturesKHR *>(rawStructPtr);
144                     else if (structType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADING_RATE_IMAGE_FEATURES_NV)
145                         shadingRateImageFeaturesNV =
146                             reinterpret_cast<VkPhysicalDeviceShadingRateImageFeaturesNV *>(rawStructPtr);
147                     else if (structType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_FEATURES_EXT)
148                         fragmentDensityMapFeatures =
149                             reinterpret_cast<VkPhysicalDeviceFragmentDensityMapFeaturesEXT *>(rawStructPtr);
150                     else if (structType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PAGEABLE_DEVICE_LOCAL_MEMORY_FEATURES_EXT)
151                         pageableDeviceLocalMemoryFeatures =
152                             reinterpret_cast<VkPhysicalDevicePageableDeviceLocalMemoryFeaturesEXT *>(rawStructPtr);
153                     else if (structType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MUTABLE_DESCRIPTOR_TYPE_FEATURES_EXT)
154                         mutableDescriptorTypeFeatures =
155                             reinterpret_cast<VkPhysicalDeviceMutableDescriptorTypeFeaturesEXT *>(rawStructPtr);
156                     else if (structType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LEGACY_DITHERING_FEATURES_EXT)
157                         legacyDitheringFeatures =
158                             reinterpret_cast<VkPhysicalDeviceLegacyDitheringFeaturesEXT *>(rawStructPtr);
159 #endif // CTS_USES_VULKANSC
160                     // add to chain
161                     *nextPtr = rawStructPtr;
162                     nextPtr  = p->getFeatureTypeNext();
163                 }
164                 m_features.push_back(p);
165             }
166             else
167             {
168 #ifndef CTS_USES_VULKANSC
169                 // Some non-standard promotions may need feature structs filled in anyway.
170                 if (!strcmp(featureName, "VK_EXT_extended_dynamic_state") &&
171                     (de::contains(allDeviceExtensions.begin(), allDeviceExtensions.end(),
172                                   "VK_EXT_extended_dynamic_state")))
173                 {
174                     FeatureStructWrapperBase *p = (*featureStructCreationData.creatorFunction)();
175                     if (p == DE_NULL)
176                         continue;
177 
178                     auto f =
179                         reinterpret_cast<VkPhysicalDeviceExtendedDynamicStateFeaturesEXT *>(p->getFeatureTypeRaw());
180                     f->extendedDynamicState = true;
181                     m_features.push_back(p);
182                 }
183                 if (!strcmp(featureName, "VK_EXT_extended_dynamic_state2") &&
184                     (de::contains(allDeviceExtensions.begin(), allDeviceExtensions.end(),
185                                   "VK_EXT_extended_dynamic_state2")))
186                 {
187                     FeatureStructWrapperBase *p = (*featureStructCreationData.creatorFunction)();
188                     if (p == DE_NULL)
189                         continue;
190 
191                     auto f =
192                         reinterpret_cast<VkPhysicalDeviceExtendedDynamicState2FeaturesEXT *>(p->getFeatureTypeRaw());
193                     f->extendedDynamicState2 = true;
194                     m_features.push_back(p);
195                 }
196 #endif // CTS_USES_VULKANSC
197             }
198         }
199 
200         vki.getPhysicalDeviceFeatures2(physicalDevice, &m_coreFeatures2);
201 
202         // fill data from VkPhysicalDeviceVulkan1{1,2,3}Features
203         if (vk12Supported)
204         {
205             AllFeaturesBlobs allBlobs = {
206                 m_vulkan11Features, m_vulkan12Features,
207 #ifndef CTS_USES_VULKANSC
208                 m_vulkan13Features,
209 #endif // CTS_USES_VULKANSC
210                 // add blobs from future vulkan versions here
211             };
212 
213             for (auto feature : featuresToFillFromBlob)
214                 feature->initializeFeatureFromBlob(allBlobs);
215         }
216     }
217     else
218         m_coreFeatures2.features = getPhysicalDeviceFeatures(vki, physicalDevice);
219 
220     // 'enableAllFeatures' is used to create a complete list of supported features.
221     if (!enableAllFeatures)
222     {
223         // Disable robustness by default, as it has an impact on performance on some HW.
224         if (robustness2Features)
225         {
226             robustness2Features->robustBufferAccess2 = false;
227             robustness2Features->robustImageAccess2  = false;
228             robustness2Features->nullDescriptor      = false;
229         }
230         if (imageRobustnessFeatures)
231         {
232             imageRobustnessFeatures->robustImageAccess = false;
233         }
234         m_coreFeatures2.features.robustBufferAccess = false;
235 
236 #ifndef CTS_USES_VULKANSC
237         m_vulkan13Features.robustImageAccess = false;
238 
239         // Disable VK_EXT_fragment_density_map and VK_NV_shading_rate_image features
240         // that must: not be enabled if KHR fragment shading rate features are enabled.
241         if (fragmentShadingRateFeatures && (fragmentShadingRateFeatures->pipelineFragmentShadingRate ||
242                                             fragmentShadingRateFeatures->primitiveFragmentShadingRate ||
243                                             fragmentShadingRateFeatures->attachmentFragmentShadingRate))
244         {
245             if (shadingRateImageFeaturesNV)
246                 shadingRateImageFeaturesNV->shadingRateImage = false;
247             if (fragmentDensityMapFeatures)
248                 fragmentDensityMapFeatures->fragmentDensityMap = false;
249         }
250 
251         // Disable pageableDeviceLocalMemory by default since it may modify the behavior
252         // of device-local, and even host-local, memory allocations for all tests.
253         // pageableDeviceLocalMemory will use targetted testing on a custom device.
254         if (pageableDeviceLocalMemoryFeatures)
255             pageableDeviceLocalMemoryFeatures->pageableDeviceLocalMemory = false;
256 
257         // Disable mutableDescriptorTypeFeatures by default because it can
258         // impact performance on some hardware.
259         if (mutableDescriptorTypeFeatures)
260             mutableDescriptorTypeFeatures->mutableDescriptorType = false;
261 
262         // Disable legacyDitheringFeatures by default because it interacts with
263         // dynamic_rendering. On some hardware DR tests may fail on precision.
264         // Float thresholds would need to be more lenient for low bitrate formats
265         // when DR is used togehrt with legacy dithering.
266         if (legacyDitheringFeatures)
267             legacyDitheringFeatures->legacyDithering = false;
268 #endif // CTS_USES_VULKANSC
269     }
270 }
271 
verifyFeatureAddCriteria(const FeatureStructCreationData & item,const std::vector<VkExtensionProperties> & properties)272 bool DeviceFeatures::verifyFeatureAddCriteria(const FeatureStructCreationData &item,
273                                               const std::vector<VkExtensionProperties> &properties)
274 {
275 #ifndef CTS_USES_VULKANSC
276     if (deStringEqual(item.name, VK_KHR_VULKAN_MEMORY_MODEL_EXTENSION_NAME))
277     {
278         for (const auto &property : properties)
279         {
280             if (deStringEqual(property.extensionName, item.name))
281                 return (property.specVersion == item.specVersion);
282         }
283     }
284 #else  // CTS_USES_VULKANSC
285     DE_UNREF(item);
286     DE_UNREF(properties);
287 #endif // CTS_USES_VULKANSC
288 
289     return true;
290 }
291 
contains(const std::string & feature,bool throwIfNotExists) const292 bool DeviceFeatures::contains(const std::string &feature, bool throwIfNotExists) const
293 {
294     for (const auto f : m_features)
295     {
296         if (deStringEqual(f->getFeatureDesc().name, feature.c_str()))
297             return true;
298     }
299 
300     if (throwIfNotExists)
301         TCU_THROW(NotSupportedError, "Feature " + feature + " is not supported");
302 
303     return false;
304 }
305 
isDeviceFeatureInitialized(VkStructureType sType) const306 bool DeviceFeatures::isDeviceFeatureInitialized(VkStructureType sType) const
307 {
308     for (const auto f : m_features)
309     {
310         if (f->getFeatureDesc().sType == sType)
311             return true;
312     }
313     return false;
314 }
315 
~DeviceFeatures(void)316 DeviceFeatures::~DeviceFeatures(void)
317 {
318     for (auto p : m_features)
319         delete p;
320 
321     m_features.clear();
322 }
323 
324 } // namespace vk
325