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