• 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 	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