• 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 	m_vulkan13Properties	= initVulkanStructure();
39 
40 	if (isInstanceExtensionSupported(apiVersion, instanceExtensions, "VK_KHR_get_physical_device_properties2"))
41 	{
42 		const std::vector<VkExtensionProperties>	deviceExtensionProperties	= enumerateDeviceExtensionProperties(vki, physicalDevice, DE_NULL);
43 		void**										nextPtr						= &m_coreProperties2.pNext;
44 		std::vector<PropertyStructWrapperBase*>		propertiesToFillFromBlob;
45 		std::vector<PropertyStructWrapperBase*>		propertiesAddedWithVK;
46 		bool										vk11Supported				= (apiVersion >= VK_API_VERSION_1_1);
47 		bool										vk12Supported				= (apiVersion >= VK_API_VERSION_1_2);
48 		bool										vk13Supported				= (apiVersion >= VK_API_VERSION_1_3);
49 
50 		// there are 3 properies structures that were added with vk11 (without being first part of extension)
51 		if (vk11Supported)
52 		{
53 			propertiesAddedWithVK =
54 			{
55 				createPropertyStructWrapper<VkPhysicalDeviceSubgroupProperties>(),
56 				createPropertyStructWrapper<VkPhysicalDeviceIDProperties>(),
57 				createPropertyStructWrapper<VkPhysicalDeviceProtectedMemoryProperties>()
58 			};
59 
60 			for (auto pAddedWithVK : propertiesAddedWithVK)
61 			{
62 				m_properties.push_back(pAddedWithVK);
63 
64 				if (!vk12Supported)
65 					addToChainStructWrapper(&nextPtr, pAddedWithVK);
66 			}
67 		}
68 
69 		// since vk12 we have blob structures combining properties of couple previously
70 		// available property structures, that now in vk12 and above must be removed from chain
71 		if (vk12Supported)
72 		{
73 			addToChainVulkanStructure(&nextPtr, m_vulkan11Properties);
74 			addToChainVulkanStructure(&nextPtr, m_vulkan12Properties);
75 
76 			if (vk13Supported)
77 				addToChainVulkanStructure(&nextPtr, m_vulkan13Properties);
78 		}
79 
80 		// iterate over data for all property that are defined in specification
81 		for (const auto& propertyStructCreationData : propertyStructCreationArray)
82 		{
83 			const char* propertyName = propertyStructCreationData.name;
84 
85 			// check if this property is available on current device
86 			if (de::contains(deviceExtensions.begin(), deviceExtensions.end(), propertyName))
87 			{
88 				PropertyStructWrapperBase* p = (*propertyStructCreationData.creatorFunction)();
89 				if (p == DE_NULL)
90 					continue;
91 
92 				// if property struct is part of VkPhysicalDeviceVulkan1{1,2}Properties
93 				// we dont add it to the chain but store and fill later from blob data
94 				bool propertyFilledFromBlob = false;
95 				if (vk12Supported)
96 				{
97 					deUint32 blobApiVersion = getBlobPropertiesVersion(p->getPropertyDesc().sType);
98 					if (blobApiVersion)
99 						propertyFilledFromBlob = (apiVersion >= blobApiVersion);
100 				}
101 
102 				if (propertyFilledFromBlob)
103 					propertiesToFillFromBlob.push_back(p);
104 				else
105 				{
106 					// add to chain
107 					addToChainStructWrapper(&nextPtr, p);
108 				}
109 				m_properties.push_back(p);
110 			}
111 		}
112 
113 		vki.getPhysicalDeviceProperties2(physicalDevice, &m_coreProperties2);
114 
115 		// fill data from VkPhysicalDeviceVulkan1{1,2,3}Properties
116 		if (vk12Supported)
117 		{
118 			AllPropertiesBlobs allBlobs =
119 			{
120 				m_vulkan11Properties,
121 				m_vulkan12Properties,
122 				m_vulkan13Properties,
123 				// add blobs from future vulkan versions here
124 			};
125 
126 			// three properties that were added with vk11 in vk12 were merged to VkPhysicalDeviceVulkan11Properties
127 			propertiesToFillFromBlob.insert(propertiesToFillFromBlob.end(), propertiesAddedWithVK.begin(), propertiesAddedWithVK.end());
128 
129 			for (auto property : propertiesToFillFromBlob)
130 				property->initializePropertyFromBlob(allBlobs);
131 		}
132 	}
133 	else
134 		m_coreProperties2.properties = getPhysicalDeviceProperties(vki, physicalDevice);
135 }
136 
addToChainStructWrapper(void *** chainPNextPtr,PropertyStructWrapperBase * structWrapper)137 void DeviceProperties::addToChainStructWrapper(void*** chainPNextPtr, PropertyStructWrapperBase* structWrapper)
138 {
139 	DE_ASSERT(chainPNextPtr != DE_NULL);
140 
141 	(**chainPNextPtr) = structWrapper->getPropertyTypeRaw();
142 	(*chainPNextPtr) = structWrapper->getPropertyTypeNext();
143 }
144 
contains(const std::string & property,bool throwIfNotExists) const145 bool DeviceProperties::contains (const std::string& property, bool throwIfNotExists) const
146 {
147 	for (const auto f : m_properties)
148 	{
149 		if (deStringEqual(f->getPropertyDesc().name, property.c_str()))
150 			return true;
151 	}
152 
153 	if (throwIfNotExists)
154 		TCU_THROW(NotSupportedError, "Property " + property + " is not supported");
155 
156 	return false;
157 }
158 
isDevicePropertyInitialized(VkStructureType sType) const159 bool DeviceProperties::isDevicePropertyInitialized (VkStructureType sType) const
160 {
161 	for (const auto f : m_properties)
162 	{
163 		if (f->getPropertyDesc().sType == sType)
164 			return true;
165 	}
166 	return false;
167 }
168 
~DeviceProperties(void)169 DeviceProperties::~DeviceProperties (void)
170 {
171 	for (auto p : m_properties)
172 		delete p;
173 
174 	m_properties.clear();
175 }
176 
177 } // vk
178 
179