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