• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef _VKQUERYUTIL_HPP
2 #define _VKQUERYUTIL_HPP
3 /*-------------------------------------------------------------------------
4  * Vulkan CTS Framework
5  * --------------------
6  *
7  * Copyright (c) 2015 Google Inc.
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  *//*!
22  * \file
23  * \brief Vulkan query utilities.
24  *//*--------------------------------------------------------------------*/
25 
26 #include "vkDefs.hpp"
27 #include "tcuMaybe.hpp"
28 #include "deMemory.h"
29 
30 #include <vector>
31 #include <string>
32 
33 namespace vk
34 {
35 
36 // API version introspection
37 
38 void											getCoreInstanceExtensions						(deUint32 apiVersion, std::vector<const char*>& dst);
39 void											getCoreDeviceExtensions							(deUint32 apiVersion, std::vector<const char*>& dst);
40 bool											isCoreInstanceExtension							(const deUint32 apiVersion, const std::string& extension);
41 bool											isCoreDeviceExtension							(const deUint32 apiVersion, const std::string& extension);
42 
43 // API queries
44 
45 std::vector<VkPhysicalDevice>					enumeratePhysicalDevices						(const InstanceInterface& vk, VkInstance instance);
46 std::vector<VkPhysicalDeviceGroupProperties>	enumeratePhysicalDeviceGroups					(const InstanceInterface& vk, VkInstance instance);
47 std::vector<VkQueueFamilyProperties>			getPhysicalDeviceQueueFamilyProperties			(const InstanceInterface& vk, VkPhysicalDevice physicalDevice);
48 VkPhysicalDeviceFeatures						getPhysicalDeviceFeatures						(const InstanceInterface& vk, VkPhysicalDevice physicalDevice);
49 VkPhysicalDeviceFeatures2						getPhysicalDeviceFeatures2						(const InstanceInterface& vk, VkPhysicalDevice physicalDevice);
50 VkPhysicalDeviceVulkan12Features				getPhysicalDeviceVulkan12Features				(const InstanceInterface& vk, VkPhysicalDevice physicalDevice);
51 VkPhysicalDeviceVulkan11Properties				getPhysicalDeviceVulkan11Properties				(const InstanceInterface& vk, VkPhysicalDevice physicalDevice);
52 VkPhysicalDeviceVulkan12Properties				getPhysicalDeviceVulkan12Properties				(const InstanceInterface& vk, VkPhysicalDevice physicalDevice);
53 VkPhysicalDeviceProperties						getPhysicalDeviceProperties						(const InstanceInterface& vk, VkPhysicalDevice physicalDevice);
54 VkPhysicalDeviceMemoryProperties				getPhysicalDeviceMemoryProperties				(const InstanceInterface& vk, VkPhysicalDevice physicalDevice);
55 VkFormatProperties								getPhysicalDeviceFormatProperties				(const InstanceInterface& vk, VkPhysicalDevice physicalDevice, VkFormat format);
56 VkImageFormatProperties							getPhysicalDeviceImageFormatProperties			(const InstanceInterface& vk, VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkImageTiling tiling, VkImageUsageFlags usage, VkImageCreateFlags flags);
57 std::vector<VkSparseImageFormatProperties>		getPhysicalDeviceSparseImageFormatProperties	(const InstanceInterface& vk, VkPhysicalDevice physicalDevice, VkFormat format, VkImageType type, VkSampleCountFlagBits samples, VkImageUsageFlags usage, VkImageTiling tiling);
58 
59 VkMemoryRequirements							getBufferMemoryRequirements						(const DeviceInterface& vk, VkDevice device, VkBuffer buffer);
60 VkMemoryRequirements							getImageMemoryRequirements						(const DeviceInterface& vk, VkDevice device, VkImage image);
61 VkMemoryRequirements							getImagePlaneMemoryRequirements					(const DeviceInterface& vk, VkDevice device, VkImage image, VkImageAspectFlagBits planeAspect);
62 std::vector<VkSparseImageMemoryRequirements>	getImageSparseMemoryRequirements				(const DeviceInterface& vk, VkDevice device, VkImage image);
63 
64 std::vector<VkLayerProperties>					enumerateInstanceLayerProperties				(const PlatformInterface& vkp);
65 std::vector<VkExtensionProperties>				enumerateInstanceExtensionProperties			(const PlatformInterface& vkp, const char* layerName);
66 std::vector<VkLayerProperties>					enumerateDeviceLayerProperties					(const InstanceInterface& vki, VkPhysicalDevice physicalDevice);
67 std::vector<VkExtensionProperties>				enumerateDeviceExtensionProperties				(const InstanceInterface& vki, VkPhysicalDevice physicalDevice, const char* layerName);
68 
69 VkQueue											getDeviceQueue									(const DeviceInterface& vkd, VkDevice device, deUint32 queueFamilyIndex, deUint32 queueIndex);
70 VkQueue											getDeviceQueue2									(const DeviceInterface& vkd, VkDevice device, const VkDeviceQueueInfo2 *queueInfo);
71 
72 // Feature / extension support
73 
74 bool											isShaderStageSupported							(const VkPhysicalDeviceFeatures& deviceFeatures, VkShaderStageFlagBits stage);
75 
76 struct RequiredExtension
77 {
78 	std::string				name;
79 	tcu::Maybe<deUint32>	minVersion;
80 	tcu::Maybe<deUint32>	maxVersion;
81 
RequiredExtensionvk::RequiredExtension82 	explicit RequiredExtension (const std::string&		name_,
83 								tcu::Maybe<deUint32>	minVersion_ = tcu::nothing<deUint32>(),
84 								tcu::Maybe<deUint32>	maxVersion_ = tcu::nothing<deUint32>())
85 		: name			(name_)
86 		, minVersion	(minVersion_)
87 		, maxVersion	(maxVersion_)
88 	{}
89 };
90 
91 struct RequiredLayer
92 {
93 	std::string				name;
94 	tcu::Maybe<deUint32>	minSpecVersion;
95 	tcu::Maybe<deUint32>	maxSpecVersion;
96 	tcu::Maybe<deUint32>	minImplVersion;
97 	tcu::Maybe<deUint32>	maxImplVersion;
98 
RequiredLayervk::RequiredLayer99 	explicit RequiredLayer (const std::string&			name_,
100 							tcu::Maybe<deUint32>		minSpecVersion_		= tcu::nothing<deUint32>(),
101 							tcu::Maybe<deUint32>		maxSpecVersion_		= tcu::nothing<deUint32>(),
102 							tcu::Maybe<deUint32>		minImplVersion_		= tcu::nothing<deUint32>(),
103 							tcu::Maybe<deUint32>		maxImplVersion_		= tcu::nothing<deUint32>())
104 		: name			(name_)
105 		, minSpecVersion(minSpecVersion_)
106 		, maxSpecVersion(maxSpecVersion_)
107 		, minImplVersion(minImplVersion_)
108 		, maxImplVersion(maxImplVersion_)
109 	{}
110 };
111 
112 bool										isCompatible							(const VkExtensionProperties& extensionProperties, const RequiredExtension& required);
113 bool										isCompatible							(const VkLayerProperties& layerProperties, const RequiredLayer& required);
114 
115 template<typename ExtensionIterator>
116 bool										isExtensionSupported					(ExtensionIterator begin, ExtensionIterator end, const RequiredExtension& required);
117 bool										isExtensionSupported					(const std::vector<VkExtensionProperties>& extensions, const RequiredExtension& required);
118 
119 bool										isInstanceExtensionSupported			(const deUint32 instanceVersion, const std::vector<std::string>& extensions, const std::string& required);
120 
121 template<typename LayerIterator>
122 bool										isLayerSupported						(LayerIterator begin, LayerIterator end, const RequiredLayer& required);
123 bool										isLayerSupported						(const std::vector<VkLayerProperties>& layers, const RequiredLayer& required);
124 
125 const void*									findStructureInChain					(const void* first, VkStructureType type);
126 void*										findStructureInChain					(void* first, VkStructureType type);
127 
128 template<typename StructType>
129 VkStructureType								getStructureType						(void);
130 
131 template<typename StructType>
findStructure(const void * first)132 const StructType*							findStructure							(const void* first)
133 {
134 	return reinterpret_cast<const StructType*>(findStructureInChain(first, getStructureType<StructType>()));
135 }
136 
137 template<typename StructType>
findStructure(void * first)138 StructType*									findStructure							(void* first)
139 {
140 	return reinterpret_cast<StructType*>(findStructureInChain(first, getStructureType<StructType>()));
141 }
142 
143 struct initVulkanStructure
144 {
initVulkanStructurevk::initVulkanStructure145 	initVulkanStructure	(void*	pNext = DE_NULL)	: m_next(pNext)	{};
146 
147 	template<class StructType>
operator StructTypevk::initVulkanStructure148 	operator StructType()
149 	{
150 		StructType result;
151 
152 		deMemset(&result, 0x00, sizeof(StructType));
153 
154 		result.sType	= getStructureType<StructType>();
155 		result.pNext	= m_next;
156 
157 		return result;
158 	}
159 
160 private:
161 	void*	m_next;
162 };
163 
164 template<class StructType>
addToChainVulkanStructure(void *** chainPNextPtr,StructType & structType)165 void addToChainVulkanStructure (void***	chainPNextPtr, StructType&	structType)
166 {
167 	DE_ASSERT(chainPNextPtr != DE_NULL);
168 
169 	(**chainPNextPtr) = &structType;
170 
171 	(*chainPNextPtr) = &structType.pNext;
172 }
173 
174 struct initVulkanStructureConst
175 {
initVulkanStructureConstvk::initVulkanStructureConst176 	initVulkanStructureConst	(const void*	pNext = DE_NULL)	: m_next(pNext)	{};
177 
178 	template<class StructType>
operator const StructTypevk::initVulkanStructureConst179 	operator const StructType()
180 	{
181 		StructType result;
182 
183 		deMemset(&result, 0x00, sizeof(StructType));
184 
185 		result.sType	= getStructureType<StructType>();
186 		result.pNext	= const_cast<void*>(m_next);
187 
188 		return result;
189 	}
190 
191 private:
192 	const void*	m_next;
193 };
194 
195 struct getPhysicalDeviceExtensionProperties
196 {
getPhysicalDeviceExtensionPropertiesvk::getPhysicalDeviceExtensionProperties197 	getPhysicalDeviceExtensionProperties (const InstanceInterface&	vki, VkPhysicalDevice physicalDevice) : m_vki(vki), m_physicalDevice(physicalDevice) {};
198 
199 	template<class ExtensionProperties>
operator ExtensionPropertiesvk::getPhysicalDeviceExtensionProperties200 	operator ExtensionProperties ()
201 	{
202 		VkPhysicalDeviceProperties2	properties2;
203 		ExtensionProperties			extensionProperties;
204 
205 		deMemset(&extensionProperties, 0x00, sizeof(ExtensionProperties));
206 		extensionProperties.sType = getStructureType<ExtensionProperties>();
207 
208 		deMemset(&properties2, 0x00, sizeof(properties2));
209 		properties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
210 		properties2.pNext = &extensionProperties;
211 
212 		m_vki.getPhysicalDeviceProperties2(m_physicalDevice, &properties2);
213 
214 		return extensionProperties;
215 	}
216 
operator VkPhysicalDeviceProperties2vk::getPhysicalDeviceExtensionProperties217 	operator VkPhysicalDeviceProperties2 ()
218 	{
219 		VkPhysicalDeviceProperties2	properties2;
220 
221 		deMemset(&properties2, 0x00, sizeof(properties2));
222 		properties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
223 
224 		m_vki.getPhysicalDeviceProperties2(m_physicalDevice, &properties2);
225 
226 		return properties2;
227 	}
228 
229 private:
230 	const InstanceInterface&	m_vki;
231 	const VkPhysicalDevice		m_physicalDevice;
232 };
233 
234 namespace ValidateQueryBits
235 {
236 
237 typedef struct
238 {
239 	size_t		offset;
240 	size_t		size;
241 } QueryMemberTableEntry;
242 
243 template <typename Context, typename Interface, typename Type>
244 //!< Return variable initialization validation
validateInitComplete(Context context,void (Interface::* Function)(Context,Type *)const,const Interface & interface,const QueryMemberTableEntry * queryMemberTableEntry)245 bool validateInitComplete(Context context, void (Interface::*Function)(Context, Type*)const, const Interface& interface, const QueryMemberTableEntry* queryMemberTableEntry)
246 {
247 	const QueryMemberTableEntry	*iterator;
248 	Type vec[2];
249 	deMemset(&vec[0], 0x00, sizeof(Type));
250 	deMemset(&vec[1], 0xFF, sizeof(Type));
251 
252 	(interface.*Function)(context, &vec[0]);
253 	(interface.*Function)(context, &vec[1]);
254 
255 	for (iterator = queryMemberTableEntry; iterator->size != 0; iterator++)
256 	{
257 		if (deMemCmp(((deUint8*)(&vec[0]))+iterator->offset, ((deUint8*)(&vec[1]))+iterator->offset, iterator->size) != 0)
258 			return false;
259 	}
260 
261 	return true;
262 }
263 
264 template <typename Type>
265 //!< Return variable initialization validation
validateStructsWithGuard(const QueryMemberTableEntry * queryMemberTableEntry,Type * vec[2],const deUint8 guardValue,const deUint32 guardSize)266 bool validateStructsWithGuard (const QueryMemberTableEntry* queryMemberTableEntry, Type* vec[2], const deUint8 guardValue, const deUint32 guardSize)
267 {
268 	const QueryMemberTableEntry	*iterator;
269 
270 	for (iterator = queryMemberTableEntry; iterator->size != 0; iterator++)
271 	{
272 		if (deMemCmp(((deUint8*)(vec[0]))+iterator->offset, ((deUint8*)(vec[1]))+iterator->offset, iterator->size) != 0)
273 			return false;
274 	}
275 
276 	for (deUint32 vecNdx = 0; vecNdx < 2; ++vecNdx)
277 	{
278 		for (deUint32 ndx = 0; ndx < guardSize; ndx++)
279 		{
280 			if (((deUint8*)(vec[vecNdx]))[ndx + sizeof(Type)] != guardValue)
281 				return false;
282 		}
283 	}
284 
285 	return true;
286 }
287 
288 template<typename IterT>
289 //! Overwrite a range of objects with an 8-bit pattern.
fillBits(IterT beg,const IterT end,const deUint8 pattern=0xdeu)290 inline void fillBits (IterT beg, const IterT end, const deUint8 pattern = 0xdeu)
291 {
292 	for (; beg < end; ++beg)
293 		deMemset(&(*beg), static_cast<int>(pattern), sizeof(*beg));
294 }
295 
296 template<typename IterT>
297 //! Verify that each byte of a range of objects is equal to an 8-bit pattern.
checkBits(IterT beg,const IterT end,const deUint8 pattern=0xdeu)298 bool checkBits (IterT beg, const IterT end, const deUint8 pattern = 0xdeu)
299 {
300 	for (; beg < end; ++beg)
301 	{
302 		const deUint8* elementBytes = reinterpret_cast<const deUint8*>(&(*beg));
303 		for (std::size_t i = 0u; i < sizeof(*beg); ++i)
304 		{
305 			if (elementBytes[i] != pattern)
306 				return false;
307 		}
308 	}
309 	return true;
310 }
311 
312 } // ValidateQueryBits
313 
314 // Template implementations
315 
316 template<typename ExtensionIterator>
isExtensionSupported(ExtensionIterator begin,ExtensionIterator end,const RequiredExtension & required)317 bool isExtensionSupported (ExtensionIterator begin, ExtensionIterator end, const RequiredExtension& required)
318 {
319 	for (ExtensionIterator cur = begin; cur != end; ++cur)
320 	{
321 		if (isCompatible(*cur, required))
322 			return true;
323 	}
324 	return false;
325 }
326 
327 template<typename LayerIterator>
isLayerSupported(LayerIterator begin,LayerIterator end,const RequiredLayer & required)328 bool isLayerSupported (LayerIterator begin, LayerIterator end, const RequiredLayer& required)
329 {
330 	for (LayerIterator cur = begin; cur != end; ++cur)
331 	{
332 		if (isCompatible(*cur, required))
333 			return true;
334 	}
335 	return false;
336 }
337 
338 } // vk
339 
340 #endif // _VKQUERYUTIL_HPP
341