• 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 "vkDeviceProperties.inl"
24 #include "vkDeviceProperties.hpp"
25 
26 namespace vk
27 {
28 
DeviceProperties(const InstanceInterface & vki,const deUint32 apiVersion,const VkPhysicalDevice physicalDevice,const std::vector<std::string> & instanceExtensions,const std::vector<std::string> & deviceExtensions)29 DeviceProperties::DeviceProperties	(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 	m_coreProperties2		= initVulkanStructure();
36 	m_vulkan11Properties	= initVulkanStructure();
37 	m_vulkan12Properties	= initVulkanStructure();
38 #ifndef CTS_USES_VULKANSC
39 	m_vulkan13Properties	= initVulkanStructure();
40 #endif // CTS_USES_VULKANSC
41 #ifdef CTS_USES_VULKANSC
42 	m_vulkanSC10Properties	= initVulkanStructure();
43 #endif // CTS_USES_VULKANSC
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_coreProperties2.pNext;
49 		std::vector<PropertyStructWrapperBase*>		propertiesToFillFromBlob;
50 		std::vector<PropertyStructWrapperBase*>		propertiesAddedWithVK;
51 		bool										vk11Supported				= (apiVersion >= VK_MAKE_API_VERSION(0, 1, 1, 0));
52 		bool										vk12Supported				= (apiVersion >= VK_MAKE_API_VERSION(0, 1, 2, 0));
53 #ifndef CTS_USES_VULKANSC
54 		bool										vk13Supported				= (apiVersion >= VK_MAKE_API_VERSION(0, 1, 3, 0));
55 #endif // CTS_USES_VULKANSC
56 #ifdef CTS_USES_VULKANSC
57 		bool										vksc10Supported				= (apiVersion >= VK_MAKE_API_VERSION(1, 1, 0, 0));
58 #endif // CTS_USES_VULKANSC
59 
60 		// there are 3 properies structures that were added with vk11 (without being first part of extension)
61 		if (vk11Supported)
62 		{
63 			propertiesAddedWithVK =
64 			{
65 				createPropertyStructWrapper<VkPhysicalDeviceSubgroupProperties>(),
66 				createPropertyStructWrapper<VkPhysicalDeviceIDProperties>(),
67 				createPropertyStructWrapper<VkPhysicalDeviceProtectedMemoryProperties>()
68 			};
69 
70 			for (auto pAddedWithVK : propertiesAddedWithVK)
71 			{
72 				m_properties.push_back(pAddedWithVK);
73 
74 				if (!vk12Supported)
75 					addToChainStructWrapper(&nextPtr, pAddedWithVK);
76 			}
77 		}
78 
79 		// since vk12 we have blob structures combining properties of couple previously
80 		// available property structures, that now in vk12 and above must be removed from chain
81 		if (vk12Supported)
82 		{
83 			addToChainVulkanStructure(&nextPtr, m_vulkan11Properties);
84 			addToChainVulkanStructure(&nextPtr, m_vulkan12Properties);
85 
86 #ifndef CTS_USES_VULKANSC
87 			if (vk13Supported)
88 				addToChainVulkanStructure(&nextPtr, m_vulkan13Properties);
89 #endif // CTS_USES_VULKANSC
90 		}
91 
92 		std::vector<std::string> allDeviceExtensions = deviceExtensions;
93 #ifdef CTS_USES_VULKANSC
94 		// VulkanSC: add missing core extensions to the list
95 		std::vector<const char*> coreExtensions;
96 		getCoreDeviceExtensions(apiVersion, coreExtensions);
97 		for (const auto& coreExt : coreExtensions)
98 			if (!de::contains(allDeviceExtensions.begin(), allDeviceExtensions.end(), std::string(coreExt)))
99 				allDeviceExtensions.push_back(coreExt);
100 		if (vksc10Supported)
101 			addToChainVulkanStructure(&nextPtr, m_vulkanSC10Properties);
102 #endif // CTS_USES_VULKANSC
103 
104 		// iterate over data for all property that are defined in specification
105 		for (const auto& propertyStructCreationData : propertyStructCreationArray)
106 		{
107 			const char* propertyName = propertyStructCreationData.name;
108 
109 			// check if this property is available on current device.
110 			if (de::contains(allDeviceExtensions.begin(), allDeviceExtensions.end(), propertyName) ||
111 				std::string(propertyName) == "core_property")
112 			{
113 				PropertyStructWrapperBase* p = (*propertyStructCreationData.creatorFunction)();
114 				if (p == DE_NULL)
115 					continue;
116 
117 #ifdef CTS_USES_VULKANSC
118 				// m_vulkanSC10Properties was already added above
119 				if (p->getPropertyDesc().sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_SC_1_0_PROPERTIES)
120 					continue;
121 #endif // CTS_USES_VULKANSC
122 
123 				// if property struct is part of VkPhysicalDeviceVulkan1{1,2}Properties
124 				// we dont add it to the chain but store and fill later from blob data
125 				bool propertyFilledFromBlob = false;
126 				if (vk12Supported)
127 				{
128 					deUint32 blobApiVersion = getBlobPropertiesVersion(p->getPropertyDesc().sType);
129 					if (blobApiVersion)
130 						propertyFilledFromBlob = (apiVersion >= blobApiVersion);
131 				}
132 
133 				if (propertyFilledFromBlob)
134 					propertiesToFillFromBlob.push_back(p);
135 				else
136 				{
137 					// add to chain
138 					addToChainStructWrapper(&nextPtr, p);
139 				}
140 				m_properties.push_back(p);
141 			}
142 		}
143 
144 		vki.getPhysicalDeviceProperties2(physicalDevice, &m_coreProperties2);
145 
146 		// fill data from VkPhysicalDeviceVulkan1{1,2,3}Properties
147 		if (vk12Supported)
148 		{
149 			AllPropertiesBlobs allBlobs =
150 			{
151 				m_vulkan11Properties,
152 				m_vulkan12Properties,
153 #ifndef CTS_USES_VULKANSC
154 				m_vulkan13Properties,
155 #endif // CTS_USES_VULKANSC
156 				// add blobs from future vulkan versions here
157 			};
158 
159 			// three properties that were added with vk11 in vk12 were merged to VkPhysicalDeviceVulkan11Properties
160 			propertiesToFillFromBlob.insert(propertiesToFillFromBlob.end(), propertiesAddedWithVK.begin(), propertiesAddedWithVK.end());
161 
162 			for (auto property : propertiesToFillFromBlob)
163 				property->initializePropertyFromBlob(allBlobs);
164 		}
165 	}
166 	else
167 		m_coreProperties2.properties = getPhysicalDeviceProperties(vki, physicalDevice);
168 }
169 
addToChainStructWrapper(void *** chainPNextPtr,PropertyStructWrapperBase * structWrapper)170 void DeviceProperties::addToChainStructWrapper(void*** chainPNextPtr, PropertyStructWrapperBase* structWrapper)
171 {
172 	DE_ASSERT(chainPNextPtr != DE_NULL);
173 
174 	(**chainPNextPtr) = structWrapper->getPropertyTypeRaw();
175 	(*chainPNextPtr) = structWrapper->getPropertyTypeNext();
176 }
177 
contains(const std::string & property,bool throwIfNotExists) const178 bool DeviceProperties::contains (const std::string& property, bool throwIfNotExists) const
179 {
180 	for (const auto f : m_properties)
181 	{
182 		if (deStringEqual(f->getPropertyDesc().name, property.c_str()))
183 			return true;
184 	}
185 
186 	if (throwIfNotExists)
187 		TCU_THROW(NotSupportedError, "Property " + property + " is not supported");
188 
189 	return false;
190 }
191 
isDevicePropertyInitialized(VkStructureType sType) const192 bool DeviceProperties::isDevicePropertyInitialized (VkStructureType sType) const
193 {
194 	for (const auto f : m_properties)
195 	{
196 		if (f->getPropertyDesc().sType == sType)
197 			return true;
198 	}
199 	return false;
200 }
201 
~DeviceProperties(void)202 DeviceProperties::~DeviceProperties (void)
203 {
204 	for (auto p : m_properties)
205 		delete p;
206 
207 	m_properties.clear();
208 }
209 
210 } // vk
211 
212