• 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 			{
112 				PropertyStructWrapperBase* p = (*propertyStructCreationData.creatorFunction)();
113 				if (p == DE_NULL)
114 					continue;
115 
116 				// if property struct is part of VkPhysicalDeviceVulkan1{1,2}Properties
117 				// we dont add it to the chain but store and fill later from blob data
118 				bool propertyFilledFromBlob = false;
119 				if (vk12Supported)
120 				{
121 					deUint32 blobApiVersion = getBlobPropertiesVersion(p->getPropertyDesc().sType);
122 					if (blobApiVersion)
123 						propertyFilledFromBlob = (apiVersion >= blobApiVersion);
124 				}
125 
126 				if (propertyFilledFromBlob)
127 					propertiesToFillFromBlob.push_back(p);
128 				else
129 				{
130 					// add to chain
131 					addToChainStructWrapper(&nextPtr, p);
132 				}
133 				m_properties.push_back(p);
134 			}
135 		}
136 
137 		vki.getPhysicalDeviceProperties2(physicalDevice, &m_coreProperties2);
138 
139 		// fill data from VkPhysicalDeviceVulkan1{1,2,3}Properties
140 		if (vk12Supported)
141 		{
142 			AllPropertiesBlobs allBlobs =
143 			{
144 				m_vulkan11Properties,
145 				m_vulkan12Properties,
146 #ifndef CTS_USES_VULKANSC
147 				m_vulkan13Properties,
148 #endif // CTS_USES_VULKANSC
149 				// add blobs from future vulkan versions here
150 			};
151 
152 			// three properties that were added with vk11 in vk12 were merged to VkPhysicalDeviceVulkan11Properties
153 			propertiesToFillFromBlob.insert(propertiesToFillFromBlob.end(), propertiesAddedWithVK.begin(), propertiesAddedWithVK.end());
154 
155 			for (auto property : propertiesToFillFromBlob)
156 				property->initializePropertyFromBlob(allBlobs);
157 		}
158 	}
159 	else
160 		m_coreProperties2.properties = getPhysicalDeviceProperties(vki, physicalDevice);
161 }
162 
addToChainStructWrapper(void *** chainPNextPtr,PropertyStructWrapperBase * structWrapper)163 void DeviceProperties::addToChainStructWrapper(void*** chainPNextPtr, PropertyStructWrapperBase* structWrapper)
164 {
165 	DE_ASSERT(chainPNextPtr != DE_NULL);
166 
167 	(**chainPNextPtr) = structWrapper->getPropertyTypeRaw();
168 	(*chainPNextPtr) = structWrapper->getPropertyTypeNext();
169 }
170 
contains(const std::string & property,bool throwIfNotExists) const171 bool DeviceProperties::contains (const std::string& property, bool throwIfNotExists) const
172 {
173 	for (const auto f : m_properties)
174 	{
175 		if (deStringEqual(f->getPropertyDesc().name, property.c_str()))
176 			return true;
177 	}
178 
179 	if (throwIfNotExists)
180 		TCU_THROW(NotSupportedError, "Property " + property + " is not supported");
181 
182 	return false;
183 }
184 
isDevicePropertyInitialized(VkStructureType sType) const185 bool DeviceProperties::isDevicePropertyInitialized (VkStructureType sType) const
186 {
187 	for (const auto f : m_properties)
188 	{
189 		if (f->getPropertyDesc().sType == sType)
190 			return true;
191 	}
192 	return false;
193 }
194 
~DeviceProperties(void)195 DeviceProperties::~DeviceProperties (void)
196 {
197 	for (auto p : m_properties)
198 		delete p;
199 
200 	m_properties.clear();
201 }
202 
203 } // vk
204 
205