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